Merge changes I87205d59,I91332da9 into wlan-cld3.driver.lnx.2.0-dev
* changes:
qcacld-3.0: fix a potential spinlock lockup issue
qcacld-3.0: add device attribute 'tsf'
diff --git a/Kbuild b/Kbuild
index 6f7a83d..d439762 100644
--- a/Kbuild
+++ b/Kbuild
@@ -178,15 +178,11 @@
CONFIG_WLAN_FASTPATH := y
# Flag to enable NAPI
-ifeq (y,$(CONFIG_LITHIUM))
- CONFIG_WLAN_NAPI := n
- CONFIG_WLAN_NAPI_DEBUG := n
-else
CONFIG_WLAN_NAPI := y
CONFIG_WLAN_NAPI_DEBUG := n
-endif
+
# Flag to enable FW based TX Flow control
- ifeq ($(CONFIG_CNSS_EOS),y)
+ ifeq (y,$(findstring y,$(CONFIG_CNSS_EOS) $(CONFIG_LITHIUM)))
CONFIG_WLAN_TX_FLOW_CONTROL_V2 := y
else
CONFIG_WLAN_TX_FLOW_CONTROL_V2 := n
@@ -887,11 +883,11 @@
$(UMAC_MGMT_TXRX_DIR)/dispatcher/src/wlan_mgmt_txrx_tgt_api.o
########## POWER MANAGEMENT OFFLOADS (PMO) ##########
-PMO_DIR := $(WLAN_COMMON_ROOT)/pmo
-PMO_INC := -I$(WLAN_COMMON_INC)/pmo/core/inc \
- -I$(WLAN_COMMON_INC)/pmo/dispatcher/inc \
- -I$(WLAN_COMMON_INC)/pmo/core/src \
- -I$(WLAN_COMMON_INC)/pmo/dispatcher/src
+PMO_DIR := components/pmo
+PMO_INC := -I$(WLAN_ROOT)/$(PMO_DIR)/core/inc \
+ -I$(WLAN_ROOT)/$(PMO_DIR)/core/src \
+ -I$(WLAN_ROOT)/$(PMO_DIR)/dispatcher/inc \
+ -I$(WLAN_ROOT)/$(PMO_DIR)/dispatcher/src \
PMO_OBJS := $(PMO_DIR)/core/src/wlan_pmo_main.o \
$(PMO_DIR)/core/src/wlan_pmo_arp.o \
@@ -917,6 +913,24 @@
$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_hw_filter.o \
$(PMO_DIR)/dispatcher/src/wlan_pmo_tgt_pkt_filter.o
+########## CLD TARGET_IF #######
+CLD_TARGET_IF_DIR := components/target_if
+
+CLD_TARGET_IF_INC := -I$(WLAN_ROOT)/$(CLD_TARGET_IF_DIR)/pmo/inc \
+ -I$(WLAN_ROOT)/$(CLD_TARGET_IF_DIR)/pmo/src \
+
+CLD_TARGET_IF_OBJ := $(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_arp.o \
+ $(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_gtk.o \
+ $(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_hw_filter.o \
+ $(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_lphb.o \
+ $(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_main.o \
+ $(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_mc_addr_filtering.o \
+ $(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_ns.o \
+ $(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_pkt_filter.o \
+ $(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_static_config.o \
+ $(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_suspend_resume.o \
+ $(CLD_TARGET_IF_DIR)/pmo/src/target_if_pmo_wow.o \
+
############## UMAC P2P ###########
P2P_DIR := umac/p2p
P2P_CORE_DIR := $(P2P_DIR)/core
@@ -977,25 +991,12 @@
TARGET_IF_INC := -I$(WLAN_COMMON_INC)/target_if/core/inc \
-I$(WLAN_COMMON_INC)/target_if/core/src \
-I$(WLAN_COMMON_INC)/target_if/init_deinit/inc \
- -I$(WLAN_COMMON_INC)/target_if/pmo/inc \
- -I$(WLAN_COMMON_INC)/target_if/pmo/src \
-I$(WLAN_COMMON_INC)/target_if/p2p/inc \
-I$(WLAN_COMMON_INC)/target_if/regulatory/inc \
-I$(WLAN_COMMON_INC)/target_if/tdls/inc
TARGET_IF_OBJ := $(TARGET_IF_DIR)/core/src/target_if_main.o \
$(TARGET_IF_DIR)/init_deinit/src/service_ready_event_handler.o \
- $(TARGET_IF_DIR)/pmo/src/target_if_pmo_main.o \
- $(TARGET_IF_DIR)/pmo/src/target_if_pmo_arp.o \
- $(TARGET_IF_DIR)/pmo/src/target_if_pmo_ns.o \
- $(TARGET_IF_DIR)/pmo/src/target_if_pmo_gtk.o \
- $(TARGET_IF_DIR)/pmo/src/target_if_pmo_wow.o \
- $(TARGET_IF_DIR)/pmo/src/target_if_pmo_hw_filter.o \
- $(TARGET_IF_DIR)/pmo/src/target_if_pmo_mc_addr_filtering.o \
- $(TARGET_IF_DIR)/pmo/src/target_if_pmo_static_config.o \
- $(TARGET_IF_DIR)/pmo/src/target_if_pmo_lphb.o \
- $(TARGET_IF_DIR)/pmo/src/target_if_pmo_suspend_resume.o \
- $(TARGET_IF_DIR)/pmo/src/target_if_pmo_pkt_filter.o \
$(TARGET_IF_DIR)/p2p/src/target_if_p2p.o \
$(TARGET_IF_DIR)/regulatory/src/target_if_reg.o \
$(TARGET_IF_DIR)/tdls/src/target_if_tdls.o
@@ -1079,6 +1080,9 @@
$(DP_SRC)/dp_rx_mon_status.o \
$(DP_SRC)/dp_rx_defrag.o \
$(DP_SRC)/dp_stats.o
+ifeq ($(CONFIG_WLAN_TX_FLOW_CONTROL_V2), y)
+DP_OBJS += $(DP_SRC)/dp_tx_flow_control.o
+endif
endif
############ CFG ############
@@ -1256,7 +1260,9 @@
HIF_COMMON_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/ath_procfs.o \
$(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/hif_main.o \
- $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/mp_dev.o
+ $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/mp_dev.o \
+ $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/hif_exec.o \
+ $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/hif_irq_affinity.o
HIF_CE_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_bmi.o \
$(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_diag.o \
@@ -1270,6 +1276,7 @@
$(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_service_srng.o
endif
+
HIF_USB_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_USB_DIR)/usbdrv.o \
$(WLAN_COMMON_ROOT)/$(HIF_USB_DIR)/hif_usb.o \
$(WLAN_COMMON_ROOT)/$(HIF_USB_DIR)/if_usb.o \
@@ -1416,6 +1423,7 @@
$(CDS_INC) \
$(DFS_INC) \
$(TARGET_IF_INC) \
+ $(CLD_TARGET_IF_INC) \
$(OS_IF_INC) \
$(GLOBAL_LMAC_IF_INC)
@@ -1508,6 +1516,7 @@
$(HTT_OBJS) \
$(OS_IF_OBJ) \
$(TARGET_IF_OBJ) \
+ $(CLD_TARGET_IF_OBJ) \
$(GLOBAL_LMAC_IF_OBJ)
ifeq ($(CONFIG_LITHIUM), y)
@@ -1647,6 +1656,7 @@
ifeq ($(CONFIG_WLAN_NAPI), y)
CDEFINES += -DFEATURE_NAPI
+CDEFINES += -DHIF_IRQ_AFFINITY
ifeq ($(CONFIG_WLAN_NAPI_DEBUG), y)
CDEFINES += -DFEATURE_NAPI_DEBUG
endif
diff --git a/Kconfig b/Kconfig
index 6536ec7..f8feafc 100644
--- a/Kconfig
+++ b/Kconfig
@@ -105,7 +105,7 @@
config WLAN_LRO
bool "Enable Large Receive Offload"
depends on HELIUMPLUS
- depends on CONFIG_INET_LRO
+ depends on INET_LRO
default n
config WLAN_SYNC_TSF
diff --git a/components/pmo/core/inc/wlan_pmo_arp.h b/components/pmo/core/inc/wlan_pmo_arp.h
new file mode 100644
index 0000000..8d97eec
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_arp.h
@@ -0,0 +1,71 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Declare arp offload feature API's
+ */
+
+#ifndef _WLAN_PMO_ARP_H_
+#define _WLAN_PMO_ARP_H_
+
+#include "wlan_pmo_arp_public_struct.h"
+
+/**
+ * pmo_core_cache_arp_offload_req() - API to cache arp req in pmo vdev priv ctx
+ * @arp_req: arp offload request
+ *
+ * API To cache ARP offload in pmo vdev priv ctx
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_core_cache_arp_offload_req(struct pmo_arp_req *arp_req);
+
+/**
+ * pmo_core_flush_arp_offload_req() - API to flush arp req from pmo vdev ctx
+ * @vdev: objmgr vdev
+ *
+ * API To flush saved ARP request from pmo vdev prov ctx
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_core_flush_arp_offload_req(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_core_enable_arp_offload_in_fwr() - API to enable arp offload in fwr
+ * @vdev: objmgr vdev
+ * @trigger: trigger reason
+ *
+ * API to enable arp offload in fwr from vdev priv ctx
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_core_enable_arp_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+ enum pmo_offload_trigger trigger);
+
+/**
+ * pmo_core_disable_arp_offload_in_fwr() - API to disable arp offload in fwr
+ * @vdev: objmgr vdev
+ * @trigger: trigger reason
+ *
+ * API to disable arp offload in fwr
+ *
+ * Return: QQDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_core_disable_arp_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+ enum pmo_offload_trigger trigger);
+
+#endif /* end of _WLAN_PMO_ARP_H_ */
diff --git a/components/pmo/core/inc/wlan_pmo_gtk.h b/components/pmo/core/inc/wlan_pmo_gtk.h
new file mode 100644
index 0000000..2a9d9f5
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_gtk.h
@@ -0,0 +1,74 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Declare gtk offload feature API's
+ */
+
+#ifndef _WLAN_PMO_GTK_H_
+#define _WLAN_PMO_GTK_H_
+
+#include "wlan_pmo_gtk_public_struct.h"
+
+/**
+ * pmo_core_cache_gtk_offload_req(): API to cache gtk req in pmo vdev priv obj
+ * @vdev: objmgr vdev handle
+ * @gtk_req: pmo gtk req param
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_core_cache_gtk_offload_req(struct wlan_objmgr_vdev *vdev,
+ struct pmo_gtk_req *gtk_req);
+
+/**
+ * pmo_core_flush_gtk_offload_req(): Flush saved gtk req from pmo vdev priv obj
+ * @vdev: objmgr vdev handle
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_core_flush_gtk_offload_req(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_core_enable_gtk_offload_in_fwr(): enable cached gtk request in fwr
+ * @vdev: objmgr vdev handle
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_core_enable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_core_disable_gtk_offload_in_fwr(): disable cached gtk request in fwr
+ * @vdev: objmgr vdev handle
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_core_disable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_core_get_gtk_rsp(): API to send gtk response request to fwr
+ * @vdev: objmgr vdev handle
+ * @gtk_rsp: pmo gtk response request
+ *
+ * This api will send gtk response request to fwr
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_core_get_gtk_rsp(struct wlan_objmgr_vdev *vdev,
+ struct pmo_gtk_rsp_req *gtk_rsp_req);
+
+#endif /* end of _WLAN_PMO_GTK_H_ */
+
diff --git a/components/pmo/core/inc/wlan_pmo_hw_filter.h b/components/pmo/core/inc/wlan_pmo_hw_filter.h
new file mode 100644
index 0000000..c3cab64
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_hw_filter.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: Declare hardware filter offload feature APIs
+ */
+
+#ifndef _WLAN_PMO_HW_FILTER_H_
+#define _WLAN_PMO_HW_FILTER_H_
+
+#include "qdf_status.h"
+#include "wlan_objmgr_vdev_obj.h"
+#include "wlan_pmo_hw_filter_public_struct.h"
+
+/**
+ * pmo_core_enable_hw_filter_in_fwr() - enable previously configured hw filter
+ * @vdev: objmgr vdev to configure
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS pmo_core_enable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_core_disable_hw_filter_in_fwr() - disable previously configured hw filter
+ * @vdev: objmgr vdev to configure
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS pmo_core_disable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev);
+
+#endif /* _WLAN_PMO_HW_FILTER_H_*/
diff --git a/components/pmo/core/inc/wlan_pmo_lphb.h b/components/pmo/core/inc/wlan_pmo_lphb.h
new file mode 100644
index 0000000..20b6952
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_lphb.h
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Declare low power heart beat offload feature API's
+ */
+
+#ifndef _WLAN_PMO_LPHB_H_
+#define _WLAN_PMO_LPHB_H_
+
+#include "wlan_pmo_lphb_public_struct.h"
+
+/**
+ * pmo_core_lphb_config_req() - API to configure lphb request
+ * @psoc: objmgr psoc handle
+ * @lphb_req: low power heart beat configuration request
+ * @lphb_cb_ctx: low power heart beat context
+ * @callback: osif callback which need to be called when host get lphb event
+ *
+ * API to configure lphb request
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_core_lphb_config_req(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_req *lphb_req, void *lphb_cb_ctx,
+ pmo_lphb_callback callback);
+
+/**
+ * pmo_core_apply_lphb(): apply cached LPHB settings
+ * @psoc: objmgr psoc handle
+ *
+ * LPHB cache, if any item was enabled, should be
+ * applied.
+ */
+void pmo_core_apply_lphb(struct wlan_objmgr_psoc *psoc);
+
+#endif /* end of _WLAN_PMO_LPHB_H_ */
diff --git a/components/pmo/core/inc/wlan_pmo_main.h b/components/pmo/core/inc/wlan_pmo_main.h
new file mode 100644
index 0000000..4f09597
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_main.h
@@ -0,0 +1,357 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: declare various api which shall be used by
+ * pmo user configuration and target interface
+ */
+
+#ifndef _WLAN_PMO_MAIN_H_
+#define _WLAN_PMO_MAIN_H_
+
+#include "wlan_pmo_common_public_struct.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include "wlan_pmo_priv.h"
+#include "wlan_pmo_objmgr.h"
+
+#define pmo_log(level, args...) QDF_TRACE(QDF_MODULE_ID_PMO, level, ## args)
+#define pmo_logfl(level, format, args...) pmo_log(level, FL(format), ## args)
+
+#define pmo_fatal(format, args...) \
+ pmo_logfl(QDF_TRACE_LEVEL_FATAL, format, ## args)
+#define pmo_err(format, args...) \
+ pmo_logfl(QDF_TRACE_LEVEL_ERROR, format, ## args)
+#define pmo_warn(format, args...) \
+ pmo_logfl(QDF_TRACE_LEVEL_WARN, format, ## args)
+#define pmo_info(format, args...) \
+ pmo_logfl(QDF_TRACE_LEVEL_INFO, format, ## args)
+#define pmo_debug(format, args...) \
+ pmo_logfl(QDF_TRACE_LEVEL_DEBUG, format, ## args)
+
+#define PMO_ENTER() pmo_debug("enter")
+#define PMO_EXIT() pmo_debug("exit")
+
+#define PMO_VDEV_IN_STA_MODE(mode) \
+ ((mode) == QDF_STA_MODE || (mode) == QDF_P2P_CLIENT_MODE ? 1 : 0)
+
+static inline enum tQDF_ADAPTER_MODE pmo_get_vdev_opmode(
+ struct wlan_objmgr_vdev *vdev)
+{
+ enum tQDF_ADAPTER_MODE opmode;
+
+ opmode = wlan_vdev_mlme_get_opmode(vdev);
+
+ return opmode;
+}
+
+/**
+ * pmo_allocate_ctx() - Api to allocate pmo ctx
+ *
+ * Helper function to allocate pmo ctx
+ *
+ * Return: Success or failure.
+ */
+QDF_STATUS pmo_allocate_ctx(void);
+
+/**
+ * pmo_free_ctx() - to free pmo context
+ *
+ * Helper function to free pmo context
+ *
+ * Return: None.
+ */
+void pmo_free_ctx(void);
+
+/**
+ * pmo_get_context() - to get pmo context
+ *
+ * Helper function to get pmo context
+ *
+ * Return: pmo context.
+ */
+struct wlan_pmo_ctx *pmo_get_context(void);
+
+/**
+ * pmo_get_vdev_bss_peer_mac_addr() - API to get bss peer mac address
+ * @vdev: objmgr vdev
+ * @bss_peer_mac_address: bss peer mac address
+ *.
+ * Helper function to get bss peer mac address
+ *
+ * Return: if success pmo vdev ctx else NULL
+ */
+QDF_STATUS pmo_get_vdev_bss_peer_mac_addr(struct wlan_objmgr_vdev *vdev,
+ struct qdf_mac_addr *bss_peer_mac_address);
+
+/**
+ * pmo_is_vdev_in_beaconning_mode() - check if vdev is in a beaconning mode
+ * @vdev_opmode: vdev opmode
+ *
+ * Helper function to know whether given vdev
+ * is in a beaconning mode or not.
+ *
+ * Return: True if vdev needs to beacon.
+ */
+bool pmo_is_vdev_in_beaconning_mode(enum tQDF_ADAPTER_MODE vdev_opmode);
+
+/**
+ * pmo_core_is_ap_mode_supports_arp_ns() - To check ap mode supports arp/ns
+ * @vdev_opmode: vdev opmode
+ *
+ * API to check if ap mode supports arp/ns offload
+ *
+ * Return: True if ap mode supports arp/ns offload
+ */
+
+bool pmo_core_is_ap_mode_supports_arp_ns(struct wlan_objmgr_psoc *psoc,
+ enum tQDF_ADAPTER_MODE vdev_opmode);
+
+/**
+ * pmo_core_is_vdev_connected() - to check whether peer is associated or not
+ * @vdev: objmgr vdev
+ *
+ * Return: true in case success else false
+ */
+bool pmo_core_is_vdev_connected(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_core_is_vdev_supports_offload() - Check offload is supported on vdev
+ * @vdev: objmgr vdev
+ *
+ * Return: true in case success else false
+ */
+bool pmo_core_is_vdev_supports_offload(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_core_get_psoc_config(): API to get the psoc user configurations of pmo
+ * @psoc: objmgr psoc handle
+ * @psoc_cfg: fill the current psoc user configurations.
+ *
+ * Return pmo psoc configurations
+ */
+QDF_STATUS pmo_core_get_psoc_config(struct wlan_objmgr_psoc *psoc,
+ struct pmo_psoc_cfg *psoc_cfg);
+
+/**
+ * pmo_core_update_psoc_config(): API to update the psoc user configurations
+ * @psoc: objmgr psoc handle
+ * @psoc_cfg: pmo psoc configurations
+ *
+ * This api shall be used for soc config initialization as well update.
+ * In case of update caller must first call pmo_get_psoc_cfg to get
+ * current config and then apply changes on top of current config.
+ *
+ * Return QDF_STATUS -in case of success else return error
+ */
+QDF_STATUS pmo_core_update_psoc_config(struct wlan_objmgr_psoc *psoc,
+ struct pmo_psoc_cfg *psoc_cfg);
+
+
+/**
+ * pmo_core_get_vdev_op_mode(): API to get the vdev operation mode
+ * @vdev: objmgr vdev handle
+ *
+ * API to get the vdev operation mode
+ *
+ * Return QDF_MAX_NO_OF_MODE - in case of error else return vdev opmode
+ */
+static inline enum tQDF_ADAPTER_MODE pmo_core_get_vdev_op_mode(
+ struct wlan_objmgr_vdev *vdev)
+{
+ enum tQDF_ADAPTER_MODE op_mode = QDF_MAX_NO_OF_MODE;
+
+ if (!vdev)
+ return op_mode;
+ op_mode = wlan_vdev_mlme_get_opmode(vdev);
+
+ return op_mode;
+}
+
+/**
+ * pmo_core_psoc_update_dp_handle() - update psoc data path handle
+ * @psoc: objmgr psoc handle
+ * @dp_hdl: psoc data path handle
+ *
+ * Return: None
+ */
+static inline
+void pmo_core_psoc_update_dp_handle(struct wlan_objmgr_psoc *psoc,
+ void *dp_hdl)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx;
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ psoc_ctx->dp_hdl = dp_hdl;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+}
+
+/**
+ * pmo_core_psoc_get_dp_handle() - Get psoc data path handle
+ * @psoc: objmgr psoc handle
+ *
+ * Return: psoc data path handle
+ */
+static inline
+void *pmo_core_psoc_get_dp_handle(struct wlan_objmgr_psoc *psoc)
+{
+ void *dp_hdl;
+ struct pmo_psoc_priv_obj *psoc_ctx;
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ dp_hdl = psoc_ctx->dp_hdl;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+
+ return dp_hdl;
+}
+
+/**
+ * pmo_core_vdev_update_dp_handle() - update vdev data path handle
+ * @vdev: objmgr vdev handle
+ * @dp_hdl: Vdev data path handle
+ *
+ * Return: None
+ */
+static inline
+void pmo_core_vdev_update_dp_handle(struct wlan_objmgr_vdev *vdev,
+ void *dp_hdl)
+{
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ vdev_ctx->vdev_dp_hdl = dp_hdl;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+}
+
+/**
+ * pmo_core_vdev_get_dp_handle() - Get vdev data path handle
+ * @vdev: objmgr vdev handle
+ *
+ * Return: Vdev data path handle
+ */
+static inline
+void *pmo_core_vdev_get_dp_handle(struct wlan_objmgr_vdev *vdev)
+{
+ void *dp_hdl;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ dp_hdl = vdev_ctx->vdev_dp_hdl;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ return dp_hdl;
+}
+
+/**
+ * pmo_core_psoc_update_htc_handle() - update psoc htc layer handle
+ * @psoc: objmgr psoc handle
+ * @htc_hdl: psoc htc layer handle
+ *
+ * Return: None
+ */
+static inline
+void pmo_core_psoc_update_htc_handle(struct wlan_objmgr_psoc *psoc,
+ void *htc_hdl)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx;
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ psoc_ctx->htc_hdl = htc_hdl;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+}
+
+/**
+ * pmo_core_psoc_get_htc_handle() - Get psoc htc layer handle
+ * @psoc: objmgr psoc handle
+ *
+ * Return: psoc htc layer handle
+ */
+static inline
+void *pmo_core_psoc_get_htc_handle(struct wlan_objmgr_psoc *psoc)
+{
+ void *htc_hdl;
+ struct pmo_psoc_priv_obj *psoc_ctx;
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ htc_hdl = psoc_ctx->htc_hdl;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+
+ return htc_hdl;
+}
+
+/**
+ * pmo_core_psoc_set_hif_handle() - update psoc hif layer handle
+ * @psoc: objmgr psoc handle
+ * @hif_hdl: hif context handle
+ *
+ * Return: None
+ */
+void pmo_core_psoc_set_hif_handle(struct wlan_objmgr_psoc *psoc,
+ void *hif_hdl);
+
+/**
+ * pmo_core_psoc_get_hif_handle() - Get psoc hif layer handle
+ * @psoc: objmgr psoc handle
+ *
+ * Return: psoc hif layer handle
+ */
+void *pmo_core_psoc_get_hif_handle(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_core_psoc_set_txrx_handle() - update psoc pdev txrx layer handle
+ * @psoc: objmgr psoc handle
+ * @txrx_hdl: pdev txrx context handle
+ *
+ * Return: None
+ */
+void pmo_core_psoc_set_txrx_handle(struct wlan_objmgr_psoc *psoc,
+ void *txrx_hdl);
+
+/**
+ * pmo_core_psoc_get_txrx_handle() - Get psoc pdev txrx handle
+ * @psoc: objmgr psoc handle
+ *
+ * Return: pdev txrx handle
+ */
+void *pmo_core_psoc_get_txrx_handle(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_is_vdev_up() - API to check whether vdev is UP
+ * @vdev: objmgr vdev handle
+ *
+ * Return:true if vdev is up else false
+ */
+static inline
+bool pmo_is_vdev_up(struct wlan_objmgr_vdev *vdev)
+{
+ enum wlan_vdev_state state = WLAN_VDEV_S_INIT;
+
+ if (!vdev) {
+ pmo_err("vdev context is invalid!");
+ return false;
+ }
+ state = wlan_vdev_mlme_get_state(vdev);
+
+ return state == WLAN_VDEV_S_RUN;
+}
+
+#endif /* end of _WLAN_PMO_MAIN_H_ */
diff --git a/components/pmo/core/inc/wlan_pmo_mc_addr_filtering.h b/components/pmo/core/inc/wlan_pmo_mc_addr_filtering.h
new file mode 100644
index 0000000..ddedb64
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_mc_addr_filtering.h
@@ -0,0 +1,129 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Declare mc addr filtering offload feature API's
+ */
+
+#ifndef _WLAN_PMO_MC_ADDR_FILTERING_H_
+#define _WLAN_PMO_MC_ADDR_FILTERING_H_
+
+#include "wlan_pmo_common_public_struct.h"
+#include "wlan_pmo_mc_addr_filtering_public_struct.h"
+
+/**
+ * pmo_core_set_mc_filter_req() -send mc filter set request
+ * @vdev: objmgr vdev
+ * @mc_list: a list of mc addresses to set in fwr
+ *
+ * Return: QDF_STATUS_SUCCESS in success else error codes
+ */
+QDF_STATUS pmo_core_set_mc_filter_req(struct wlan_objmgr_vdev *vdev,
+ struct pmo_mc_addr_list *mc_list);
+
+/**
+ * pmo_clear_mc_filter_req() -send mc filter clear request
+ * @vdev: objmgr vdev
+ * @mc_list: a list of mc addresses to clear in fwr
+ *
+ * Return: QDF_STATUS_SUCCESS in success else error codes
+ */
+QDF_STATUS pmo_core_clear_mc_filter_req(struct wlan_objmgr_vdev *vdev,
+ struct pmo_mc_addr_list *mc_list);
+
+/**
+ * pmo_core_cache_mc_addr_list(): API to cache mc addr list in pmo vdev priv obj
+ * @psoc: objmgr psoc handle
+ * @vdev_id: vdev id
+ * @gtk_req: pmo gtk req param
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_core_cache_mc_addr_list(
+ struct pmo_mc_addr_list_params *mc_list_config);
+
+/**
+ * pmo_core_flush_mc_addr_list(): API to flush mc addr list in pmo vdev priv obj
+ * @psoc: objmgr psoc handle
+ * @vdev_id: vdev id
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_core_flush_mc_addr_list(struct wlan_objmgr_psoc *psoc,
+ uint8_t vdev_id);
+
+/**
+ * pmo_core_enable_mc_addr_filtering_in_fwr(): Enable cached mc add list in fwr
+ * @psoc: objmgr psoc handle
+ * @vdev_id: vdev id
+ * @gtk_req: pmo gtk req param
+ * @action: true for enable els false
+ *
+ * API to enable cached mc add list in fwr
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_core_enable_mc_addr_filtering_in_fwr(
+ struct wlan_objmgr_psoc *psoc,
+ uint8_t vdev_id,
+ enum pmo_offload_trigger trigger);
+
+/**
+ * pmo_core_disable_mc_addr_filtering_in_fwr(): Disable cached mc addr list
+ * @psoc: objmgr psoc handle
+ * @vdev_id: vdev id
+ * @gtk_req: pmo gtk req param
+ * @action: true for enable els false
+ *
+ * API to disable cached mc add list in fwr
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_core_disable_mc_addr_filtering_in_fwr(
+ struct wlan_objmgr_psoc *psoc,
+ uint8_t vdev_id,
+ enum pmo_offload_trigger trigger);
+
+/**
+ * pmo_core_get_mc_addr_list_count() -set mc address count
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id
+ *
+ * Return: set mc address count
+ */
+void pmo_core_set_mc_addr_list_count(struct wlan_objmgr_psoc *psoc,
+ uint8_t vdev_id, uint8_t count);
+
+/**
+ * pmo_core_get_mc_addr_list_count() -get current mc address count
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id
+ *
+ * Return: current mc address count
+ */
+int pmo_core_get_mc_addr_list_count(struct wlan_objmgr_psoc *psoc,
+ uint8_t vdev_id);
+
+/**
+ * pmo_core_max_mc_addr_supported() -get max supported mc addresses
+ * @psoc: objmgr psoc
+ *
+ * Return: max supported mc addresses
+ */
+uint8_t pmo_core_max_mc_addr_supported(struct wlan_objmgr_psoc *psoc);
+
+#endif /* end of _WLAN_PMO_MC_ADDR_FILTERING_H_ */
diff --git a/components/pmo/core/inc/wlan_pmo_ns.h b/components/pmo/core/inc/wlan_pmo_ns.h
new file mode 100644
index 0000000..de30ba9
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_ns.h
@@ -0,0 +1,72 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Declare ns offload feature API's
+ */
+
+#ifndef _WLAN_PMO_NS_H_
+#define _WLAN_PMO_NS_H_
+
+#include "wlan_pmo_common_public_struct.h"
+#include "wlan_pmo_ns_public_struct.h"
+
+/**
+ * pmo_core_cache_ns_offload_req() - API to cache ns req in pmo vdev priv ctx
+ * @ns_req: ns offload request
+ *
+ * API to cache ns offload in pmo vdev priv ctx
+ *
+ * Return:QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_core_cache_ns_offload_req(struct pmo_ns_req *ns_req);
+
+/**
+ * pmo_core_flush_ns_offload_req() - API to flush ns req from pmo vdev priv ctx
+ * @vdev: vdev objmgr handle
+ *
+ * API to flush ns offload from pmo vdev priv ctx
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_core_flush_ns_offload_req(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_core_enable_ns_offload_in_fwr() - API to enable ns offload in fwr
+ * @vdev: objmgr vdev
+ * @trigger: trigger reason enable ns offload
+ *
+ * API to enable ns offload in fwr from vdev priv ctx
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_core_enable_ns_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+ enum pmo_offload_trigger trigger);
+
+/**
+ * pmo_core_disable_ns_offload_in_fwr() - API to disable ns offload in fwr
+ * @vdev: objmgr vdev
+ * @trigger: trigger reason disable ns offload
+ *
+ * API to disable arp offload in fwr
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_core_disable_ns_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+ enum pmo_offload_trigger trigger);
+
+#endif /* end of _WLAN_PMO_NS_H_ */
diff --git a/components/pmo/core/inc/wlan_pmo_objmgr.h b/components/pmo/core/inc/wlan_pmo_objmgr.h
new file mode 100644
index 0000000..10b9889
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_objmgr.h
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: This file contains various object manager related wrappers and helpers
+ */
+
+#ifndef _WLAN_PMO_OBJMGR_H
+#define _WLAN_PMO_OBJMGR_H
+
+#include "wlan_cmn.h"
+#include "wlan_objmgr_cmn.h"
+#include "wlan_objmgr_peer_obj.h"
+#include "wlan_objmgr_vdev_obj.h"
+#include "wlan_objmgr_pdev_obj.h"
+#include "wlan_objmgr_psoc_obj.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+/* Get/Put Ref */
+
+#define pmo_peer_get_ref(peer) wlan_objmgr_peer_try_get_ref(peer, WLAN_PMO_ID)
+#define pmo_peer_put_ref(peer) wlan_objmgr_peer_release_ref(peer, WLAN_PMO_ID)
+
+#define pmo_vdev_get_ref(vdev) wlan_objmgr_vdev_try_get_ref(vdev, WLAN_PMO_ID)
+#define pmo_vdev_put_ref(vdev) wlan_objmgr_vdev_release_ref(vdev, WLAN_PMO_ID)
+
+#define pmo_pdev_get_ref(pdev) wlan_objmgr_pdev_try_get_ref(pdev, WLAN_PMO_ID)
+#define pmo_pdev_put_ref(pdev) wlan_objmgr_pdev_release_ref(pdev, WLAN_PMO_ID)
+
+#define pmo_psoc_get_ref(psoc) wlan_objmgr_psoc_try_get_ref(psoc, WLAN_PMO_ID)
+#define pmo_psoc_put_ref(psoc) wlan_objmgr_psoc_release_ref(psoc, WLAN_PMO_ID)
+
+/* Private Data */
+
+#define pmo_vdev_get_priv_nolock(vdev) \
+ wlan_objmgr_vdev_get_comp_private_obj(vdev, WLAN_UMAC_COMP_PMO)
+#define pmo_psoc_get_priv_nolock(psoc) \
+ wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_PMO)
+
+/* Ids */
+
+static inline uint8_t
+pmo_vdev_get_id(struct wlan_objmgr_vdev *vdev)
+{
+ uint8_t vdev_id;
+
+ vdev_id = wlan_vdev_get_id(vdev);
+
+ QDF_BUG(vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS);
+
+ return vdev_id;
+}
+
+/* Tree Navigation */
+
+/**
+ * !PLEASE READ!
+ *
+ * The following are objmgr naviation helpers for traversing objmgr object
+ * trees.
+ *
+ * Objmgr ensures parents of an objmgr object cannot be freed while a valid
+ * reference to one of its children is held. Based on this fact, all of these
+ * navigation helpers make the following assumptions to ensure safe usage:
+ *
+ * 1) The caller must hold a valid reference to the input objmgr object!
+ * E.g. Use pmo_[peer|vdev|pdev|psoc]_get_ref() on the input objmgr object
+ * before using these APIs
+ * 2) Given assumption #1, the caller does not need to hold a reference to the
+ * parents of the input objmgr object
+ * 3) Given assumption #1, parents of the input objmgr object cannot be null
+ * 4) Given assumption #1, private contexts of any parent of the input objmgr
+ * object cannot be null
+ *
+ * These characteristics remove the need for most sanity checks when dealing
+ * with objmgr objects. However, please note that if you ever walk the tree
+ * from parent to child, references must be acquired all the way down!
+ *
+ * Example #1:
+ *
+ * psoc = pmo_vdev_get_psoc(vdev);
+ * if (!psoc)
+ * // this is dead code
+ *
+ * Example #2:
+ *
+ * psoc_priv = pmo_psoc_get_priv(psoc);
+ * if (!psoci_priv)
+ * // this is dead code
+ *
+ * Example #3:
+ *
+ * status = pmo_vdev_get_ref(vdev);
+ *
+ * ...
+ *
+ * psoc = pmo_vdev_get_psoc(vdev);
+ *
+ * // the next line is redundant, don't do it!
+ * status = pmo_psoc_get_ref(psoc);
+ */
+
+/* Tree Navigation: psoc */
+
+static inline struct wlan_objmgr_vdev *
+pmo_psoc_get_vdev(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
+{
+ struct wlan_objmgr_vdev *vdev;
+
+ if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) {
+ QDF_BUG(0);
+ return NULL;
+ }
+
+ wlan_psoc_obj_lock(psoc);
+ vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_id];
+ wlan_psoc_obj_unlock(psoc);
+
+ return vdev;
+}
+
+static inline struct pmo_psoc_priv_obj *
+pmo_psoc_get_priv(struct wlan_objmgr_psoc *psoc)
+{
+ struct pmo_psoc_priv_obj *psoc_priv;
+
+ psoc_priv = pmo_psoc_get_priv_nolock(psoc);
+
+ QDF_BUG(psoc_priv);
+
+ return psoc_priv;
+}
+
+/* Tree Navigation: pdev */
+
+static inline struct wlan_objmgr_psoc *
+pmo_pdev_get_psoc(struct wlan_objmgr_pdev *pdev)
+{
+ struct wlan_objmgr_psoc *psoc;
+
+ psoc = wlan_pdev_get_psoc(pdev);
+
+ QDF_BUG(psoc);
+
+ return psoc;
+}
+
+static inline struct pmo_psoc_priv_obj *
+pmo_pdev_get_psoc_priv(struct wlan_objmgr_pdev *pdev)
+{
+ return pmo_psoc_get_priv(pmo_pdev_get_psoc(pdev));
+}
+
+/* Tree Navigation: vdev */
+
+static inline struct pmo_vdev_priv_obj *
+pmo_vdev_get_priv(struct wlan_objmgr_vdev *vdev)
+{
+ struct pmo_vdev_priv_obj *vdev_priv;
+
+ vdev_priv = pmo_vdev_get_priv_nolock(vdev);
+
+ QDF_BUG(vdev_priv);
+
+ return vdev_priv;
+}
+
+static inline struct wlan_objmgr_pdev *
+pmo_vdev_get_pdev(struct wlan_objmgr_vdev *vdev)
+{
+ struct wlan_objmgr_pdev *pdev;
+
+ pdev = wlan_vdev_get_pdev(vdev);
+
+ QDF_BUG(pdev);
+
+ return pdev;
+}
+
+static inline struct wlan_objmgr_psoc *
+pmo_vdev_get_psoc(struct wlan_objmgr_vdev *vdev)
+{
+ return pmo_pdev_get_psoc(pmo_vdev_get_pdev(vdev));
+}
+
+static inline struct pmo_psoc_priv_obj *
+pmo_vdev_get_psoc_priv(struct wlan_objmgr_vdev *vdev)
+{
+ return pmo_psoc_get_priv(pmo_pdev_get_psoc(pmo_vdev_get_pdev(vdev)));
+}
+
+#endif /* _WLAN_PMO_OBJMGR_H */
diff --git a/components/pmo/core/inc/wlan_pmo_pkt_filter.h b/components/pmo/core/inc/wlan_pmo_pkt_filter.h
new file mode 100644
index 0000000..0a900e5
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_pkt_filter.h
@@ -0,0 +1,57 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Declare packet filter feature API's
+ */
+
+#ifndef _WLAN_PMO_PKT_FILTER_H_
+#define _WLAN_PMO_PKT_FILTER_
+
+#include "wlan_pmo_pkt_filter_public_struct.h"
+
+struct wlan_objmgr_psoc;
+
+/**
+ * pmo_set_pkt_fltr_req() - Set packet filter
+ * @vdev: objmgr vdev
+ * @pmo_set_pkt_fltr_req:
+ * @vdev_id:
+ * API to set packet filter
+ *
+ * Return: QQDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_core_set_pkt_filter(struct wlan_objmgr_psoc *psoc,
+ struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req,
+ uint8_t vdev_id);
+
+/**
+ * pmo_core_clear_pkt_filter() - Clear packet filter
+ * @vdev: objmgr vdev
+ * @pmo_clr_pkt_fltr_req:
+ * @vdev_id:
+ *
+ * API to clear packet filter
+ *
+ * Return: QQDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_core_clear_pkt_filter(struct wlan_objmgr_psoc *psoc,
+ struct pmo_rcv_pkt_fltr_clear_param *pmo_clr_pkt_fltr_req,
+ uint8_t vdev_id);
+
+#endif /* end of _WLAN_PMO_PKT_FILTER_H_ */
+
diff --git a/components/pmo/core/inc/wlan_pmo_priv.h b/components/pmo/core/inc/wlan_pmo_priv.h
new file mode 100644
index 0000000..8c7614d
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_priv.h
@@ -0,0 +1,130 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+ /**
+ * DOC: Declare various struct, macros which are used for private to PMO.
+ *
+ * Note: This file shall not contain public API's prototype/declarations.
+ *
+ */
+
+#ifndef _WLAN_PMO_PRIV_STRUCT_H_
+#define _WLAN_PMO_PRIV_STRUCT_H_
+
+#include "wlan_pmo_common_public_struct.h"
+#include "wlan_pmo_arp_public_struct.h"
+#include "wlan_pmo_ns_public_struct.h"
+#include "wlan_pmo_gtk_public_struct.h"
+#include "wlan_pmo_wow_public_struct.h"
+#include "wlan_pmo_mc_addr_filtering_public_struct.h"
+
+/**
+ * struct pmo_psoc_priv_obj - psoc related data require for pmo
+ * @psoc_cfg: place holder for psoc configuration
+ * @pmo_tx_ops: transmit ops for PMO
+ * @wow: wow configuration
+ * @dp_hdl: psoc data path handle
+ * @htc_hdl: htc layer handle
+ * @hif_hdl: hif layer handle
+ * @txrx_hdl: txrx pdev handle
+ * @pause_bitmap_notifier: registered callback to update pause bitmap value
+ * @pmo_get_pause_bitmap: registered callback to get pause bitmap value
+ * @lock: spin lock for pmo psoc
+ */
+struct pmo_psoc_priv_obj {
+ struct pmo_psoc_cfg psoc_cfg;
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+ struct pmo_wow wow;
+ void *dp_hdl;
+ void *htc_hdl;
+ void *hif_hdl;
+ void *txrx_hdl;
+ pmo_notify_pause_bitmap pause_bitmap_notifier;
+ pmo_get_pause_bitmap get_pause_bitmap;
+ pmo_is_device_in_low_pwr_mode is_device_in_low_pwr_mode;
+ qdf_spinlock_t lock;
+};
+
+/**
+ * struct wlan_pmo_ctx -offload mgr context
+ * @psoc_context: psoc context
+ * @pmo_suspend_handler: suspend handler table for all componenets
+ * @pmo_suspend_handler_arg: suspend handler argument sfor all componenets
+ * @pmo_resume_handler: resume handler table for all componenets
+ * @pmo_resume_handler_arg: resume handler argument for all componenets
+ * @lock: lock for global pmo ctx
+ */
+struct wlan_pmo_ctx {
+ pmo_psoc_suspend_handler
+ pmo_suspend_handler[WLAN_UMAC_MAX_COMPONENTS];
+ void *pmo_suspend_handler_arg[WLAN_UMAC_MAX_COMPONENTS];
+ pmo_psoc_resume_handler
+ pmo_resume_handler[WLAN_UMAC_MAX_COMPONENTS];
+ void *pmo_resume_handler_arg[WLAN_UMAC_MAX_COMPONENTS];
+ qdf_spinlock_t lock;
+};
+
+/**
+ * struct pmo_vdev_priv_obj -vdev specific user configuration required for pmo
+ * @pmo_psoc_ctx: pmo psoc ctx
+ * @vdev_arp_req: place holder for arp request for vdev
+ * @vdev_ns_req: place holder for ns request for vdev
+ * @vdev_mc_list_req: place holder for mc addr list for vdev
+ * @addr_filter_pattern: addr filter pattern for vdev
+ * @vdev_gtk_params: place holder for gtk request for vdev
+ * @gtk_err_enable: gtk error is enabled or not
+ * @vdev_bpf_req: place holder for apf/bpf for vdev
+ * @vdev_pkt_filter: place holder for vdev packet filter
+ * @ptrn_match_enable: true when pattern match is enabled else false
+ * @num_wow_default_patterns: number of wow default patterns for vdev
+ * @num_wow_user_patterns: number of user wow patterns for vdev
+ * @nlo_in_progress: true when pno/nlo in progress else false
+ * @nlo_match_received: true when nlo match recevied from fwr else false
+ * @extscan_in_progress: true when extscan in progress else false
+ * @p2plo_in_progress: true when p2plo_in_progress in progress else false
+ * @dtim_period: dtim period for vdev
+ * @beacon_interval: vdev beacon interval
+ * @alt_modulated_dtim_enabled:dynamic modulated dtim enabled
+ * @dtim_policy: tells vdev beacon dtim policy
+ * @vdev_dp_hdl: vdev data path handle
+ * @pmo_vdev_lock: spin lock for pmo vdev priv ctx
+ */
+struct pmo_vdev_priv_obj {
+ struct pmo_psoc_priv_obj *pmo_psoc_ctx;
+ struct pmo_arp_offload_params vdev_arp_req;
+ struct pmo_ns_offload_params vdev_ns_req;
+ struct pmo_mc_addr_list vdev_mc_list_req;
+ uint8_t addr_filter_pattern;
+ struct pmo_gtk_req vdev_gtk_req;
+ struct pmo_gtk_rsp_req vdev_gtk_rsp_req;
+ qdf_atomic_t gtk_err_enable;
+ bool ptrn_match_enable;
+ uint8_t num_wow_default_patterns;
+ uint8_t num_wow_user_patterns;
+ bool nlo_in_progress;
+ bool nlo_match_received;
+ bool extscan_in_progress;
+ bool p2plo_in_progress;
+ uint8_t dtim_period;
+ uint8_t beacon_interval;
+ bool alt_modulated_dtim_enable;
+ uint32_t dtim_policy;
+ void *vdev_dp_hdl;
+ qdf_spinlock_t pmo_vdev_lock;
+};
+
+#endif /* end of _WLAN_PMO_PRIV_STRUCT_H_ */
diff --git a/components/pmo/core/inc/wlan_pmo_static_config.h b/components/pmo/core/inc/wlan_pmo_static_config.h
new file mode 100644
index 0000000..fe4544b
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_static_config.h
@@ -0,0 +1,117 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Declare static configuration on vdev attach
+ */
+
+#ifndef _WLAN_PMO_STATIC_CONFIG_H_
+#define _WLAN_PMO_STATIC_CONFIG_H_
+
+#include "wlan_pmo_common_public_struct.h"
+#include "wlan_pmo_wow.h"
+
+/**
+ * pmo_register_wow_wakeup_events() - register vdev specific wake events with fw
+ * @vdev: objmgr vdev
+ *
+ * WoW wake up event rule is following:
+ * 1) STA mode and P2P CLI mode wake up events are same
+ * 2) SAP mode and P2P GO mode wake up events are same
+ * 3) IBSS mode wake events are same as STA mode plus WOW_BEACON_EVENT
+ *
+ * Return: none
+ */
+void pmo_register_wow_wakeup_events(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_register_wow_default_patterns() - register default wow patterns with fw
+ * @vdev_id: vdev id
+ *
+ * WoW default wake up pattern rule is:
+ * - For STA & P2P CLI mode register for same STA specific wow patterns
+ * - For SAP/P2P GO & IBSS mode register for same SAP specific wow patterns
+ *
+ * Return: none
+ */
+void pmo_register_wow_default_patterns(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_register_action_frame_patterns() - register action frame map to fw
+ * @vdev: objmgr vdev
+ *
+ * This is called to push action frames wow patterns from local
+ * cache to firmware.
+ *
+ * Return: None
+ */
+void pmo_register_action_frame_patterns(
+ struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_update_target_service(): API to update wmi target service info to PMO.
+ * @psoc: objmgr psoc
+ * @wmi_service: wmi service number
+ * @value: true when wmi service is enabled in firmware otherwise false.
+ *
+ * Return void
+ */
+void pmo_update_target_service(struct wlan_objmgr_psoc *psoc,
+ WMI_SERVICE service, bool value);
+
+/**
+ * pmo_update_ra_limit() - update ra limit based on bpf filter
+ * enabled or not
+ * @psoc: objmgr psoc
+ * @bpf_enabled: true when bpf service is enabled else false
+ *
+ * Return: none
+ */
+void pmo_update_ra_limit(struct wlan_objmgr_psoc *psoc,
+ bool bpf_enabled);
+
+/**
+ * pmo_set_wow_event_bitmap() - Assign bitmask with wow event
+ * @event: wow event
+ * @wow_bitmap_size: wow bitmask size
+ * @bitmask: wow bitmask field
+ *
+ * Return: none
+ */
+void pmo_set_wow_event_bitmap(WOW_WAKE_EVENT_TYPE event,
+ uint32_t wow_bitmap_size,
+ uint32_t *bitmask);
+
+/**
+ * pmo_set_sta_wow_bitmask() - set predefined STA wow wakeup events
+ * @bitmask: bitmask field
+ * @wow_bitmask_size: bitmask field size
+ *
+ * Return: none
+ */
+void pmo_set_sta_wow_bitmask(uint32_t *bitmask, uint32_t wow_bitmask_size);
+
+/**
+ * pmo_set_sap_wow_bitmask() - set predefined SAP wow wakeup events
+ * @bitmask: bitmask field
+ * @wow_bitmask_size: bitmask field size
+ *
+ * Return: none
+ */
+void pmo_set_sap_wow_bitmask(uint32_t *bitmask, uint32_t wow_bitmask_size);
+
+#endif /* end of _WLAN_PMO_STATIC_CONFIG_H_ */
diff --git a/components/pmo/core/inc/wlan_pmo_suspend_resume.h b/components/pmo/core/inc/wlan_pmo_suspend_resume.h
new file mode 100644
index 0000000..516f428
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_suspend_resume.h
@@ -0,0 +1,437 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Declare suspend / resume related API's
+ */
+
+#ifndef _WLAN_PMO_SUSPEND_RESUME_H_
+#define _WLAN_PMO_SUSPEND_RESUME_H_
+
+#include "wlan_pmo_common_public_struct.h"
+#include "wlan_pmo_wow.h"
+
+/**
+ * pmo_core_configure_dynamic_wake_events(): configure dyanmic wake events
+ * @wma: wma handle
+ *
+ * Some wake events need to be enabled dynamically. Control those here.
+ *
+ * Return: none
+ */
+void pmo_core_configure_dynamic_wake_events(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_core_get_wow_bus_suspend(): API to get wow bus is suspended or not
+ * @psoc: objmgr psoc handle
+ *
+ * Return: True if bus suspende else false
+ */
+static inline
+bool pmo_core_get_wow_bus_suspend(struct wlan_objmgr_psoc *psoc)
+{
+ bool value;
+ struct pmo_psoc_priv_obj *psoc_ctx;
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ value = psoc_ctx->wow.is_wow_bus_suspended;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+
+ return value;
+}
+
+/**
+ * pmo_core_psoc_user_space_suspend_req() - Core handle user space suspend req
+ * @psoc: objmgr psoc handle
+ * @type: type of suspend
+ *
+ * Pmo core Handles user space suspend request for psoc
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_core_psoc_user_space_suspend_req(struct wlan_objmgr_psoc *psoc,
+ enum qdf_suspend_type type);
+
+/**
+ * pmo_core_psoc_user_space_resume_req() - Core handle user space resume req
+ * @psoc: objmgr psoc handle
+ * @type: type of suspend from resume required
+ *
+ * Pmo core Handles user space resume request for psoc
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_core_psoc_user_space_resume_req(struct wlan_objmgr_psoc *psoc,
+ enum qdf_suspend_type type);
+
+/**
+ * pmo_core_psoc_bus_suspend_req(): handles bus suspend for psoc
+ * @psoc: objmgr psoc
+ * @type: is this suspend part of runtime suspend or system suspend?
+ * @wow_params: collection of wow enable override parameters
+ *
+ * Bails if a scan is in progress.
+ * Calls the appropriate handlers based on configuration and event.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_core_psoc_bus_suspend_req(struct wlan_objmgr_psoc *psoc,
+ enum qdf_suspend_type type,
+ struct pmo_wow_enable_params *wow_params);
+
+#ifdef FEATURE_RUNTIME_PM
+/**
+ * pmo_core_psoc_bus_runtime_suspend(): handles bus runtime suspend
+ * @psoc: objmgr psoc
+ * @pld_cb: callback to do link auto suspend
+ *
+ * Suspend the wlan bus without apps suspend.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_core_psoc_bus_runtime_suspend(struct wlan_objmgr_psoc *psoc,
+ pmo_pld_auto_suspend_cb pld_cb);
+
+/**
+ * pmo_core_psoc_bus_runtime_resume(): handles bus runtime resume
+ * @psoc: objmgr psoc
+ * @pld_cb: callback to do link auto resume
+ *
+ * Resume the wlan bus from runtime suspend.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_core_psoc_bus_runtime_resume(struct wlan_objmgr_psoc *psoc,
+ pmo_pld_auto_resume_cb pld_cb);
+#endif
+
+/**
+ * pmo_core_psoc_suspend_target() -Send suspend target command
+ * @psoc: objmgr psoc handle
+ * @disable_target_intr: disable target interrupt
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_core_psoc_suspend_target(struct wlan_objmgr_psoc *psoc,
+ int disable_target_intr);
+
+/**
+ * pmo_core_psoc_bus_resume() -handle bus resume request for psoc
+ * @psoc: objmgr psoc handle
+ * @type: is this suspend part of runtime suspend or system suspend?
+ *
+ * Return:QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS pmo_core_psoc_bus_resume_req(struct wlan_objmgr_psoc *psoc,
+ enum qdf_suspend_type type);
+
+/**
+ * pmo_core_get_vdev_dtim_period() - Get vdev dtim period
+ * @vdev: objmgr vdev handle
+ *
+ * Return: Vdev dtim period
+ */
+static inline
+uint8_t pmo_core_get_vdev_dtim_period(struct wlan_objmgr_vdev *vdev)
+{
+ uint8_t dtim_period = 0;
+
+ if (!vdev) {
+ pmo_err("vdev is null");
+ QDF_ASSERT(0);
+ return 0;
+ }
+ /* TODO */
+ /* dtim_period = wlan_vdev_mlme_get_dtim_period(vdev); */
+
+ return dtim_period;
+}
+
+/**
+ * pmo_core_get_vdev_beacon_interval() - Get vdev beacon interval
+ * @vdev: objmgr vdev handle
+ *
+ * Return: Vdev beacon interval
+ */
+static inline
+uint16_t pmo_core_get_vdev_beacon_interval(struct wlan_objmgr_vdev *vdev)
+{
+ uint16_t beacon_interval = 0;
+
+ if (!vdev) {
+ pmo_err("vdev is null");
+ QDF_ASSERT(0);
+ return 0;
+ }
+ /* TODO */
+ /* beacon_interval = wlan_vdev_mlme_get_beacon_interval(vdev); */
+
+ return beacon_interval;
+}
+
+/**
+ * pmo_core_update_alt_modulated_dtim_enable() - update alt modulatate dtim
+ * @vdev: objmgr vdev handle
+ * @value: true when alt modulated dtim enable else false
+ *
+ * Return: None
+ */
+static inline
+void pmo_core_update_alt_modulated_dtim_enable(struct wlan_objmgr_vdev *vdev,
+ bool value)
+{
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ vdev_ctx->alt_modulated_dtim_enable = value;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+}
+
+/**
+ * pmo_core_vdev_set_dtim_policy() - Set vdev beacon dtim policy
+ * @vdev: objmgr vdev handle
+ * @value: carry vdev dtim policy
+ *
+ * Return: None
+ */
+static inline
+void pmo_core_vdev_set_dtim_policy(struct wlan_objmgr_vdev *vdev,
+ uint32_t value)
+{
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ vdev_ctx->dtim_policy = value;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+}
+
+/**
+ * pmo_core_vdev_get_dtim_policy() - Get vdev beacon dtim policy
+ * @vdev: objmgr vdev handle
+ *
+ * Return: vdev dtim policy
+ */
+static inline
+uint32_t pmo_core_vdev_get_dtim_policy(struct wlan_objmgr_vdev *vdev)
+{
+ uint32_t value;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ value = vdev_ctx->dtim_policy;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ return value;
+}
+
+/**
+ * pmo_core_update_power_save_mode() - update power save mode
+ * @vdev: objmgr vdev handle
+ * @value:describe vdev power save mode
+ *
+ * Return: None
+ */
+static inline
+void pmo_core_psoc_update_power_save_mode(struct wlan_objmgr_psoc *psoc,
+ uint8_t value)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx;
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ psoc_ctx->psoc_cfg.power_save_mode = value;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+}
+
+/**
+ * pmo_core_psoc_get_power_save_mode() - Get psoc power save mode
+ * @psoc: objmgr psoc handle
+ *
+ * Return: vdev psoc power save mode value
+ */
+static inline
+uint8_t pmo_core_psoc_get_power_save_mode(struct wlan_objmgr_psoc *psoc)
+{
+ uint8_t value;
+ struct pmo_psoc_priv_obj *psoc_ctx;
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ value = psoc_ctx->psoc_cfg.power_save_mode;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+
+ return value;
+}
+
+/**
+ * pmo_core_psoc_get_qpower_config() - get qpower configuration
+ * @psoc: objmgr psoc handle
+ *
+ * Power Save Offload configuration:
+ * 0 -> Power save offload is disabled
+ * 1 -> Legacy Power save enabled + Deep sleep Disabled
+ * 2 -> QPower enabled + Deep sleep Disabled
+ * 3 -> Legacy Power save enabled + Deep sleep Enabled
+ * 4 -> QPower enabled + Deep sleep Enabled
+ * 5 -> Duty cycling QPower enabled
+ *
+ * Return: enum powersave_qpower_mode with below values
+ * QPOWER_DISABLED if QPOWER is disabled
+ * QPOWER_ENABLED if QPOWER is enabled
+ * QPOWER_DUTY_CYCLING if DUTY CYCLING QPOWER is enabled
+ */
+static inline
+enum pmo_power_save_qpower_mode pmo_core_psoc_get_qpower_config(
+ struct wlan_objmgr_psoc *psoc)
+{
+ uint8_t ps_mode = pmo_core_psoc_get_power_save_mode(psoc);
+
+ switch (ps_mode) {
+ case pmo_ps_qpower_no_deep_sleep:
+ case pmo_ps_qpower_deep_sleep:
+ pmo_info("QPOWER is enabled in power save mode %d", ps_mode);
+ return pmo_qpower_enabled;
+ case pmo_ps_duty_cycling_qpower:
+ pmo_info("DUTY cycling QPOWER is enabled in power save mode %d",
+ ps_mode);
+ return pmo_qpower_duty_cycling;
+ default:
+ pmo_info("QPOWER is disabled in power save mode %d",
+ ps_mode);
+ return pmo_qpower_disabled;
+ }
+}
+
+/**
+ * pmo_core_vdev_get_pause_bitmap() - Get vdev pause bitmap
+ * @psoc_ctx: psoc priv ctx
+ * @vdev_id: vdev id
+ *
+ * Return: vdev pause bitmap
+ */
+static inline
+uint16_t pmo_core_vdev_get_pause_bitmap(struct pmo_psoc_priv_obj *psoc_ctx,
+ uint8_t vdev_id)
+{
+ uint16_t value = 0;
+ pmo_get_pause_bitmap handler;
+
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ handler = psoc_ctx->get_pause_bitmap;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+
+ if (handler)
+ value = handler(vdev_id);
+
+ return value;
+}
+
+/**
+ * wma_is_vdev_in_ap_mode() - check that vdev is in ap mode or not
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ *
+ * Helper function to know whether given vdev id
+ * is in AP mode or not.
+ *
+ * Return: True/False
+ */
+static inline
+bool pmo_is_vdev_in_ap_mode(struct wlan_objmgr_vdev *vdev)
+{
+ enum tQDF_ADAPTER_MODE mode;
+
+ mode = pmo_get_vdev_opmode(vdev);
+
+ return (mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE) == 1 ? 1 : 0;
+}
+
+#ifdef QCA_IBSS_SUPPORT
+/**
+ * pmo_is_vdev_in_ibss_mode() - check that vdev is in ibss mode or not
+ * @vdev: objmgr vdev handle
+ * @vdev_id: vdev id
+ *
+ * Helper function to know whether given vdev id
+ * is in IBSS mode or not.
+ *
+ * Return: True/False
+ */
+static inline
+bool pmo_is_vdev_in_ibss_mode(struct wlan_objmgr_vdev *vdev)
+{
+ enum tQDF_ADAPTER_MODE mode;
+
+ mode = pmo_get_vdev_opmode(vdev);
+
+ return (mode == QDF_IBSS_MODE) ? true : false;
+}
+#else
+static inline bool pmo_is_vdev_in_ibss_mode(struct wlan_objmgr_vdev *vdev)
+{
+ return false;
+}
+#endif /* QCA_IBSS_SUPPORT */
+
+/**
+ * pmo_handle_initial_wake_up() - handle initial wake up
+ * @cb_ctx: callback context
+ *
+ * Return: None
+ */
+void pmo_core_psoc_handle_initial_wake_up(void *cb_ctx);
+
+/**
+ * pmo_core_psoc_is_target_wake_up_received() - check for initial wake up
+ *
+ * Check if target initial wake up is received and fail PM suspend gracefully
+ *
+ * Return: -EAGAIN if initial wake up is received else 0
+ */
+int pmo_core_psoc_is_target_wake_up_received(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_core_psoc_clear_target_wake_up() - clear initial wake up
+ *
+ * Clear target initial wake up reason
+ *
+ * Return: 0 for success and negative error code for failure
+ */
+int pmo_core_psoc_clear_target_wake_up(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_core_psoc_target_suspend_acknowledge() - update target susspend status
+ * @context: HTC_INIT_INFO->context
+ * @wow_nack: true when wow is rejected
+ *
+ * Return: none
+ */
+void pmo_core_psoc_target_suspend_acknowledge(void *context, bool wow_nack);
+
+/**
+ * pmo_core_psoc_wakeup_host_event_received() - received host wake up event
+ * @psoc: objmgr psoc handle
+ *
+ * Return: None
+ */
+void pmo_core_psoc_wakeup_host_event_received(struct wlan_objmgr_psoc *psoc);
+
+#endif /* end of _WLAN_PMO_SUSPEND_RESUME_H_ */
diff --git a/components/pmo/core/inc/wlan_pmo_wow.h b/components/pmo/core/inc/wlan_pmo_wow.h
new file mode 100644
index 0000000..47d2eb5
--- /dev/null
+++ b/components/pmo/core/inc/wlan_pmo_wow.h
@@ -0,0 +1,605 @@
+/*
+ * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/**
+ * DOC: Declare API's for wow pattern addition and deletion in fwr
+ */
+
+#ifndef _WLAN_PMO_WOW_H_
+#define _WLAN_PMO_WOW_H_
+
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_wow_public_struct.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_common_public_struct.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+/**
+ * DOC: wlan_pmo_wowl
+ *
+ * This module houses all the logic for WOW(wake on wireless) in
+ * PMO(Power Management and Offload).
+ *
+ * It provides the following APIs
+ *
+ * - Ability to enable/disable following WoWL modes
+ * 1) Magic packet (MP) mode
+ * 2) Pattern Byte Matching (PBM) mode
+ * - Ability to add/remove patterns for PBM
+ *
+ * A Magic Packet is a packet that contains 6 0xFFs followed by 16
+ * contiguous copies of the receiving NIC's Ethernet address. There is
+ * no API to configure Magic Packet Pattern.
+ *
+ * Wakeup pattern (used for PBM) is defined as following:
+ * struct
+ * {
+ * U8 PatternSize; // Non-Zero pattern size
+ * U8 PatternMaskSize; // Non-zero pattern mask size
+ * U8 PatternMask[PatternMaskSize]; // Pattern mask
+ * U8 Pattern[PatternSize]; // Pattern
+ * } hdd_wowl_ptrn_t;
+ *
+ * PatternSize and PatternMaskSize indicate size of the variable
+ * length Pattern and PatternMask. PatternMask indicates which bytes
+ * of an incoming packet should be compared with corresponding bytes
+ * in the pattern.
+ *
+ * Maximum allowed pattern size is 128 bytes. Maximum allowed
+ * PatternMaskSize is 16 bytes.
+ *
+ * Maximum number of patterns that can be configured is 8
+ *
+ * PMO will add following 2 commonly used patterns for PBM by default:
+ * 1) ARP Broadcast Pattern
+ * 2) Unicast Pattern
+ *
+ * However note that WoWL will not be enabled by default by PMO. WoWL
+ * needs to enabled explcitly by exercising the iwpriv command.
+ *
+ * PMO will expose an API that accepts patterns as Hex string in the
+ * following format:
+ * "PatternSize:PatternMaskSize:PatternMask:Pattern"
+ *
+ * Multiple patterns can be specified by deleimiting each pattern with
+ * the ';' token:
+ * "PatternSize1:PatternMaskSize1:PatternMask1:Pattern1;PatternSize2:..."
+ *
+ * Patterns can be configured dynamically via iwpriv cmd or statically
+ * via qcom_cfg.ini file
+ *
+ * PBM (when enabled) can perform filtering on unicast data or
+ * broadcast data or both. These configurations are part of factory
+ * default (cfg.dat) and the default behavior is to perform filtering
+ * on both unicast and data frames.
+ *
+ * MP filtering (when enabled) is performed ALWAYS on both unicast and
+ * broadcast data frames.
+ *
+ * Management frames are not subjected to WoWL filtering and are
+ * discarded when WoWL is enabled.
+ *
+ * Whenever a patern match succeeds, RX path is restored and packets
+ * (both management and data) will be pushed to the host from that
+ * point onwards. Therefore, exit from WoWL is implicit and happens
+ * automatically when the first packet match succeeds.
+ *
+ * WoWL works on top of BMPS. So when WoWL is requested, SME will
+ * attempt to put the device in BMPS mode (if not already in BMPS). If
+ * attempt to BMPS fails, request for WoWL will be rejected.
+ */
+
+#define PMO_WOW_MAX_EVENT_BM_LEN 4
+
+/**
+ * pmo_get_and_increment_wow_default_ptrn() -Get and increment wow default ptrn
+ * @vdev_ctx: pmo vdev priv ctx
+ *
+ * API to get and increment wow default ptrn
+ *
+ * Return: current wow default ptrn count
+ */
+static inline uint8_t pmo_get_and_increment_wow_default_ptrn(
+ struct pmo_vdev_priv_obj *vdev_ctx)
+{
+ uint8_t count;
+
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ count = vdev_ctx->num_wow_default_patterns++;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ return count;
+}
+
+/**
+ * pmo_increment_wow_default_ptrn() -increment wow default ptrn
+ * @vdev_ctx: pmo vdev priv ctx
+ *
+ * API to increment wow default ptrn
+ *
+ * Return: None
+ */
+static inline void pmo_increment_wow_default_ptrn(
+ struct pmo_vdev_priv_obj *vdev_ctx)
+{
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ vdev_ctx->num_wow_default_patterns++;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+}
+
+/**
+ * pmo_decrement_wow_default_ptrn() -decrement wow default ptrn
+ * @vdev_ctx: pmo vdev priv ctx
+ *
+ * API to decrement wow default ptrn
+ *
+ * Return: None
+ */
+static inline void pmo_decrement_wow_default_ptrn(
+ struct pmo_vdev_priv_obj *vdev_ctx)
+{
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ vdev_ctx->num_wow_default_patterns--;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+}
+
+/**
+ * pmo_increment_wow_user_ptrn() -increment wow user ptrn
+ * @vdev_ctx: pmo vdev priv ctx
+ *
+ * API to increment wow user ptrn
+ *
+ * Return: None
+ */
+static inline void pmo_increment_wow_user_ptrn(
+ struct pmo_vdev_priv_obj *vdev_ctx)
+{
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ vdev_ctx->num_wow_user_patterns++;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+}
+
+/**
+ * pmo_decrement_wow_user_ptrn() -decrement wow user ptrn
+ * @vdev_ctx: pmo vdev priv ctx
+ *
+ * API to decrement wow user ptrn
+ *
+ * Return: None
+ */
+static inline void pmo_decrement_wow_user_ptrn(
+ struct pmo_vdev_priv_obj *vdev_ctx)
+{
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ vdev_ctx->num_wow_user_patterns--;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+}
+
+void pmo_dump_wow_ptrn(struct pmo_wow_add_pattern *ptrn);
+
+/**
+ * pmo_core_add_wow_pattern() - Function which will add the WoWL pattern to be
+ * used when PBM filtering is enabled
+ * @vdev: pointer to the vdev
+ * @ptrn: pointer to the pattern string to be added
+ *
+ * Return: false if any errors encountered, QDF_STATUS_SUCCESS otherwise
+ */
+QDF_STATUS pmo_core_add_wow_pattern(struct wlan_objmgr_vdev *vdev,
+ const char *ptrn);
+
+/**
+ * pmo_core_del_wow_pattern() - Function which will delete the WoWL pattern
+ * @vdev: pointer to the vdev
+ * @ptrn: pointer to the pattern string to be added
+ *
+ * Return: error if any errors encountered, QDF_STATUS_SUCCESS otherwise
+ */
+QDF_STATUS pmo_core_del_wow_pattern(struct wlan_objmgr_vdev *vdev,
+ const char *ptrn);
+
+/**
+ * pmo_core_wow_enter() - store enable/disable status for pattern
+ * @wma: wma handle
+ * @info: wow parameters
+ *
+ * Records pattern enable/disable status locally. This choice will
+ * take effect when the driver enter into suspend state.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_core_wow_enter(struct wlan_objmgr_vdev *vdev,
+ struct pmo_wow_enter_params *wow_enter_param);
+
+/**
+ * pmo_core_wow_exit() - clear all wma states
+ * @wma: wma handle
+ * @info: wow params
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_core_wow_exit(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_core_enable_wakeup_event() - enable wow wakeup events
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id
+ * @bitmap: Event bitmap
+ *
+ * Return: none
+ */
+void pmo_core_enable_wakeup_event(struct wlan_objmgr_psoc *psoc,
+ uint32_t vdev_id, uint32_t *bitmap);
+
+/**
+ * pmo_core_disable_wakeup_event() - disable wow wakeup events
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id
+ * @bitmap: Event bitmap
+ *
+ * Return: none
+ */
+void pmo_core_disable_wakeup_event(struct wlan_objmgr_psoc *psoc,
+ uint32_t vdev_id, uint32_t *bitmap);
+
+/**
+ * pmo_is_wow_applicable(): should enable wow
+ * @psoc: objmgr psoc object
+ *
+ * Enable WOW if any one of the condition meets,
+ * 1) Is any one of vdev in beaconning mode (in AP mode) ?
+ * 2) Is any one of vdev in connected state (in STA mode) ?
+ * 3) Is PNO in progress in any one of vdev ?
+ * 4) Is Extscan in progress in any one of vdev ?
+ * 5) Is P2P listen offload in any one of vdev?
+ * 6) Is any vdev in NAN data mode? BSS is already started at the
+ * the time of device creation. It is ready to accept data
+ * requests.
+ * 7) If LPASS feature is enabled
+ * 8) If NaN feature is enabled
+ * If none of above conditions is true then return false
+ *
+ * Return: true if wma needs to configure wow false otherwise.
+ */
+bool pmo_core_is_wow_applicable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_core_update_wow_enable() - update wow enable flag
+ * @psoc_ctx: Pointer to objmgr psoc handle
+ * @value: true if wow mode enable else false
+ *
+ * Return: None
+ */
+static inline
+void pmo_core_update_wow_enable(struct pmo_psoc_priv_obj *psoc_ctx,
+ bool value)
+{
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ psoc_ctx->wow.wow_enable = value;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+}
+
+/**
+ * pmo_core_is_wow_mode_enabled() - check if wow needs to be enabled in fw
+ * @psoc_ctx: Pointer to objmgr psoc handle
+ *
+ * API to check if wow mode is enabled in fwr as part of apps suspend or not
+ *
+ * Return: true is wow mode is enabled else false
+ */
+static inline
+bool pmo_core_is_wow_enabled(struct pmo_psoc_priv_obj *psoc_ctx)
+{
+ bool value;
+
+ if (!psoc_ctx) {
+ pmo_err("psoc_ctx is null");
+ return false;
+ }
+
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ value = psoc_ctx->wow.wow_enable;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+ pmo_debug("WoW enable %d", value);
+
+ return value;
+}
+
+/**
+ * pmo_core_set_wow_nack() - Set wow nack flag
+ * @psoc_ctx: Pointer to objmgr psoc handle
+ * @value: true if received wow nack from else false
+ *
+ * Return: None
+ */
+static inline
+void pmo_core_set_wow_nack(struct pmo_psoc_priv_obj *psoc_ctx, bool value)
+{
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ psoc_ctx->wow.wow_nack = value;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+}
+
+/**
+ * pmo_core_get_wow_nack() - Get wow nack flag
+ * @psoc_ctx: Pointer to objmgr psoc handle
+ *
+ * Return: wow nack flag
+ */
+static inline
+bool pmo_core_get_wow_nack(struct pmo_psoc_priv_obj *psoc_ctx)
+{
+ bool value;
+
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ value = psoc_ctx->wow.wow_nack;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+
+ return value;
+}
+/**
+ * pmo_core_update_wow_enable_cmd_sent() - update wow enable cmd sent flag
+ * @psoc_ctx: Pointer to objmgr psoc handle
+ * @value: true if wow enable cmd sent else false
+ *
+ * Return: None
+ */
+static inline
+void pmo_core_update_wow_enable_cmd_sent(struct pmo_psoc_priv_obj *psoc_ctx,
+ bool value)
+{
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ psoc_ctx->wow.wow_enable_cmd_sent = value;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+}
+
+/**
+ * pmo_core_get_wow_enable_cmd_sent() - Get wow enable cmd sent flag
+ * @psoc_ctx: Pointer to objmgr psoc handle
+ *
+ * Return: return true if wow enable cmd sent else false
+ */
+static inline
+bool pmo_core_get_wow_enable_cmd_sent(struct pmo_psoc_priv_obj *psoc_ctx)
+{
+ bool value;
+
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ value = psoc_ctx->wow.wow_enable_cmd_sent;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+
+ return value;
+}
+
+/**
+ * pmo_core_update_wow_initial_wake_up() - update wow initial wake up
+ * @psoc_ctx: Pointer to objmgr psoc handle
+ * @value: true if wow initial wake up is received else false
+ *
+ * Return: None
+ */
+static inline
+void pmo_core_update_wow_initial_wake_up(struct pmo_psoc_priv_obj *psoc_ctx,
+ bool value)
+{
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ psoc_ctx->wow.wow_initial_wake_up = value;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+}
+
+/**
+ * pmo_core_get_wow_initial_wake_up() - Get wow initial wake up
+ * @psoc_ctx: Pointer to objmgr psoc handle
+ *
+ * Return: true if wow initial wake up is received else false
+ */
+static inline
+bool pmo_core_get_wow_initial_wake_up(struct pmo_psoc_priv_obj *psoc_ctx)
+{
+ bool value;
+
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ value = psoc_ctx->wow.wow_initial_wake_up;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+
+ return value;
+}
+
+#ifdef FEATURE_WLAN_EXTSCAN
+/**
+ * pmo_core_is_extscan_in_progress(): check if a extscan is in progress
+ * @vdev: objmgr vdev handle
+ *
+ * Return: TRUE/FALSE
+ */
+static inline
+bool pmo_core_is_extscan_in_progress(struct wlan_objmgr_vdev *vdev)
+{
+ bool extscan_in_progress;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ extscan_in_progress = vdev_ctx->extscan_in_progress;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ return extscan_in_progress;
+}
+
+/**
+ * pmo_core_update_extscan_in_progress(): update extscan is in progress flags
+ * @vdev: objmgr vdev handle
+ * @value:true if extscan is in progress else false
+ *
+ * Return: TRUE/FALSE
+ */
+static inline
+void pmo_core_update_extscan_in_progress(struct wlan_objmgr_vdev *vdev,
+ bool value)
+{
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ vdev_ctx->extscan_in_progress = value;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+}
+#else
+static inline
+bool pmo_core_is_extscan_in_progress(struct wlan_objmgr_vdev *vdev)
+{
+ return false;
+}
+
+static inline
+void pmo_core_update_extscan_in_progress(struct wlan_objmgr_vdev *vdev,
+ bool value)
+{
+}
+#endif
+
+/**
+ * pmo_core_is_p2plo_in_progress(): check if p2plo is in progress
+ * @vdev: objmgr vdev handle
+ *
+ * Return: TRUE/FALSE
+ */
+static inline
+bool pmo_core_is_p2plo_in_progress(struct wlan_objmgr_vdev *vdev)
+{
+ bool p2plo_in_progress;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ p2plo_in_progress = vdev_ctx->p2plo_in_progress;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ return p2plo_in_progress;
+}
+
+/**
+ * pmo_core_update_p2plo_in_progress(): update p2plo is in progress flags
+ * @vdev: objmgr vdev handle
+ * @value:true if p2plo is in progress else false
+ *
+ * Return: TRUE/FALSE
+ */
+static inline
+void pmo_core_update_p2plo_in_progress(struct wlan_objmgr_vdev *vdev,
+ bool value)
+{
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ vdev_ctx->p2plo_in_progress = value;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+}
+
+#ifdef WLAN_FEATURE_LPSS
+/**
+ * pmo_is_lpass_enabled() - check if lpass is enabled
+ * @vdev: objmgr vdev handle
+ *
+ * WoW is needed if LPASS or NaN feature is enabled in INI because
+ * target can't wake up itself if its put in PDEV suspend when LPASS
+ * or NaN features are supported
+ *
+ * Return: true if lpass is enabled else false
+ */
+static inline
+bool pmo_core_is_lpass_enabled(struct wlan_objmgr_vdev *vdev)
+{
+ bool lpass_enable;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ lpass_enable = vdev_ctx->pmo_psoc_ctx->psoc_cfg.lpass_enable;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ return lpass_enable;
+}
+#else
+static inline
+bool pmo_core_is_lpass_enabled(struct wlan_objmgr_vdev *vdev)
+{
+ return false;
+}
+#endif
+
+#ifdef WLAN_FEATURE_NAN
+/**
+ * pmo_is_nan_enabled() - check if NaN is enabled
+ * @vdev: objmgr vdev handle
+ *
+ * WoW is needed if LPASS or NaN feature is enabled in INI because
+ * target can't wake up itself if its put in PDEV suspend when LPASS
+ * or NaN features are supported
+ *
+ * Return: true if NaN is enabled else false
+ */
+static inline
+bool pmo_core_is_nan_enabled(struct wlan_objmgr_vdev *vdev)
+{
+ bool nan_enable;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ nan_enable = vdev_ctx->pmo_psoc_ctx->psoc_cfg.nan_enable;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ return nan_enable;
+}
+#else
+static inline
+bool pmo_core_is_nan_enabled(struct wlan_objmgr_vdev *vdev)
+{
+ return false;
+}
+#endif
+
+/**
+ * pmo_get_event_bitmap_idx() - get indices for extended wow bitmaps
+ * @event: wow event
+ * @wow_bitmap_size: WOW bitmap size
+ * @bit_idx: bit index
+ * @idx: byte index
+ *
+ * Return: none
+ */
+static inline void pmo_get_event_bitmap_idx(WOW_WAKE_EVENT_TYPE event,
+ uint32_t wow_bitmap_size,
+ uint32_t *bit_idx,
+ uint32_t *idx)
+{
+
+ if (!bit_idx || !idx || wow_bitmap_size == 0) {
+ pmo_err("bit_idx:%p idx:%p wow_bitmap_size:%u",
+ bit_idx, idx, wow_bitmap_size);
+ return;
+ }
+ if (event == 0) {
+ *idx = *bit_idx = 0;
+ } else {
+ *idx = event / (wow_bitmap_size * 8);
+ *bit_idx = event % (wow_bitmap_size * 8);
+ }
+}
+#endif /* end of _WLAN_PMO_WOW_H_ */
diff --git a/components/pmo/core/src/wlan_pmo_arp.c b/components/pmo/core/src/wlan_pmo_arp.c
new file mode 100644
index 0000000..c419414
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_arp.c
@@ -0,0 +1,368 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Implements arp offload feature API's
+ */
+
+#include "wlan_pmo_arp.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+static QDF_STATUS pmo_core_cache_arp_in_vdev_priv(
+ struct pmo_arp_req *arp_req,
+ struct wlan_objmgr_vdev *vdev)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ struct pmo_arp_offload_params *request = NULL;
+ struct pmo_psoc_priv_obj *psoc_ctx;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+ int index;
+ struct qdf_mac_addr peer_bssid;
+
+ PMO_ENTER();
+ psoc_ctx = pmo_psoc_get_priv(arp_req->psoc);
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ request = qdf_mem_malloc(sizeof(*request));
+ if (!request) {
+ pmo_err("cannot allocate arp request");
+ status = QDF_STATUS_E_NOMEM;
+ goto out;
+ }
+
+ status = pmo_get_vdev_bss_peer_mac_addr(vdev,
+ &peer_bssid);
+ if (status != QDF_STATUS_SUCCESS)
+ goto out;
+
+ qdf_mem_copy(&request->bssid.bytes, &peer_bssid.bytes,
+ QDF_MAC_ADDR_SIZE);
+ pmo_info("vdev self mac addr: %pM bss peer mac addr: %pM",
+ wlan_vdev_mlme_get_macaddr(vdev),
+ peer_bssid.bytes);
+
+ request->enable = PMO_OFFLOAD_ENABLE;
+ /* converting u32 to IPV4 address */
+ for (index = 0; index < PMO_IPV4_ADDR_LEN; index++)
+ request->host_ipv4_addr[index] =
+ (arp_req->ipv4_addr >> (index * 8)) & 0xFF;
+
+ /* cache arp request */
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ qdf_mem_copy(&vdev_ctx->vdev_arp_req, request,
+ sizeof(vdev_ctx->vdev_arp_req));
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+ pmo_info("arp offload ipv4 addr: %d.%d.%d.%d enable: %d",
+ request->host_ipv4_addr[0],
+ request->host_ipv4_addr[1],
+ request->host_ipv4_addr[2],
+ request->host_ipv4_addr[3],
+ request->enable);
+out:
+ if (request)
+ qdf_mem_free(request);
+ PMO_EXIT();
+
+ return status;
+}
+
+static QDF_STATUS pmo_core_flush_arp_from_vdev_priv(
+ struct wlan_objmgr_vdev *vdev)
+{
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ PMO_ENTER();
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ /* clear arp request */
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ qdf_mem_zero(&vdev_ctx->vdev_arp_req, sizeof(vdev_ctx->vdev_arp_req));
+ vdev_ctx->vdev_arp_req.enable = PMO_OFFLOAD_DISABLE;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ PMO_EXIT();
+
+ return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS pmo_core_do_enable_arp_offload(struct wlan_objmgr_vdev *vdev,
+ uint8_t vdev_id, enum pmo_offload_trigger trigger)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ struct pmo_psoc_priv_obj *psoc_ctx;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ PMO_ENTER();
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ psoc_ctx = vdev_ctx->pmo_psoc_ctx;
+ if (!psoc_ctx) {
+ pmo_err("psoc_ctx is NULL");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ switch (trigger) {
+ case pmo_ipv4_change_notify:
+ if (!psoc_ctx->psoc_cfg.active_mode_offload) {
+ pmo_info("active offload is disabled, skip in mode:%d",
+ trigger);
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+ /* enable arp when active offload is true (ipv4 notifier) */
+ status = pmo_tgt_enable_arp_offload_req(vdev, vdev_id);
+ break;
+ case pmo_apps_suspend:
+ if (psoc_ctx->psoc_cfg.active_mode_offload) {
+ pmo_info("active offload is enabled, skip in mode: %d",
+ trigger);
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+ /* enable arp when active offload is false (apps suspend) */
+ status = pmo_tgt_enable_arp_offload_req(vdev, vdev_id);
+ break;
+ default:
+ status = QDF_STATUS_E_INVAL;
+ pmo_err("invalid pmo trigger");
+ break;
+ }
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+static QDF_STATUS pmo_core_do_disable_arp_offload(struct wlan_objmgr_vdev *vdev,
+ uint8_t vdev_id, enum pmo_offload_trigger trigger)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ struct pmo_psoc_priv_obj *psoc_ctx;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ PMO_ENTER();
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ psoc_ctx = vdev_ctx->pmo_psoc_ctx;
+ if (!psoc_ctx) {
+ pmo_err("psoc_ctx is NULL");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ switch (trigger) {
+ case pmo_apps_resume:
+ if (psoc_ctx->psoc_cfg.active_mode_offload) {
+ pmo_info("active offload is enabled, skip in mode: %d",
+ trigger);
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+ /* disable arp on apps resume when active offload is disable */
+ status = pmo_tgt_disable_arp_offload_req(vdev, vdev_id);
+ break;
+ default:
+ status = QDF_STATUS_E_INVAL;
+ pmo_err("invalid pmo trigger");
+ break;
+ }
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+static QDF_STATUS pmo_core_arp_offload_sanity(
+ struct wlan_objmgr_vdev *vdev)
+{
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ if (!vdev) {
+ pmo_err("vdev is NULL");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+ if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.arp_offload_enable) {
+ pmo_err("user disabled arp offload using ini");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ if (!pmo_core_is_vdev_supports_offload(vdev)) {
+ pmo_info("vdev in invalid opmode for arp offload %d",
+ pmo_get_vdev_opmode(vdev));
+ return QDF_STATUS_E_INVAL;
+ }
+
+ if (!pmo_core_is_vdev_connected(vdev))
+ return QDF_STATUS_E_INVAL;
+
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_core_cache_arp_offload_req(struct pmo_arp_req *arp_req)
+{
+ QDF_STATUS status;
+ struct wlan_objmgr_vdev *vdev;
+
+ PMO_ENTER();
+ if (!arp_req) {
+ pmo_err("arp_req is NULL");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ if (!arp_req->psoc) {
+ pmo_err("psoc is NULL");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ vdev = pmo_psoc_get_vdev(arp_req->psoc, arp_req->vdev_id);
+ if (!vdev) {
+ pmo_err("vdev is NULL");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ status = pmo_vdev_get_ref(vdev);
+ if (QDF_IS_STATUS_ERROR(status))
+ goto out;
+
+ status = pmo_core_arp_offload_sanity(vdev);
+ if (status != QDF_STATUS_SUCCESS)
+ goto dec_ref;
+
+ pmo_info("Cache arp for vdev id: %d psoc: %p vdev: %p",
+ arp_req->vdev_id, arp_req->psoc, vdev);
+
+ status = pmo_core_cache_arp_in_vdev_priv(arp_req, vdev);
+dec_ref:
+ pmo_vdev_put_ref(vdev);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_core_flush_arp_offload_req(struct wlan_objmgr_vdev *vdev)
+{
+ QDF_STATUS status;
+ uint8_t vdev_id;
+
+ PMO_ENTER();
+ if (!vdev) {
+ pmo_err("vdev is NULL");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ status = pmo_vdev_get_ref(vdev);
+ if (status != QDF_STATUS_SUCCESS)
+ goto out;
+
+ status = pmo_core_arp_offload_sanity(vdev);
+ if (status != QDF_STATUS_SUCCESS)
+ goto def_ref;
+
+ vdev_id = pmo_vdev_get_id(vdev);
+ pmo_info("Flush arp for vdev id: %d vdev: %p", vdev_id, vdev);
+
+ status = pmo_core_flush_arp_from_vdev_priv(vdev);
+def_ref:
+ pmo_vdev_put_ref(vdev);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_core_enable_arp_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+ enum pmo_offload_trigger trigger)
+{
+ QDF_STATUS status;
+ uint8_t vdev_id;
+
+ PMO_ENTER();
+ if (!vdev) {
+ pmo_err("vdev is NULL");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ status = pmo_vdev_get_ref(vdev);
+ if (status != QDF_STATUS_SUCCESS)
+ goto out;
+
+ status = pmo_core_arp_offload_sanity(vdev);
+ if (status != QDF_STATUS_SUCCESS)
+ goto def_ref;
+
+ vdev_id = pmo_vdev_get_id(vdev);
+ pmo_info("Enable arp offload in fwr vdev id: %d vdev: %p",
+ vdev_id, vdev);
+
+ status = pmo_core_do_enable_arp_offload(vdev, vdev_id, trigger);
+def_ref:
+ pmo_vdev_put_ref(vdev);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_core_disable_arp_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+ enum pmo_offload_trigger trigger)
+{
+ QDF_STATUS status;
+ uint8_t vdev_id;
+
+ PMO_ENTER();
+ if (!vdev) {
+ pmo_err("vdev is NULL");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ status = pmo_vdev_get_ref(vdev);
+ if (status != QDF_STATUS_SUCCESS)
+ goto out;
+
+ status = pmo_core_arp_offload_sanity(vdev);
+ if (status != QDF_STATUS_SUCCESS)
+ goto def_ref;
+
+ vdev_id = pmo_vdev_get_id(vdev);
+ pmo_info("Disable arp offload in fwr vdev id: %d vdev: %p",
+ vdev_id, vdev);
+
+ status = pmo_core_do_disable_arp_offload(vdev, vdev_id, trigger);
+def_ref:
+ pmo_vdev_put_ref(vdev);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
diff --git a/components/pmo/core/src/wlan_pmo_gtk.c b/components/pmo/core/src/wlan_pmo_gtk.c
new file mode 100644
index 0000000..120ff04
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_gtk.c
@@ -0,0 +1,358 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Implements gtk offload feature API's
+ */
+
+#include "wlan_pmo_gtk.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+static QDF_STATUS pmo_core_cache_gtk_req_in_vdev_priv(
+ struct wlan_objmgr_vdev *vdev,
+ struct pmo_gtk_req *gtk_req)
+{
+ struct pmo_vdev_priv_obj *vdev_ctx;
+ QDF_STATUS status;
+ struct qdf_mac_addr peer_bssid;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ status = pmo_get_vdev_bss_peer_mac_addr(vdev, &peer_bssid);
+ if (status != QDF_STATUS_SUCCESS)
+ return status;
+
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ qdf_mem_copy(&vdev_ctx->vdev_gtk_req, gtk_req,
+ sizeof(vdev_ctx->vdev_gtk_req));
+ qdf_mem_copy(&vdev_ctx->vdev_gtk_req.bssid,
+ &peer_bssid, QDF_MAC_ADDR_SIZE);
+ vdev_ctx->vdev_gtk_req.flags = PMO_GTK_OFFLOAD_ENABLE;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS pmo_core_flush_gtk_req_from_vdev_priv(
+ struct wlan_objmgr_vdev *vdev)
+{
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ qdf_mem_zero(&vdev_ctx->vdev_gtk_req, sizeof(vdev_ctx->vdev_gtk_req));
+ vdev_ctx->vdev_gtk_req.flags = PMO_GTK_OFFLOAD_DISABLE;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS pmo_core_do_enable_gtk_offload(
+ struct wlan_objmgr_vdev *vdev,
+ struct pmo_vdev_priv_obj *vdev_ctx,
+ struct pmo_gtk_req *op_gtk_req)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ uint8_t vdev_id;
+
+ if (!pmo_core_is_vdev_supports_offload(vdev)) {
+ pmo_info("vdev in invalid opmode for gtk offload %d",
+ pmo_get_vdev_opmode(vdev));
+ return QDF_STATUS_E_INVAL;
+ }
+
+ if (!pmo_core_is_vdev_connected(vdev))
+ return QDF_STATUS_E_INVAL;
+
+ vdev_id = pmo_vdev_get_id(vdev);
+
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ qdf_mem_copy(op_gtk_req, &vdev_ctx->vdev_gtk_req,
+ sizeof(*op_gtk_req));
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ if ((op_gtk_req->flags == PMO_GTK_OFFLOAD_ENABLE) &&
+ (qdf_atomic_read(&vdev_ctx->gtk_err_enable) == 1)) {
+ pmo_info("GTK Offload already enabled, Disabling vdev_id: %d",
+ vdev_id);
+ op_gtk_req->flags = PMO_GTK_OFFLOAD_DISABLE;
+ status = pmo_tgt_send_gtk_offload_req(vdev, op_gtk_req);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("Failed to disable GTK Offload");
+ goto out;
+ }
+ pmo_debug("Enable GTK Offload again with updated inputs");
+ op_gtk_req->flags = PMO_GTK_OFFLOAD_ENABLE;
+ }
+
+ status = pmo_tgt_send_gtk_offload_req(vdev, op_gtk_req);
+out:
+
+ return status;
+}
+
+static QDF_STATUS pmo_core_is_gtk_enabled_in_fwr(
+ struct wlan_objmgr_vdev *vdev,
+ struct pmo_vdev_priv_obj *vdev_ctx)
+{
+ QDF_STATUS status;
+ struct qdf_mac_addr peer_bssid;
+
+ if (!pmo_core_is_vdev_supports_offload(vdev)) {
+ pmo_info("vdev in invalid opmode for gtk offload enable %d",
+ pmo_get_vdev_opmode(vdev));
+ return QDF_STATUS_E_INVAL;
+ }
+
+ if (!pmo_core_is_vdev_connected(vdev))
+ return QDF_STATUS_E_INVAL;
+
+ status = pmo_get_vdev_bss_peer_mac_addr(vdev,
+ &peer_bssid);
+ if (status != QDF_STATUS_SUCCESS)
+ return QDF_STATUS_E_INVAL;
+
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ if (qdf_mem_cmp(&vdev_ctx->vdev_gtk_req.bssid,
+ &peer_bssid, QDF_MAC_ADDR_SIZE)) {
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+ pmo_err("cache request mac:%pM, peer mac:%pM are not same",
+ vdev_ctx->vdev_gtk_req.bssid.bytes,
+ peer_bssid.bytes);
+ return QDF_STATUS_E_INVAL;
+ }
+
+ if (vdev_ctx->vdev_gtk_req.flags != PMO_GTK_OFFLOAD_ENABLE) {
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+ pmo_err("gtk flag is disabled hence no gtk rsp required");
+ return QDF_STATUS_E_INVAL;
+ }
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS pmo_core_do_disable_gtk_offload(
+ struct wlan_objmgr_vdev *vdev,
+ struct pmo_vdev_priv_obj *vdev_ctx,
+ struct pmo_gtk_req *op_gtk_req)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+ status = pmo_core_is_gtk_enabled_in_fwr(vdev, vdev_ctx);
+ if (status != QDF_STATUS_SUCCESS)
+ return status;
+
+ op_gtk_req->flags = PMO_GTK_OFFLOAD_DISABLE;
+ status = pmo_tgt_send_gtk_offload_req(vdev, op_gtk_req);
+
+ return status;
+}
+
+QDF_STATUS pmo_core_cache_gtk_offload_req(struct wlan_objmgr_vdev *vdev,
+ struct pmo_gtk_req *gtk_req)
+{
+ QDF_STATUS status;
+ enum tQDF_ADAPTER_MODE opmode;
+ uint8_t vdev_id;
+
+ PMO_ENTER();
+ if (!gtk_req) {
+ pmo_err("gtk_req is NULL");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ if (!vdev) {
+ pmo_err("vdev is NULL");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ status = pmo_vdev_get_ref(vdev);
+ if (status != QDF_STATUS_SUCCESS)
+ goto out;
+
+ opmode = pmo_get_vdev_opmode(vdev);
+ vdev_id = pmo_vdev_get_id(vdev);
+ pmo_info("vdev opmode: %d vdev_id: %d", opmode, vdev_id);
+ if (!pmo_core_is_vdev_supports_offload(vdev)) {
+ pmo_info("vdev in invalid opmode for caching gtk request %d",
+ opmode);
+ status = QDF_STATUS_E_INVAL;
+ goto dec_ref;
+ }
+
+ status = pmo_core_cache_gtk_req_in_vdev_priv(vdev, gtk_req);
+dec_ref:
+ pmo_vdev_put_ref(vdev);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_core_flush_gtk_offload_req(struct wlan_objmgr_vdev *vdev)
+{
+ enum tQDF_ADAPTER_MODE opmode;
+ uint8_t vdev_id;
+ QDF_STATUS status;
+
+ PMO_ENTER();
+ if (!vdev) {
+ pmo_err("psoc is NULL");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ status = pmo_vdev_get_ref(vdev);
+ if (status != QDF_STATUS_SUCCESS)
+ goto out;
+
+ opmode = pmo_get_vdev_opmode(vdev);
+ vdev_id = pmo_vdev_get_id(vdev);
+ pmo_info("vdev opmode: %d vdev_id: %d", opmode, vdev_id);
+ if (!pmo_core_is_vdev_supports_offload(vdev)) {
+ pmo_info("vdev in invalid opmode for flushing gtk request %d",
+ opmode);
+ status = QDF_STATUS_E_INVAL;
+ goto dec_ref;
+ }
+
+ status = pmo_core_flush_gtk_req_from_vdev_priv(vdev);
+dec_ref:
+ pmo_vdev_put_ref(vdev);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_core_enable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev)
+{
+ QDF_STATUS status;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+ struct pmo_gtk_req *op_gtk_req = NULL;
+
+ PMO_ENTER();
+ if (!vdev) {
+ pmo_err("vdev is NULL");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ status = pmo_vdev_get_ref(vdev);
+ if (status != QDF_STATUS_SUCCESS)
+ goto out;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ op_gtk_req = qdf_mem_malloc(sizeof(*op_gtk_req));
+ if (!op_gtk_req) {
+ pmo_err("op_gtk_req is NULL");
+ status = QDF_STATUS_E_INVAL;
+ goto dec_ref;
+ }
+ status = pmo_core_do_enable_gtk_offload(vdev, vdev_ctx, op_gtk_req);
+dec_ref:
+ pmo_vdev_put_ref(vdev);
+out:
+ if (op_gtk_req)
+ qdf_mem_free(op_gtk_req);
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_core_disable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev)
+{
+ QDF_STATUS status;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+ struct pmo_gtk_req *op_gtk_req = NULL;
+
+ PMO_ENTER();
+ if (!vdev) {
+ pmo_err("vdev is NULL");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ status = pmo_vdev_get_ref(vdev);
+ if (status != QDF_STATUS_SUCCESS)
+ goto out;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ op_gtk_req = qdf_mem_malloc(sizeof(*op_gtk_req));
+ if (!op_gtk_req) {
+ pmo_err("op_gtk_req is NULL");
+ status = QDF_STATUS_E_NOMEM;
+ goto dec_ref;
+ }
+
+ status = pmo_core_do_disable_gtk_offload(vdev, vdev_ctx, op_gtk_req);
+dec_ref:
+ pmo_vdev_put_ref(vdev);
+out:
+ if (op_gtk_req)
+ qdf_mem_free(op_gtk_req);
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_core_get_gtk_rsp(struct wlan_objmgr_vdev *vdev,
+ struct pmo_gtk_rsp_req *gtk_rsp_req)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ PMO_ENTER();
+ if (!gtk_rsp_req || !vdev) {
+ pmo_err("%s is null", !vdev ? "vdev":"gtk_rsp_req");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ status = pmo_vdev_get_ref(vdev);
+ if (status != QDF_STATUS_SUCCESS)
+ goto out;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ status = pmo_core_is_gtk_enabled_in_fwr(vdev, vdev_ctx);
+ if (status != QDF_STATUS_SUCCESS)
+ goto dec_ref;
+
+ /* cache gtk rsp request */
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ qdf_mem_copy(&vdev_ctx->vdev_gtk_rsp_req, gtk_rsp_req,
+ sizeof(vdev_ctx->vdev_gtk_rsp_req));
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+ /* send cmd to fwr */
+ status = pmo_tgt_get_gtk_rsp(vdev);
+dec_ref:
+ pmo_vdev_put_ref(vdev);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
diff --git a/components/pmo/core/src/wlan_pmo_hw_filter.c b/components/pmo/core/src/wlan_pmo_hw_filter.c
new file mode 100644
index 0000000..ea93d1d
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_hw_filter.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: Implements arp offload feature API's
+ */
+
+#include "qdf_lock.h"
+#include "wlan_pmo_hw_filter.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+static QDF_STATUS pmo_core_conf_hw_filter(struct wlan_objmgr_vdev *vdev,
+ enum pmo_hw_filter_mode mode)
+{
+ QDF_STATUS status;
+ struct pmo_hw_filter_params req = { .mode = mode, };
+
+ PMO_ENTER();
+
+ if (!pmo_core_is_vdev_connected(vdev)) {
+ status = QDF_STATUS_E_NOSUPPORT;
+ goto exit_with_status;
+ }
+
+ req.vdev_id = pmo_vdev_get_id(vdev);
+ status = pmo_tgt_conf_hw_filter(pmo_vdev_get_psoc(vdev), &req);
+
+exit_with_status:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_core_enable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev)
+{
+ QDF_STATUS status;
+ struct pmo_psoc_priv_obj *psoc_priv;
+ enum pmo_hw_filter_mode mode;
+
+ PMO_ENTER();
+
+ status = pmo_vdev_get_ref(vdev);
+ if (QDF_IS_STATUS_ERROR(status))
+ goto exit_with_status;
+
+ psoc_priv = pmo_vdev_get_psoc_priv(vdev);
+ qdf_spin_lock_bh(&psoc_priv->lock);
+ mode = psoc_priv->psoc_cfg.hw_filter_mode;
+ qdf_spin_unlock_bh(&psoc_priv->lock);
+
+ status = pmo_core_conf_hw_filter(vdev, mode);
+
+ pmo_vdev_put_ref(vdev);
+
+exit_with_status:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_core_disable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev)
+{
+ QDF_STATUS status;
+
+ PMO_ENTER();
+
+ status = pmo_vdev_get_ref(vdev);
+ if (QDF_IS_STATUS_ERROR(status))
+ goto exit_with_status;
+
+ status = pmo_core_conf_hw_filter(vdev, PMO_HW_FILTER_DISABLED);
+
+ pmo_vdev_put_ref(vdev);
+
+exit_with_status:
+ PMO_EXIT();
+
+ return status;
+}
diff --git a/components/pmo/core/src/wlan_pmo_lphb.c b/components/pmo/core/src/wlan_pmo_lphb.c
new file mode 100644
index 0000000..31a6372
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_lphb.c
@@ -0,0 +1,243 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Implements low power heart beat offload feature API's
+ */
+
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_lphb.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+#ifdef FEATURE_WLAN_LPHB
+/**
+ * pmo_core_send_lphb_enable() - enable command of LPHB configuration requests
+ * @psoc: objmgr psoc handle
+ * @psoc_ctx: pmo private psoc ctx
+ * @lphb_conf_req: lphb request which need s to configure in fwr
+ * @by_user: whether this call is from user or cached resent
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS pmo_core_send_lphb_enable(struct wlan_objmgr_psoc *psoc,
+ struct pmo_psoc_priv_obj *psoc_ctx,
+ struct pmo_lphb_req *lphb_conf_req, bool by_user)
+{
+ QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+ struct pmo_lphb_enable_req *ts_lphb_enable;
+ int i;
+
+ if (lphb_conf_req == NULL) {
+ pmo_err("LPHB configuration is NULL");
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ ts_lphb_enable = &(lphb_conf_req->params.lphb_enable_req);
+ qdf_status = pmo_tgt_send_lphb_enable(psoc, ts_lphb_enable);
+ if (qdf_status != QDF_STATUS_SUCCESS)
+ goto out;
+
+ /* No need to cache non user request */
+ if (!by_user) {
+ qdf_status = QDF_STATUS_SUCCESS;
+ goto out;
+ }
+
+ /* target already configured, now cache command status */
+ if (ts_lphb_enable->enable) {
+ i = ts_lphb_enable->item - 1;
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ psoc_ctx->wow.lphb_cache[i].cmd
+ = pmo_lphb_set_en_param_indid;
+ psoc_ctx->wow.lphb_cache[i].params.lphb_enable_req.enable =
+ ts_lphb_enable->enable;
+ psoc_ctx->wow.lphb_cache[i].params.lphb_enable_req.item =
+ ts_lphb_enable->item;
+ psoc_ctx->wow.lphb_cache[i].params.lphb_enable_req.session =
+ ts_lphb_enable->session;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+ pmo_info("cached LPHB status in WMA context for item %d", i);
+ } else {
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ qdf_mem_zero((void *)&psoc_ctx->wow.lphb_cache,
+ sizeof(psoc_ctx->wow.lphb_cache));
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+ pmo_info("cleared all cached LPHB status in WMA context");
+ }
+
+out:
+ return qdf_status;
+}
+
+/**
+ * pmo_core_send_lphb_tcp_params() - Send tcp params of LPHB requests
+ * @psoc: objmgr psoc handle
+ * @lphb_conf_req: lphb request which needs to be configured in fwr
+ *
+ * Return: QDF status
+ */
+static
+QDF_STATUS pmo_core_send_lphb_tcp_params(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_req *lphb_conf_req)
+{
+ return pmo_tgt_send_lphb_tcp_params(psoc,
+ &lphb_conf_req->params.lphb_tcp_params);
+
+}
+
+/**
+ * pmo_core_send_lphb_tcp_pkt_filter() - Send tcp packet filter command of LPHB
+ * @psoc: objmgr psoc handle
+ * @lphb_conf_req: lphb request which needs to be configured in fwr
+ *
+ * Return: QDF status
+ */
+static
+QDF_STATUS pmo_core_send_lphb_tcp_pkt_filter(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_req *lphb_conf_req)
+{
+ return pmo_tgt_send_lphb_tcp_pkt_filter(psoc,
+ &lphb_conf_req->params.lphb_tcp_filter_req);
+}
+
+/**
+ * pmo_core_send_lphb_udp_params() - Send udp param command of LPHB
+ * @psoc: objmgr psoc handle
+ * @lphb_conf_req: lphb request which needs to be configured in fwr
+ *
+ * Return: QDF status
+ */
+static
+QDF_STATUS pmo_core_send_lphb_udp_params(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_req *lphb_conf_req)
+{
+ return pmo_tgt_send_lphb_udp_params(psoc,
+ &lphb_conf_req->params.lphb_udp_params);
+}
+
+/**
+ * pmo_core_send_lphb_udp_pkt_filter() - Send udp pkt filter command of LPHB
+ * @psoc: objmgr psoc handle
+ * @lphb_conf_req: lphb request which need s to configure in fwr
+ *
+ * Return: QDF status
+ */
+static
+QDF_STATUS pmo_core_send_lphb_udp_pkt_filter(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_req *lphb_conf_req)
+{
+ return pmo_tgt_send_lphb_udp_pkt_filter(psoc,
+ &lphb_conf_req->params.lphb_udp_filter_req);
+}
+
+/**
+ * pmo_process_lphb_conf_req() - handle LPHB configuration requests
+ * @psoc: objmgr psoc handle
+ * @psoc_ctx: pmo private psoc ctx
+ * @lphb_conf_req: lphb request which needs to be configured in fwr
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS pmo_process_lphb_conf_req(struct wlan_objmgr_psoc *psoc,
+ struct pmo_psoc_priv_obj *psoc_ctx,
+ struct pmo_lphb_req *lphb_conf_req)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+ pmo_info("LPHB configuration cmd id is %d", lphb_conf_req->cmd);
+ switch (lphb_conf_req->cmd) {
+ case pmo_lphb_set_en_param_indid:
+ status = pmo_core_send_lphb_enable(psoc, psoc_ctx,
+ lphb_conf_req, true);
+ break;
+
+ case pmo_lphb_set_tcp_pararm_indid:
+ status = pmo_core_send_lphb_tcp_params(psoc, lphb_conf_req);
+ break;
+
+ case pmo_lphb_set_tcp_pkt_filter_indid:
+ status = pmo_core_send_lphb_tcp_pkt_filter(psoc, lphb_conf_req);
+ break;
+
+ case pmo_lphb_set_udp_pararm_indid:
+ status = pmo_core_send_lphb_udp_params(psoc, lphb_conf_req);
+ break;
+
+ case pmo_lphb_set_udp_pkt_filter_indid:
+ status = pmo_core_send_lphb_udp_pkt_filter(psoc, lphb_conf_req);
+ break;
+
+ case pmo_lphb_set_network_info_indid:
+ default:
+ break;
+ }
+
+ return status;
+}
+
+void pmo_core_apply_lphb(struct wlan_objmgr_psoc *psoc)
+{
+ int i;
+ struct pmo_psoc_priv_obj *psoc_ctx;
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+
+ pmo_debug("checking LPHB cache");
+ for (i = 0; i < 2; i++) {
+ if (psoc_ctx->wow.lphb_cache[i].params.lphb_enable_req.enable) {
+ pmo_debug("LPHB cache for item %d is marked as enable",
+ i + 1);
+ pmo_core_send_lphb_enable(psoc, psoc_ctx,
+ &(psoc_ctx->wow.lphb_cache[i]), false);
+ }
+ }
+}
+
+QDF_STATUS pmo_core_lphb_config_req(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_req *lphb_req, void *lphb_cb_ctx,
+ pmo_lphb_callback callback)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx;
+
+ if (lphb_req == NULL) {
+ pmo_err("LPHB configuration is NULL");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+
+ if (pmo_lphb_set_en_param_indid == lphb_req->cmd) {
+ if (!lphb_cb_ctx) {
+ pmo_err("lphb callback context is null");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+ if (!callback) {
+ pmo_err("lphb callback function is null");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ psoc_ctx->wow.lphb_cb_ctx = lphb_cb_ctx;
+ psoc_ctx->wow.lphb_cb = callback;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+ }
+
+ return pmo_process_lphb_conf_req(psoc, psoc_ctx, lphb_req);
+}
+
+#endif /* FEATURE_WLAN_LPHB */
+
diff --git a/components/pmo/core/src/wlan_pmo_main.c b/components/pmo/core/src/wlan_pmo_main.c
new file mode 100644
index 0000000..58fac41
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_main.c
@@ -0,0 +1,256 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Implement various api / helper function which shall be used
+ * PMO user and target interface.
+ */
+
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+static struct wlan_pmo_ctx *gp_pmo_ctx;
+
+QDF_STATUS pmo_allocate_ctx(void)
+{
+ /* If it is already created, ignore */
+ if (gp_pmo_ctx != NULL) {
+ pmo_debug("already allocated pmo_ctx");
+ return QDF_STATUS_SUCCESS;
+ }
+
+ /* allocate offload mgr ctx */
+ gp_pmo_ctx = (struct wlan_pmo_ctx *)qdf_mem_malloc(
+ sizeof(*gp_pmo_ctx));
+ if (!gp_pmo_ctx) {
+ pmo_err("unable to allocate pmo_ctx");
+ QDF_ASSERT(0);
+ return QDF_STATUS_E_NOMEM;
+ }
+ qdf_spinlock_create(&gp_pmo_ctx->lock);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+void pmo_free_ctx(void)
+{
+ if (!gp_pmo_ctx) {
+ pmo_err("pmo ctx is already freed");
+ QDF_ASSERT(0);
+ return;
+ }
+ qdf_spinlock_destroy(&gp_pmo_ctx->lock);
+ qdf_mem_free(gp_pmo_ctx);
+ gp_pmo_ctx = NULL;
+}
+
+struct wlan_pmo_ctx *pmo_get_context(void)
+{
+ return gp_pmo_ctx;
+}
+
+bool pmo_is_vdev_in_beaconning_mode(enum tQDF_ADAPTER_MODE vdev_opmode)
+{
+ switch (vdev_opmode) {
+ case QDF_SAP_MODE:
+ case QDF_P2P_GO_MODE:
+ case QDF_IBSS_MODE:
+ return true;
+ default:
+ return false;
+ }
+}
+
+QDF_STATUS pmo_get_vdev_bss_peer_mac_addr(struct wlan_objmgr_vdev *vdev,
+ struct qdf_mac_addr *bss_peer_mac_address)
+{
+ struct wlan_objmgr_peer *peer;
+
+ if (!vdev) {
+ pmo_err("vdev is null");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ peer = wlan_vdev_get_bsspeer(vdev);
+ if (!peer) {
+ pmo_err("peer is null");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ wlan_peer_obj_lock(peer);
+ qdf_mem_copy(bss_peer_mac_address->bytes, wlan_peer_get_macaddr(peer),
+ QDF_MAC_ADDR_SIZE);
+ wlan_peer_obj_unlock(peer);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+bool pmo_core_is_ap_mode_supports_arp_ns(struct wlan_objmgr_psoc *psoc,
+ enum tQDF_ADAPTER_MODE vdev_opmode)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx;
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+
+ if ((vdev_opmode == QDF_SAP_MODE ||
+ vdev_opmode == QDF_P2P_GO_MODE) &&
+ !psoc_ctx->psoc_cfg.ap_arpns_support) {
+ pmo_info("ARP/NS Offload is not supported in SAP/P2PGO mode");
+ return false;
+ }
+
+ return true;
+}
+
+bool pmo_core_is_vdev_connected(struct wlan_objmgr_vdev *vdev)
+{
+ struct wlan_objmgr_peer *peer;
+ enum wlan_peer_state peer_state;
+
+ peer = wlan_vdev_get_bsspeer(vdev);
+
+ if (!peer) {
+ pmo_err("peer is null");
+ return false;
+ }
+ peer_state = wlan_peer_mlme_get_state(peer);
+
+ if (peer_state != WLAN_ASSOC_STATE) {
+ pmo_err("peer is not associated.peer state: %d",
+ peer_state);
+ return false;
+ }
+
+ return true;
+}
+
+bool pmo_core_is_vdev_supports_offload(struct wlan_objmgr_vdev *vdev)
+{
+ enum tQDF_ADAPTER_MODE opmode;
+ bool val;
+
+ opmode = pmo_get_vdev_opmode(vdev);
+ pmo_info("vdev opmode: %d", opmode);
+ switch (opmode) {
+ case QDF_STA_MODE:
+ case QDF_P2P_CLIENT_MODE:
+ case QDF_NDI_MODE:
+ val = true;
+ break;
+ default:
+ val = false;
+ break;
+ }
+
+ return val;
+}
+
+QDF_STATUS pmo_core_get_psoc_config(struct wlan_objmgr_psoc *psoc,
+ struct pmo_psoc_cfg *psoc_cfg)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx;
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+ PMO_ENTER();
+ if (!psoc || !psoc_cfg) {
+ pmo_err("%s is null", !psoc ? "psoc":"psoc_cfg");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+
+ qdf_spin_lock(&psoc_ctx->lock);
+ qdf_mem_copy(psoc_cfg, &psoc_ctx->psoc_cfg, sizeof(*psoc_cfg));
+ qdf_spin_unlock(&psoc_ctx->lock);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_core_update_psoc_config(struct wlan_objmgr_psoc *psoc,
+ struct pmo_psoc_cfg *psoc_cfg)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx;
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+ PMO_ENTER();
+ if (!psoc || !psoc_cfg) {
+ pmo_err("%s is null", !psoc ? "psoc":"psoc_cfg");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+
+ qdf_spin_lock(&psoc_ctx->lock);
+ qdf_mem_copy(&psoc_ctx->psoc_cfg, psoc_cfg, sizeof(*psoc_cfg));
+ qdf_spin_unlock(&psoc_ctx->lock);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+void pmo_core_psoc_set_hif_handle(struct wlan_objmgr_psoc *psoc,
+ void *hif_hdl)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx;
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ psoc_ctx->hif_hdl = hif_hdl;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+}
+
+void *pmo_core_psoc_get_hif_handle(struct wlan_objmgr_psoc *psoc)
+{
+ void *hif_hdl;
+ struct pmo_psoc_priv_obj *psoc_ctx;
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ hif_hdl = psoc_ctx->hif_hdl;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+
+ return hif_hdl;
+}
+
+void pmo_core_psoc_set_txrx_handle(struct wlan_objmgr_psoc *psoc,
+ void *txrx_hdl)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx;
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ psoc_ctx->txrx_hdl = txrx_hdl;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+}
+
+void *pmo_core_psoc_get_txrx_handle(struct wlan_objmgr_psoc *psoc)
+{
+ void *txrx_hdl;
+ struct pmo_psoc_priv_obj *psoc_ctx;
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ txrx_hdl = psoc_ctx->txrx_hdl;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+
+ return txrx_hdl;
+}
diff --git a/components/pmo/core/src/wlan_pmo_mc_addr_filtering.c b/components/pmo/core/src/wlan_pmo_mc_addr_filtering.c
new file mode 100644
index 0000000..be4bb2d
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_mc_addr_filtering.c
@@ -0,0 +1,616 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Implements mc addr filtering offload feature API's
+ */
+
+#include "wlan_pmo_mc_addr_filtering.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+
+#define PMO_INVALID_MC_ADDR_COUNT (-1)
+
+static void pmo_core_fill_mc_list(struct pmo_vdev_priv_obj **vdev_ctx,
+ struct pmo_mc_addr_list_params *ip)
+{
+ struct pmo_mc_addr_list *op_list;
+ int i;
+ static const uint8_t ipv6_rs[] = {
+ 0x33, 0x33, 0x00, 0x00, 0x00, 0x02};
+ struct pmo_vdev_priv_obj *temp_ctx;
+ uint8_t addr_fp;
+
+ temp_ctx = *vdev_ctx;
+ addr_fp = temp_ctx->addr_filter_pattern;
+ op_list = &temp_ctx->vdev_mc_list_req;
+
+ qdf_spin_lock_bh(&temp_ctx->pmo_vdev_lock);
+ op_list->mc_cnt = ip->count;
+ qdf_spin_unlock_bh(&temp_ctx->pmo_vdev_lock);
+
+ for (i = 0; i < ip->count; i++) {
+ pmo_debug("%pM", ip->mc_addr[i].bytes);
+ /*
+ * Skip following addresses:
+ * 1)IPv6 router solicitation address
+ * 2)Any other address pattern if its set during
+ * RXFILTER REMOVE driver command based on
+ * addr_filter_pattern
+ */
+ if ((!qdf_mem_cmp(ip->mc_addr[i].bytes, ipv6_rs,
+ QDF_MAC_ADDR_SIZE)) ||
+ (addr_fp &&
+ (!qdf_mem_cmp(ip->mc_addr[i].bytes, &addr_fp, 1)))) {
+ pmo_debug("MC/BC filtering Skip addr %pM",
+ ip->mc_addr[i].bytes);
+ qdf_spin_lock_bh(&temp_ctx->pmo_vdev_lock);
+ op_list->mc_cnt--;
+ qdf_spin_unlock_bh(&temp_ctx->pmo_vdev_lock);
+ continue;
+ }
+ qdf_spin_lock_bh(&temp_ctx->pmo_vdev_lock);
+ qdf_mem_set(&(op_list->mc_addr[i].bytes), 0,
+ QDF_MAC_ADDR_SIZE);
+ qdf_mem_copy(&(op_list->mc_addr[i].bytes),
+ ip->mc_addr[i].bytes, QDF_MAC_ADDR_SIZE);
+ qdf_spin_unlock_bh(&temp_ctx->pmo_vdev_lock);
+ pmo_debug("mlist[%pM] = ", op_list->mc_addr[i].bytes);
+ }
+}
+
+static QDF_STATUS pmo_core_cache_mc_addr_list_in_vdev_priv(
+ struct pmo_mc_addr_list_params *mc_list_config,
+ struct wlan_objmgr_vdev *vdev)
+{
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+ pmo_core_fill_mc_list(&vdev_ctx, mc_list_config);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS pmo_core_flush_mc_addr_list_from_vdev_priv(
+ struct wlan_objmgr_vdev *vdev)
+{
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ qdf_mem_zero(&vdev_ctx->vdev_mc_list_req,
+ sizeof(vdev_ctx->vdev_mc_list_req));
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_core_set_mc_filter_req(struct wlan_objmgr_vdev *vdev,
+ struct pmo_mc_addr_list *mc_list)
+{
+ uint8_t vdev_id;
+ int i;
+
+ PMO_ENTER();
+
+ vdev_id = pmo_vdev_get_id(vdev);
+ /*
+ * Configure enhance multicast offload feature for filtering out
+ * multicast IP data packets transmitted using unicast MAC address
+ */
+
+ /*
+ * TODO
+ {//(WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap,
+ //WMI_SERVICE_ENHANCED_MCAST_FILTER)) {
+ */
+ if (1) {
+ pmo_info("FW supports enhance multicast offload");
+ pmo_tgt_send_enhance_multicast_offload_req(vdev, vdev_id,
+ false);
+ } else {
+ pmo_info("FW does not support enhance multicast offload");
+ }
+
+ /*
+ * set mc_param->action to clear MCList and reset
+ * to configure the MCList in FW
+ */
+ for (i = 0; i < mc_list->mc_cnt; i++) {
+ pmo_tgt_set_mc_filter_req(vdev,
+ mc_list->mc_addr[i]);
+ }
+
+ PMO_EXIT();
+
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_core_clear_mc_filter_req(struct wlan_objmgr_vdev *vdev,
+ struct pmo_mc_addr_list *mc_list)
+{
+ uint8_t vdev_id;
+ int i;
+
+ PMO_ENTER();
+
+ vdev_id = pmo_vdev_get_id(vdev);
+
+ /*
+ * Configure enhance multicast offload feature for filtering out
+ * multicast IP data packets transmitted using unicast MAC address
+ */
+
+ /*
+ * TODO
+ {//(WMI_SERVICE_IS_ENABLED(wma_handle->wmi_service_bitmap,
+ //WMI_SERVICE_ENHANCED_MCAST_FILTER)) {
+ */
+ if (1) {
+ pmo_info("FW supports enhance multicast offload");
+ pmo_tgt_send_enhance_multicast_offload_req(vdev, vdev_id,
+ true);
+ } else {
+ pmo_info("FW does not support enhance multicast offload");
+ }
+
+ /*
+ * set mcbc_param->action to clear MCList and reset
+ * to configure the MCList in FW
+ */
+ for (i = 0; i < mc_list->mc_cnt; i++) {
+ pmo_tgt_clear_mc_filter_req(vdev, mc_list->mc_addr[i]);
+ }
+
+ PMO_EXIT();
+
+ return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS pmo_core_do_enable_mc_addr_list(struct wlan_objmgr_vdev *vdev,
+ struct pmo_vdev_priv_obj *vdev_ctx,
+ struct pmo_mc_addr_list *op_mc_list_req)
+{
+ QDF_STATUS status;
+
+ PMO_ENTER();
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ if (!vdev_ctx->vdev_mc_list_req.mc_cnt) {
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+ pmo_err("mc_cnt is zero so skip to add mc list");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+ qdf_mem_copy(op_mc_list_req, &vdev_ctx->vdev_mc_list_req,
+ sizeof(*op_mc_list_req));
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ status = pmo_core_set_mc_filter_req(vdev, op_mc_list_req);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("cannot apply mc filter request");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ vdev_ctx->vdev_mc_list_req.is_filter_applied = true;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+static QDF_STATUS pmo_core_do_disable_mc_addr_list(
+ struct wlan_objmgr_vdev *vdev,
+ struct pmo_vdev_priv_obj *vdev_ctx,
+ struct pmo_mc_addr_list *op_mc_list_req)
+{
+ QDF_STATUS status;
+
+ PMO_ENTER();
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ /* validate filter is applied before clearing in fwr */
+ if (!vdev_ctx->vdev_mc_list_req.is_filter_applied) {
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+ pmo_err("mc filter is not applied in fwr");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+ qdf_mem_copy(op_mc_list_req, &vdev_ctx->vdev_mc_list_req,
+ sizeof(*op_mc_list_req));
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ status = pmo_core_clear_mc_filter_req(vdev, op_mc_list_req);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("cannot apply mc filter request");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ vdev_ctx->vdev_mc_list_req.is_filter_applied = false;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+uint8_t pmo_core_max_mc_addr_supported(struct wlan_objmgr_psoc *psoc)
+{
+ return PMO_MAX_MC_ADDR_LIST;
+}
+
+int pmo_core_get_mc_addr_list_count(struct wlan_objmgr_psoc *psoc,
+ uint8_t vdev_id)
+{
+ QDF_STATUS status;
+ struct wlan_objmgr_vdev *vdev;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+ uint8_t mc_cnt;
+
+ vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+ if (!vdev) {
+ pmo_err("vdev is NULL");
+ return PMO_INVALID_MC_ADDR_COUNT;
+ }
+
+ status = pmo_vdev_get_ref(vdev);
+ if (QDF_IS_STATUS_ERROR(status)) {
+ pmo_warn("failed to get vdev reference");
+ return PMO_INVALID_MC_ADDR_COUNT;
+ }
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ mc_cnt = vdev_ctx->vdev_mc_list_req.mc_cnt;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ pmo_vdev_put_ref(vdev);
+
+ return mc_cnt;
+}
+
+void pmo_core_set_mc_addr_list_count(struct wlan_objmgr_psoc *psoc,
+ uint8_t vdev_id, uint8_t count)
+{
+ QDF_STATUS status;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+ struct wlan_objmgr_vdev *vdev;
+
+ vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+ if (!vdev) {
+ pmo_err("vdev is NULL");
+ return;
+ }
+
+ status = pmo_vdev_get_ref(vdev);
+ if (QDF_IS_STATUS_ERROR(status)) {
+ pmo_warn("failed to get vdev reference");
+ return;
+ }
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ vdev_ctx->vdev_mc_list_req.mc_cnt = count;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ pmo_vdev_put_ref(vdev);
+}
+
+static QDF_STATUS pmo_core_mc_addr_flitering_sanity(
+ struct wlan_objmgr_vdev *vdev)
+{
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ if (!vdev) {
+ pmo_err("vdev is NULL");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ /* Check if INI is enabled or not, otherwise just return */
+ if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.enable_mc_list) {
+ pmo_info("user disabled mc_addr_list using INI");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ if (!pmo_core_is_vdev_supports_offload(vdev)) {
+ pmo_info("vdev in invalid opmode for mc addr filtering %d",
+ pmo_get_vdev_opmode(vdev));
+ return QDF_STATUS_E_INVAL;
+ }
+
+ if (!pmo_core_is_vdev_connected(vdev))
+ return QDF_STATUS_E_INVAL;
+
+ return QDF_STATUS_SUCCESS;
+}
+QDF_STATUS pmo_core_cache_mc_addr_list(
+ struct pmo_mc_addr_list_params *mc_list_config)
+{
+ struct wlan_objmgr_vdev *vdev;
+ QDF_STATUS status;
+
+ PMO_ENTER();
+
+ if (!mc_list_config->psoc) {
+ pmo_err("psoc is NULL");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ vdev = pmo_psoc_get_vdev(mc_list_config->psoc, mc_list_config->vdev_id);
+ if (!vdev) {
+ pmo_err("vdev is NULL");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ status = pmo_vdev_get_ref(vdev);
+ if (QDF_IS_STATUS_ERROR(status)) {
+ pmo_warn("failed to get vdev reference");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ status = pmo_core_mc_addr_flitering_sanity(vdev);
+ if (status != QDF_STATUS_SUCCESS)
+ goto dec_ref;
+
+ pmo_info("Cache mc addr list for vdev id: %d psoc: %p vdev: %p",
+ mc_list_config->vdev_id, mc_list_config->psoc, vdev);
+
+ status = pmo_core_cache_mc_addr_list_in_vdev_priv(mc_list_config, vdev);
+dec_ref:
+ pmo_vdev_put_ref(vdev);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_core_flush_mc_addr_list(struct wlan_objmgr_psoc *psoc,
+ uint8_t vdev_id)
+{
+ struct wlan_objmgr_vdev *vdev;
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+ PMO_ENTER();
+ if (!psoc) {
+ pmo_err("psoc is NULL");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+ if (!vdev) {
+ pmo_err("vdev is NULL");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ status = pmo_vdev_get_ref(vdev);
+ if (QDF_IS_STATUS_ERROR(status)) {
+ pmo_warn("failed to get vdev reference");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ status = pmo_core_mc_addr_flitering_sanity(vdev);
+ if (status != QDF_STATUS_SUCCESS)
+ goto dec_ref;
+
+ pmo_info("Flush mc addr list for vdev id: %d psoc: %p vdev: %p",
+ vdev_id, psoc, vdev);
+
+ status = pmo_core_flush_mc_addr_list_from_vdev_priv(vdev);
+
+dec_ref:
+ pmo_vdev_put_ref(vdev);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+static QDF_STATUS pmo_core_handle_enable_mc_list_trigger(
+ struct wlan_objmgr_vdev *vdev,
+ enum pmo_offload_trigger trigger)
+{
+ struct pmo_vdev_priv_obj *vdev_ctx;
+ QDF_STATUS status;
+ struct pmo_mc_addr_list *op_mc_list_req = NULL;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ op_mc_list_req = qdf_mem_malloc(sizeof(*op_mc_list_req));
+ if (!op_mc_list_req) {
+ pmo_err("op_mc_list_req is NULL");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ switch (trigger) {
+ case pmo_mc_list_change_notify:
+ if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.active_mode_offload) {
+ pmo_info("active offload is disabled, skip in mode: %d",
+ trigger);
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+ status = pmo_core_do_enable_mc_addr_list(vdev, vdev_ctx,
+ op_mc_list_req);
+ break;
+ case pmo_apps_suspend:
+ if (vdev_ctx->pmo_psoc_ctx->psoc_cfg.active_mode_offload) {
+ pmo_info("active offload is enabled, skip in mode: %d",
+ trigger);
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+ status = pmo_core_do_enable_mc_addr_list(vdev, vdev_ctx,
+ op_mc_list_req);
+ break;
+ default:
+ status = QDF_STATUS_E_INVAL;
+ pmo_err("invalid pmo trigger for enable mc list");
+ break;
+ }
+out:
+ if (op_mc_list_req)
+ qdf_mem_free(op_mc_list_req);
+
+ return status;
+}
+
+QDF_STATUS pmo_core_enable_mc_addr_filtering_in_fwr(
+ struct wlan_objmgr_psoc *psoc,
+ uint8_t vdev_id,
+ enum pmo_offload_trigger trigger)
+{
+ QDF_STATUS status;
+ struct wlan_objmgr_vdev *vdev;
+
+ PMO_ENTER();
+ if (!psoc) {
+ pmo_err("psoc is NULL");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+ if (!vdev) {
+ pmo_err("vdev is NULL");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ status = pmo_vdev_get_ref(vdev);
+ if (QDF_IS_STATUS_ERROR(status))
+ goto out;
+
+ status = pmo_core_mc_addr_flitering_sanity(vdev);
+ if (status != QDF_STATUS_SUCCESS)
+ goto dec_ref;
+
+ pmo_info("enable mclist trigger: %d", trigger);
+ status = pmo_core_handle_enable_mc_list_trigger(vdev, trigger);
+dec_ref:
+ pmo_vdev_put_ref(vdev);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+static QDF_STATUS pmo_core_handle_disable_mc_list_trigger(
+ struct wlan_objmgr_vdev *vdev,
+ enum pmo_offload_trigger trigger)
+{
+ struct pmo_vdev_priv_obj *vdev_ctx;
+ QDF_STATUS status;
+ struct pmo_mc_addr_list *op_mc_list_req = NULL;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ op_mc_list_req = qdf_mem_malloc(sizeof(*op_mc_list_req));
+ if (!op_mc_list_req) {
+ pmo_err("op_mc_list_req is NULL");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ switch (trigger) {
+ case pmo_peer_disconnect:
+ case pmo_mc_list_change_notify:
+ if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.active_mode_offload) {
+ pmo_info("active offload is disabled, skip in mode: %d",
+ trigger);
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+ status = pmo_core_do_disable_mc_addr_list(vdev, vdev_ctx,
+ op_mc_list_req);
+ break;
+ case pmo_apps_resume:
+ if (vdev_ctx->pmo_psoc_ctx->psoc_cfg.active_mode_offload) {
+ pmo_info("active offload is enabled, skip in mode: %d",
+ trigger);
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+ status = pmo_core_do_disable_mc_addr_list(vdev, vdev_ctx,
+ op_mc_list_req);
+ break;
+ default:
+ status = QDF_STATUS_E_INVAL;
+ pmo_err("invalid pmo trigger for disable mc list");
+ break;
+ }
+out:
+ if (op_mc_list_req)
+ qdf_mem_free(op_mc_list_req);
+
+ return status;
+}
+
+QDF_STATUS pmo_core_disable_mc_addr_filtering_in_fwr(
+ struct wlan_objmgr_psoc *psoc,
+ uint8_t vdev_id,
+ enum pmo_offload_trigger trigger)
+{
+ QDF_STATUS status;
+ struct wlan_objmgr_vdev *vdev;
+
+ PMO_ENTER();
+ if (!psoc) {
+ pmo_err("psoc is NULL");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+ if (!vdev) {
+ pmo_err("vdev is NULL");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ status = pmo_vdev_get_ref(vdev);
+ if (QDF_IS_STATUS_ERROR(status))
+ goto out;
+
+ status = pmo_core_mc_addr_flitering_sanity(vdev);
+ if (status != QDF_STATUS_SUCCESS)
+ goto dec_ref;
+
+ pmo_info("disable mclist trigger: %d", trigger);
+ status = pmo_core_handle_disable_mc_list_trigger(vdev, trigger);
+dec_ref:
+ pmo_vdev_put_ref(vdev);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
diff --git a/components/pmo/core/src/wlan_pmo_ns.c b/components/pmo/core/src/wlan_pmo_ns.c
new file mode 100644
index 0000000..b34374e
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_ns.c
@@ -0,0 +1,454 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Implements ns offload feature API's
+ */
+
+#include "wlan_pmo_ns.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+static void pmo_core_fill_ns_addr(struct pmo_ns_offload_params *request,
+ struct pmo_ns_req *ns_req)
+{
+ int i;
+
+ for (i = 0; i < ns_req->count; i++) {
+ /*
+ * Filling up the request structure
+ * Filling the selfIPv6Addr with solicited address
+ * A Solicited-Node multicast address is created by
+ * taking the last 24 bits of a unicast or anycast
+ * address and appending them to the prefix
+ *
+ * FF02:0000:0000:0000:0000:0001:FFXX:XXXX
+ *
+ * here XX is the unicast/anycast bits
+ */
+ request->self_ipv6_addr[i][0] = 0xFF;
+ request->self_ipv6_addr[i][1] = 0x02;
+ request->self_ipv6_addr[i][11] = 0x01;
+ request->self_ipv6_addr[i][12] = 0xFF;
+ request->self_ipv6_addr[i][13] =
+ ns_req->ipv6_addr[i][13];
+ request->self_ipv6_addr[i][14] =
+ ns_req->ipv6_addr[i][14];
+ request->self_ipv6_addr[i][15] =
+ ns_req->ipv6_addr[i][15];
+ request->slot_idx = i;
+ qdf_mem_copy(&request->target_ipv6_addr[i],
+ &ns_req->ipv6_addr[i][0], PMO_MAC_IPV6_ADDR_LEN);
+
+ request->target_ipv6_addr_valid[i] =
+ PMO_IPV6_ADDR_VALID;
+ request->target_ipv6_addr_ac_type[i] =
+ ns_req->ipv6_addr_type[i];
+
+ pmo_info("NSoffload solicitIp: %pI6 targetIp: %pI6 Index: %d",
+ &request->self_ipv6_addr[i],
+ &request->target_ipv6_addr[i], i);
+ }
+}
+
+static QDF_STATUS pmo_core_cache_ns_in_vdev_priv(
+ struct pmo_ns_req *ns_req,
+ struct wlan_objmgr_vdev *vdev)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+ struct pmo_ns_offload_params request;
+ struct wlan_objmgr_peer *peer;
+
+ PMO_ENTER();
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ qdf_mem_zero(&request, sizeof(request));
+ pmo_core_fill_ns_addr(&request, ns_req);
+
+ request.enable = PMO_OFFLOAD_ENABLE;
+ qdf_mem_copy(&request.self_macaddr.bytes,
+ wlan_vdev_mlme_get_macaddr(vdev),
+ QDF_MAC_ADDR_SIZE);
+
+ /* set number of ns offload address count */
+ request.num_ns_offload_count = ns_req->count;
+
+ peer = wlan_vdev_get_bsspeer(vdev);
+ if (!peer) {
+ pmo_err("peer is null");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+ pmo_info("vdev self mac addr: %pM bss peer mac addr: %pM",
+ wlan_vdev_mlme_get_macaddr(vdev),
+ wlan_peer_get_macaddr(peer));
+ /* get peer and peer mac accdress aka ap mac address */
+ qdf_mem_copy(&request.bssid,
+ wlan_peer_get_macaddr(peer),
+ QDF_MAC_ADDR_SIZE);
+ /* cache ns request */
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ qdf_mem_copy(&vdev_ctx->vdev_ns_req, &request,
+ sizeof(vdev_ctx->vdev_ns_req));
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+static QDF_STATUS pmo_core_flush_ns_from_vdev_priv(
+ struct wlan_objmgr_vdev *vdev)
+{
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ PMO_ENTER();
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ /* clear ns request */
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ qdf_mem_zero(&vdev_ctx->vdev_ns_req, sizeof(vdev_ctx->vdev_ns_req));
+ vdev_ctx->vdev_ns_req.enable = PMO_OFFLOAD_DISABLE;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ PMO_EXIT();
+
+ return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS pmo_core_do_enable_ns_offload(struct wlan_objmgr_vdev *vdev,
+ uint8_t vdev_id, enum pmo_offload_trigger trigger)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ struct pmo_psoc_priv_obj *psoc_ctx;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ PMO_ENTER();
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ psoc_ctx = vdev_ctx->pmo_psoc_ctx;
+ if (!psoc_ctx) {
+ pmo_err("psoc_ctx is NULL");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ switch (trigger) {
+ case pmo_ipv6_change_notify:
+ case pmo_ns_offload_dynamic_update:
+ if (!psoc_ctx->psoc_cfg.active_mode_offload) {
+ pmo_info("active offload is disabled, skip in mode:%d",
+ trigger);
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+ /* enable arp when active offload is true (ipv6 notifier) */
+ status = pmo_tgt_enable_ns_offload_req(vdev, vdev_id);
+ break;
+ case pmo_apps_suspend:
+ if (psoc_ctx->psoc_cfg.active_mode_offload) {
+ pmo_info("active offload is enabled, skip in mode: %d",
+ trigger);
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+ /* enable arp when active offload is false (apps suspend) */
+ status = pmo_tgt_enable_ns_offload_req(vdev, vdev_id);
+ break;
+ default:
+ status = QDF_STATUS_E_INVAL;
+ pmo_err("invalid pmo trigger");
+ break;
+ }
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+static QDF_STATUS pmo_core_do_disable_ns_offload(struct wlan_objmgr_vdev *vdev,
+ uint8_t vdev_id, enum pmo_offload_trigger trigger)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ struct pmo_psoc_priv_obj *psoc_ctx;
+
+ PMO_ENTER();
+
+ psoc_ctx = pmo_vdev_get_psoc_priv(vdev);
+
+ switch (trigger) {
+ case pmo_ipv6_change_notify:
+ case pmo_ns_offload_dynamic_update:
+ if (!psoc_ctx->psoc_cfg.active_mode_offload) {
+ pmo_info("active offload is disabled, skip in mode:%d",
+ trigger);
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+ /* config ns when active offload is enable */
+ status = pmo_tgt_disable_ns_offload_req(vdev, vdev_id);
+ break;
+ case pmo_apps_resume:
+ if (psoc_ctx->psoc_cfg.active_mode_offload) {
+ pmo_info("active offload is enabled, skip in mode: %d",
+ trigger);
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+ /* config arp/ns when active offload is disable */
+ status = pmo_tgt_disable_ns_offload_req(vdev, vdev_id);
+ break;
+ default:
+ status = QDF_STATUS_E_INVAL;
+ pmo_err("invalid pmo trigger");
+ break;
+ }
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+
+static QDF_STATUS pmo_core_ns_offload_sanity(struct wlan_objmgr_vdev *vdev)
+{
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.ns_offload_enable_static) {
+ pmo_info("ns offload statically disable");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.ns_offload_enable_dynamic) {
+ pmo_info("ns offload dynamically disable");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ if (!pmo_core_is_vdev_supports_offload(vdev)) {
+ pmo_info("vdev in invalid opmode for ns offload %d",
+ pmo_get_vdev_opmode(vdev));
+ return QDF_STATUS_E_INVAL;
+ }
+
+ if (pmo_core_is_vdev_connected(vdev) == false)
+ return QDF_STATUS_E_INVAL;
+
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_core_cache_ns_offload_req(
+ struct pmo_ns_req *ns_req)
+{
+ QDF_STATUS status;
+ struct wlan_objmgr_vdev *vdev;
+
+ PMO_ENTER();
+ if (!ns_req) {
+ pmo_err("ns is NULL");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ if (!ns_req->psoc) {
+ pmo_err("psoc is NULL");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ vdev = pmo_psoc_get_vdev(ns_req->psoc, ns_req->vdev_id);
+ if (!vdev) {
+ pmo_err("vdev is NULL");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ status = pmo_vdev_get_ref(vdev);
+ if (QDF_IS_STATUS_ERROR(status))
+ goto out;
+
+ status = pmo_core_ns_offload_sanity(vdev);
+ if (status != QDF_STATUS_SUCCESS)
+ goto dec_ref;
+
+ if (ns_req->count == 0) {
+ pmo_info("skip ns offload caching as ns count is 0");
+ status = QDF_STATUS_E_INVAL;
+ goto dec_ref;
+ }
+
+ status = pmo_core_cache_ns_in_vdev_priv(ns_req, vdev);
+dec_ref:
+ pmo_vdev_put_ref(vdev);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_core_flush_ns_offload_req(struct wlan_objmgr_vdev *vdev)
+{
+ QDF_STATUS status;
+ uint8_t vdev_id;
+
+ PMO_ENTER();
+ if (!vdev) {
+ pmo_err("vdev is NULL");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ status = pmo_vdev_get_ref(vdev);
+ if (status != QDF_STATUS_SUCCESS)
+ goto out;
+
+ status = pmo_core_ns_offload_sanity(vdev);
+ if (status != QDF_STATUS_SUCCESS)
+ goto dec_ref;
+
+ vdev_id = pmo_vdev_get_id(vdev);
+ pmo_info("Flush ns offload on vdev id: %d vdev: %p", vdev_id, vdev);
+
+ status = pmo_core_flush_ns_from_vdev_priv(vdev);
+dec_ref:
+ pmo_vdev_put_ref(vdev);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_core_enable_ns_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+ enum pmo_offload_trigger trigger)
+{
+ QDF_STATUS status;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+ uint8_t vdev_id;
+
+ PMO_ENTER();
+ if (!vdev) {
+ pmo_err("vdev is NULL");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ status = pmo_vdev_get_ref(vdev);
+ if (status != QDF_STATUS_SUCCESS)
+ goto out;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ status = pmo_core_ns_offload_sanity(vdev);
+ if (status != QDF_STATUS_SUCCESS)
+ goto dec_ref;
+
+ if (trigger == pmo_ns_offload_dynamic_update) {
+ /*
+ * user disable ns offload using ioctl/vendor cmd dynamically.
+ */
+ vdev_ctx->pmo_psoc_ctx->psoc_cfg.ns_offload_enable_dynamic =
+ true;
+ goto skip_ns_dynamic_check;
+ }
+
+ if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.ns_offload_enable_dynamic) {
+ pmo_info("ns offload dynamically disable");
+ status = QDF_STATUS_E_INVAL;
+ goto dec_ref;
+ }
+
+skip_ns_dynamic_check:
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ if (vdev_ctx->vdev_ns_req.num_ns_offload_count == 0) {
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+ pmo_info("skip ns offload enable as ns count is 0");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ vdev_id = pmo_vdev_get_id(vdev);
+ pmo_info("Enable ns offload in fwr vdev id: %d vdev: %p trigger: %d",
+ vdev_id, vdev, trigger);
+ status = pmo_core_do_enable_ns_offload(vdev, vdev_id, trigger);
+dec_ref:
+ pmo_vdev_put_ref(vdev);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_core_disable_ns_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+ enum pmo_offload_trigger trigger)
+{
+ QDF_STATUS status;
+ uint8_t vdev_id;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ PMO_ENTER();
+ if (!vdev) {
+ pmo_err("vdev is NULL");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ status = pmo_vdev_get_ref(vdev);
+ if (status != QDF_STATUS_SUCCESS)
+ goto out;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ status = pmo_core_ns_offload_sanity(vdev);
+ if (status != QDF_STATUS_SUCCESS)
+ goto dec_ref;
+
+ if (trigger == pmo_ns_offload_dynamic_update) {
+ /*
+ * user disable ns offload using ioctl/vendor cmd dynamically.
+ */
+ vdev_ctx->pmo_psoc_ctx->psoc_cfg.ns_offload_enable_dynamic =
+ false;
+ goto skip_ns_dynamic_check;
+ }
+
+ if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.ns_offload_enable_dynamic) {
+ pmo_info("ns offload dynamically disable");
+ status = QDF_STATUS_E_INVAL;
+ goto dec_ref;
+ }
+
+skip_ns_dynamic_check:
+ vdev_id = pmo_vdev_get_id(vdev);
+ pmo_info("disable ns offload in fwr vdev id: %d vdev: %p trigger: %d",
+ vdev_id, vdev, trigger);
+
+ status = pmo_core_do_disable_ns_offload(vdev, vdev_id, trigger);
+dec_ref:
+ pmo_vdev_put_ref(vdev);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
diff --git a/components/pmo/core/src/wlan_pmo_pkt_filter.c b/components/pmo/core/src/wlan_pmo_pkt_filter.c
new file mode 100644
index 0000000..a59e25d
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_pkt_filter.c
@@ -0,0 +1,96 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Implements Packet filter feature API's
+ */
+
+#include "wlan_pmo_pkt_filter.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+QDF_STATUS pmo_core_set_pkt_filter(struct wlan_objmgr_psoc *psoc,
+ struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req,
+ uint8_t vdev_id)
+{
+ struct wlan_objmgr_vdev *vdev;
+ QDF_STATUS status;
+
+ PMO_ENTER();
+
+ if (!psoc) {
+ pmo_err("psoc is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, WLAN_PMO_ID);
+ if (!vdev) {
+ pmo_err("vdev is NULL");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ status = pmo_tgt_set_pkt_filter(vdev, pmo_set_pkt_fltr_req, vdev_id);
+ if (status != QDF_STATUS_SUCCESS)
+ goto dec_ref;
+
+dec_ref:
+ wlan_objmgr_vdev_release_ref(vdev, WLAN_PMO_ID);
+out:
+ PMO_EXIT();
+
+ return status;
+
+}
+
+QDF_STATUS pmo_core_clear_pkt_filter(struct wlan_objmgr_psoc *psoc,
+ struct pmo_rcv_pkt_fltr_clear_param *pmo_clr_pkt_fltr_param,
+ uint8_t vdev_id)
+{
+ struct wlan_objmgr_vdev *vdev;
+ QDF_STATUS status;
+
+ PMO_ENTER();
+
+ if (!psoc) {
+ pmo_err("psoc is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, WLAN_PMO_ID);
+ if (!vdev) {
+ pmo_err("vdev is NULL");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ status = pmo_tgt_clear_pkt_filter(vdev, pmo_clr_pkt_fltr_param,
+ vdev_id);
+ if (status != QDF_STATUS_SUCCESS)
+ goto dec_ref;
+
+dec_ref:
+ wlan_objmgr_vdev_release_ref(vdev, WLAN_PMO_ID);
+out:
+ PMO_EXIT();
+
+ return status;
+
+}
diff --git a/components/pmo/core/src/wlan_pmo_static_config.c b/components/pmo/core/src/wlan_pmo_static_config.c
new file mode 100644
index 0000000..b0653f3
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_static_config.c
@@ -0,0 +1,380 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Implements static configuration on vdev attach
+ */
+
+#include "wlan_pmo_static_config.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_wow.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+static const uint8_t arp_ptrn[] = {0x08, 0x06};
+static const uint8_t arp_mask[] = {0xff, 0xff};
+static const uint8_t ns_ptrn[] = {0x86, 0xDD};
+static const uint8_t discvr_ptrn[] = {0xe0, 0x00, 0x00, 0xf8};
+static const uint8_t discvr_mask[] = {0xf0, 0x00, 0x00, 0xf8};
+
+void pmo_register_wow_wakeup_events(struct wlan_objmgr_vdev *vdev)
+{
+ uint32_t event_bitmap[PMO_WOW_MAX_EVENT_BM_LEN] = {0};
+ uint8_t vdev_id;
+ enum tQDF_ADAPTER_MODE vdev_opmode;
+ const char *iface_type;
+
+ vdev_opmode = pmo_get_vdev_opmode(vdev);
+ vdev_id = pmo_vdev_get_id(vdev);
+ pmo_info("vdev_opmode %d vdev_id %d", vdev_opmode, vdev_id);
+
+ switch (vdev_opmode) {
+ case QDF_P2P_CLIENT_MODE:
+ case QDF_P2P_DEVICE_MODE:
+ case QDF_OCB_MODE:
+ case QDF_STA_MODE:
+ case QDF_MONITOR_MODE:
+ iface_type = "STA";
+ pmo_set_sta_wow_bitmask(event_bitmap, PMO_WOW_MAX_EVENT_BM_LEN);
+ break;
+
+ case QDF_IBSS_MODE:
+ iface_type = "IBSS";
+ pmo_set_sta_wow_bitmask(event_bitmap, PMO_WOW_MAX_EVENT_BM_LEN);
+ pmo_set_wow_event_bitmap(WOW_BEACON_EVENT,
+ PMO_WOW_MAX_EVENT_BM_LEN,
+ event_bitmap);
+ break;
+
+ case QDF_P2P_GO_MODE:
+ case QDF_SAP_MODE:
+ iface_type = "SAP";
+ pmo_set_sap_wow_bitmask(event_bitmap, PMO_WOW_MAX_EVENT_BM_LEN);
+ break;
+
+ case QDF_NDI_MODE:
+#ifdef WLAN_FEATURE_NAN_DATAPATH
+ iface_type = "NAN";
+ pmo_set_wow_event_bitmap(WOW_NAN_DATA_EVENT,
+ PMO_WOW_MAX_EVENT_BM_LEN,
+ event_bitmap);
+#endif
+ break;
+
+ default:
+ pmo_err("Skipping wake event configuration for vdev_opmode %d",
+ vdev_opmode);
+ return;
+ }
+
+ pmo_info("Selected %s wake event mask 0x%x%x%x%x, vdev %d",
+ iface_type, event_bitmap[0], event_bitmap[1],
+ event_bitmap[2], event_bitmap[3], vdev_id);
+
+ pmo_tgt_enable_wow_wakeup_event(vdev, event_bitmap);
+}
+
+/**
+ * pmo_configure_wow_ap() - set WOW patterns in ap mode
+ * @vdev: objmgr vdev handle
+ *
+ * Configures default WOW pattern for the given vdev_id which is in AP mode.
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS pmo_configure_wow_ap(struct wlan_objmgr_vdev *vdev)
+{
+ QDF_STATUS ret;
+ uint8_t arp_offset = 20;
+ uint8_t mac_mask[PMO_80211_ADDR_LEN];
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ /*
+ * Setup unicast pkt pattern
+ * WoW pattern id should be unique for each vdev
+ * WoW pattern id can be same on 2 different VDEVs
+ */
+ qdf_mem_set(&mac_mask, PMO_80211_ADDR_LEN, 0xFF);
+ ret = pmo_tgt_send_wow_patterns_to_fw(vdev,
+ pmo_get_and_increment_wow_default_ptrn(vdev_ctx),
+ wlan_vdev_mlme_get_macaddr(vdev),
+ PMO_80211_ADDR_LEN, 0, mac_mask,
+ PMO_80211_ADDR_LEN, false);
+ if (ret != QDF_STATUS_SUCCESS) {
+ pmo_err("Failed to add WOW unicast pattern ret %d", ret);
+ return ret;
+ }
+
+ /*
+ * Setup all ARP pkt pattern. This is dummy pattern hence the length
+ * is zero. Pattern ID should be unique per vdev.
+ */
+ ret = pmo_tgt_send_wow_patterns_to_fw(vdev,
+ pmo_get_and_increment_wow_default_ptrn(vdev_ctx),
+ arp_ptrn, 0, arp_offset, arp_mask, 0, false);
+ if (ret != QDF_STATUS_SUCCESS)
+ pmo_err("Failed to add WOW ARP pattern ret %d", ret);
+
+ return ret;
+}
+
+/**
+ * pmo_configure_mc_ssdp() - API to configure SSDP address as MC list
+ *@vdev: objmgr vdev handle.
+ *
+ * SSDP address 239.255.255.250 is converted to Multicast Mac address
+ * and configure it to FW. Firmware will apply this pattern on the incoming
+ * packets to filter them out during chatter/wow mode.
+ *
+ * Return: Success/Failure
+ */
+static QDF_STATUS pmo_configure_mc_ssdp(
+ struct wlan_objmgr_vdev *vdev)
+{
+ struct wlan_objmgr_psoc *psoc;
+ const uint8_t ssdp_addr[QDF_MAC_ADDR_SIZE] = {
+ 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xfa };
+ struct qdf_mac_addr multicast_addr;
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+ psoc = pmo_vdev_get_psoc(vdev);
+
+ qdf_mem_copy(&multicast_addr.bytes, &ssdp_addr, QDF_MAC_ADDR_SIZE);
+ status = pmo_tgt_set_mc_filter_req(vdev,
+ multicast_addr);
+ if (status != QDF_STATUS_SUCCESS)
+ pmo_err("unable to set ssdp as mc addr list filter");
+
+ return status;
+}
+
+/**
+ * pmo_configure_wow_ssdp() - API to configure WoW SSDP
+ *@vdev: objmgr vdev handle
+ *
+ * API to configure SSDP pattern as WoW pattern
+ *
+ * Return: Success/Failure
+ */
+static QDF_STATUS pmo_configure_wow_ssdp(
+ struct wlan_objmgr_vdev *vdev)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ uint8_t discvr_offset = 30;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ /*
+ * WoW pattern ID should be unique for each vdev
+ * Different WoW patterns can use same pattern ID
+ */
+ status = pmo_tgt_send_wow_patterns_to_fw(vdev,
+ pmo_get_and_increment_wow_default_ptrn(vdev_ctx),
+ discvr_ptrn, sizeof(discvr_ptrn), discvr_offset,
+ discvr_mask, sizeof(discvr_ptrn), false);
+
+ if (status != QDF_STATUS_SUCCESS)
+ pmo_err("Failed to add WOW mDNS/SSDP/LLMNR pattern");
+
+ return status;
+}
+
+/**
+ * pmo_configure_ssdp() - API to Configure SSDP pattern to FW
+ *@vdev: objmgr vdev handle
+ *
+ * Setup multicast pattern for mDNS 224.0.0.251, SSDP 239.255.255.250 and LLMNR
+ * 224.0.0.252
+ *
+ * Return: Success/Failure.
+ */
+static QDF_STATUS pmo_configure_ssdp(struct wlan_objmgr_vdev *vdev)
+{
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.ssdp) {
+ pmo_err("mDNS, SSDP, LLMNR patterns are disabled from ini");
+ return QDF_STATUS_SUCCESS;
+ }
+
+ pmo_debug("enable_mc_list:%d",
+ vdev_ctx->pmo_psoc_ctx->psoc_cfg.enable_mc_list);
+
+ if (vdev_ctx->pmo_psoc_ctx->psoc_cfg.enable_mc_list)
+ return pmo_configure_mc_ssdp(vdev);
+
+ return pmo_configure_wow_ssdp(vdev);
+}
+
+/**
+ * pmo_configure_wow_sta() - set WOW patterns in sta mode
+ * @vdev: objmgr vdev handle
+ *
+ * Configures default WOW pattern for the given vdev_id which is in sta mode.
+ *
+ * Return: QDF status
+ */
+static QDF_STATUS pmo_configure_wow_sta(struct wlan_objmgr_vdev *vdev)
+{
+ uint8_t arp_offset = 12;
+ uint8_t mac_mask[PMO_80211_ADDR_LEN];
+ QDF_STATUS ret = QDF_STATUS_SUCCESS;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ qdf_mem_set(&mac_mask, PMO_80211_ADDR_LEN, 0xFF);
+ /*
+ * Set up unicast wow pattern
+ * WoW pattern ID should be unique for each vdev
+ * Different WoW patterns can use same pattern ID
+ */
+ ret = pmo_tgt_send_wow_patterns_to_fw(vdev,
+ pmo_get_and_increment_wow_default_ptrn(vdev_ctx),
+ wlan_vdev_mlme_get_macaddr(vdev),
+ PMO_80211_ADDR_LEN, 0, mac_mask,
+ PMO_80211_ADDR_LEN, false);
+ if (ret != QDF_STATUS_SUCCESS) {
+ pmo_err("Failed to add WOW unicast pattern ret %d", ret);
+ return ret;
+ }
+
+ ret = pmo_configure_ssdp(vdev);
+ if (ret != QDF_STATUS_SUCCESS)
+ pmo_err("Failed to configure SSDP patterns to FW");
+
+ /*
+ * when arp offload or ns offloaded is disabled
+ * from ini file, configure broad cast arp pattern
+ * to fw, so that host can wake up
+ */
+ if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.arp_offload_enable) {
+ /* Setup all ARP pkt pattern */
+ pmo_info("ARP offload is disabled in INI enable WoW for ARP");
+ ret = pmo_tgt_send_wow_patterns_to_fw(vdev,
+ pmo_get_and_increment_wow_default_ptrn(
+ vdev_ctx),
+ arp_ptrn, sizeof(arp_ptrn), arp_offset,
+ arp_mask, sizeof(arp_mask), false);
+ if (ret != QDF_STATUS_SUCCESS) {
+ pmo_err("Failed to add WOW ARP pattern");
+ return ret;
+ }
+ }
+ /* for NS or NDP offload packets */
+ if (!vdev_ctx->pmo_psoc_ctx->psoc_cfg.ns_offload_enable_static) {
+ /* Setup all NS pkt pattern */
+ pmo_info("NS offload is disabled in INI enable WoW for NS");
+ ret = pmo_tgt_send_wow_patterns_to_fw(vdev,
+ pmo_get_and_increment_wow_default_ptrn(
+ vdev_ctx),
+ ns_ptrn, sizeof(arp_ptrn), arp_offset,
+ arp_mask, sizeof(arp_mask), false);
+ if (ret != QDF_STATUS_SUCCESS) {
+ pmo_err("Failed to add WOW NS pattern");
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+void pmo_register_wow_default_patterns(struct wlan_objmgr_vdev *vdev)
+{
+ enum tQDF_ADAPTER_MODE vdev_opmode = QDF_MAX_NO_OF_MODE;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+ uint8_t vdev_id;
+ struct pmo_psoc_priv_obj *psoc_ctx;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ vdev_id = pmo_vdev_get_id(vdev);
+ if (vdev_id > WLAN_UMAC_PSOC_MAX_VDEVS) {
+ pmo_err("Invalid vdev id %d", vdev_id);
+ return;
+ }
+
+ vdev_opmode = pmo_get_vdev_opmode(vdev);
+ if (vdev_opmode == QDF_MAX_NO_OF_MODE) {
+ pmo_err("Invalid vdev opmode %d", vdev_id);
+ return;
+ }
+
+ if (!vdev_ctx->ptrn_match_enable) {
+ pmo_err("ptrn_match is disable for vdev %d", vdev_id);
+ return;
+ }
+
+ if (pmo_is_vdev_in_beaconning_mode(vdev_opmode)) {
+ /* Configure SAP/GO/IBSS mode default wow patterns */
+ pmo_info("Config SAP default wow patterns vdev_id %d",
+ vdev_id);
+ pmo_configure_wow_ap(vdev);
+ } else {
+ /* Configure STA/P2P CLI mode default wow patterns */
+ pmo_info("Config STA default wow patterns vdev_id %d",
+ vdev_id);
+ pmo_configure_wow_sta(vdev);
+ psoc_ctx = vdev_ctx->pmo_psoc_ctx;
+ if (psoc_ctx && psoc_ctx->psoc_cfg.ra_ratelimit_enable) {
+ pmo_info("Config STA RA wow pattern vdev_id %d",
+ vdev_id);
+ pmo_tgt_send_ra_filter_req(vdev);
+ }
+ }
+
+}
+
+void pmo_register_action_frame_patterns(struct wlan_objmgr_vdev *vdev)
+{
+
+ struct pmo_action_wakeup_set_params cmd = {0};
+ int i = 0;
+ QDF_STATUS status;
+
+ cmd.vdev_id = pmo_vdev_get_id(vdev);
+ cmd.operation = pmo_action_wakeup_set;
+
+ cmd.action_category_map[i++] = ALLOWED_ACTION_FRAMES_BITMAP0;
+ cmd.action_category_map[i++] = ALLOWED_ACTION_FRAMES_BITMAP1;
+ cmd.action_category_map[i++] = ALLOWED_ACTION_FRAMES_BITMAP2;
+ cmd.action_category_map[i++] = ALLOWED_ACTION_FRAMES_BITMAP3;
+ cmd.action_category_map[i++] = ALLOWED_ACTION_FRAMES_BITMAP4;
+ cmd.action_category_map[i++] = ALLOWED_ACTION_FRAMES_BITMAP5;
+ cmd.action_category_map[i++] = ALLOWED_ACTION_FRAMES_BITMAP6;
+ cmd.action_category_map[i++] = ALLOWED_ACTION_FRAMES_BITMAP7;
+
+ for (i = 0; i < PMO_SUPPORTED_ACTION_CATE_ELE_LIST; i++) {
+ if (i < ALLOWED_ACTION_FRAME_MAP_WORDS)
+ pmo_debug("%s: %d action Wakeup pattern 0x%x in fw",
+ __func__, i, cmd.action_category_map[i]);
+ else
+ cmd.action_category_map[i] = 0;
+ }
+
+ /* config action frame patterns */
+ status = pmo_tgt_send_action_frame_pattern_req(vdev, &cmd);
+ if (status != QDF_STATUS_SUCCESS)
+ pmo_err("Failed to config wow action frame map, ret %d",
+ status);
+}
+
diff --git a/components/pmo/core/src/wlan_pmo_suspend_resume.c b/components/pmo/core/src/wlan_pmo_suspend_resume.c
new file mode 100644
index 0000000..65e3a20
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_suspend_resume.c
@@ -0,0 +1,1225 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Define API's for suspend / resume handling
+ */
+
+#include "wlan_pmo_wow.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include "wlan_pmo_lphb.h"
+#include "wlan_pmo_suspend_resume.h"
+#include "cdp_txrx_ops.h"
+#include "cdp_txrx_misc.h"
+#include "cdp_txrx_flow_ctrl_legacy.h"
+#include "hif.h"
+#include "htc_api.h"
+#include "wlan_pmo_obj_mgmt_api.h"
+#include <wlan_scan_ucfg_api.h>
+#include "cds_api.h"
+#include "wlan_pmo_static_config.h"
+
+/**
+ * pmo_core_calculate_listen_interval() - Calculate vdev listen interval
+ * @vdev: objmgr vdev handle
+ * @vdev_ctx: pmo vdev priv ctx
+ * @listen_interval: listen interval which is computed for vdev
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS pmo_core_calculate_listen_interval(
+ struct wlan_objmgr_vdev *vdev,
+ struct pmo_vdev_priv_obj *vdev_ctx,
+ uint32_t *listen_interval)
+{
+ uint32_t max_mod_dtim;
+ uint32_t beacon_interval_mod;
+ struct pmo_psoc_cfg *psoc_cfg = &vdev_ctx->pmo_psoc_ctx->psoc_cfg;
+
+ if (psoc_cfg->sta_dynamic_dtim) {
+ *listen_interval = psoc_cfg->sta_dynamic_dtim;
+ } else if ((psoc_cfg->sta_mod_dtim) &&
+ (psoc_cfg->sta_max_li_mod_dtim)) {
+ /*
+ * When the system is in suspend
+ * (maximum beacon will be at 1s == 10)
+ * If maxModulatedDTIM ((MAX_LI_VAL = 10) / AP_DTIM)
+ * equal or larger than MDTIM
+ * (configured in WCNSS_qcom_cfg.ini)
+ * Set LI to MDTIM * AP_DTIM
+ * If Dtim = 2 and Mdtim = 2 then LI is 4
+ * Else
+ * Set LI to maxModulatedDTIM * AP_DTIM
+ */
+ beacon_interval_mod =
+ pmo_core_get_vdev_beacon_interval(vdev) / 100;
+ if (beacon_interval_mod == 0)
+ beacon_interval_mod = 1;
+
+ max_mod_dtim = psoc_cfg->sta_max_li_mod_dtim /
+ (pmo_core_get_vdev_dtim_period(vdev)
+ * beacon_interval_mod);
+
+ if (max_mod_dtim <= 0)
+ max_mod_dtim = 1;
+
+ if (max_mod_dtim >= psoc_cfg->sta_mod_dtim) {
+ *listen_interval =
+ (psoc_cfg->sta_mod_dtim *
+ pmo_core_get_vdev_dtim_period(vdev));
+ } else {
+ *listen_interval =
+ (max_mod_dtim *
+ pmo_core_get_vdev_dtim_period(vdev));
+ }
+ } else {
+ return QDF_STATUS_E_FAULT;
+ }
+ return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * pmo_core_set_vdev_suspend_dtim() - set suspend dtim parameters in fw
+ * @psoc: objmgr psoc handle
+ * @vdev: objmgr vdev handle
+ * @vdev_ctx: pmo vdev priv ctx
+ *
+ * Return: none
+ */
+static void pmo_core_set_vdev_suspend_dtim(struct wlan_objmgr_psoc *psoc,
+ struct wlan_objmgr_vdev *vdev,
+ struct pmo_vdev_priv_obj *vdev_ctx)
+{
+ uint32_t listen_interval;
+ QDF_STATUS ret;
+ uint8_t vdev_id;
+ enum pmo_power_save_qpower_mode qpower_config;
+ enum tQDF_ADAPTER_MODE opmode = pmo_core_get_vdev_op_mode(vdev);
+
+ qpower_config = pmo_core_psoc_get_qpower_config(psoc);
+ vdev_id = pmo_vdev_get_id(vdev);
+ if (PMO_VDEV_IN_STA_MODE(opmode) &&
+ pmo_core_get_vdev_dtim_period(vdev) != 0) {
+ /* calculate listen interval */
+ ret = pmo_core_calculate_listen_interval(vdev, vdev_ctx,
+ &listen_interval);
+ if (ret != QDF_STATUS_SUCCESS) {
+ /* even it fails continue fwr will take default LI */
+ pmo_info("Fail to calculate listen interval");
+ }
+
+ ret = pmo_tgt_vdev_update_param_req(vdev,
+ pmo_vdev_param_listen_interval,
+ listen_interval);
+ if (QDF_IS_STATUS_ERROR(ret)) {
+ /* even it fails continue fwr will take default LI */
+ pmo_info("Failed to Set Listen Interval vdevId %d",
+ vdev_id);
+ }
+ pmo_debug("Set Listen Interval vdevId %d Listen Intv %d",
+ vdev_id, listen_interval);
+
+ if (qpower_config) {
+ pmo_debug("disable Qpower in suspend mode!");
+ ret = pmo_tgt_send_vdev_sta_ps_param(vdev,
+ pmo_sta_ps_enable_qpower, 0);
+ if (QDF_IS_STATUS_ERROR(ret))
+ pmo_info("Failed to disable Qpower in suspend mode!");
+ }
+
+ ret = pmo_tgt_vdev_update_param_req(vdev,
+ pmo_vdev_param_dtim_policy,
+ pmo_normal_dtim);
+ if (QDF_IS_STATUS_ERROR(ret))
+ pmo_info("Failed to Set to Normal DTIM vdevId %d",
+ vdev_id);
+
+ /* Set it to Normal DTIM */
+ pmo_core_vdev_set_dtim_policy(vdev, pmo_normal_dtim);
+ pmo_debug("Set DTIM Policy to Normal Dtim vdevId %d", vdev_id);
+ }
+}
+
+/**
+ * pmo_core_set_suspend_dtim() - set suspend dtim
+ * @psoc: objmgr psoc handle
+ *
+ * Return: none
+ */
+static void pmo_core_set_suspend_dtim(struct wlan_objmgr_psoc *psoc)
+{
+ uint8_t vdev_id;
+ struct wlan_objmgr_vdev *vdev;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+ bool alt_mdtim_enabled;
+ QDF_STATUS status;
+
+ /* Iterate through VDEV list */
+ for (vdev_id = 0; vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS; vdev_id++) {
+ vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+ if (!vdev)
+ continue;
+
+ status = pmo_vdev_get_ref(vdev);
+ if (QDF_IS_STATUS_ERROR(status))
+ continue;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ alt_mdtim_enabled = vdev_ctx->alt_modulated_dtim_enable;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ if (!alt_mdtim_enabled)
+ pmo_core_set_vdev_suspend_dtim(psoc, vdev, vdev_ctx);
+
+ pmo_vdev_put_ref(vdev);
+ }
+}
+
+/**
+ * pmo_core_update_wow_bus_suspend() - set wow bus suspend flag
+ * @psoc: objmgr psoc handle
+ * @psoc_ctx: pmo psoc priv ctx
+ * @val: true for enable else false
+ * Return: none
+ */
+static inline
+void pmo_core_update_wow_bus_suspend(struct wlan_objmgr_psoc *psoc,
+ struct pmo_psoc_priv_obj *psoc_ctx, int val)
+{
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ psoc_ctx->wow.is_wow_bus_suspended = val;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+ pmo_tgt_psoc_update_wow_bus_suspend_state(psoc, val);
+}
+
+/* Define for conciseness */
+#define BM_LEN PMO_WOW_MAX_EVENT_BM_LEN
+#define EV_NLO WOW_NLO_SCAN_COMPLETE_EVENT
+#define EV_PWR WOW_CHIP_POWER_FAILURE_DETECT_EVENT
+
+void pmo_core_configure_dynamic_wake_events(struct wlan_objmgr_psoc *psoc)
+{
+ int vdev_id;
+ uint32_t adapter_type;
+ uint32_t enable_mask[BM_LEN];
+ uint32_t disable_mask[BM_LEN];
+ struct wlan_objmgr_vdev *vdev;
+ struct pmo_psoc_priv_obj *psoc_ctx;
+ bool enable_configured;
+ bool disable_configured;
+
+ /* Iterate through VDEV list */
+ for (vdev_id = 0; vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS; vdev_id++) {
+
+ enable_configured = false;
+ disable_configured = false;
+
+ qdf_mem_set(enable_mask, sizeof(uint32_t) * BM_LEN, 0);
+ qdf_mem_set(disable_mask, sizeof(uint32_t) * BM_LEN, 0);
+
+ vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+ if (!vdev)
+ continue;
+
+ if (ucfg_scan_get_pno_in_progress(vdev)) {
+ if (ucfg_scan_get_pno_match(vdev)) {
+ pmo_set_wow_event_bitmap(EV_NLO,
+ BM_LEN,
+ enable_mask);
+ enable_configured = true;
+ } else {
+ pmo_set_wow_event_bitmap(EV_NLO,
+ BM_LEN,
+ disable_mask);
+ disable_configured = true;
+ }
+ }
+
+ adapter_type = pmo_get_vdev_opmode(vdev);
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+
+ if (psoc_ctx->psoc_cfg.auto_power_save_fail_mode &&
+ (adapter_type == QDF_STA_MODE ||
+ adapter_type == QDF_P2P_CLIENT_MODE)
+ ) {
+ if (psoc_ctx->is_device_in_low_pwr_mode &&
+ psoc_ctx->is_device_in_low_pwr_mode(vdev_id))
+ pmo_set_wow_event_bitmap(EV_PWR,
+ BM_LEN,
+ enable_mask);
+ pmo_core_enable_wakeup_event(psoc, vdev_id,
+ enable_mask);
+ enable_configured = true;
+ }
+ if (enable_configured)
+ pmo_core_enable_wakeup_event(psoc, vdev_id,
+ enable_mask);
+
+ if (disable_configured)
+ pmo_core_disable_wakeup_event(psoc, vdev_id,
+ disable_mask);
+ }
+
+}
+
+/**
+ * pmo_core_psoc_configure_suspend(): configure suspend req events
+ * @psoc: objmgr psoc
+ *
+ * Responsibility of the caller to take the psoc reference.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS pmo_core_psoc_configure_suspend(struct wlan_objmgr_psoc *psoc)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx;
+
+ PMO_ENTER();
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+
+ if (pmo_core_is_wow_applicable(psoc)) {
+ pmo_info("WOW Suspend");
+ pmo_core_apply_lphb(psoc);
+
+ pmo_core_configure_dynamic_wake_events(psoc);
+ pmo_core_update_wow_enable(psoc_ctx, true);
+ pmo_core_update_wow_enable_cmd_sent(psoc_ctx, false);
+ }
+
+ pmo_core_set_suspend_dtim(psoc);
+
+ /*
+ * To handle race between hif_pci_suspend and unpause/pause tx handler.
+ * This happens when host sending WMI_WOW_ENABLE_CMDID to FW and receive
+ * WMI_TX_PAUSE_EVENT with ACTON_UNPAUSE almost at same time.
+ */
+ pmo_core_update_wow_bus_suspend(psoc, psoc_ctx, true);
+
+ PMO_EXIT();
+
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_core_psoc_user_space_suspend_req(struct wlan_objmgr_psoc *psoc,
+ enum qdf_suspend_type type)
+{
+ QDF_STATUS status;
+
+ PMO_ENTER();
+
+ status = pmo_psoc_get_ref(psoc);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("pmo cannot get the reference out of psoc");
+ goto out;
+ }
+
+ /* Suspend all components before sending target suspend command */
+ status = pmo_suspend_all_components(psoc, type);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("Failed to suspend all component");
+ goto dec_psoc_ref;
+ }
+
+ status = pmo_core_psoc_configure_suspend(psoc);
+ if (status != QDF_STATUS_SUCCESS)
+ pmo_err("Failed to configure suspend");
+
+dec_psoc_ref:
+ pmo_psoc_put_ref(psoc);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+/**
+ * pmo_core_set_vdev_resume_dtim() - set resume dtim parameters in fw
+ * @psoc: objmgr psoc handle
+ * @vdev: objmgr vdev handle
+ * @vdev_ctx: pmo vdev priv ctx
+ *
+ * Return: none
+ */
+static void pmo_core_set_vdev_resume_dtim(struct wlan_objmgr_psoc *psoc,
+ struct wlan_objmgr_vdev *vdev,
+ struct pmo_vdev_priv_obj *vdev_ctx)
+{
+ enum pmo_power_save_qpower_mode qpower_config;
+ QDF_STATUS ret;
+ uint8_t vdev_id;
+ enum tQDF_ADAPTER_MODE opmode = pmo_core_get_vdev_op_mode(vdev);
+ uint32_t cfg_data_val = 0;
+
+ qpower_config = pmo_core_psoc_get_qpower_config(psoc);
+ vdev_id = pmo_vdev_get_id(vdev);
+ if ((PMO_VDEV_IN_STA_MODE(opmode)) &&
+ (pmo_core_vdev_get_dtim_policy(vdev) == pmo_normal_dtim)) {
+/*
+ if (!mac) {
+ WMA_LOGE(FL("Failed to get mac context"));
+ return;
+ }
+ if ((wlan_cfg_get_int(mac, WNI_CFG_LISTEN_INTERVAL,
+ &cfg_data_val) != eSIR_SUCCESS)) {
+ pmo_err("Failed to get value for listen interval");
+ cfg_data_val = POWERSAVE_DEFAULT_LISTEN_INTERVAL;
+ }
+*/
+ cfg_data_val = 1;
+ ret = pmo_tgt_vdev_update_param_req(vdev,
+ pmo_vdev_param_listen_interval, cfg_data_val);
+ if (QDF_IS_STATUS_ERROR(ret)) {
+ /* Even it fails continue Fw will take default LI */
+ pmo_err("Failed to Set Listen Interval vdevId %d",
+ vdev_id);
+ }
+ pmo_debug("Set Listen Interval vdevId %d Listen Intv %d",
+ vdev_id, cfg_data_val);
+
+ ret = pmo_tgt_vdev_update_param_req(vdev,
+ pmo_vdev_param_dtim_policy,
+ pmo_stick_dtim);
+ if (QDF_IS_STATUS_ERROR(ret)) {
+ /* Set it back to Stick DTIM */
+ pmo_err("Failed to Set to Stick DTIM vdevId %d",
+ vdev_id);
+ }
+ pmo_core_vdev_set_dtim_policy(vdev, pmo_stick_dtim);
+ pmo_debug("Set DTIM Policy to Stick Dtim vdevId %d", vdev_id);
+
+ if (qpower_config) {
+ pmo_debug("enable Qpower in resume mode!");
+ ret = pmo_tgt_send_vdev_sta_ps_param(vdev,
+ pmo_sta_ps_enable_qpower, qpower_config);
+ if (QDF_IS_STATUS_ERROR(ret))
+ pmo_err("Failed to enable Qpower in resume");
+ }
+ }
+}
+
+/**
+ * pmo_core_set_resume_dtim() - set resume time dtim
+ * @psoc: objmgr psoc handle
+ *
+ * Return: none
+ */
+static void pmo_core_set_resume_dtim(struct wlan_objmgr_psoc *psoc)
+{
+ uint8_t vdev_id;
+ struct wlan_objmgr_vdev *vdev;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+ bool alt_mdtim_enabled;
+ QDF_STATUS status;
+
+ /* Iterate through VDEV list */
+ for (vdev_id = 0; vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS; vdev_id++) {
+ vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+ if (!vdev)
+ continue;
+
+ status = pmo_vdev_get_ref(vdev);
+ if (QDF_IS_STATUS_ERROR(status))
+ continue;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ alt_mdtim_enabled = vdev_ctx->alt_modulated_dtim_enable;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ if (!alt_mdtim_enabled)
+ pmo_core_set_vdev_resume_dtim(psoc, vdev, vdev_ctx);
+
+ pmo_vdev_put_ref(vdev);
+ }
+}
+
+/**
+ * pmo_unpause_vdev - unpause all vdev
+ * @psoc: objmgr psoc handle
+ *
+ * unpause all vdev aftter resume/coming out of wow mode
+ *
+ * Return: none
+ */
+static void pmo_unpause_all_vdev(struct wlan_objmgr_psoc *psoc,
+ struct pmo_psoc_priv_obj *psoc_ctx)
+{
+ uint8_t vdev_id;
+ struct wlan_objmgr_psoc_objmgr *objmgr;
+ struct wlan_objmgr_vdev *vdev;
+
+ /* Iterate through VDEV list */
+ for (vdev_id = 0; vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS; vdev_id++) {
+ wlan_psoc_obj_lock(psoc);
+ objmgr = &psoc->soc_objmgr;
+ if (!objmgr->wlan_vdev_list[vdev_id]) {
+ wlan_psoc_obj_unlock(psoc);
+ continue;
+ }
+ vdev = objmgr->wlan_vdev_list[vdev_id];
+ wlan_psoc_obj_unlock(psoc);
+ if (vdev) {
+#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
+ /*
+ * When host resume, by default,
+ * unpause all active vdev
+ */
+ if (pmo_core_vdev_get_pause_bitmap(psoc_ctx, vdev_id)) {
+ cdp_fc_vdev_unpause(
+ pmo_core_psoc_get_dp_handle(psoc),
+ pmo_core_vdev_get_dp_handle(vdev),
+ 0xffffffff);
+ if (psoc_ctx->pause_bitmap_notifier)
+ psoc_ctx->pause_bitmap_notifier(vdev_id,
+ 0);
+ }
+#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
+ }
+ }
+}
+
+/**
+ * pmo_core_psoc_configure_resume(): configure events after bus resume
+ * @psoc: objmgr psoc
+ *
+ * Responsibility of the caller to take the psoc reference.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS pmo_core_psoc_configure_resume(struct wlan_objmgr_psoc *psoc)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx;
+
+ PMO_ENTER();
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+
+ pmo_core_set_resume_dtim(psoc);
+ pmo_core_update_wow_bus_suspend(psoc, psoc_ctx, false);
+ pmo_unpause_all_vdev(psoc, psoc_ctx);
+
+ PMO_EXIT();
+
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_core_psoc_user_space_resume_req(struct wlan_objmgr_psoc *psoc,
+ enum qdf_suspend_type type)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+ PMO_ENTER();
+
+ status = pmo_psoc_get_ref(psoc);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("pmo cannot get the reference out of psoc");
+ goto out;
+ }
+
+ /* Resume all components */
+ status = pmo_resume_all_components(psoc, type);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("Failed to resume all the components");
+ goto dec_psoc_ref;
+ }
+
+ status = pmo_core_psoc_configure_resume(psoc);
+ if (status != QDF_STATUS_SUCCESS)
+ pmo_err("Failed to configure resume");
+
+dec_psoc_ref:
+ pmo_psoc_put_ref(psoc);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+/**
+ * pmo_core_enable_wow_in_fw() - enable wow in fw
+ * @psoc: objmgr psoc handle
+ * @psoc_ctx: pmo psoc private ctx
+ * @wow_params: collection of wow enable override parameters
+ *
+ * Return: QDF status
+ */
+static
+QDF_STATUS pmo_core_enable_wow_in_fw(struct wlan_objmgr_psoc *psoc,
+ struct pmo_psoc_priv_obj *psoc_ctx,
+ struct pmo_wow_enable_params *wow_params)
+{
+ int host_credits, wmi_pending_cmds;
+ struct pmo_wow_cmd_params param = {0};
+ QDF_STATUS status;
+
+ PMO_ENTER();
+ qdf_event_reset(&psoc_ctx->wow.target_suspend);
+ pmo_core_set_wow_nack(psoc_ctx, false);
+ host_credits = pmo_tgt_psoc_get_host_credits(psoc);
+ wmi_pending_cmds = pmo_tgt_psoc_get_pending_cmnds(psoc);
+ pmo_debug("Credits:%d; Pending_Cmds: %d",
+ host_credits, wmi_pending_cmds);
+
+ param.enable = true;
+ if (wow_params->is_unit_test)
+ param.flags = WMI_WOW_FLAG_UNIT_TEST_ENABLE;
+
+ switch (wow_params->interface_pause) {
+ default:
+ pmo_err("Invalid interface pause setting: %d",
+ wow_params->interface_pause);
+ /* intentional fall-through to default */
+ case PMO_WOW_INTERFACE_PAUSE_DEFAULT:
+ param.can_suspend_link =
+ htc_can_suspend_link(
+ pmo_core_psoc_get_htc_handle(psoc));
+ break;
+ case PMO_WOW_INTERFACE_PAUSE_ENABLE:
+ param.can_suspend_link = true;
+ break;
+ case PMO_WOW_INTERFACE_PAUSE_DISABLE:
+ param.can_suspend_link = false;
+ break;
+ }
+
+ switch (wow_params->resume_trigger) {
+ default:
+ pmo_err("Invalid resume trigger setting: %d",
+ wow_params->resume_trigger);
+ /* intentional fall-through to default */
+ case PMO_WOW_RESUME_TRIGGER_DEFAULT:
+ case PMO_WOW_RESUME_TRIGGER_GPIO:
+ /*
+ * GPIO is currently implicit. This means you can't actually
+ * force GPIO if a platform's default wake trigger is HTC wakeup
+ */
+ break;
+ case PMO_WOW_RESUME_TRIGGER_HTC_WAKEUP:
+ param.flags |= WMI_WOW_FLAG_DO_HTC_WAKEUP;
+ break;
+ }
+
+ status = pmo_tgt_psoc_send_wow_enable_req(psoc, ¶m);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("Failed to enable wow in fw");
+ goto out;
+ }
+
+ pmo_tgt_update_target_suspend_flag(psoc, true);
+
+ if (qdf_wait_single_event(&psoc_ctx->wow.target_suspend,
+ PMO_TGT_SUSPEND_COMPLETE_TIMEOUT)
+ != QDF_STATUS_SUCCESS) {
+ pmo_err("Failed to receive WoW Enable Ack from FW");
+ pmo_err("Credits:%d; Pending_Cmds: %d",
+ pmo_tgt_psoc_get_host_credits(psoc),
+ pmo_tgt_psoc_get_pending_cmnds(psoc));
+ pmo_tgt_update_target_suspend_flag(psoc, false);
+ status = QDF_STATUS_E_FAILURE;
+ QDF_BUG(0);
+ goto out;
+ }
+
+ if (pmo_core_get_wow_nack(psoc_ctx)) {
+ pmo_err("FW not ready to WOW");
+ pmo_tgt_update_target_suspend_flag(psoc, false);
+ status = QDF_STATUS_E_AGAIN;
+ goto out;
+ }
+
+ host_credits = pmo_tgt_psoc_get_host_credits(psoc);
+ wmi_pending_cmds = pmo_tgt_psoc_get_pending_cmnds(psoc);
+
+ if (host_credits < PMO_WOW_REQUIRED_CREDITS) {
+ pmo_err("No Credits after HTC ACK:%d, pending_cmds:%d,"
+ "cannot resume back", host_credits, wmi_pending_cmds);
+ htc_dump_counter_info(pmo_core_psoc_get_htc_handle(psoc));
+/*
+ if (!cds_is_driver_recovering())
+ QDF_BUG(0);
+ else
+ pmo_err("SSR in progress, ignore no credit issue");
+*/
+ }
+ pmo_debug("WOW enabled successfully in fw: credits:%d pending_cmds: %d",
+ host_credits, wmi_pending_cmds);
+
+ pmo_core_update_wow_enable_cmd_sent(psoc_ctx, true);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_core_psoc_suspend_target(struct wlan_objmgr_psoc *psoc,
+ int disable_target_intr)
+{
+ QDF_STATUS status;
+ struct pmo_suspend_params param;
+ struct pmo_psoc_priv_obj *psoc_ctx;
+
+ PMO_ENTER();
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+
+ qdf_event_reset(&psoc_ctx->wow.target_suspend);
+ param.disable_target_intr = disable_target_intr;
+ status = pmo_tgt_psoc_send_supend_req(psoc, ¶m);
+ if (status != QDF_STATUS_SUCCESS)
+ goto out;
+
+ pmo_tgt_update_target_suspend_flag(psoc, true);
+
+ if (qdf_wait_single_event(&psoc_ctx->wow.target_suspend,
+ PMO_TGT_SUSPEND_COMPLETE_TIMEOUT)
+ != QDF_STATUS_SUCCESS) {
+ status = QDF_STATUS_E_TIMEOUT;
+ pmo_err("Failed to get ACK from firmware for pdev suspend");
+ pmo_tgt_update_target_suspend_flag(psoc, false);
+ /* wma_suspend_target_timeout(pmac->sme.enableSelfRecovery); */
+ }
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_core_psoc_bus_suspend_req(struct wlan_objmgr_psoc *psoc,
+ enum qdf_suspend_type type,
+ struct pmo_wow_enable_params *wow_params)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx;
+ QDF_STATUS status;
+ bool wow_mode_selected = false;
+
+ PMO_ENTER();
+ if (!psoc) {
+ pmo_err("psoc is NULL");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ if (!wow_params) {
+ pmo_err("wow_params is NULL");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ status = pmo_psoc_get_ref(psoc);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("pmo cannot get the reference out of psoc");
+ goto out;
+ }
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+
+/* TODO - scan manager need to provide the below public api
+ if (wma_check_scan_in_progress(handle)) {
+ pmo_err("Scan in progress. Aborting suspend");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+*/
+
+ wow_mode_selected = pmo_core_is_wow_enabled(psoc_ctx);
+ pmo_info("wow mode selected %d", wow_mode_selected);
+
+ if (wow_mode_selected)
+ status = pmo_core_enable_wow_in_fw(psoc, psoc_ctx, wow_params);
+ else
+ status = pmo_core_psoc_suspend_target(psoc, 0);
+
+ pmo_psoc_put_ref(psoc);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+#ifdef FEATURE_RUNTIME_PM
+QDF_STATUS pmo_core_psoc_bus_runtime_suspend(struct wlan_objmgr_psoc *psoc,
+ pmo_pld_auto_suspend_cb pld_cb)
+{
+ void *hif_ctx;
+ void *dp_soc;
+ void *txrx_pdev;
+ void *htc_ctx;
+ QDF_STATUS status;
+ struct pmo_wow_enable_params wow_params = {0};
+
+ PMO_ENTER();
+
+ if (!psoc) {
+ pmo_err("psoc is NULL");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ status = pmo_psoc_get_ref(psoc);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("pmo cannot get the reference out of psoc");
+ goto out;
+ }
+
+ hif_ctx = pmo_core_psoc_get_hif_handle(psoc);
+ dp_soc = pmo_core_psoc_get_dp_handle(psoc);
+ txrx_pdev = pmo_core_psoc_get_txrx_handle(psoc);
+ htc_ctx = pmo_core_psoc_get_htc_handle(psoc);
+ if (!hif_ctx || !dp_soc || !txrx_pdev || !htc_ctx) {
+ pmo_err("Invalid hif: %p, dp: %p, txrx: %p, htc: %p",
+ hif_ctx, dp_soc, txrx_pdev, htc_ctx);
+ status = QDF_STATUS_E_INVAL;
+ goto dec_psoc_ref;
+ }
+
+ wow_params.interface_pause = PMO_WOW_INTERFACE_PAUSE_ENABLE;
+ wow_params.resume_trigger = PMO_WOW_RESUME_TRIGGER_GPIO;
+
+ if (hif_pre_runtime_suspend(hif_ctx))
+ goto runtime_failure;
+
+ status = cdp_runtime_suspend(dp_soc, txrx_pdev);
+ if (status != QDF_STATUS_SUCCESS)
+ goto runtime_failure;
+
+ if (htc_runtime_suspend(htc_ctx))
+ goto cdp_runtime_resume;
+
+ status = pmo_tgt_psoc_set_runtime_pm_inprogress(psoc, true);
+ if (status != QDF_STATUS_SUCCESS)
+ goto resume_htc;
+
+ status = pmo_core_psoc_configure_suspend(psoc);
+ if (status != QDF_STATUS_SUCCESS)
+ goto resume_htc;
+
+ status = pmo_core_psoc_bus_suspend_req(psoc, QDF_RUNTIME_SUSPEND,
+ &wow_params);
+ if (status != QDF_STATUS_SUCCESS)
+ goto pmo_resume_configure;
+
+ if (hif_runtime_suspend(hif_ctx))
+ goto pmo_bus_resume;
+
+ if (pld_cb && pld_cb())
+ goto resume_hif;
+
+ hif_process_runtime_suspend_success(hif_ctx);
+
+ goto dec_psoc_ref;
+
+resume_hif:
+ QDF_BUG(!hif_runtime_resume(hif_ctx));
+
+pmo_bus_resume:
+ QDF_BUG(QDF_STATUS_SUCCESS ==
+ pmo_core_psoc_bus_resume_req(psoc, QDF_RUNTIME_SUSPEND));
+
+pmo_resume_configure:
+ QDF_BUG(QDF_STATUS_SUCCESS ==
+ pmo_core_psoc_configure_resume(psoc));
+
+resume_htc:
+ QDF_BUG(QDF_STATUS_SUCCESS ==
+ pmo_tgt_psoc_set_runtime_pm_inprogress(psoc, false));
+
+ QDF_BUG(!htc_runtime_resume(htc_ctx));
+
+cdp_runtime_resume:
+ QDF_BUG(QDF_STATUS_SUCCESS ==
+ cdp_runtime_resume(dp_soc, txrx_pdev));
+
+runtime_failure:
+ hif_process_runtime_suspend_failure(hif_ctx);
+
+dec_psoc_ref:
+ pmo_psoc_put_ref(psoc);
+
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_core_psoc_bus_runtime_resume(struct wlan_objmgr_psoc *psoc,
+ pmo_pld_auto_resume_cb pld_cb)
+{
+ void *hif_ctx;
+ void *dp_soc;
+ void *txrx_pdev;
+ void *htc_ctx;
+ QDF_STATUS status;
+
+ PMO_ENTER();
+
+ if (!psoc) {
+ pmo_err("psoc is NULL");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ status = pmo_psoc_get_ref(psoc);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("pmo cannot get the reference out of psoc");
+ goto out;
+ }
+
+ hif_ctx = pmo_core_psoc_get_hif_handle(psoc);
+ dp_soc = pmo_core_psoc_get_dp_handle(psoc);
+ txrx_pdev = pmo_core_psoc_get_txrx_handle(psoc);
+ htc_ctx = pmo_core_psoc_get_htc_handle(psoc);
+ if (!hif_ctx || !dp_soc || !txrx_pdev || !htc_ctx) {
+ pmo_err("Invalid hif: %p, dp: %p, txrx: %p, htc: %p",
+ hif_ctx, dp_soc, txrx_pdev, htc_ctx);
+ status = QDF_STATUS_E_INVAL;
+ goto dec_psoc_ref;
+ }
+
+ hif_pre_runtime_resume(hif_ctx);
+
+ if (pld_cb)
+ QDF_BUG(!pld_cb());
+
+ QDF_BUG(!hif_runtime_resume(hif_ctx));
+
+ status = pmo_core_psoc_bus_resume_req(psoc, QDF_RUNTIME_SUSPEND);
+ QDF_BUG(status == QDF_STATUS_SUCCESS);
+
+ status = pmo_core_psoc_configure_resume(psoc);
+ QDF_BUG(status == QDF_STATUS_SUCCESS);
+
+ status = pmo_tgt_psoc_set_runtime_pm_inprogress(psoc, false);
+ QDF_BUG(status == QDF_STATUS_SUCCESS);
+
+ QDF_BUG(!htc_runtime_resume(htc_ctx));
+
+ status = cdp_runtime_resume(dp_soc, txrx_pdev);
+ QDF_BUG(status == QDF_STATUS_SUCCESS);
+
+ hif_process_runtime_resume_success(hif_ctx);
+
+dec_psoc_ref:
+ pmo_psoc_put_ref(psoc);
+
+out:
+ PMO_EXIT();
+
+ return status;
+}
+#endif
+
+/**
+ * pmo_core_psoc_send_host_wakeup_ind_to_fw() - send wakeup ind to fw
+ * @psoc: objmgr psoc handle
+ * @psoc_ctx: pmo psoc private context
+ *
+ * Sends host wakeup indication to FW. On receiving this indication,
+ * FW will come out of WOW.
+ *
+ * Return: QDF status
+ */
+static
+QDF_STATUS pmo_core_psoc_send_host_wakeup_ind_to_fw(
+ struct wlan_objmgr_psoc *psoc,
+ struct pmo_psoc_priv_obj *psoc_ctx)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+ PMO_ENTER();
+ qdf_event_reset(&psoc_ctx->wow.target_resume);
+
+ status = pmo_tgt_psoc_send_host_wakeup_ind(psoc);
+ if (status) {
+ status = QDF_STATUS_E_FAILURE;
+ goto out;
+ }
+ pmo_debug("Host wakeup indication sent to fw");
+
+ status = qdf_wait_single_event(&psoc_ctx->wow.target_resume,
+ PMO_RESUME_TIMEOUT);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("Timeout waiting for resume event from FW");
+ pmo_err("Pending commands %d credits %d",
+ pmo_tgt_psoc_get_pending_cmnds(psoc),
+ pmo_tgt_psoc_get_host_credits(psoc));
+ QDF_BUG(0);
+ } else {
+ pmo_debug("Host wakeup received");
+ }
+
+ if (status == QDF_STATUS_SUCCESS)
+ pmo_tgt_update_target_suspend_flag(psoc, false);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+/**
+ * pmo_core_psoc_disable_wow_in_fw() - Disable wow in bus resume context.
+ * @psoc: objmgr psoc handle
+ * @psoc_ctx: pmo psoc private context
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static
+QDF_STATUS pmo_core_psoc_disable_wow_in_fw(struct wlan_objmgr_psoc *psoc,
+ struct pmo_psoc_priv_obj *psoc_ctx)
+{
+ QDF_STATUS ret;
+
+ PMO_ENTER();
+ ret = pmo_core_psoc_send_host_wakeup_ind_to_fw(psoc, psoc_ctx);
+ if (ret != QDF_STATUS_SUCCESS)
+ goto out;
+
+ pmo_core_update_wow_enable(psoc_ctx, false);
+ pmo_core_update_wow_enable_cmd_sent(psoc_ctx, false);
+
+ /* To allow the tx pause/unpause events */
+ pmo_core_update_wow_bus_suspend(psoc, psoc_ctx, false);
+ /* Unpause the vdev as we are resuming */
+ pmo_unpause_all_vdev(psoc, psoc_ctx);
+out:
+ PMO_EXIT();
+
+ return ret;
+}
+
+/**
+ * pmo_core_psoc_resume_target() - resume target
+ * @psoc: objmgr psoc handle
+ * @psoc_ctx: pmo psoc private context
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static
+QDF_STATUS pmo_core_psoc_resume_target(struct wlan_objmgr_psoc *psoc,
+ struct pmo_psoc_priv_obj *psoc_ctx)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+ PMO_ENTER();
+ qdf_event_reset(&psoc_ctx->wow.target_resume);
+
+ status = pmo_tgt_psoc_send_target_resume_req(psoc);
+ if (status != QDF_STATUS_SUCCESS) {
+ status = QDF_STATUS_E_FAILURE;
+ goto out;
+ }
+
+ status = qdf_wait_single_event(&psoc_ctx->wow.target_resume,
+ PMO_RESUME_TIMEOUT);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_fatal("Timeout waiting for resume event from FW");
+ pmo_fatal("Pending commands %d credits %d",
+ pmo_tgt_psoc_get_pending_cmnds(psoc),
+ pmo_tgt_psoc_get_host_credits(psoc));
+ QDF_BUG(0);
+ } else {
+ pmo_debug("Host wakeup received");
+ }
+
+ if (status == QDF_STATUS_SUCCESS)
+ pmo_tgt_update_target_suspend_flag(psoc, false);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_core_psoc_bus_resume_req(struct wlan_objmgr_psoc *psoc,
+ enum qdf_suspend_type type)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx;
+ bool wow_mode;
+ QDF_STATUS status;
+
+ PMO_ENTER();
+ if (!psoc) {
+ pmo_err("psoc is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ status = pmo_psoc_get_ref(psoc);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("pmo cannot get the reference out of psoc");
+ goto out;
+ }
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+ wow_mode = pmo_core_is_wow_enabled(psoc_ctx);
+ pmo_info("wow mode %d", wow_mode);
+
+ pmo_core_update_wow_initial_wake_up(psoc_ctx, false);
+
+ if (wow_mode)
+ status = pmo_core_psoc_disable_wow_in_fw(psoc, psoc_ctx);
+ else
+ status = pmo_core_psoc_resume_target(psoc, psoc_ctx);
+
+ pmo_psoc_put_ref(psoc);
+
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+void pmo_core_psoc_target_suspend_acknowledge(void *context, bool wow_nack)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx;
+ struct wlan_objmgr_psoc *psoc = (struct wlan_objmgr_psoc *)context;
+ QDF_STATUS status;
+
+ PMO_ENTER();
+ if (!psoc) {
+ pmo_err("psoc is null");
+ goto out;
+ }
+
+ status = pmo_psoc_get_ref(psoc);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("Failed to get psoc reference");
+ goto out;
+ }
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+
+ pmo_core_set_wow_nack(psoc_ctx, wow_nack);
+ qdf_event_set(&psoc_ctx->wow.target_suspend);
+ if (wow_nack && !pmo_tgt_psoc_get_runtime_pm_in_progress(psoc)) {
+ qdf_wake_lock_timeout_acquire(&psoc_ctx->wow.wow_wake_lock,
+ PMO_WAKE_LOCK_TIMEOUT);
+ }
+
+ pmo_psoc_put_ref(psoc);
+out:
+ PMO_EXIT();
+}
+
+void pmo_core_psoc_wakeup_host_event_received(struct wlan_objmgr_psoc *psoc)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx;
+
+ PMO_ENTER();
+ if (!psoc) {
+ pmo_err("psoc is null");
+ goto out;
+ }
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+ qdf_event_set(&psoc_ctx->wow.target_resume);
+out:
+ PMO_EXIT();
+}
+
+int pmo_core_psoc_is_target_wake_up_received(struct wlan_objmgr_psoc *psoc)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx;
+ int ret = 0;
+ QDF_STATUS status;
+
+ if (!psoc) {
+ pmo_err("psoc is NULL");
+ ret = -EAGAIN;
+ goto out;
+ }
+
+ status = pmo_psoc_get_ref(psoc);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("Failed to get psoc reference");
+ ret = -EAGAIN;
+ goto out;
+ }
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+ if (pmo_core_get_wow_initial_wake_up(psoc_ctx)) {
+ pmo_err("Target initial wake up received try again");
+ ret = -EAGAIN;
+ }
+
+ pmo_psoc_put_ref(psoc);
+out:
+ PMO_EXIT();
+
+ return ret;
+}
+
+
+int pmo_core_psoc_clear_target_wake_up(struct wlan_objmgr_psoc *psoc)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx;
+ int ret = 0;
+ QDF_STATUS status;
+
+ if (!psoc) {
+ pmo_err("psoc is NULL");
+ ret = -EAGAIN;
+ goto out;
+ }
+
+ status = pmo_psoc_get_ref(psoc);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("Failed to get psoc reference");
+ ret = -EAGAIN;
+ goto out;
+ }
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+ pmo_core_update_wow_initial_wake_up(psoc_ctx, false);
+
+ pmo_psoc_put_ref(psoc);
+out:
+ PMO_EXIT();
+
+ return ret;
+}
+
+void pmo_core_psoc_handle_initial_wake_up(void *cb_ctx)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx;
+ struct wlan_objmgr_psoc *psoc = (struct wlan_objmgr_psoc *)cb_ctx;
+ QDF_STATUS status;
+
+ PMO_ENTER();
+ if (!psoc) {
+ pmo_err("cb ctx/psoc is null");
+ goto out;
+ }
+
+ status = pmo_psoc_get_ref(psoc);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("Failed to get psoc reference");
+ goto out;
+ }
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+ pmo_core_update_wow_initial_wake_up(psoc_ctx, true);
+
+ pmo_psoc_put_ref(psoc);
+
+out:
+ PMO_EXIT();
+}
+
diff --git a/components/pmo/core/src/wlan_pmo_wow.c b/components/pmo/core/src/wlan_pmo_wow.c
new file mode 100644
index 0000000..e32e32f
--- /dev/null
+++ b/components/pmo/core/src/wlan_pmo_wow.c
@@ -0,0 +1,350 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Define API's for wow pattern addition and deletion in fwr
+ */
+
+#include "wlan_pmo_wow.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include <wlan_scan_ucfg_api.h>
+#include "wlan_pmo_static_config.h"
+#include "wlan_reg_services_api.h"
+
+static inline int pmo_find_wow_ptrn_len(const char *ptrn)
+{
+ int len = 0;
+
+ while (*ptrn != '\0' && *ptrn != PMO_WOW_INTER_PTRN_TOKENIZER) {
+ len++;
+ ptrn++;
+ }
+
+ return len;
+}
+
+QDF_STATUS pmo_core_add_wow_pattern(struct wlan_objmgr_vdev *vdev,
+ const char *ptrn)
+{
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_core_del_wow_pattern(struct wlan_objmgr_vdev *vdev,
+ const char *ptrn)
+{
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_core_wow_enter(struct wlan_objmgr_vdev *vdev,
+ struct pmo_wow_enter_params *wow_enter_param)
+{
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_core_wow_exit(struct wlan_objmgr_vdev *vdev)
+{
+ return QDF_STATUS_SUCCESS;
+}
+
+void pmo_core_enable_wakeup_event(struct wlan_objmgr_psoc *psoc,
+ uint32_t vdev_id, uint32_t *bitmap)
+{
+ QDF_STATUS status;
+ struct wlan_objmgr_vdev *vdev;
+
+ PMO_ENTER();
+ if (!psoc) {
+ pmo_err("psoc is null");
+ goto out;
+ }
+
+ vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+ if (!vdev) {
+ pmo_err("vdev is NULL");
+ goto out;
+ }
+
+ status = pmo_vdev_get_ref(vdev);
+ if (QDF_IS_STATUS_ERROR(status))
+ goto out;
+
+ pmo_info("enable wakeup event vdev_id %d wake up event 0x%x%x%x%x",
+ vdev_id, bitmap[0], bitmap[1], bitmap[2], bitmap[3]);
+ pmo_tgt_enable_wow_wakeup_event(vdev, bitmap);
+
+ pmo_vdev_put_ref(vdev);
+
+out:
+ PMO_EXIT();
+}
+
+void pmo_core_disable_wakeup_event(struct wlan_objmgr_psoc *psoc,
+ uint32_t vdev_id, uint32_t *bitmap)
+{
+ QDF_STATUS status;
+ struct wlan_objmgr_vdev *vdev;
+
+ PMO_ENTER();
+ if (!psoc) {
+ pmo_err("psoc is null");
+ goto out;
+ }
+
+ vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+ if (!vdev) {
+ pmo_err("vdev is NULL");
+ goto out;
+ }
+
+ status = pmo_vdev_get_ref(vdev);
+ if (QDF_IS_STATUS_ERROR(status))
+ goto out;
+
+ pmo_info("Disable wakeup event vdev_id %d wake up event 0x%x%x%x%x",
+ vdev_id, bitmap[0], bitmap[1], bitmap[2], bitmap[3]);
+ pmo_tgt_disable_wow_wakeup_event(vdev, bitmap);
+
+ pmo_vdev_put_ref(vdev);
+
+out:
+ PMO_EXIT();
+}
+
+/**
+ * pmo_is_beaconing_vdev_up(): check if a beaconning vdev is up
+ * @psoc: objmgr psoc handle
+ *
+ * Return TRUE if beaconning vdev is up
+ */
+static
+bool pmo_is_beaconing_vdev_up(struct wlan_objmgr_psoc *psoc)
+{
+ int vdev_id;
+ struct wlan_objmgr_vdev *vdev;
+ enum tQDF_ADAPTER_MODE vdev_opmode;
+ bool is_beaconing;
+ QDF_STATUS status;
+
+ /* Iterate through VDEV list */
+ for (vdev_id = 0; vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS; vdev_id++) {
+ vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+ if (!vdev)
+ continue;
+
+ status = pmo_vdev_get_ref(vdev);
+ if (QDF_IS_STATUS_ERROR(status))
+ continue;
+
+ vdev_opmode = pmo_get_vdev_opmode(vdev);
+ is_beaconing = pmo_is_vdev_in_beaconning_mode(vdev_opmode) &&
+ pmo_is_vdev_up(vdev);
+
+ pmo_vdev_put_ref(vdev);
+
+ if (is_beaconing)
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * pmo_support_wow_for_beaconing: wow query for beaconning
+ * @psoc: objmgr psoc handle
+ *
+ * Need to configure wow to enable beaconning offload when
+ * a beaconing vdev is up and beaonning offload is configured.
+ *
+ * Return: true if we need to enable wow for beaconning offload
+ */
+static
+bool pmo_support_wow_for_beaconing(struct wlan_objmgr_psoc *psoc)
+{
+ /*
+ * if (WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
+ * WMI_SERVICE_BEACON_OFFLOAD))
+ */
+ return pmo_is_beaconing_vdev_up(psoc);
+}
+
+bool pmo_core_is_wow_applicable(struct wlan_objmgr_psoc *psoc)
+{
+ int vdev_id;
+ struct wlan_objmgr_vdev *vdev;
+ bool is_wow_applicable;
+ QDF_STATUS status;
+
+ if (!psoc) {
+ pmo_err("psoc is null");
+ return false;
+ }
+
+ if (pmo_support_wow_for_beaconing(psoc)) {
+ pmo_debug("one of vdev is in beaconning mode, enabling wow");
+ return true;
+ }
+
+ if (wlan_reg_is_11d_scan_inprogress(psoc)) {
+ pmo_debug("11d scan is in progress, enabling wow");
+ return true;
+ }
+
+ /* Iterate through VDEV list */
+ for (vdev_id = 0; vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS; vdev_id++) {
+ vdev = pmo_psoc_get_vdev(psoc, vdev_id);
+ if (!vdev)
+ continue;
+
+ status = pmo_vdev_get_ref(vdev);
+ if (QDF_IS_STATUS_ERROR(status))
+ continue;
+
+ if (pmo_core_is_vdev_connected(vdev)) {
+ pmo_debug("STA is connected, enabling wow");
+ is_wow_applicable = true;
+ } else if (ucfg_scan_get_pno_in_progress(vdev)) {
+ pmo_debug("NLO is in progress, enabling wow");
+ is_wow_applicable = true;
+ } else if (pmo_core_is_extscan_in_progress(vdev)) {
+ pmo_debug("EXT is in progress, enabling wow");
+ is_wow_applicable = true;
+ } else if (pmo_core_is_p2plo_in_progress(vdev)) {
+ pmo_debug("P2P LO is in progress, enabling wow");
+ is_wow_applicable = true;
+ } else if (pmo_core_is_lpass_enabled(vdev)) {
+ pmo_debug("LPASS is enabled, enabling WoW");
+ is_wow_applicable = true;
+ } else if (pmo_core_is_nan_enabled(vdev)) {
+ pmo_debug("NAN is enabled, enabling WoW");
+ is_wow_applicable = true;
+ } else if (pmo_core_get_vdev_op_mode(vdev) == QDF_NDI_MODE) {
+ pmo_debug("vdev %d is in NAN data mode, enabling wow",
+ vdev_id);
+ is_wow_applicable = true;
+ }
+
+ pmo_vdev_put_ref(vdev);
+
+ if (is_wow_applicable)
+ return true;
+ }
+
+ pmo_debug("All vdev are in disconnected state\n"
+ "and pno/extscan is not in progress, skipping wow");
+
+ return false;
+}
+
+void pmo_set_wow_event_bitmap(WOW_WAKE_EVENT_TYPE event,
+ uint32_t wow_bitmap_size,
+ uint32_t *bitmask)
+{
+ uint32_t bit_idx = 0, idx = 0;
+
+ if (!bitmask || wow_bitmap_size < PMO_WOW_MAX_EVENT_BM_LEN) {
+ pmo_err("wow bitmask length shorter than %d",
+ PMO_WOW_MAX_EVENT_BM_LEN);
+ return;
+ }
+ pmo_get_event_bitmap_idx(event, wow_bitmap_size, &bit_idx, &idx);
+ bitmask[idx] |= 1 << bit_idx;
+
+ pmo_debug("%s: bitmask updated %x%x%x%x",
+ __func__, bitmask[0], bitmask[1], bitmask[2], bitmask[3]);
+}
+
+void pmo_set_sta_wow_bitmask(uint32_t *bitmask, uint32_t wow_bitmap_size)
+{
+
+ pmo_set_wow_event_bitmap(WOW_CSA_IE_EVENT,
+ wow_bitmap_size,
+ bitmask);
+ pmo_set_wow_event_bitmap(WOW_CLIENT_KICKOUT_EVENT,
+ wow_bitmap_size,
+ bitmask);
+ pmo_set_wow_event_bitmap(WOW_PATTERN_MATCH_EVENT,
+ wow_bitmap_size,
+ bitmask);
+ pmo_set_wow_event_bitmap(WOW_MAGIC_PKT_RECVD_EVENT,
+ wow_bitmap_size,
+ bitmask);
+ pmo_set_wow_event_bitmap(WOW_DEAUTH_RECVD_EVENT,
+ wow_bitmap_size,
+ bitmask);
+ pmo_set_wow_event_bitmap(WOW_DISASSOC_RECVD_EVENT,
+ wow_bitmap_size,
+ bitmask);
+ pmo_set_wow_event_bitmap(WOW_BMISS_EVENT,
+ wow_bitmap_size,
+ bitmask);
+ pmo_set_wow_event_bitmap(WOW_GTK_ERR_EVENT,
+ wow_bitmap_size,
+ bitmask);
+ pmo_set_wow_event_bitmap(WOW_BETTER_AP_EVENT,
+ wow_bitmap_size,
+ bitmask);
+ pmo_set_wow_event_bitmap(WOW_HTT_EVENT,
+ wow_bitmap_size,
+ bitmask);
+ pmo_set_wow_event_bitmap(WOW_RA_MATCH_EVENT,
+ wow_bitmap_size,
+ bitmask);
+ pmo_set_wow_event_bitmap(WOW_NLO_DETECTED_EVENT,
+ wow_bitmap_size,
+ bitmask);
+ pmo_set_wow_event_bitmap(WOW_EXTSCAN_EVENT,
+ wow_bitmap_size,
+ bitmask);
+ pmo_set_wow_event_bitmap(WOW_OEM_RESPONSE_EVENT,
+ wow_bitmap_size,
+ bitmask);
+ pmo_set_wow_event_bitmap(WOW_TDLS_CONN_TRACKER_EVENT,
+ wow_bitmap_size,
+ bitmask);
+ pmo_set_wow_event_bitmap(WOW_11D_SCAN_EVENT,
+ wow_bitmap_size,
+ bitmask);
+
+}
+
+void pmo_set_sap_wow_bitmask(uint32_t *bitmask, uint32_t wow_bitmap_size)
+{
+
+ pmo_set_wow_event_bitmap(WOW_PROBE_REQ_WPS_IE_EVENT,
+ wow_bitmap_size,
+ bitmask);
+ pmo_set_wow_event_bitmap(WOW_PATTERN_MATCH_EVENT,
+ wow_bitmap_size,
+ bitmask);
+ pmo_set_wow_event_bitmap(WOW_AUTH_REQ_EVENT,
+ wow_bitmap_size,
+ bitmask);
+ pmo_set_wow_event_bitmap(WOW_ASSOC_REQ_EVENT,
+ wow_bitmap_size,
+ bitmask);
+ pmo_set_wow_event_bitmap(WOW_DEAUTH_RECVD_EVENT,
+ wow_bitmap_size,
+ bitmask);
+ pmo_set_wow_event_bitmap(WOW_DISASSOC_RECVD_EVENT,
+ wow_bitmap_size,
+ bitmask);
+ pmo_set_wow_event_bitmap(WOW_HTT_EVENT,
+ wow_bitmap_size,
+ bitmask);
+}
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_arp_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_arp_public_struct.h
new file mode 100644
index 0000000..533b809
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_arp_public_struct.h
@@ -0,0 +1,58 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+ /**
+ * DOC: Declare various struct, macros which shall be used in
+ * pmo arp offload feature.
+ *
+ * Note: This file shall not contain public API's prototype/declarations.
+ *
+ */
+
+#ifndef _WLAN_PMO_ARP_PUBLIC_STRUCT_H_
+#define _WLAN_PMO_ARP_PUBLIC_STRUCT_H_
+
+#include "wlan_pmo_common_public_struct.h"
+
+/**
+ * struct pmo_arp_req - pmo arp request
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id on which arp offload needed
+ * @ipv4_addr: ipv4 address for the interface
+ * @trigger: context from where arp offload triggered
+ */
+struct pmo_arp_req {
+ struct wlan_objmgr_psoc *psoc;
+ uint8_t vdev_id;
+ uint32_t ipv4_addr;
+ enum pmo_offload_trigger trigger;
+};
+
+/**
+ * struct pmo_arp_req - pmo arp offload param for target interface
+ * @enable: true when arp offload is enabled else false
+ * @host_ipv4_addr: host interface ipv4 address
+ * @bssid: peer ap address
+ */
+struct pmo_arp_offload_params {
+ uint8_t enable;
+ uint8_t host_ipv4_addr[PMO_IPV4_ADDR_LEN];
+ struct qdf_mac_addr bssid;
+};
+
+#endif /* end of _WLAN_PMO_ARP_PUBLIC_STRUCT_H_ */
+
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h
new file mode 100644
index 0000000..31b9edb
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h
@@ -0,0 +1,298 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Declare various struct, macros which are common for
+ * various pmo related features.
+ *
+ * Note: This file shall not contain public API's prototype/declartions.
+ *
+ */
+
+#ifndef _WLAN_PMO_COMMONP_PUBLIC_STRUCT_H_
+#define _WLAN_PMO_COMMONP_PUBLIC_STRUCT_H_
+
+#include "wlan_cmn.h"
+#include "wlan_objmgr_cmn.h"
+#include "wlan_objmgr_global_obj.h"
+#include "wlan_objmgr_psoc_obj.h"
+#include "wlan_objmgr_pdev_obj.h"
+#include "wlan_objmgr_vdev_obj.h"
+#include "wlan_objmgr_peer_obj.h"
+#include "wmi_unified.h"
+#include "qdf_status.h"
+#include "qdf_lock.h"
+#include "qdf_event.h"
+#include "wlan_pmo_hw_filter_public_struct.h"
+
+#define PMO_IPV4_ADDR_LEN 4
+
+#define PMO_IPV4_ARP_REPLY_OFFLOAD 0
+#define PMO_IPV6_NEIGHBOR_DISCOVERY_OFFLOAD 1
+#define PMO_IPV6_NS_OFFLOAD 2
+#define PMO_OFFLOAD_DISABLE 0
+#define PMO_OFFLOAD_ENABLE 1
+
+#define PMO_MAC_NS_OFFLOAD_SIZE 1
+#define PMO_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA 16
+#define PMO_MAC_IPV6_ADDR_LEN 16
+#define PMO_IPV6_ADDR_VALID 1
+#define PMO_IPV6_ADDR_UC_TYPE 0
+#define PMO_IPV6_ADDR_AC_TYPE 1
+
+#define PMO_80211_ADDR_LEN 6 /* size of 802.11 address */
+
+#define PMO_WOW_REQUIRED_CREDITS 1
+
+/**
+ * enum pmo_offload_type: tell offload type
+ * @pmo_arp_offload: arp offload
+ * @pmo_ns_offload: ns offload
+ * @pmo_gtk_offload: gtk offload
+ */
+enum pmo_offload_type {
+ pmo_arp_offload = 0,
+ pmo_ns_offload,
+ pmo_gtk_offload,
+};
+
+/**
+ * enum pmo_vdev_param_id: tell vdev param id
+ * @pmo_vdev_param_listen_interval: vdev listen interval param id
+ * @pmo_vdev_param_dtim_policy: vdev param dtim policy
+ * @pmo_vdev_max_param: Max vdev param id
+ */
+enum pmo_vdev_param_id {
+ pmo_vdev_param_listen_interval = 0,
+ pmo_vdev_param_dtim_policy,
+ pmo_vdev_max_param
+};
+
+/**
+ * enum pmo_beacon_dtim_policy: tell vdev beacon policy
+ * @pmo_ignore_dtim: fwr need to igonre dtime policy
+ * @pmo_normal_dtim: fwr need to use normal dtime policy
+ * @pmo_stick_dtim: fwr need to use stick dtime policy
+ * @auto_dtim: fwr need to auto dtime policy
+ */
+enum pmo_beacon_dtim_policy {
+ pmo_ignore_dtim = 0x01,
+ pmo_normal_dtim = 0x02,
+ pmo_stick_dtim = 0x03,
+ pmo_auto_dtim = 0x04,
+};
+
+/**
+ * @pmo_sta_ps_param_rx_wake_policy: Controls how frames are retrievd from AP
+ * while STA is sleeping.
+ * @pmo_sta_ps_param_tx_wake_threshold: STA will go active after this many TX
+ * @pmo_sta_ps_param_pspoll_count:No of PS-Poll to send before STA wakes up
+ * @pmo_sta_ps_param_inactivity_time: TX/RX inactivity time in msec before
+ going to sleep.
+ * @pmo_sta_ps_param_uapsd: Set uapsd configuration.
+ * @pmo_sta_ps_param_qpower_pspoll_count: No of PS-Poll to send before
+ STA wakes up in QPower Mode.
+ * @pmo_sta_ps_enable_qpower: Enable QPower
+ * @pmo_sta_ps_param_qpower_max_tx_before_wake: Number of TX frames before the
+ entering the Active state
+ */
+enum pmo_sta_powersave_param {
+ pmo_sta_ps_param_rx_wake_policy = 0,
+ pmo_sta_ps_param_tx_wake_threshold = 1,
+ pmo_sta_ps_param_pspoll_count = 2,
+ pmo_sta_ps_param_inactivity_time = 3,
+ pmo_sta_ps_param_uapsd = 4,
+ pmo_sta_ps_param_qpower_pspoll_count = 5,
+ pmo_sta_ps_enable_qpower = 6,
+ pmo_sta_ps_param_qpower_max_tx_before_wake = 7,
+};
+
+/**
+ * enum powersave_qpower_mode: QPOWER modes
+ * @pmo_qpower_disabled: Qpower is disabled
+ * @pmo_qpower_enabled: Qpower is enabled
+ * @pmo_qpower_duty_cycling: Qpower is enabled with duty cycling
+ */
+enum pmo_power_save_qpower_mode {
+ pmo_qpower_disabled = 0,
+ pmo_qpower_enabled = 1,
+ pmo_qpower_duty_cycling = 2
+};
+
+/**
+ * enum powersave_qpower_mode: powersave_mode
+ * @pmo_ps_not_supported: Power save is not supported
+ * @pmo_ps_legacy_no_deep_sleep: Legacy pwr save enabled and deep sleep disabled
+ * @pmo_ps_qpower_no_deep_sleep: QPOWER enabled and deep sleep disabled
+ * @pmo_ps_legacy_deep_sleep: Legacy power save enabled and deep sleep enabled
+ * @pmo_ps_qpower_deep_sleep: QPOWER enabled and deep sleep enabled
+ * @pmo_ps_duty_cycling_qpower: QPOWER enabled in duty cycling mode
+ */
+enum pmo_powersave_mode {
+ pmo_ps_not_supported = 0,
+ pmo_ps_legacy_no_deep_sleep = 1,
+ pmo_ps_qpower_no_deep_sleep = 2,
+ pmo_ps_legacy_deep_sleep = 3,
+ pmo_ps_qpower_deep_sleep = 4,
+ pmo_ps_duty_cycling_qpower = 5
+};
+
+/**
+ * enum wow_resume_trigger - resume trigger override setting values
+ * @PMO_WOW_RESUME_TRIGGER_DEFAULT: fw to use platform default resume trigger
+ * @PMO_WOW_RESUME_TRIGGER_HTC_WAKEUP: force fw to use HTC Wakeup to resume
+ * @PMO_WOW_RESUME_TRIGGER_GPIO: force fw to use GPIO to resume
+ * @PMO_WOW_RESUME_TRIGGER_COUNT: number of resume trigger options
+ */
+enum pmo_wow_resume_trigger {
+ /* always first */
+ PMO_WOW_RESUME_TRIGGER_DEFAULT = 0,
+ PMO_WOW_RESUME_TRIGGER_HTC_WAKEUP,
+ PMO_WOW_RESUME_TRIGGER_GPIO,
+ /* always last */
+ PMO_WOW_RESUME_TRIGGER_COUNT
+};
+
+/**
+ * enum wow_interface_pause - interface pause override setting values
+ * @PMO_WOW_INTERFACE_PAUSE_DEFAULT: use platform default iface pause setting
+ * @PMO_WOW_INTERFACE_PAUSE_ENABLE: force interface pause setting to enabled
+ * @PMO_WOW_INTERFACE_PAUSE_DISABLE: force interface pause setting to disabled
+ * @PMO_WOW_INTERFACE_PAUSE_COUNT: number of interface pause options
+ */
+enum pmo_wow_interface_pause {
+ /* always first */
+ PMO_WOW_INTERFACE_PAUSE_DEFAULT = 0,
+ PMO_WOW_INTERFACE_PAUSE_ENABLE,
+ PMO_WOW_INTERFACE_PAUSE_DISABLE,
+ /* always last */
+ PMO_WOW_INTERFACE_PAUSE_COUNT
+};
+
+#define PMO_TGT_SUSPEND_COMPLETE_TIMEOUT 6000
+#define PMO_WAKE_LOCK_TIMEOUT 1000
+#define PMO_RESUME_TIMEOUT 25000
+
+/**
+ * struct wow_enable_params - A collection of wow enable override parameters
+ * @is_unit_test: true to notify fw this is a unit-test suspend
+ * @interface_pause: used to override the interface pause indication sent to fw
+ * @resume_trigger: used to force fw to use a particular resume method
+ */
+struct pmo_wow_enable_params {
+ bool is_unit_test;
+ enum pmo_wow_interface_pause interface_pause;
+ enum pmo_wow_resume_trigger resume_trigger;
+};
+
+/**
+ * typedef for psoc suspend handler
+ */
+typedef QDF_STATUS(*pmo_psoc_suspend_handler)
+ (struct wlan_objmgr_psoc *psoc, void *arg);
+/**
+ * typedef for psoc resume handler
+ */
+typedef QDF_STATUS(*pmo_psoc_resume_handler)
+ (struct wlan_objmgr_psoc *psoc, void *arg);
+
+/**
+ * enum pmo_offload_trigger: trigger information
+ * @pmo_apps_suspend: trigger is apps suspend
+ * @pmo_apps_resume: trigger is apps resume
+ * @pmo_runtime_suspend: trigger is runtime suspend
+ * @pmo_runtime_resume: trigger is runtime resume
+ * @pmo_ipv4_change_notify: trigger is ipv4 change handler
+ * @pmo_ipv6_change_notify: trigger is ipv6 change handler
+ * @pmo_ns_offload_dynamic_update: enable/disable ns offload on the fly
+ * @pmo_peer_disconnect: trigger is peer disconnect
+ * @pmo_mcbc_setting_dynamic_update: mcbc value update on the fly
+ *
+ * @pmo_offload_trigger_max: Max trigger value
+ */
+enum pmo_offload_trigger {
+ pmo_apps_suspend = 0,
+ pmo_apps_resume,
+ pmo_runtime_suspend,
+ pmo_runtime_resume,
+ pmo_ipv4_change_notify,
+ pmo_ipv6_change_notify,
+ pmo_mc_list_change_notify,
+ pmo_ns_offload_dynamic_update,
+ pmo_peer_disconnect,
+ pmo_mcbc_setting_dynamic_update,
+
+ pmo_offload_trigger_max,
+};
+
+/**
+ * struct pmo_psoc_cfg - user configuration required for pmo
+ * @ptrn_match_enable_all_vdev: true when pattern match is enable for all vdev
+ * @bpf_enable: true if psoc supports bpf else false
+ * @arp_offload_enable: true if arp offload is supported for psoc else false
+ * @hw_filter_mode: which mode the hardware filter should use during DTIM
+ * @ns_offload_enable_static: true if psoc supports ns offload in ini else false
+ * @ns_offload_enable_dynamic: to enable / disable the ns offload using
+ * ioctl or vendor command.
+ * @ssdp: true if psoc supports if ssdp configuration in wow mode
+ * @enable_mc_list: true if psoc supports mc addr list else false
+ * @active_mode_offload: true if psoc supports active mode offload else false
+ * @ap_arpns_support: true if psoc supports arp ns for ap mode
+ * @max_wow_filters: maximum number of wow filter supported
+ * @ra_ratelimit_enable: true when ra filtering ins eanbled else false
+ * @ra_ratelimit_interval: ra packets interval
+ * @magic_ptrn_enable: true when magic pattern is enabled else false
+ * @deauth_enable: true when wake up on deauth is enabled else false
+ * @disassoc_enable: true when wake up on disassoc is enabled else false
+ * @bmiss_enable: true when wake up on bmiss is enabled else false
+ * @nan_enable: true when nan is enabled else false
+ * @lpass_enable: true when lpass is enabled else false
+ * @sta_dynamic_dtim: station dynamic DTIM value
+ * @sta_mod_dtim: station modulated DTIM value
+ * @sta_max_li_mod_dtim: station max listen interval DTIM value
+ * @power_save_mode: power save mode for psoc
+ * @auto_power_save_fail_mode: auto detect power save failure
+ */
+struct pmo_psoc_cfg {
+ bool ptrn_match_enable_all_vdev;
+ bool bpf_enable;
+ bool arp_offload_enable;
+ enum pmo_hw_filter_mode hw_filter_mode;
+ bool ns_offload_enable_static;
+ bool ns_offload_enable_dynamic;
+ bool ssdp;
+ bool enable_mc_list;
+ bool active_mode_offload;
+ bool ap_arpns_support;
+ uint8_t max_wow_filters;
+ bool ra_ratelimit_enable;
+ uint16_t ra_ratelimit_interval;
+ bool magic_ptrn_enable;
+ bool deauth_enable;
+ bool disassoc_enable;
+ bool bmiss_enable;
+ bool nan_enable;
+ bool lpass_enable;
+ uint8_t sta_dynamic_dtim;
+ uint8_t sta_mod_dtim;
+ uint8_t sta_max_li_mod_dtim;
+ uint8_t power_save_mode;
+ bool auto_power_save_fail_mode;
+};
+
+#endif /* end of _WLAN_PMO_COMMONP_STRUCT_H_ */
+
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_gtk_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_gtk_public_struct.h
new file mode 100644
index 0000000..8c27cc0
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_gtk_public_struct.h
@@ -0,0 +1,95 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+ /**
+ * DOC: Declare various struct, macros which shall be used in
+ * pmo gtk related feature.
+ *
+ * Note: This file shall not contain public API's prototype/declarations.
+ *
+ */
+
+#ifndef _WLAN_PMO_GTK_PUBLIC_STRUCT_H
+#define _WLAN_PMO_GTK_PUBLIC_STRUCT_H
+
+#include "wlan_pmo_common_public_struct.h"
+
+#define PMO_GTK_OFFLOAD_ENABLE 0
+#define PMO_GTK_OFFLOAD_DISABLE 1
+#define PMO_KEK_LEN 16
+#define PMO_KCK_LEN 16
+#define PMO_REPLAY_COUNTER_LEN 8
+#define PMO_MAC_MAX_KEY_LENGTH 32
+#define PMO_IGTK_PN_SIZE 6
+
+/**
+ * struct pmo_gtk_req - pmo gtk request
+ * @flags: optional flags
+ * @kck: Key confirmation key
+ * @kek: key encryption key
+ * @replay_counter: replay_counter
+ * @bssid: bssid
+ */
+struct pmo_gtk_req {
+ uint32_t flags;
+ uint8_t kck[PMO_KCK_LEN];
+ uint8_t kek[PMO_KEK_LEN];
+ uint64_t replay_counter;
+ struct qdf_mac_addr bssid;
+};
+
+/**
+ * struct pmo_gtk_rsp_params - pmo gtk response
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id on which arp offload needed
+ * @status_flag: status flags
+ * @refresh_cnt: number of successful GTK refresh exchanges since SET operation
+ * @igtk_key_index: igtk key index
+ * @igtk_key_length: igtk key length
+ * @igtk_key_rsc: igtk key index
+ * @igtk_key: igtk key length
+ */
+struct pmo_gtk_rsp_params {
+ uint8_t vdev_id;
+ uint32_t status_flag;
+ uint32_t refresh_cnt;
+ uint64_t replay_counter;
+ uint8_t igtk_key_index;
+ uint8_t igtk_key_length;
+ uint8_t igtk_key_rsc[PMO_IGTK_PN_SIZE];
+ uint8_t igtk_key[PMO_MAC_MAX_KEY_LENGTH];
+ struct qdf_mac_addr bssid;
+};
+
+/**
+ * typedef for gtk response callback
+ */
+typedef void (*pmo_gtk_rsp_callback)(void *callback_context,
+ struct pmo_gtk_rsp_params *gtk_rsp);
+
+/**
+ * struct pmo_gtk_rsp_req -gtk respsonse request
+ * @callback: client callback for providing gtk resposne when fwr send event
+ * @callback_context: client callback response
+ */
+struct pmo_gtk_rsp_req {
+ pmo_gtk_rsp_callback callback;
+ void *callback_context;
+};
+
+#endif /* end of _WLAN_PMO_GTK_PUBLIC_STRUCT_H */
+
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_hw_filter_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_hw_filter_public_struct.h
new file mode 100644
index 0000000..106cef7
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_hw_filter_public_struct.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: This file shall contain all public parameter (struct/macro/enum)
+ * definitions to support hardware filtering configuration. No APIs, or
+ * implememtations of APIs, shall be contained within.
+ */
+
+#ifndef _WLAN_PMO_HW_FILTER_PUBLIC_STRUCT_H
+#define _WLAN_PMO_HW_FILTER_PUBLIC_STRUCT_H
+
+/**
+ * pmo_hw_filter_mode - bitmap for enabled hardware filters
+ * @HW_FILTER_DISABLED: hardware filter is completely disabled
+ * @HW_FILTER_NON_ARP_BC: drop all broadcast frames, except ARP
+ * @HW_FILTER_NON_ICMPV6_MC: drop all multicast frames, except ICMPv6
+ *
+ * The hardware filter is only effective in DTIM mode. Use this configuration
+ * to blanket drop broadcast/multicast packets at the hardware level, without
+ * waking up the firmware.
+ */
+enum pmo_hw_filter_mode {
+ PMO_HW_FILTER_DISABLED = 0,
+ PMO_HW_FILTER_NON_ARP_BC = 1,
+ PMO_HW_FILTER_NON_ICMPV6_MC = 2,
+};
+
+/**
+ * struct pmo_hw_filter_params - hardware filter configuration parameters
+ * @vdev_id: Id of the virtual device to configure
+ * @mode: the hardware filter mode to configure
+ */
+struct pmo_hw_filter_params {
+ uint8_t vdev_id;
+ enum pmo_hw_filter_mode mode;
+};
+
+#endif /* _WLAN_PMO_HW_FILTER_PUBLIC_STRUCT_H */
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_lphb_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_lphb_public_struct.h
new file mode 100644
index 0000000..7778f91
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_lphb_public_struct.h
@@ -0,0 +1,176 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+ /**
+ * DOC: Declare various struct, macros which shall be used in
+ * pmo lphb offload feature.
+ *
+ * Note: This file shall not contain public API's prototype/declarations.
+ *
+ */
+
+#ifndef _WLAN_PMO_LPHB_PUBLIC_STRUCT_H_
+#define _WLAN_PMO_LPHB_PUBLIC_STRUCT_H_
+
+#include "wlan_pmo_common_public_struct.h"
+
+#ifdef FEATURE_WLAN_LPHB
+#define PMO_SIR_LPHB_FILTER_LEN 64
+
+/**
+ * enum lphb_ind_type -Low power heart beat indication type
+ * @pmo_lphb_set_en_param_indid: lphb enable indication
+ * @pmo_lphb_set_tcp_pararm_indid: lphb tcp param indication
+ * @pmo_lphb_set_tcp_pkt_filter_indid: lphb tcp packet filter indication
+ * @pmo_lphb_set_udp_pararm_indid: lphb udp param indication
+ * @pmo_lphb_set_udp_pkt_filter_indid: lphb udp packet filter indication
+ * @pmo_lphb_set_network_info_indid: lphb network information indication
+ */
+enum lphb_ind_type {
+ pmo_lphb_set_en_param_indid,
+ pmo_lphb_set_tcp_pararm_indid,
+ pmo_lphb_set_tcp_pkt_filter_indid,
+ pmo_lphb_set_udp_pararm_indid,
+ pmo_lphb_set_udp_pkt_filter_indid,
+ pmo_lphb_set_network_info_indid,
+};
+
+/**
+ * struct pmo_lphb_enable_req -Low power heart beat enable request
+ * @enable: lphb enable request
+ * @item: request item
+ * @session: lphb session
+ */
+struct pmo_lphb_enable_req {
+ uint8_t enable;
+ uint8_t item;
+ uint8_t session;
+};
+
+/**
+ * struct pmo_lphb_tcp_params - Low power heart beat tcp params
+ * @srv_ip: source ip address
+ * @dev_ip: destination ip address
+ * @src_port: source port
+ * @dst_port: destination port
+ * @timeout: tcp timeout value
+ * @session: session on which lphb needs to be configured
+ * @gateway_mac: gateway mac address
+ * @time_period_sec: time period in seconds
+ * @tcp_sn: tcp sequence number
+ */
+struct pmo_lphb_tcp_params {
+ uint32_t srv_ip;
+ uint32_t dev_ip;
+ uint16_t src_port;
+ uint16_t dst_port;
+ uint16_t timeout;
+ uint8_t session;
+ struct qdf_mac_addr gateway_mac;
+ uint16_t time_period_sec;
+ uint32_t tcp_sn;
+};
+
+/**
+ * struct pmo_lphb_tcp_filter_req - Low power heart beat tcp filter request
+ * @length: length of filter
+ * @offset: offset of filter
+ * @session: session on which lphb needs to be configured
+ * @filter: filter buffer
+ */
+struct pmo_lphb_tcp_filter_req {
+ uint16_t length;
+ uint8_t offset;
+ uint8_t session;
+ uint8_t filter[PMO_SIR_LPHB_FILTER_LEN];
+};
+
+/**
+ * struct pmo_lphb_udp_params - Low power heart beat udp params
+ * @srv_ip: source ip address
+ * @dev_ip: destination ip address
+ * @src_port: source port
+ * @dst_port: destination port
+ * @timeout: tcp timeout value
+ * @session: session on which lphb needs to be configured
+ * @gateway_mac: gateway mac address
+ * @time_period_sec: time period in seconds
+ */
+struct pmo_lphb_udp_params {
+ uint32_t srv_ip;
+ uint32_t dev_ip;
+ uint16_t src_port;
+ uint16_t dst_port;
+ uint16_t interval;
+ uint16_t timeout;
+ uint8_t session;
+ struct qdf_mac_addr gateway_mac;
+};
+
+/**
+ * struct pmo_lphb_udp_filter_req - Low power heart beat udp filter request
+ * @length: length of filter
+ * @offset: offset of filter
+ * @session: session on which lphb needs to be configured
+ * @filter: filter buffer
+ */
+struct pmo_lphb_udp_filter_req {
+ uint16_t length;
+ uint8_t offset;
+ uint8_t session;
+ uint8_t filter[PMO_SIR_LPHB_FILTER_LEN];
+};
+
+/**
+ * struct pmo_lphb_req - Low power heart beat request
+ * @cmd: lphb command type
+ * @dummy: whether dummy or not
+ * @params: based on command lphb request buffer
+ */
+struct pmo_lphb_req {
+ uint16_t cmd;
+ uint16_t dummy;
+ union {
+ struct pmo_lphb_enable_req lphb_enable_req;
+ struct pmo_lphb_tcp_params lphb_tcp_params;
+ struct pmo_lphb_tcp_filter_req lphb_tcp_filter_req;
+ struct pmo_lphb_udp_params lphb_udp_params;
+ struct pmo_lphb_udp_filter_req lphb_udp_filter_req;
+ } params;
+};
+
+/**
+ * struct pmo_lphb_rsp - Low power heart beat response
+ * @session_idx: session id
+ * @protocol_type: tell protocol type
+ * @event_reason: carry reason of lphb event
+ */
+struct pmo_lphb_rsp {
+ uint8_t session_idx;
+ uint8_t protocol_type; /*TCP or UDP */
+ uint8_t event_reason;
+};
+#endif /* FEATURE_WLAN_LPHB */
+
+/*
+ * Define typedef for lphb callback when fwr send response
+ */
+typedef
+void (*pmo_lphb_callback)(void *cb_ctx, struct pmo_lphb_rsp *ind_param);
+
+#endif /* end of _WLAN_PMO_LPHB_PUBLIC_STRUCT_H_ */
+
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_mc_addr_filtering_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_mc_addr_filtering_public_struct.h
new file mode 100644
index 0000000..8607c17
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_mc_addr_filtering_public_struct.h
@@ -0,0 +1,60 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+ /**
+ * DOC: Declare various struct, macros which shall be used in
+ * pmo mc address filterign related features.
+ *
+ * Note: This file shall not contain public API's prototype/declarations.
+ *
+ */
+
+
+#ifndef _WLAN_PMO_MC_ADDR_FILTERING_STRUCT_H_
+#define _WLAN_PMO_MC_ADDR_FILTERING_STRUCT_H_
+
+#include "wlan_pmo_common_public_struct.h"
+
+#define PMO_MAX_MC_ADDR_LIST 32
+
+/**
+ * struct pmo_mc_addr_list_params -pmo mc address list request params
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id on which arp offload needed
+ * @count: multicast address count
+ * @mc_addr: multicast address array
+ */
+struct pmo_mc_addr_list_params {
+ struct wlan_objmgr_psoc *psoc;
+ uint8_t vdev_id;
+ uint8_t count;
+ struct qdf_mac_addr mc_addr[PMO_MAX_MC_ADDR_LIST];
+};
+
+/**
+ * struct pmo_mc_addr_list -pmo mc address list params for vdev
+ * @is_filter_applied: is mc list filter applied on vdev
+ * @mc_cnt: mc address count
+ * @mc_addr:mc address list
+ */
+struct pmo_mc_addr_list {
+ uint8_t is_filter_applied;
+ uint8_t mc_cnt;
+ struct qdf_mac_addr mc_addr[PMO_MAX_MC_ADDR_LIST];
+};
+
+#endif /* end of _WLAN_PMO_MC_ADDR_FILTERING_STRUCT_H_ */
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_ns_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_ns_public_struct.h
new file mode 100644
index 0000000..27a0c04
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_ns_public_struct.h
@@ -0,0 +1,79 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+ /**
+ * DOC: Declare various struct, macros which shall be used in
+ * pmo ns offload feature.
+ *
+ * Note: This file shall not contain public API's prototype/declarations.
+ *
+ */
+
+
+#ifndef _WLAN_PMO_NS_PUBLIC_STRUCT_H_
+#define _WLAN_PMO_NS_PUBLIC_STRUCT_H_
+
+#include "wlan_pmo_common_public_struct.h"
+
+/**
+ * struct pmo_ns_offload_params - pmo ns offload parameters
+ * @enable: true when ns offload enable
+ * @num_ns_offload_count: total ns entries
+ * @src_ipv6_addr: in request source ipv 6 address
+ * @self_ipv6_addr: self ipv6 address
+ * @target_ipv6_addr: target ipv6 address
+ * @self_macaddr: self mac address
+ * @src_ipv6_addr_valid: true if source ipv6 address is valid else false
+ * @target_ipv6_addr_valid: target ipv6 address are valid or not
+ * @target_ipv6_addr_ac_type: target ipv6 address type (unicast or anycast)
+ * @slot_idx: slot index
+ */
+struct pmo_ns_offload_params {
+ uint8_t enable;
+ uint32_t num_ns_offload_count;
+ uint8_t src_ipv6_addr[PMO_MAC_IPV6_ADDR_LEN];
+ uint8_t self_ipv6_addr[PMO_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA]
+ [PMO_MAC_IPV6_ADDR_LEN];
+ uint8_t target_ipv6_addr[PMO_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA]
+ [PMO_MAC_IPV6_ADDR_LEN];
+ struct qdf_mac_addr self_macaddr;
+ uint8_t src_ipv6_addr_valid;
+ uint8_t target_ipv6_addr_valid[PMO_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA];
+ uint8_t target_ipv6_addr_ac_type[PMO_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA];
+ uint8_t slot_idx;
+ struct qdf_mac_addr bssid;
+};
+
+/**
+ * struct pmo_ns_req - pmo ns request
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id on which arp offload needed
+ * @trigger: context from where arp offload triggered
+ * @count: ns entries count
+ * @ipv6_addr: ipv6 address array
+ * @ipv6_addr_type: ipv6 address type (unicast/anycast) array
+ */
+struct pmo_ns_req {
+ struct wlan_objmgr_psoc *psoc;
+ uint8_t vdev_id;
+ enum pmo_offload_trigger trigger;
+ uint32_t count;
+ uint8_t ipv6_addr[PMO_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA]
+ [PMO_MAC_IPV6_ADDR_LEN];
+ uint8_t ipv6_addr_type[PMO_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA];
+};
+#endif /* end of _WLAN_PMO_NS_PUBLIC_STRUCT_H_ */
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_api.h b/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_api.h
new file mode 100644
index 0000000..42ee0b9
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_api.h
@@ -0,0 +1,241 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: declare utility API related to the pmo component
+ * called by other components
+ */
+
+#ifndef _WLAN_PMO_OBJ_MGMT_API_H_
+#define _WLAN_PMO_OBJ_MGMT_API_H_
+
+#include "wlan_pmo_common_public_struct.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+/**
+ * pmo_init() - initialize pmo_ctx context.
+ *
+ * This function initializes the power manager offloads (a.k.a pmo) context.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error
+ */
+QDF_STATUS pmo_init(void);
+
+/**
+ * pmo_deinit() - De initialize pmo_ctx context.
+ *
+ * This function De initializes power manager offloads (a.k.a pmo) contex.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error
+ */
+QDF_STATUS pmo_deinit(void);
+
+/**
+ * pmo_psoc_object_created_notification(): pmo psoc create handler
+ * @psoc: psoc which is going to created by objmgr
+ * @arg: argument for vdev create handler
+ *
+ * PMO, register this api with objmgr to detect psoc is created in fwr
+ *
+ * Return QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS pmo_psoc_object_created_notification(
+ struct wlan_objmgr_psoc *psoc, void *arg);
+
+/**
+ * pmo_psoc_object_destroyed_notification(): pmo psoc delete handler
+ * @psco: psoc which is going to delete by objmgr
+ * @arg: argument for vdev delete handler
+ *
+ * PMO, register this api with objmgr to detect psoc is deleted in fwr
+ *
+ * Return QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS pmo_psoc_object_destroyed_notification(
+ struct wlan_objmgr_psoc *psoc, void *arg);
+
+/**
+ * pmo_vdev_object_created_notification(): pmo vdev create handler
+ * @vdev: vdev which is going to created by objmgr
+ * @arg: argument for vdev create handler
+ *
+ * PMO, register this api with objmgr to detect vdev is created in fwr
+ *
+ * Return QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS pmo_vdev_object_created_notification(
+ struct wlan_objmgr_vdev *vdev, void *arg);
+
+/**
+ * pmo_vdev_ready() - handles vdev ready in firmware event
+ * @vdev: vdev which is ready in firmware
+ *
+ * Objmgr vdev_create event does not guarantee vdev creation in firmware.
+ * Any logic that would normally go in the vdev_create event, but needs to
+ * communicate with firmware, needs to go here instead.
+ *
+ * Return QDF_STATUS
+ */
+QDF_STATUS pmo_vdev_ready(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_vdev_object_destroyed_notification(): pmo vdev delete handler
+ * @vdev: vdev which is going to delete by objmgr
+ * @arg: argument for vdev delete handler
+ *
+ * PMO, register this api with objmgr to detect vdev is deleted in fwr
+ *
+ * Return QDF_STATUS status in case of success else return error
+ */
+QDF_STATUS pmo_vdev_object_destroyed_notification(
+ struct wlan_objmgr_vdev *vdev, void *arg);
+
+/**
+ * pmo_register_suspend_handler(): register suspend handler for components
+ * @id: component id
+ * @handler: resume handler for the mention component
+ * @arg: argument to pass while calling resume handler
+ *
+ * Return QDF_STATUS status -in case of success else return error
+ */
+QDF_STATUS pmo_register_suspend_handler(
+ enum wlan_umac_comp_id id,
+ pmo_psoc_suspend_handler handler,
+ void *arg);
+
+/**
+ * pmo_unregister_suspend_handler():unregister suspend handler for components
+ * @id: component id
+ * @handler: resume handler for the mention component
+ *
+ * Return QDF_STATUS status -in case of success else return error
+ */
+QDF_STATUS pmo_unregister_suspend_handler(
+ enum wlan_umac_comp_id id,
+ pmo_psoc_suspend_handler handler);
+
+/**
+ * pmo_register_resume_handler(): API to register resume handler for components
+ * @id: component id
+ * @handler: resume handler for the mention component
+ * @arg: argument to pass while calling resume handler
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_register_resume_handler(
+ enum wlan_umac_comp_id id,
+ pmo_psoc_resume_handler handler,
+ void *arg);
+
+/**
+ * pmo_unregister_resume_handler(): unregister resume handler for components
+ * @id: component id
+ * @handler: resume handler for the mention component
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_unregister_resume_handler(
+ enum wlan_umac_comp_id id,
+ pmo_psoc_resume_handler handler);
+
+/**
+ * pmo_suspend_all_components(): API to suspend all component
+ * @psoc:objmgr psoc
+ * @suspend_type: Tell suspend type (apps suspend / runtime suspend)
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_suspend_all_components(struct wlan_objmgr_psoc *psoc,
+ enum qdf_suspend_type suspend_type);
+
+/**
+ * pmo_resume_all_components(): API to resume all component
+ * @psoc:objmgr psoc
+ * @suspend_type: Tell suspend type from which resume is required
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_resume_all_components(struct wlan_objmgr_psoc *psoc,
+ enum qdf_suspend_type suspend_type);
+
+/**
+ * pmo_register_pause_bitmap_notifier(): API to register pause bitmap notifier
+ * @psoc: objmgr psoc handle
+ * @handler: pause bitmap updated notifier
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_register_pause_bitmap_notifier(
+ struct wlan_objmgr_psoc *psoc,
+ pmo_notify_pause_bitmap handler);
+
+/**
+ * pmo_unregister_pause_bitmap_notifier(): API to unregister pause bitmap notifier
+ * @psoc: objmgr psoc handle
+ * @handler: pause bitmap updated notifier
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_unregister_pause_bitmap_notifier(
+ struct wlan_objmgr_psoc *psoc,
+ pmo_notify_pause_bitmap handler);
+
+/**
+ * pmo_register_get_pause_bitmap(): API to get register pause bitmap notifier
+ * @psoc: objmgr psoc handle
+ * @handler: pause bitmap updated notifier
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_register_get_pause_bitmap(struct wlan_objmgr_psoc *psoc,
+ pmo_get_pause_bitmap handler);
+
+/**
+ * pmo_unregister_get_pause_bitmap(): API to unregister get pause bitmap callback
+ * @psoc: objmgr psoc handle
+ * @handler: pause bitmap updated notifier
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_unregister_get_pause_bitmap(struct wlan_objmgr_psoc *psoc,
+ pmo_get_pause_bitmap handler);
+
+
+/**
+ * pmo_register_is_device_in_low_pwr_mode(): API to get register device power
+ * save check notifier.
+ * @psoc: objmgr psoc handle
+ * @handler: device power save check notifier
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_register_is_device_in_low_pwr_mode(struct wlan_objmgr_psoc *psoc,
+ pmo_is_device_in_low_pwr_mode handler);
+
+/**
+ * pmo_unregister_is_device_in_low_pwr_mode(): API to unregister device power
+ * save check notifier.
+ * @psoc: objmgr psoc handle
+ * @handler: device power save check notifier
+ *
+ * Return QDF_STATUS status - in case of success else return error
+ */
+QDF_STATUS pmo_unregister_is_device_in_low_pwr_mode(
+ struct wlan_objmgr_psoc *psoc,
+ pmo_is_device_in_low_pwr_mode handler);
+
+#endif /* end of _WLAN_PMO_OBJ_MGMT_API_H_ */
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_public_struct.h
new file mode 100644
index 0000000..4be33ff
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_obj_mgmt_public_struct.h
@@ -0,0 +1,189 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+ /**
+ * DOC: Declare various struct, macros which are used for object mgmt in pmo.
+ *
+ * Note: This file shall not contain public API's prototype/declarations.
+ *
+ */
+
+
+#ifndef _WLAN_PMO_OBJ_MGMT_PUBLIC_STRUCT_H_
+#define _WLAN_PMO_OBJ_MGMT_PUBLIC_STRUCT_H_
+
+#include "wlan_pmo_common_public_struct.h"
+#include "wlan_pmo_arp_public_struct.h"
+#include "wlan_pmo_ns_public_struct.h"
+#include "wlan_pmo_gtk_public_struct.h"
+#include "wlan_pmo_wow_public_struct.h"
+#include "wlan_pmo_mc_addr_filtering_public_struct.h"
+#include "wlan_pmo_hw_filter_public_struct.h"
+#include "wlan_pmo_pkt_filter_public_struct.h"
+#include "wlan_pmo_lphb_public_struct.h"
+
+/**
+ * typedef for vdev notifying the vdev pause bitmap new value to mlme
+ */
+typedef void (*pmo_notify_pause_bitmap)(
+ uint8_t vdev_id, uint16_t value);
+
+/**
+ * typedef for getting vdev pause bitmap
+ */
+typedef uint16_t(*pmo_get_pause_bitmap)(uint8_t vdev_id);
+
+/**
+ * typedef to know is deviec is in power save mode
+ */
+typedef bool (*pmo_is_device_in_low_pwr_mode)(uint8_t vdev_id);
+
+/*
+ * typedef for pld auto suspend callback during runtime suspend
+ */
+typedef
+int (*pmo_pld_auto_suspend_cb)(void);
+
+/*
+ * typedef for pld auto resume callback during runtime resume
+ */
+typedef
+int (*pmo_pld_auto_resume_cb)(void);
+
+/**
+ * struct wlan_pmo_tx_ops - structure of tx function
+ * pointers for pmo component
+ * @send_arp_offload_req: fp to send arp offload request
+ * @send_ns_offload_req: fp to send ns offload request
+ * @send_non_arp_bcast_filter_req: for enable/disable broadcast filter
+ * @send_set_pkt_filter: send set packet filter
+ * @send_clear_pkt_filter: send clear packet filter
+ * @send_enable_wakeup_event_req: fp to send enable wow wakeup events req
+ * @send_disable_wakeup_event_req: fp to send disable wow wakeup events req
+ * @send_add_wow_pattern: fp to send wow pattern request
+ * @send_enhance_mc_offload_req: fp to send enhanced multicast offload request
+ * @send_set_mc_filter_req: fp to send set mc filter request
+ * @send_clear_mc_filter_req: fp to send clear mc filter request
+ * @send_ra_filter_req: fp to send ra filter request
+ * @send_gtk_offload_req: fp to send gtk offload request command
+ * @send_get_gtk_rsp_cmd: fp to send get gtk response request cmd to firmware
+ * @send_action_frame_pattern_req: fp to send wow action frame patterns request
+ * @send_lphb_enable: fp to send lphb enable request command
+ * @send_lphb_tcp_params: fp to send lphb tcp params request command
+ * @send_lphb_tcp_filter_req: fp to send lphb tcp packet filter request command
+ * @send_lphb_upd_params: fp to send lphb udp params request command
+ * @send_lphb_udp_filter_req: fp to send lphb udp packet filter request command
+ * @send_vdev_param_update_req: fp to send vdev param request
+ * @send_vdev_set_sta_ps_param: fp to send sta vdev ps power set req
+ * @psoc_update_wow_bus_suspend: fp to update bus suspend req flag at wmi
+ * @psoc_get_host_credits: fp to get the host credits
+ * @psoc_get_pending_cmnds: fp to get the host pending wmi commands
+ * @update_target_suspend_flag: fp to update target suspend flag at wmi
+ * @psoc_send_wow_enable_req: fp to send wow enable request
+ * @psoc_send_supend_req: fp to send target suspend request
+ * @psoc_set_runtime_pm_in_progress: fp to set runtime pm is in progress status
+ * @psoc_get_runtime_pm_in_progress: fp to get runtime pm is in progress status
+ * @psoc_send_host_wakeup_ind: fp tp send host wake indication to fwr
+ * @psoc_send_target_resume_req: fp to send target resume request
+ */
+struct wlan_pmo_tx_ops {
+ QDF_STATUS (*send_arp_offload_req)(struct wlan_objmgr_vdev *vdev,
+ struct pmo_arp_offload_params *arp_offload_req,
+ struct pmo_ns_offload_params *ns_offload_req);
+ QDF_STATUS (*send_conf_hw_filter_req)(
+ struct wlan_objmgr_psoc *psoc,
+ struct pmo_hw_filter_params *req);
+ QDF_STATUS (*send_ns_offload_req)(struct wlan_objmgr_vdev *vdev,
+ struct pmo_arp_offload_params *arp_offload_req,
+ struct pmo_ns_offload_params *ns_offload_req);
+ QDF_STATUS(*send_set_pkt_filter)(struct wlan_objmgr_vdev *vdev,
+ struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req);
+ QDF_STATUS(*send_clear_pkt_filter)(struct wlan_objmgr_vdev *vdev,
+ struct pmo_rcv_pkt_fltr_clear_param
+ *pmo_clr_pkt_fltr_param);
+ QDF_STATUS (*send_enable_wow_wakeup_event_req)(
+ struct wlan_objmgr_vdev *vdev,
+ uint32_t *bitmap);
+ QDF_STATUS (*send_disable_wow_wakeup_event_req)(
+ struct wlan_objmgr_vdev *vdev,
+ uint32_t *bitmap);
+ QDF_STATUS (*send_add_wow_pattern)(
+ struct wlan_objmgr_vdev *vdev,
+ uint8_t ptrn_id, const uint8_t *ptrn, uint8_t ptrn_len,
+ uint8_t ptrn_offset, const uint8_t *mask,
+ uint8_t mask_len, bool user);
+ QDF_STATUS (*send_enhance_mc_offload_req)(
+ struct wlan_objmgr_vdev *vdev, bool enable);
+ QDF_STATUS (*send_set_mc_filter_req)(
+ struct wlan_objmgr_vdev *vdev,
+ struct qdf_mac_addr multicast_addr);
+ QDF_STATUS (*send_clear_mc_filter_req)(
+ struct wlan_objmgr_vdev *vdev,
+ struct qdf_mac_addr multicast_addr);
+ QDF_STATUS (*send_ra_filter_req)(
+ struct wlan_objmgr_vdev *vdev,
+ uint8_t default_pattern, uint16_t rate_limit_interval);
+ QDF_STATUS (*send_gtk_offload_req)(
+ struct wlan_objmgr_vdev *vdev,
+ struct pmo_gtk_req *gtk_offload_req);
+ QDF_STATUS (*send_get_gtk_rsp_cmd)(struct wlan_objmgr_vdev *vdev);
+ QDF_STATUS (*send_action_frame_pattern_req)(
+ struct wlan_objmgr_vdev *vdev,
+ struct pmo_action_wakeup_set_params *ip_cmd);
+ QDF_STATUS (*send_lphb_enable)(
+ struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_enable_req *ts_lphb_enable);
+ QDF_STATUS (*send_lphb_tcp_params)(
+ struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_tcp_params *ts_lphb_tcp_param);
+ QDF_STATUS (*send_lphb_tcp_filter_req)(
+ struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_tcp_filter_req *ts_lphb_tcp_filter);
+ QDF_STATUS (*send_lphb_upd_params)(
+ struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_udp_params *ts_lphb_udp_param);
+ QDF_STATUS (*send_lphb_udp_filter_req)(
+ struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_udp_filter_req *ts_lphb_udp_filter);
+ QDF_STATUS (*send_vdev_param_update_req)(
+ struct wlan_objmgr_vdev *vdev,
+ uint32_t param_id, uint32_t param_value);
+ QDF_STATUS (*send_vdev_sta_ps_param_req)(
+ struct wlan_objmgr_vdev *vdev,
+ uint32_t ps_mode, uint32_t value);
+ void (*psoc_update_wow_bus_suspend)(
+ struct wlan_objmgr_psoc *psoc, uint8_t value);
+ int (*psoc_get_host_credits)(
+ struct wlan_objmgr_psoc *psoc);
+ int (*psoc_get_pending_cmnds)(
+ struct wlan_objmgr_psoc *psoc);
+ void (*update_target_suspend_flag)(
+ struct wlan_objmgr_psoc *psoc, uint8_t value);
+ QDF_STATUS (*psoc_send_wow_enable_req)(struct wlan_objmgr_psoc *psoc,
+ struct pmo_wow_cmd_params *param);
+ QDF_STATUS (*psoc_send_supend_req)(struct wlan_objmgr_psoc *psoc,
+ struct pmo_suspend_params *param);
+ void (*psoc_set_runtime_pm_in_progress)(struct wlan_objmgr_psoc *psoc,
+ bool value);
+ bool (*psoc_get_runtime_pm_in_progress)(struct wlan_objmgr_psoc *psoc);
+ QDF_STATUS (*psoc_send_host_wakeup_ind)(struct wlan_objmgr_psoc *psoc);
+ QDF_STATUS (*psoc_send_target_resume_req)(
+ struct wlan_objmgr_psoc *psoc);
+
+};
+
+#endif /* end of _WLAN_PMO_OBJ_MGMT_PUBLIC_STRUCT_H_ */
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_pkt_filter_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_pkt_filter_public_struct.h
new file mode 100644
index 0000000..d067fe1
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_pkt_filter_public_struct.h
@@ -0,0 +1,141 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+ /**
+ * DOC: Declare various struct, macros which shall be used in
+ * pmo packet filter feature.
+ *
+ * Note: This file shall not contain public API's prototype/declarations.
+ *
+ */
+
+#ifndef _WLAN_PMO_PKT_FILTER_PUBLIC_STRUCT_H_
+#define _WLAN_PMO_PKT_FILTER_PUBLIC_STRUCT_H_
+
+#include "qdf_types.h"
+
+#define PMO_MAX_FILTER_TEST_DATA_LEN 8
+#define PMO_MAX_NUM_TESTS_PER_FILTER 10
+
+/**
+ * enum pmo_rcv_pkt_fltr_type: Receive Filter Parameters
+ * @PMO_RCV_FILTER_TYPE_INVALID: invalied filter type
+ * @PMO_RCV_FILTER_TYPE_FILTER_PKT: packet filter
+ * @PMO_RCV_FILTER_TYPE_BUFFER_PKT: buffer packet
+ * @PMO_RCV_FILTER_TYPE_MAX_ENUM_SIZE: max filter
+ */
+enum pmo_rcv_pkt_fltr_type {
+ PMO_RCV_FILTER_TYPE_INVALID,
+ PMO_RCV_FILTER_TYPE_FILTER_PKT,
+ PMO_RCV_FILTER_TYPE_BUFFER_PKT,
+ PMO_RCV_FILTER_TYPE_MAX_ENUM_SIZE
+};
+
+/**
+ * enum pmo_rcv_pkt_fltr_flag_type: Receive Filter flags
+ * @PMO_FILTER_CMP_TYPE_INVALID: invalied flag
+ * @PMO_FILTER_CMP_TYPE_EQUAL: equal
+ * @PMO_FILTER_CMP_TYPE_MASK_EQUAL: mask
+ * @PMO_FILTER_CMP_TYPE_NOT_EQUAL: not equal
+ * @PMO_FILTER_CMP_TYPE_MASK_NOT_EQUAL: mask not equal
+ * @PMO_FILTER_CMP_TYPE_MAX: max size of flag
+ */
+enum pmo_rcv_pkt_fltr_flag_type {
+ PMO_FILTER_CMP_TYPE_INVALID,
+ PMO_FILTER_CMP_TYPE_EQUAL,
+ PMO_FILTER_CMP_TYPE_MASK_EQUAL,
+ PMO_FILTER_CMP_TYPE_NOT_EQUAL,
+ PMO_FILTER_CMP_TYPE_MASK_NOT_EQUAL,
+ PMO_FILTER_CMP_TYPE_MAX
+};
+
+/**
+ * enum pmo_rcv_pkt_fltr_protocol_params: Receive Filter protocal parameters
+ * @PMO_FILTER_HDR_TYPE_INVALID: invalied type
+ * @PMO_FILTER_HDR_TYPE_MAC: mac protocol
+ * @PMO_FILTER_HDR_TYPE_ARP: arp protocol
+ * @PMO_FILTER_HDR_TYPE_IPV4: ipv4 protocol
+ * @PMO_FILTER_HDR_TYPE_IPV6: ipv6 protocol
+ * @PMO_FILTER_HDR_TYPE_UDP: udp protocol
+ * @PMO_FILTER_HDR_TYPE_MAX: max of type of protocol
+ */
+enum pmo_rcv_pkt_fltr_protocol_params {
+ PMO_FILTER_HDR_TYPE_INVALID,
+ PMO_FILTER_HDR_TYPE_MAC,
+ PMO_FILTER_HDR_TYPE_ARP,
+ PMO_FILTER_HDR_TYPE_IPV4,
+ PMO_FILTER_HDR_TYPE_IPV6,
+ PMO_FILTER_HDR_TYPE_UDP,
+ PMO_FILTER_HDR_TYPE_MAX
+};
+
+/**
+ * struct pmo_rcv_pkt_fltr_field_params - pmo packet filter field parameters
+ * @protocol_layer: Protocol layer
+ * @compare_flag: Comparison flag
+ * @data_length: Length of the data to compare
+ * @data_offset: from start of the respective frame header
+ * @reserved: Reserved field
+ * @compare_data: Data to compare
+ * @data_mask: Mask to be applied on the received packet data before compare
+ */
+struct pmo_rcv_pkt_fltr_field_params {
+ enum pmo_rcv_pkt_fltr_protocol_params protocol_layer;
+ enum pmo_rcv_pkt_fltr_flag_type compare_flag;
+ uint16_t data_length;
+ uint8_t data_offset;
+ uint8_t reserved;
+ uint8_t compare_data[PMO_MAX_FILTER_TEST_DATA_LEN];
+ uint8_t data_mask[PMO_MAX_FILTER_TEST_DATA_LEN];
+};
+
+/**
+ * struct pmo_rcv_pkt_fltr_cfg - pmo packet filter config
+ * @filter_id: filter id
+ * @filter_type: filter type
+ * @num_params: number of parameters
+ * @coalesce_time: time
+ * @self_macaddr: mac address
+ * @bssid: Bssid of the connected AP
+ * @params_data: data
+ */
+struct pmo_rcv_pkt_fltr_cfg {
+ uint8_t filter_id;
+ enum pmo_rcv_pkt_fltr_type filter_type;
+ uint32_t num_params;
+ uint32_t coalesce_time;
+ struct qdf_mac_addr self_macaddr;
+ struct qdf_mac_addr bssid;
+ struct pmo_rcv_pkt_fltr_field_params
+ params_data[PMO_MAX_NUM_TESTS_PER_FILTER];
+};
+
+/**
+ * struct pmo_rcv_pkt_fltr_cfg - pmo receive Filter Clear Parameters
+ * @status: only valid for response message
+ * @filter_id:
+ * @self_macaddr:
+ * @bssid: peer ap address
+ */
+struct pmo_rcv_pkt_fltr_clear_param {
+ uint32_t status;
+ uint8_t filter_id;
+ struct qdf_mac_addr self_macaddr;
+ struct qdf_mac_addr bssid;
+};
+
+#endif /* end of _WLAN_PMO_PKT_FILTER_PUBLIC_STRUCT_H_ */
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_tgt_api.h b/components/pmo/dispatcher/inc/wlan_pmo_tgt_api.h
new file mode 100644
index 0000000..e702da8
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_tgt_api.h
@@ -0,0 +1,406 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Declare public API for pmo to interact with target/WMI
+ */
+
+#ifndef _WLAN_PMO_TGT_API_H_
+#define _WLAN_PMO_TGT_API_H_
+
+#include "wlan_pmo_common_public_struct.h"
+#include "wlan_pmo_arp_public_struct.h"
+#include "wlan_pmo_ns_public_struct.h"
+#include "wlan_pmo_gtk_public_struct.h"
+#include "wlan_pmo_wow_public_struct.h"
+#include "wlan_pmo_mc_addr_filtering_public_struct.h"
+#include "wlan_pmo_hw_filter_public_struct.h"
+#include "wlan_pmo_pkt_filter_public_struct.h"
+
+#define GET_PMO_TX_OPS_FROM_PSOC(psoc) \
+ (pmo_psoc_get_priv(psoc)->pmo_tx_ops)
+
+/**
+ * pmo_tgt_conf_hw_filter() - configure hardware filter mode in firmware
+ * @psoc: the psoc to use to communicate with firmware
+ * @req: the configuration request
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS pmo_tgt_conf_hw_filter(struct wlan_objmgr_psoc *psoc,
+ struct pmo_hw_filter_params *req);
+
+/**
+ * pmo_tgt_set_pkt_filter() - Set packet filter
+ * @vdev: objmgr vdev
+ * @pmo_set_pkt_fltr_req:
+ * @vdev_id: vdev id
+ *
+ * API to set packet filter
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_tgt_set_pkt_filter(struct wlan_objmgr_vdev *vdev,
+ struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req,
+ uint8_t vdev_id);
+
+/**
+ * pmo_tgt_clear_pkt_filter() - Clear packet filter
+ * @vdev: objmgr vdev
+ * @pmo_clr_pkt_fltr_param:
+ * @vdev_id: vdev id
+ *
+ * API to clear packet filter
+ *
+ * Return: QDF_STATUS_SUCCESS in case of success else return error
+ */
+QDF_STATUS pmo_tgt_clear_pkt_filter(struct wlan_objmgr_vdev *vdev,
+ struct pmo_rcv_pkt_fltr_clear_param *pmo_clr_pkt_fltr_param,
+ uint8_t vdev_id);
+
+/**
+ * pmo_tgt_enable_arp_offload_req() - Enable arp offload req to target
+ * @vdev: objmgr vdev
+ * @vdev_id: vdev id
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_enable_arp_offload_req(struct wlan_objmgr_vdev *vdev,
+ uint8_t vdev_id);
+
+/**
+ * pmo_tgt_disable_arp_offload_req() - Disable arp offload req to target
+ * @vdev: objmgr vdev
+ * @vdev_id: vdev id
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_disable_arp_offload_req(struct wlan_objmgr_vdev *vdev,
+ uint8_t vdev_id);
+
+/**
+ * pmo_tgt_enable_ns_offload_req() - Send ns offload req to targe
+ * @vdev: objmgr vdev
+ * @vdev_id: vdev id
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_enable_ns_offload_req(struct wlan_objmgr_vdev *vdev,
+ uint8_t vdev_id);
+
+/**
+ * pmo_tgt_disable_ns_offload_req() - Disable arp offload req to target
+ * @vdev: objmgr vdev
+ * @vdev_id: vdev id
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_disable_ns_offload_req(struct wlan_objmgr_vdev *vdev,
+ uint8_t vdev_id);
+
+/**
+ * pmo_tgt_enable_wow_wakeup_event() - Send Enable wow wakeup events req to fwr
+ * @vdev: objmgr vdev handle
+ * @bitmap: Event bitmap
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_enable_wow_wakeup_event(struct wlan_objmgr_vdev *vdev,
+ uint32_t *bitmap);
+
+/**
+ * pmo_tgt_disable_wow_wakeup_event() - Send Disable wow wakeup events to fwr
+ * @vdev: objmgr vdev handle
+ * @bitmap: Event bitmap
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_disable_wow_wakeup_event(struct wlan_objmgr_vdev *vdev,
+ uint32_t *bitmap);
+
+/**
+ * pmo_tgt_send_wow_patterns_to_fw() - Sends WOW patterns to FW.
+ * @vdev: objmgr vdev
+ * @ptrn_id: pattern id
+ * @ptrn: pattern
+ * @ptrn_len: pattern length
+ * @ptrn_offset: pattern offset
+ * @mask: mask
+ * @mask_len: mask length
+ * @user: true for user configured pattern and false for default pattern
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_send_wow_patterns_to_fw(struct wlan_objmgr_vdev *vdev,
+ uint8_t ptrn_id, const uint8_t *ptrn, uint8_t ptrn_len,
+ uint8_t ptrn_offset, const uint8_t *mask,
+ uint8_t mask_len, bool user);
+
+/**
+ * pmo_tgt_set_mc_filter_req() - Set mcast filter command to fw
+ * @vdev: objmgr vdev
+ * @multicastAddr: mcast address
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_tgt_set_mc_filter_req(struct wlan_objmgr_vdev *vdev,
+ struct qdf_mac_addr multicast_addr);
+
+/**
+ * pmo_tgt_clear_mc_filter_req() - Clear mcast filter command to fw
+ * @vdev: objmgr vdev
+ * @multicastAddr: mcast address
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_tgt_clear_mc_filter_req(struct wlan_objmgr_vdev *vdev,
+ struct qdf_mac_addr multicast_addr);
+
+/**
+ * pmo_tgt_send_enhance_multicast_offload_req() - send enhance mc offload req
+ * @wma_handle: wma handle
+ * @vdev_id: vdev id
+ * @action: enable or disable enhance multicast offload
+ *
+ * Return: QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS pmo_tgt_send_enhance_multicast_offload_req(
+ struct wlan_objmgr_vdev *vdev,
+ uint8_t vdev_id,
+ uint8_t action);
+
+/**
+ * pmo_tgt_send_ra_filter_req() - send ra filter request to target
+ * @vdev: objmgr vdev handle
+ *
+ * Return: QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS pmo_tgt_send_ra_filter_req(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_tgt_send_action_frame_pattern_req - send wow action frame patterns req
+ * @vdev: objmgr vdev handle
+ * @cmd: action frame pattern cmd
+ *
+ * Return: QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS pmo_tgt_send_action_frame_pattern_req(
+ struct wlan_objmgr_vdev *vdev,
+ struct pmo_action_wakeup_set_params *cmd);
+
+/**
+ * pmo_tgt_send_gtk_offload_req() - send GTK offload command to fw
+ * @vdev: objmgr vdev
+ * @gtk_req: pmo gtk req
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_send_gtk_offload_req(struct wlan_objmgr_vdev *vdev,
+ struct pmo_gtk_req *gtk_req);
+
+/**
+ * pmo_tgt_get_gtk_rsp() - send get gtk rsp command to fw
+ * @vdev: objmgr vdev
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_get_gtk_rsp(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_tgt_gtk_rsp_evt() - receive gtk rsp event from fwr
+ * @psoc: objmgr psoc
+ * @gtk_rsp_param: gtk response parameters
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_gtk_rsp_evt(struct wlan_objmgr_psoc *psoc,
+ struct pmo_gtk_rsp_params *rsp_param);
+
+/**
+ * pmo_tgt_send_lphb_enable() - enable command of LPHB configuration requests
+ * @psoc: objmgr psoc handle
+ * @ts_lphb_enable: lphb enable request which needs to configure in fwr
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_send_lphb_enable(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_enable_req *ts_lphb_enable);
+
+/**
+ * pmo_tgt_send_lphb_tcp_params() - set tcp params of LPHB configuration req
+ * @psoc: objmgr psoc handle
+ * @ts_lphb_tcp_param: lphb tcp params which needs to configure in fwr
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_send_lphb_tcp_params(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_tcp_params *ts_lphb_tcp_param);
+
+/**
+ * pmo_tgt_send_lphb_tcp_pkt_filter() - send tcp packet filter command of LPHB
+ * @psoc: objmgr psoc handle
+ * @ts_lphb_tcp_filter: lphb tcp filter request which needs to configure in fwr
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_send_lphb_tcp_pkt_filter(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_tcp_filter_req *ts_lphb_tcp_filter);
+
+/**
+ * pmo_tgt_send_lphb_udp_params() - Send udp param command of LPHB
+ * @psoc: objmgr psoc handle
+ * @ts_lphb_udp_param: lphb udp params which needs to configure in fwr
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_send_lphb_udp_params(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_udp_params *ts_lphb_udp_param);
+
+/**
+ * pmo_tgt_send_lphb_udp_pkt_filter() - Send udp pkt filter command of LPHB
+ * @psoc: objmgr psoc handle
+ * @ts_lphb_udp_filter: lphb udp filter request which needs to configure in fwr
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_send_lphb_udp_pkt_filter(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_udp_filter_req *ts_lphb_udp_filter);
+
+
+/**
+ * pmo_tgt_lphb_rsp_evt() - receive lphb rsp event from fwr
+ * @psoc: objmgr psoc
+ * @rsp_param: lphb response parameters
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS pmo_tgt_lphb_rsp_evt(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_rsp *rsp_param);
+
+/**
+ * pmo_tgt_vdev_update_param_req() - Update vdev param value to fwr
+ * @vdev: objmgr vdev
+ * @param_id: tell vdev param id which needs to be updated in fwr
+ * @param_value: vdev parameter value
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_vdev_update_param_req(struct wlan_objmgr_vdev *vdev,
+ enum pmo_vdev_param_id param_id, uint32_t param_value);
+
+/**
+ * pmo_tgt_send_vdev_sta_ps_param() - Send vdev sta power save param to fwr
+ * @vdev: objmgr vdev
+ * @ps_param: sta mode ps power save params type
+ * @param_value: power save parameter value
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_tgt_send_vdev_sta_ps_param(struct wlan_objmgr_vdev *vdev,
+ enum pmo_sta_powersave_param ps_param, uint32_t param_value);
+
+/**
+ * pmo_tgt_update_wow_bus_suspend_state() - update wow bus suspend state flag
+ * @psoc: objmgr psoc
+ * @val: true for setting wow suspend flag to set else false
+ *
+ * Return: None
+ */
+void pmo_tgt_psoc_update_wow_bus_suspend_state(struct wlan_objmgr_psoc *psoc,
+ uint8_t val);
+
+/**
+ * pmo_tgt_get_host_credits() - Get host credits
+ * @psoc: objmgr psoc
+ *
+ * Return: Pending WMI commands on success else EAGAIN on error
+ */
+int pmo_tgt_psoc_get_host_credits(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_tgt_get_pending_cmnds() - Get pending commands
+ * @psoc: objmgr psoc
+ *
+ * Return: Pending WMI commands on success else EAGAIN on error
+ */
+int pmo_tgt_psoc_get_pending_cmnds(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_tgt_update_target_suspend_flag() - Set WMI target Suspend flag
+ * @psoc: objmgr psoc
+ * @val: true on suspend false for resume
+ *
+ * Return: Pending WMI commands on success else EAGAIN on error
+ */
+void pmo_tgt_update_target_suspend_flag(struct wlan_objmgr_psoc *psoc,
+ uint8_t val);
+
+/**
+ * pmo_tgt_psoc_send_wow_enable_req() -Send wow enable request
+ * @psoc: objmgr psoc
+ * @param: WOW enable request buffer
+ *
+ * Return: QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS pmo_tgt_psoc_send_wow_enable_req(struct wlan_objmgr_psoc *psoc,
+ struct pmo_wow_cmd_params *param);
+
+/**
+ * pmo_tgt_psoc_send_supend_req() -Send target suspend request to fwr
+ * @psoc: objmgr psoc
+ * @param: suspend request buffer
+ *
+ * Return: QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS pmo_tgt_psoc_send_supend_req(struct wlan_objmgr_psoc *psoc,
+ struct pmo_suspend_params *param);
+
+/**
+ * pmo_tgt_psoc_set_runtime_pm_inprogress() -set runtime status
+ * @psoc: objmgr psoc
+ * @value: set runtime pm in progress true or false
+ *
+ * Return: none
+ */
+QDF_STATUS pmo_tgt_psoc_set_runtime_pm_inprogress(struct wlan_objmgr_psoc *psoc,
+ bool value);
+
+/**
+ * pmo_tgt_psoc_get_runtime_pm_in_progress() -get runtime status
+ * @psoc: objmgr psoc
+ *
+ * Return: true if runtime pm is in progress else false
+ */
+bool pmo_tgt_psoc_get_runtime_pm_in_progress(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_tgt_psoc_send_host_wakeup_ind() -Send host wake up indication to fwr
+ * @psoc: objmgr psoc
+ *
+ * Return: QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS pmo_tgt_psoc_send_host_wakeup_ind(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_tgt_psoc_send_target_resume_req() -Send target resume request
+ * @psoc: objmgr psoc
+ *
+ * Return: QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS pmo_tgt_psoc_send_target_resume_req(struct wlan_objmgr_psoc *psoc);
+
+#endif /* end of _WLAN_PMO_TGT_API_H_ */
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h b/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h
new file mode 100644
index 0000000..beb2ade
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h
@@ -0,0 +1,565 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Declare public API related to the pmo called by north bound HDD/OSIF
+ */
+
+#ifndef _WLAN_PMO_UCFG_API_H_
+#define _WLAN_PMO_UCFG_API_H_
+
+#include "wlan_pmo_arp_public_struct.h"
+#include "wlan_pmo_ns_public_struct.h"
+#include "wlan_pmo_gtk_public_struct.h"
+#include "wlan_pmo_mc_addr_filtering_public_struct.h"
+#include "wlan_pmo_wow_public_struct.h"
+#include "wlan_pmo_common_public_struct.h"
+#include "wlan_pmo_obj_mgmt_api.h"
+#include "wlan_pmo_pkt_filter_public_struct.h"
+#include "wlan_pmo_hw_filter_public_struct.h"
+
+/**
+ * pmo_ucfg_is_ap_mode_supports_arp_ns() - Check ap mode support arp&ns offload
+ * @psoc: objmgr psoc
+ * @vdev_opmode: vdev opmode
+ *
+ * Return: true in case support else false
+ */
+bool pmo_ucfg_is_ap_mode_supports_arp_ns(struct wlan_objmgr_psoc *psoc,
+ enum tQDF_ADAPTER_MODE vdev_opmode);
+
+/**
+ * pmo_ucfg_is_vdev_connected() - to check whether peer is associated or not
+ * @vdev: objmgr vdev
+ *
+ * Return: true in case success else false
+ */
+bool pmo_ucfg_is_vdev_connected(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_ucfg_is_vdev_supports_offload() - check offload is supported on vdev
+ * @vdev: objmgr vdev
+ *
+ * Return: true in case success else false
+ */
+bool pmo_ucfg_is_vdev_supports_offload(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_ucfg_get_psoc_config(): API to get the psoc user configurations of pmo
+ * @psoc: objmgr psoc handle
+ * @psoc_cfg: fill the current psoc user configurations.
+ *
+ * Return pmo psoc configurations
+ */
+QDF_STATUS pmo_ucfg_get_psoc_config(struct wlan_objmgr_psoc *psoc,
+ struct pmo_psoc_cfg *psoc_cfg);
+
+/**
+ * pmo_ucfg_update_psoc_config(): API to update the psoc user configurations
+ * @psoc: objmgr psoc handle
+ * @psoc_cfg: pmo psoc configurations
+ *
+ * This api shall be used for soc config initialization as well update.
+ * In case of update caller must first call pmo_get_psoc_cfg to get
+ * current config and then apply changes on top of current config.
+ *
+ * Return QDF_STATUS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_update_psoc_config(struct wlan_objmgr_psoc *psoc,
+ struct pmo_psoc_cfg *psoc_cfg);
+
+/**
+ * pmo_ucfg_enable_wakeup_event() - enable wow wakeup events
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id
+ * @bitmap: Event bitmap
+ *
+ * Return: none
+ */
+void pmo_ucfg_enable_wakeup_event(struct wlan_objmgr_psoc *psoc,
+ uint32_t vdev_id, uint32_t *bitmap);
+
+/**
+ * pmo_ucfg_disable_wakeup_event() - disable wow wakeup events
+ * @psoc: objmgr psoc
+ * @vdev_id: vdev id
+ * @bitmap: Event bitmap
+ *
+ * Return: none
+ */
+void pmo_ucfg_disable_wakeup_event(struct wlan_objmgr_psoc *psoc,
+ uint32_t vdev_id, uint32_t bitmap);
+
+/**
+ * pmo_ucfg_cache_arp_offload_req(): API to cache arp req in pmo vdev priv ctx
+ * @arp_req: pmo arp req param
+ *
+ * Return QDF_STATUS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_cache_arp_offload_req(struct pmo_arp_req *arp_req);
+
+/**
+ * pmo_ucfg_flush_arp_offload_req(): API to flush arp req from pmo vdev priv ctx
+ * @vdev: objmgr vdev param
+ *
+ * Return QDF_STATUS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_flush_arp_offload_req(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_ucfg_enable_arp_offload_in_fwr(): API to enable arp req in fwr
+ * @vdev: objmgr vdev param
+ * @trigger: triger reason for enable arp offload
+ *
+ * API to enable cache arp req in fwr from pmo vdev priv ctx
+ *
+ * Return QDF_STATUS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_enable_arp_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+ enum pmo_offload_trigger trigger);
+
+/**
+ * pmo_ucfg_disable_arp_offload_in_fwr(): API to disable arp req in fwr
+ * @vdev: objmgr vdev param
+ * @trigger: triger reason for disable arp offload
+ * API to disable cache arp req in fwr
+ *
+ * Return QDF_STATUS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_disable_arp_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+ enum pmo_offload_trigger trigger);
+
+/**
+ * pmo_ucfg_cache_ns_offload_req(): API to cache ns req in pmo vdev priv ctx
+ * @ns_req: pmo ns req param
+ *
+ * Return QDF_STATUS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_cache_ns_offload_req(struct pmo_ns_req *ns_req);
+
+/**
+ * pmo_ucfg_flush_ns_offload_req(): API to flush ns req from pmo vdev priv ctx
+ * @vdev: vdev ojbmgr handle
+ *
+ * Return QDF_STATUS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_flush_ns_offload_req(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_ucfg_enable_ns_offload_in_fwr(): API to enable ns req in fwr
+ * @arp_req: pmo arp req param
+ * @trigger: trigger reason to enable ns offload
+ *
+ * API to enable cache ns req in fwr from pmo vdev priv ctx
+ *
+ * Return QDF_STATUS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_enable_ns_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+ enum pmo_offload_trigger trigger);
+
+/**
+ * pmo_ucfg_disable_ns_offload_in_fwr(): API to disable ns req in fwr
+ * @arp_req: pmo arp req param
+ * @trigger: trigger reason to disable ns offload
+ *
+ * API to disable ns req in fwr
+ *
+ * Return QDF_STATUS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_disable_ns_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+ enum pmo_offload_trigger trigger);
+
+/**
+ * pmo_ucfg_enable_hw_filter_in_fwr() - enable previously configured hw filter
+ * @vdev: objmgr vdev to configure
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS pmo_ucfg_enable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_ucfg_disable_hw_filter_in_fwr() - disable previously configured hw filter
+ * @vdev: objmgr vdev to configure
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS pmo_ucfg_disable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_ucfg_max_mc_addr_supported() - to get max support mc address
+ * @psoc: objmgr psoc
+ *
+ * Return: max mc addr supported count for all vdev in corresponding psoc
+ */
+uint8_t pmo_ucfg_max_mc_addr_supported(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_ucfg_cache_mc_addr_list(): API to cache mc addr list in pmo vdev priv obj
+ * @psoc: objmgr psoc handle
+ * @vdev_id: vdev id
+ * @gtk_req: pmo gtk req param
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_cache_mc_addr_list(
+ struct pmo_mc_addr_list_params *mc_list_config);
+
+/**
+ * pmo_ucfg_flush_mc_addr_list(): API to flush mc addr list in pmo vdev priv obj
+ * @psoc: objmgr psoc handle
+ * @vdev_id: vdev id
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_flush_mc_addr_list(struct wlan_objmgr_psoc *psoc,
+ uint8_t vdev_id);
+
+/**
+ * pmo_ucfg_enable_mc_addr_filtering_in_fwr(): Enable cached mc add list in fwr
+ * @psoc: objmgr psoc handle
+ * @vdev_id: vdev id
+ * @gtk_req: pmo gtk req param
+ * @action: true for enable els false
+ *
+ * API to enable cached mc add list in fwr
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_enable_mc_addr_filtering_in_fwr(
+ struct wlan_objmgr_psoc *psoc,
+ uint8_t vdev_id,
+ enum pmo_offload_trigger trigger);
+
+/**
+ * pmo_ucfg_disable_mc_addr_filtering_in_fwr(): Disable cached mc addr list
+ * @psoc: objmgr psoc handle
+ * @vdev_id: vdev id
+ * @gtk_req: pmo gtk req param
+ * @action: true for enable els false
+ *
+ * API to disable cached mc add list in fwr
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_disable_mc_addr_filtering_in_fwr(
+ struct wlan_objmgr_psoc *psoc,
+ uint8_t vdev_id,
+ enum pmo_offload_trigger trigger);
+
+/**
+ * pmo_ucfg_cache_gtk_offload_req(): API to cache gtk req in pmo vdev priv obj
+ * @vdev: objmgr vdev handle
+ * @gtk_req: pmo gtk req param
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_cache_gtk_offload_req(struct wlan_objmgr_vdev *vdev,
+ struct pmo_gtk_req *gtk_req);
+
+/**
+ * pmo_ucfg_flush_gtk_offload_req(): Flush saved gtk req from pmo vdev priv obj
+ * @vdev: objmgr vdev handle
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_flush_gtk_offload_req(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_ucfg_enable_gtk_offload_in_fwr(): enable cached gtk request in fwr
+ * @vdev: objmgr vdev handle
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_enable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_ucfg_disable_gtk_offload_in_fwr(): disable cached gtk request in fwr
+ * @vdev: objmgr vdev handle
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_disable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * pmo_ucfg_set_pkt_filter() - Set packet filter
+ * @psoc: objmgr psoc handle
+ * @pmo_set_pkt_fltr_req:
+ * @vdev_id: vdev id
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_set_pkt_filter(struct wlan_objmgr_psoc *psoc,
+ struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req,
+ uint8_t vdev_id);
+
+/**
+ * pmo_ucfg_clear_pkt_filter() - Clear packet filter
+ * @psoc: objmgr psoc handle
+ * @pmo_clr_pkt_fltr_req:
+ * @vdev_id: vdev id
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_clear_pkt_filter(struct wlan_objmgr_psoc *psoc,
+ struct pmo_rcv_pkt_fltr_clear_param *pmo_clr_pkt_fltr_param,
+ uint8_t vdev_id);
+
+/**
+ * pmo_ucfg_get_gtk_rsp(): API to send gtk response request to fwr
+ * @vdev: objmgr vdev handle
+ * @gtk_rsp: pmo gtk response request
+ *
+ * This api will send gtk response request to fwr
+ *
+ * Return QDF_STATUS_SUCCESS -in case of success else return error
+ */
+QDF_STATUS pmo_ucfg_get_gtk_rsp(struct wlan_objmgr_vdev *vdev,
+ struct pmo_gtk_rsp_req *gtk_rsp_req);
+
+/**
+ * pmo_ucfg_update_extscan_in_progress(): update extscan is in progress flags
+ * @vdev: objmgr vdev handle
+ * @value:true if extscan is in progress else false
+ *
+ * Return: TRUE/FALSE
+ */
+void pmo_ucfg_update_extscan_in_progress(struct wlan_objmgr_vdev *vdev,
+ bool value);
+
+/**
+ * pmo_ucfg_update_p2plo_in_progress(): update p2plo is in progress flags
+ * @vdev: objmgr vdev handle
+ * @value:true if p2plo is in progress else false
+ *
+ * Return: TRUE/FALSE
+ */
+void pmo_ucfg_update_p2plo_in_progress(struct wlan_objmgr_vdev *vdev,
+ bool value);
+
+/**
+ * pmo_ucfg_lphb_config_req() - Handles lphb config request for psoc
+ * @psoc: objmgr psoc handle
+ * @lphb_req: low power heart beat request
+ * @lphb_cb_ctx: Context which needs to pass to soif when lphb callback called
+ * @callback: upon receiving of lphb indication from fwr call lphb callback
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_ucfg_lphb_config_req(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_req *lphb_req, void *lphb_cb_ctx,
+ pmo_lphb_callback callback);
+
+/**
+ * pmo_ucfg_update_alt_modulated_dtim_enable() - update alt modulatate dtim
+ * @vdev: objmgr vdev handle
+ * @value: true for alt_modulated_dtim enable else false
+ *
+ * Return: QDF status
+ */
+void pmo_ucfg_update_alt_modulated_dtim_enable(struct wlan_objmgr_vdev *vdev,
+ bool value);
+
+/**
+ * pmo_ucfg_psoc_update_power_save_mode() - update power save mode
+ * @vdev: objmgr vdev handle
+ * @value:vdev power save mode
+ *
+ * Return: None
+ */
+void pmo_ucfg_psoc_update_power_save_mode(struct wlan_objmgr_psoc *psoc,
+ uint8_t value);
+
+/**
+ * pmo_ucfg_psoc_update_dp_handle() - update psoc data path handle
+ * @psoc: objmgr psoc handle
+ * @dp_hdl: psoc data path handle
+ *
+ * Return: None
+ */
+void pmo_ucfg_psoc_update_dp_handle(struct wlan_objmgr_psoc *psoc,
+ void *dp_hdl);
+
+/**
+ * pmo_ucfg_vdev_update_dp_handle() - update vdev data path handle
+ * @vdev: objmgr vdev handle
+ * @dp_hdl: vdev data path handle
+ *
+ * Return: None
+ */
+void pmo_ucfg_vdev_update_dp_handle(struct wlan_objmgr_vdev *vdev,
+ void *dp_hdl);
+
+/**
+ * pmo_ucfg_psoc_update_htc_handle() - update psoc htc layer handle
+ * @psoc: objmgr psoc handle
+ * @htc_handle: psoc host-to-tagret layer (htc) handle
+ *
+ * Return: None
+ */
+void pmo_ucfg_psoc_update_htc_handle(struct wlan_objmgr_psoc *psoc,
+ void *htc_handle);
+
+/**
+ * pmo_ucfg_psoc_set_hif_handle() - Set psoc hif layer handle
+ * @psoc: objmgr psoc handle
+ * @hif_handle: hif context handle
+ *
+ * Return: None
+ */
+void pmo_ucfg_psoc_set_hif_handle(struct wlan_objmgr_psoc *psoc,
+ void *hif_handle);
+
+/**
+ * pmo_ucfg_psoc_set_txrx_handle() - Set psoc pdev txrx layer handle
+ * @psoc: objmgr psoc handle
+ * @txrx_handle: pdev txrx context handle
+ *
+ * Return: None
+ */
+void pmo_ucfg_psoc_set_txrx_handle(struct wlan_objmgr_psoc *psoc,
+ void *txrx_handle);
+
+/**
+ * pmo_ucfg_psoc_user_space_suspend_req() - Handles user space suspend req
+ * @psoc: objmgr psoc handle
+ * @type: type of suspend
+ *
+ * Handles user space suspend indication for psoc
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_ucfg_psoc_user_space_suspend_req(struct wlan_objmgr_psoc *psoc,
+ enum qdf_suspend_type type);
+
+/**
+ * pmo_ucfg_psoc_user_space_resume_req() - Handles user space resume req
+ * @psoc: objmgr psoc handle
+ * @type: type of suspend from which resume needed
+ *
+ * Handles user space resume indication for psoc
+ *
+ * Return: QDF status
+ */
+QDF_STATUS pmo_ucfg_psoc_user_space_resume_req(struct wlan_objmgr_psoc *psoc,
+ enum qdf_suspend_type type);
+
+/**
+ * pmo_ucfg_psoc_bus_suspend_req(): handles bus suspend for psoc
+ * @psoc: objmgr psoc
+ * @type: is this suspend part of runtime suspend or system suspend?
+ * @wow_params: collection of wow enable override parameters
+ *
+ * Bails if a scan is in progress.
+ * Calls the appropriate handlers based on configuration and event.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_ucfg_psoc_bus_suspend_req(struct wlan_objmgr_psoc *psoc,
+ enum qdf_suspend_type type,
+ struct pmo_wow_enable_params *wow_params);
+
+#ifdef FEATURE_RUNTIME_PM
+/**
+ * pmo_ucfg_psoc_bus_runtime_suspend(): handles bus runtime suspend for psoc
+ * @psoc: objmgr psoc
+ * @pld_cb: callback to call link auto suspend
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_ucfg_psoc_bus_runtime_suspend(struct wlan_objmgr_psoc *psoc,
+ pmo_pld_auto_suspend_cb pld_cb);
+
+/**
+ * pmo_ucfg_psoc_bus_runtime_resume(): handles bus runtime resume for psoc
+ * @psoc: objmgr psoc
+ * @pld_cb: callback to call link auto resume
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_ucfg_psoc_bus_runtime_resume(struct wlan_objmgr_psoc *psoc,
+ pmo_pld_auto_resume_cb pld_cb);
+#endif
+
+/**
+ * pmo_ucfg_psoc_suspend_target() -Send suspend target command
+ * @psoc: objmgr psoc handle
+ * @disable_target_intr: disable target interrupt
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS pmo_ucfg_psoc_suspend_target(struct wlan_objmgr_psoc *psoc,
+ int disable_target_intr);
+
+/**
+ * pmo_ucfg_psoc_bus_resume() -handle bus resume request for psoc
+ * @psoc: objmgr psoc handle
+ * @type: is this suspend part of runtime suspend or system suspend?
+ *
+ * Return:QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS pmo_ucfg_psoc_bus_resume_req(struct wlan_objmgr_psoc *psoc,
+ enum qdf_suspend_type type);
+
+/**
+ * pmo_ucfg_get_wow_bus_suspend(): API to check if wow bus is suspended or not
+ * @psoc: objmgr psoc handle
+ *
+ * Return: True if bus suspende else false
+ */
+bool pmo_ucfg_get_wow_bus_suspend(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_ucfg_psoc_handle_initial_wake_up() - update initial wake up
+ * @cb_ctx: objmgr psoc handle as void * due to htc layer is not aware psoc
+ *
+ * Return: None
+ */
+void pmo_ucfg_psoc_handle_initial_wake_up(void *cb_ctx);
+
+/**
+ * pmo_ucfg_psoc_is_target_wake_up_received() - Get initial wake up status
+ * @psoc: objmgr psoc handle
+ *
+ * Return: 0 on success else error code
+ */
+int pmo_ucfg_psoc_is_target_wake_up_received(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_ucfg_psoc_is_target_wake_up_received() - Clear initial wake up status
+ * @psoc: objmgr psoc handle
+ *
+ * Return: 0 on success else error code
+ */
+int pmo_ucfg_psoc_clear_target_wake_up(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * pmo_ucfg_psoc_target_suspend_acknowledge() - Clear initial wake up status
+ * @psoc: objmgr psoc handle
+ *
+ * Return: None
+ */
+void pmo_ucfg_psoc_target_suspend_acknowledge(void *context, bool wow_nack);
+
+/**
+ * pmo_ucfg_psoc_wakeup_host_event_received() - got host wake up evennt from fwr
+ * @psoc: objmgr psoc handle
+ *
+ * Return: None
+ */
+void pmo_ucfg_psoc_wakeup_host_event_received(struct wlan_objmgr_psoc *psoc);
+
+#endif /* end of _WLAN_PMO_UCFG_API_H_ */
diff --git a/components/pmo/dispatcher/inc/wlan_pmo_wow_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_wow_public_struct.h
new file mode 100644
index 0000000..46d7048
--- /dev/null
+++ b/components/pmo/dispatcher/inc/wlan_pmo_wow_public_struct.h
@@ -0,0 +1,241 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+ /**
+ * DOC: Declare various struct, macros which shall be used in
+ * pmo wow related features.
+ *
+ * Note: This file shall not contain public API's prototype/declarations.
+ *
+ */
+
+#ifndef _WLAN_PMO_WOW_PUBLIC_STRUCT_H_
+#include "wlan_pmo_lphb_public_struct.h"
+
+#define _WLAN_PMO_WOW_PUBLIC_STRUCT_H_
+
+#define PMO_WOWL_PTRN_MAX_SIZE 146
+#define PMO_WOWL_PTRN_MASK_MAX_SIZE 19
+#define PMO_WOWL_MAX_PTRNS_ALLOWED CFG_MAX_WOW_FILTERS_MAX
+#define PMO_WOWL_BCAST_PATTERN_MAX_SIZE 146
+
+#define PMO_WOW_INTER_PTRN_TOKENIZER ';'
+#define PMO_WOW_INTRA_PTRN_TOKENIZER ':'
+
+
+/* Action frame categories */
+
+#define PMO_MAC_ACTION_SPECTRUM_MGMT 0
+#define PMO_MAC_ACTION_QOS_MGMT 1
+#define PMO_MAC_ACTION_DLP 2
+#define PMO_MAC_ACTION_BLKACK 3
+#define PMO_MAC_ACTION_PUBLIC_USAGE 4
+#define PMO_MAC_ACTION_RRM 5
+#define PMO_MAC_ACTION_FAST_BSS_TRNST 6
+#define PMO_MAC_ACTION_HT 7
+#define PMO_MAC_ACTION_SA_QUERY 8
+#define PMO_MAC_ACTION_PROT_DUAL_PUB 9
+#define PMO_MAC_ACTION_WNM 10
+#define PMO_MAC_ACTION_UNPROT_WNM 11
+#define PMO_MAC_ACTION_TDLS 12
+#define PMO_MAC_ACITON_MESH 13
+#define PMO_MAC_ACTION_MHF 14
+#define PMO_MAC_SELF_PROTECTED 15
+#define PMO_MAC_ACTION_WME 17
+#define PMO_MAC_ACTION_FST 18
+#define PMO_MAC_ACTION_VHT 21
+#define PMO_MAC_ACTION_MAX 256
+
+/*
+ * ALLOWED_ACTION_FRAMES_BITMAP
+ *
+ * Bitmask is based on the below. The frames with 0's
+ * set to their corresponding bit can be dropped in FW.
+ *
+ * -----------------------------+-----+-------+
+ * Type | Bit | Allow |
+ * -----------------------------+-----+-------+
+ * PMO_ACTION_SPECTRUM_MGMT 0 1
+ * PMO_ACTION_QOS_MGMT 1 1
+ * PMO_ACTION_DLP 2 0
+ * PMO_ACTION_BLKACK 3 0
+ * PMO_ACTION_PUBLIC_USAGE 4 1
+ * PMO_ACTION_RRM 5 1
+ * PMO_ACTION_FAST_BSS_TRNST 6 0
+ * PMO_ACTION_HT 7 0
+ * PMO_ACTION_SA_QUERY 8 1
+ * PMO_ACTION_PROT_DUAL_PUB 9 1
+ * PMO_ACTION_WNM 10 1
+ * PMO_ACTION_UNPROT_WNM 11 0
+ * PMO_ACTION_TDLS 12 0
+ * PMO_ACITON_MESH 13 0
+ * PMO_ACTION_MHF 14 0
+ * PMO_SELF_PROTECTED 15 0
+ * PMO_ACTION_WME 17 1
+ * PMO_ACTION_FST 18 1
+ * PMO_ACTION_VHT 21 1
+ * ----------------------------+------+-------+
+ */
+#define ALLOWED_ACTION_FRAMES_BITMAP0 \
+ ((1 << PMO_MAC_ACTION_SPECTRUM_MGMT) | \
+ (1 << PMO_MAC_ACTION_QOS_MGMT) | \
+ (1 << PMO_MAC_ACTION_PUBLIC_USAGE) | \
+ (1 << PMO_MAC_ACTION_RRM) | \
+ (1 << PMO_MAC_ACTION_SA_QUERY) | \
+ (1 << PMO_MAC_ACTION_PROT_DUAL_PUB) | \
+ (1 << PMO_MAC_ACTION_WNM) | \
+ (1 << PMO_MAC_ACTION_WME) | \
+ (1 << PMO_MAC_ACTION_FST) | \
+ (1 << PMO_MAC_ACTION_VHT))
+
+#define ALLOWED_ACTION_FRAMES_BITMAP1 0x0
+#define ALLOWED_ACTION_FRAMES_BITMAP2 0x0
+#define ALLOWED_ACTION_FRAMES_BITMAP3 0x0
+#define ALLOWED_ACTION_FRAMES_BITMAP4 0x0
+#define ALLOWED_ACTION_FRAMES_BITMAP5 0x0
+#define ALLOWED_ACTION_FRAMES_BITMAP6 0x0
+#define ALLOWED_ACTION_FRAMES_BITMAP7 0x0
+
+#define ALLOWED_ACTION_FRAME_MAP_WORDS (PMO_MAC_ACTION_MAX / 32)
+
+
+#define PMO_SUPPORTED_ACTION_CATE 256
+#define PMO_SUPPORTED_ACTION_CATE_ELE_LIST (PMO_SUPPORTED_ACTION_CATE/32)
+
+/**
+ * struct pmo_action_wakeup_set_params - action wakeup set params
+ * @vdev_id: virtual device id
+ * @operation: 0 reset to fw default, 1 set the bits,
+ * 2 add the setting bits, 3 delete the setting bits
+ * @action_category_map: bit mapping.
+ */
+struct pmo_action_wakeup_set_params {
+ uint32_t vdev_id;
+ uint32_t operation;
+ uint32_t action_category_map[PMO_SUPPORTED_ACTION_CATE_ELE_LIST];
+};
+
+/**
+ * enum pmo_wow_action_wakeup_opertion: describe action wakeup operation
+ * @pmo_action_wakeup_reset: reset
+ * @pmo_action_wakeup_set: set
+ * @pmo_action_wakeup_add_set: add and set
+ * @pmo_action_wakeup_del_set: delete and set
+ */
+enum pmo_wow_action_wakeup_opertion {
+ pmo_action_wakeup_reset = 0,
+ pmo_action_wakeup_set,
+ pmo_action_wakeup_add_set,
+ pmo_action_wakeup_del_set,
+};
+
+/**
+ * struct pmo_wow - store wow patterns
+ * @wow_enable: wow enable/disable
+ * @wow_enable_cmd_sent: is wow enable command sent to fw
+ * @is_wow_bus_suspended: true if bus is suspended
+ * @target_suspend: target suspend event
+ * @target_resume: target resume event
+ * @wow_nack: wow negative ack flag
+ * @wow_initial_wake_up: target initial wake up is received
+ * @wow_wake_lock: wow wake lock
+ * @lphb_cache: lphb cache
+ * @lphb_cb_ctx: callback context for lphb, kept as void* as
+ * osif structures are opaque to pmo.
+ * @pmo_lphb_callback: registered os if calllback function
+ *
+ * This structure stores wow patterns and
+ * wow related parameters in host.
+ */
+struct pmo_wow {
+ bool wow_enable;
+ bool wow_enable_cmd_sent;
+ bool is_wow_bus_suspended;
+ qdf_event_t target_suspend;
+ qdf_event_t target_resume;
+ int wow_nack;
+ bool wow_initial_wake_up;
+ qdf_wake_lock_t wow_wake_lock;
+ /*
+ * currently supports only vdev 0.
+ * cache has two entries: one for TCP and one for UDP.
+ */
+ struct pmo_lphb_req lphb_cache[2];
+ void *lphb_cb_ctx;
+ pmo_lphb_callback lphb_cb;
+};
+
+/* WOW related structures */
+/**
+ * struct pmo_wow_add_pattern - wow pattern add structure
+ * @pattern_id: pattern id
+ * @pattern_byte_offset: pattern byte offset from beginning of the 802.11
+ * packet to start of the wake-up pattern
+ * @pattern_size: pattern size
+ * @pattern: pattern byte stream
+ * @pattern_mask_size: pattern mask size
+ * @pattern_mask: pattern mask
+ * @session_id: session id
+ */
+struct pmo_wow_add_pattern {
+ uint8_t pattern_id;
+ uint8_t pattern_byte_offset;
+ uint8_t pattern_size;
+ uint8_t pattern[PMO_WOWL_BCAST_PATTERN_MAX_SIZE];
+ uint8_t pattern_mask_size;
+ uint8_t pattern_mask[PMO_WOWL_BCAST_PATTERN_MAX_SIZE];
+ uint8_t session_id;
+};
+
+/**
+ * struct pmo_wow_add_pattern - wow pattern add structure
+ * @magic_pkt_enable: enables or disables magic packet filtering
+ * @wow_deauth_rcv: This configuration is valid only when magicPktEnable=1,
+ * It requests hardware to wake up when it receives the
+ * Deauthentication Frame.
+ * @pattern_filtering_enable: Enables/disables packet pattern filtering
+ * @wow_bss_conn_loss: wake up host when bss connection lost
+ */
+struct pmo_wow_enter_params {
+ uint8_t magic_pkt_enable;
+ uint8_t wow_deauth_rcv;
+ uint8_t pattern_filtering_enable;
+ uint8_t wow_bss_conn_loss;
+};
+
+/**
+ * struct pmo_wow_cmd_params - wow cmd parameter
+ * @enable: wow enable or disable flag
+ * @can_suspend_link: flag to indicate if link can be suspended
+ * @pause_iface_config: interface config
+ */
+struct pmo_wow_cmd_params {
+ bool enable;
+ bool can_suspend_link;
+ uint8_t pause_iface_config;
+ uint32_t flags;
+};
+
+/**
+ * struct pmo_suspend_params - suspend cmd parameter
+ * @disable_target_intr: disable target interrupt
+ */
+struct pmo_suspend_params {
+ uint8_t disable_target_intr;
+};
+
+#endif /* end of _WLAN_PMO_WOW_PUBLIC_STRUCT_H_ */
diff --git a/components/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c b/components/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c
new file mode 100644
index 0000000..0041fa2
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_obj_mgmt_api.c
@@ -0,0 +1,761 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: define utility API related to the pmo component
+ * called by other components
+ */
+
+#include "wlan_pmo_obj_mgmt_api.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_static_config.h"
+#include "wlan_pmo_main.h"
+#include "target_if_pmo.h"
+
+QDF_STATUS pmo_init(void)
+{
+ QDF_STATUS status;
+ struct wlan_pmo_ctx *pmo_ctx;
+
+ PMO_ENTER();
+ if (pmo_allocate_ctx() != QDF_STATUS_SUCCESS) {
+ pmo_err("unable to allocate psoc ctx");
+ status = QDF_STATUS_E_FAULT;
+ goto out;
+ }
+
+ pmo_ctx = pmo_get_context();
+ if (!pmo_ctx) {
+ pmo_err("unable to get pmo ctx");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ status = wlan_objmgr_register_psoc_create_handler(
+ WLAN_UMAC_COMP_PMO,
+ pmo_psoc_object_created_notification,
+ (void *)pmo_ctx);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("unable to register psoc create handle");
+ goto out;
+ }
+
+ status = wlan_objmgr_register_psoc_destroy_handler(
+ WLAN_UMAC_COMP_PMO,
+ pmo_psoc_object_destroyed_notification,
+ (void *)pmo_ctx);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("unable to register psoc create handle");
+ goto out;
+ }
+
+ status = wlan_objmgr_register_vdev_create_handler(
+ WLAN_UMAC_COMP_PMO,
+ pmo_vdev_object_created_notification,
+ (void *)pmo_ctx);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("unable to register vdev create handle");
+ goto out;
+ }
+
+ status = wlan_objmgr_register_vdev_destroy_handler(
+ WLAN_UMAC_COMP_PMO,
+ pmo_vdev_object_destroyed_notification,
+ (void *)pmo_ctx);
+ if (status != QDF_STATUS_SUCCESS)
+ pmo_err("unable to register vdev create handle");
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_deinit(void)
+{
+ QDF_STATUS status;
+ struct wlan_pmo_ctx *pmo_ctx;
+
+ PMO_ENTER();
+ pmo_ctx = pmo_get_context();
+ if (!pmo_ctx) {
+ pmo_err("unable to get pmo ctx");
+ status = QDF_STATUS_E_FAILURE;
+ goto out;
+ }
+
+ status = wlan_objmgr_unregister_psoc_create_handler(
+ WLAN_UMAC_COMP_PMO,
+ pmo_psoc_object_created_notification,
+ (void *)pmo_ctx);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("unable to unregister psoc create handle");
+ goto out;
+ }
+
+ status = wlan_objmgr_unregister_psoc_destroy_handler(
+ WLAN_UMAC_COMP_PMO,
+ pmo_psoc_object_destroyed_notification,
+ (void *)pmo_ctx);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("unable to unregister psoc create handle");
+ goto out;
+ }
+
+ status = wlan_objmgr_unregister_vdev_create_handler(
+ WLAN_UMAC_COMP_PMO,
+ pmo_vdev_object_created_notification,
+ (void *)pmo_ctx);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("unable to unregister vdev create handle");
+ goto out;
+ }
+
+ status = wlan_objmgr_unregister_vdev_destroy_handler(
+ WLAN_UMAC_COMP_PMO,
+ pmo_vdev_object_destroyed_notification,
+ (void *)pmo_ctx);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("unable to unregister vdev create handle");
+ goto out;
+ }
+
+out:
+ pmo_free_ctx();
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_psoc_object_created_notification(
+ struct wlan_objmgr_psoc *psoc, void *arg)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx = NULL;
+ QDF_STATUS status;
+ struct wlan_pmo_ctx *pmo_ctx;
+
+ PMO_ENTER();
+ pmo_ctx = pmo_get_context();
+ if (!pmo_ctx) {
+ QDF_ASSERT(0);
+ pmo_err("unable to get pmo ctx");
+ status = QDF_STATUS_E_FAILURE;
+ goto out;
+ }
+
+ psoc_ctx = qdf_mem_malloc(sizeof(*psoc_ctx));
+ if (psoc_ctx == NULL) {
+ pmo_err("Failed to allocate pmo_psoc");
+ status = QDF_STATUS_E_NOMEM;
+ goto out;
+ }
+
+ status = wlan_objmgr_psoc_component_obj_attach(psoc,
+ WLAN_UMAC_COMP_PMO,
+ psoc_ctx,
+ QDF_STATUS_SUCCESS);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("Failed to attach psoc_ctx with psoc");
+ qdf_mem_free(psoc_ctx);
+ status = QDF_STATUS_E_FAILURE;
+ goto out;
+ }
+ qdf_spinlock_create(&psoc_ctx->lock);
+ qdf_wake_lock_create(&psoc_ctx->wow.wow_wake_lock, "pmo_wow_wl");
+ status = qdf_event_create(&psoc_ctx->wow.target_suspend);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("target suspend event initialization failed");
+ status = QDF_STATUS_E_FAILURE;
+ goto out;
+ }
+ status = qdf_event_create(&psoc_ctx->wow.target_resume);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("target resume event initialization failed");
+ status = QDF_STATUS_E_FAILURE;
+ goto out;
+ }
+ /* Register PMO tx ops*/
+ target_if_pmo_register_tx_ops(&psoc_ctx->pmo_tx_ops);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_psoc_object_destroyed_notification(
+ struct wlan_objmgr_psoc *psoc, void *arg)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx = NULL;
+ QDF_STATUS status;
+
+ PMO_ENTER();
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+
+ status = wlan_objmgr_psoc_component_obj_detach(psoc,
+ WLAN_UMAC_COMP_PMO,
+ psoc_ctx);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("Failed to detach psoc_ctx from psoc");
+ status = QDF_STATUS_E_FAILURE;
+ goto out;
+ }
+
+ qdf_spinlock_destroy(&psoc_ctx->lock);
+ qdf_event_destroy(&psoc_ctx->wow.target_suspend);
+ qdf_event_destroy(&psoc_ctx->wow.target_resume);
+ qdf_wake_lock_destroy(&psoc_ctx->wow.wow_wake_lock);
+ qdf_mem_zero(psoc_ctx, sizeof(*psoc_ctx));
+ qdf_mem_free(psoc_ctx);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_vdev_object_created_notification(
+ struct wlan_objmgr_vdev *vdev, void *arg)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx = NULL;
+ struct wlan_objmgr_psoc *psoc;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+ QDF_STATUS status;
+
+ PMO_ENTER();
+
+ psoc = pmo_vdev_get_psoc(vdev);
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+
+ vdev_ctx = qdf_mem_malloc(sizeof(*vdev_ctx));
+ if (vdev_ctx == NULL) {
+ pmo_err("Failed to allocate vdev_ctx");
+ status = QDF_STATUS_E_NOMEM;
+ goto out;
+ }
+
+ status = wlan_objmgr_vdev_component_obj_attach(vdev,
+ WLAN_UMAC_COMP_PMO,
+ (void *)vdev_ctx, QDF_STATUS_SUCCESS);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("Failed to attach vdev_ctx with vdev");
+ qdf_mem_free(vdev_ctx);
+ goto out;
+ }
+
+ qdf_spinlock_create(&vdev_ctx->pmo_vdev_lock);
+ vdev_ctx->ptrn_match_enable =
+ psoc_ctx->psoc_cfg.ptrn_match_enable_all_vdev;
+ vdev_ctx->pmo_psoc_ctx = psoc_ctx;
+ qdf_atomic_init(&vdev_ctx->gtk_err_enable);
+
+out:
+ PMO_EXIT();
+
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_vdev_ready(struct wlan_objmgr_vdev *vdev)
+{
+ QDF_STATUS status;
+
+ PMO_ENTER();
+
+ status = pmo_vdev_get_ref(vdev);
+ if (QDF_IS_STATUS_ERROR(status))
+ return status;
+
+ /* Register static configuration with firmware */
+ pmo_register_wow_wakeup_events(vdev);
+ pmo_register_action_frame_patterns(vdev);
+
+ /* Register default wow patterns with firmware */
+ pmo_register_wow_default_patterns(vdev);
+
+ pmo_vdev_put_ref(vdev);
+
+ PMO_EXIT();
+
+ /*
+ * The above APIs should return a status but don't.
+ * Just return success for now.
+ */
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_vdev_object_destroyed_notification(
+ struct wlan_objmgr_vdev *vdev, void *arg)
+{
+ struct pmo_vdev_priv_obj *vdev_ctx = NULL;
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+ PMO_ENTER();
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ status = wlan_objmgr_vdev_component_obj_detach(vdev,
+ WLAN_UMAC_COMP_PMO,
+ (void *)vdev_ctx);
+ if (status != QDF_STATUS_SUCCESS)
+ pmo_err("Failed to detach vdev_ctx with vdev");
+
+ qdf_spinlock_destroy(&vdev_ctx->pmo_vdev_lock);
+ qdf_mem_free(vdev_ctx);
+
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_register_suspend_handler(
+ enum wlan_umac_comp_id id,
+ pmo_psoc_suspend_handler handler,
+ void *arg)
+{
+ struct wlan_pmo_ctx *pmo_ctx;
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+ PMO_ENTER();
+ pmo_ctx = pmo_get_context();
+ if (!pmo_ctx) {
+ QDF_ASSERT(0);
+ pmo_err("unable to get pmo ctx");
+ status = QDF_STATUS_E_FAILURE;
+ goto out;
+ }
+
+ if (id > WLAN_UMAC_MAX_COMPONENTS || id < 0) {
+ pmo_err("component id: %d is %s then valid components id",
+ id, id < 0 ? "Less" : "More");
+ status = QDF_STATUS_E_FAILURE;
+ goto out;
+ }
+
+ qdf_spin_lock_bh(&pmo_ctx->lock);
+ pmo_ctx->pmo_suspend_handler[id] = handler;
+ pmo_ctx->pmo_suspend_handler_arg[id] = arg;
+ qdf_spin_unlock_bh(&pmo_ctx->lock);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_unregister_suspend_handler(
+ enum wlan_umac_comp_id id,
+ pmo_psoc_suspend_handler handler)
+{
+ struct wlan_pmo_ctx *pmo_ctx;
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+ PMO_ENTER();
+ pmo_ctx = pmo_get_context();
+ if (!pmo_ctx) {
+ QDF_ASSERT(0);
+ pmo_err("unable to get pmo ctx");
+ status = QDF_STATUS_E_FAILURE;
+ goto out;
+ }
+
+ if (id > WLAN_UMAC_MAX_COMPONENTS || id < 0) {
+ pmo_err("component id: %d is %s then valid components id",
+ id, id < 0 ? "Less" : "More");
+ status = QDF_STATUS_E_FAILURE;
+ goto out;
+ }
+
+ qdf_spin_lock_bh(&pmo_ctx->lock);
+ if (pmo_ctx->pmo_suspend_handler[id] == handler) {
+ pmo_ctx->pmo_suspend_handler[id] = NULL;
+ pmo_ctx->pmo_suspend_handler_arg[id] = NULL;
+ qdf_spin_unlock_bh(&pmo_ctx->lock);
+ } else {
+ qdf_spin_unlock_bh(&pmo_ctx->lock);
+ pmo_err("can't find suspend handler for component id: %d ", id);
+ status = QDF_STATUS_E_FAILURE;
+ }
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_register_resume_handler(
+ enum wlan_umac_comp_id id,
+ pmo_psoc_resume_handler handler,
+ void *arg)
+{
+ struct wlan_pmo_ctx *pmo_ctx;
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+ PMO_ENTER();
+ pmo_ctx = pmo_get_context();
+ if (!pmo_ctx) {
+ pmo_err("unable to get pmo ctx");
+ status = QDF_STATUS_E_FAILURE;
+ goto out;
+ }
+
+ if (id > WLAN_UMAC_MAX_COMPONENTS || id < 0) {
+ pmo_err("component id: %d is %s then valid components id",
+ id, id < 0 ? "Less" : "More");
+ status = QDF_STATUS_E_FAILURE;
+ goto out;
+ }
+
+ qdf_spin_lock_bh(&pmo_ctx->lock);
+ pmo_ctx->pmo_resume_handler[id] = handler;
+ pmo_ctx->pmo_resume_handler_arg[id] = arg;
+ qdf_spin_unlock_bh(&pmo_ctx->lock);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_unregister_resume_handler(
+ enum wlan_umac_comp_id id,
+ pmo_psoc_resume_handler handler)
+{
+ struct wlan_pmo_ctx *pmo_ctx;
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+ PMO_ENTER();
+ pmo_ctx = pmo_get_context();
+ if (!pmo_ctx) {
+ pmo_err("unable to get pmo ctx");
+ status = QDF_STATUS_E_FAILURE;
+ goto out;
+ }
+
+ if (id > WLAN_UMAC_MAX_COMPONENTS || id < 0) {
+ pmo_err("component id: %d is %s then valid components id",
+ id, id < 0 ? "Less" : "More");
+ status = QDF_STATUS_E_FAILURE;
+ goto out;
+ }
+
+ qdf_spin_lock_bh(&pmo_ctx->lock);
+ if (pmo_ctx->pmo_resume_handler[id] == handler) {
+ pmo_ctx->pmo_resume_handler[id] = NULL;
+ pmo_ctx->pmo_resume_handler_arg[id] = NULL;
+ qdf_spin_unlock_bh(&pmo_ctx->lock);
+ } else {
+ qdf_spin_unlock_bh(&pmo_ctx->lock);
+ pmo_err("can't find resume handler for component id: %d ", id);
+ status = QDF_STATUS_E_FAILURE;
+ }
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_suspend_all_components(struct wlan_objmgr_psoc *psoc,
+ enum qdf_suspend_type suspend_type)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ QDF_STATUS resume_status;
+ struct wlan_pmo_ctx *pmo_ctx;
+ uint8_t i;
+ pmo_psoc_suspend_handler handler;
+ void *arg;
+
+ PMO_ENTER();
+
+ pmo_ctx = pmo_get_context();
+ if (!pmo_ctx) {
+ pmo_err("unable to get pmo ctx");
+ QDF_ASSERT(0);
+ status = QDF_STATUS_E_FAILURE;
+ goto exit_with_status;
+ }
+
+ /* call each component's suspend handler */
+ for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) {
+ qdf_spin_lock_bh(&pmo_ctx->lock);
+ handler = pmo_ctx->pmo_suspend_handler[i];
+ arg = pmo_ctx->pmo_suspend_handler_arg[i];
+ qdf_spin_unlock_bh(&pmo_ctx->lock);
+
+ if (!handler)
+ continue;
+
+ status = handler(psoc, arg);
+ if (QDF_IS_STATUS_ERROR(status)) {
+ pmo_err("component %d failed to suspend; status: %d",
+ i, status);
+ QDF_ASSERT(0);
+ goto suspend_recovery;
+ }
+ }
+
+ goto exit_with_status;
+
+suspend_recovery:
+ /* resume, starting with the last successfully suspended component */
+ for (i -= 1; i >= 0; i--) {
+ qdf_spin_lock_bh(&pmo_ctx->lock);
+ handler = pmo_ctx->pmo_resume_handler[i];
+ arg = pmo_ctx->pmo_resume_handler_arg[i];
+ qdf_spin_unlock_bh(&pmo_ctx->lock);
+
+ if (!handler)
+ continue;
+
+ resume_status = handler(psoc, arg);
+ if (QDF_IS_STATUS_ERROR(resume_status)) {
+ pmo_fatal("Non-recoverable failure occurred!");
+ pmo_fatal("component %d failed to resume; status: %d",
+ i, resume_status);
+ QDF_BUG(0);
+ }
+ }
+
+exit_with_status:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_resume_all_components(struct wlan_objmgr_psoc *psoc,
+ enum qdf_suspend_type suspend_type)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ struct wlan_pmo_ctx *pmo_ctx;
+ uint8_t i;
+ pmo_psoc_suspend_handler handler;
+ void *arg;
+
+ PMO_ENTER();
+
+ pmo_ctx = pmo_get_context();
+ if (!pmo_ctx) {
+ pmo_err("unable to get pmo ctx");
+ QDF_ASSERT(0);
+ status = QDF_STATUS_E_FAILURE;
+ goto exit_with_status;
+ }
+
+ /* call each component's resume handler */
+ for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) {
+ qdf_spin_lock_bh(&pmo_ctx->lock);
+ handler = pmo_ctx->pmo_resume_handler[i];
+ arg = pmo_ctx->pmo_resume_handler_arg[i];
+ qdf_spin_unlock_bh(&pmo_ctx->lock);
+
+ if (!handler)
+ continue;
+
+ status = handler(psoc, arg);
+ if (QDF_IS_STATUS_ERROR(status)) {
+ pmo_fatal("Non-recoverable failure occurred!");
+ pmo_fatal("component %d failed to resume; status: %d",
+ i, status);
+ QDF_BUG(0);
+ }
+ }
+
+exit_with_status:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_register_pause_bitmap_notifier(struct wlan_objmgr_psoc *psoc,
+ pmo_notify_pause_bitmap handler)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx;
+ QDF_STATUS status;
+
+ if (!psoc) {
+ pmo_err("psoc is null");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ if (!handler) {
+ pmo_err("pmo_notify_vdev_pause_bitmap is null");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ status = pmo_psoc_get_ref(psoc);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("pmo cannot get the reference out of psoc");
+ return status;
+ }
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ psoc_ctx->pause_bitmap_notifier = handler;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+ pmo_psoc_put_ref(psoc);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_unregister_pause_bitmap_notifier(struct wlan_objmgr_psoc *psoc,
+ pmo_notify_pause_bitmap handler)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx;
+ QDF_STATUS status;
+
+ if (!psoc) {
+ pmo_err("psoc is null");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ if (!handler) {
+ pmo_err("pmo_notify_vdev_pause_bitmap is null");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ status = pmo_psoc_get_ref(psoc);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("pmo cannot get the reference out of psoc");
+ return status;
+ }
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ if (psoc_ctx->pause_bitmap_notifier == handler)
+ psoc_ctx->pause_bitmap_notifier = NULL;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+ pmo_psoc_put_ref(psoc);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_register_get_pause_bitmap(struct wlan_objmgr_psoc *psoc,
+ pmo_get_pause_bitmap handler)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx;
+ QDF_STATUS status;
+
+ if (!psoc) {
+ pmo_err("psoc is null");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ if (!handler) {
+ pmo_err("pmo_get_pause_bitmap is null");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ status = pmo_psoc_get_ref(psoc);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("pmo cannot get the reference out of psoc");
+ return status;
+ }
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ psoc_ctx->get_pause_bitmap = handler;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+ pmo_psoc_put_ref(psoc);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_unregister_get_pause_bitmap(struct wlan_objmgr_psoc *psoc,
+ pmo_get_pause_bitmap handler)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx;
+ QDF_STATUS status;
+
+ if (!psoc) {
+ pmo_err("psoc is null");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ if (!handler) {
+ pmo_err("pmo_get_pause_bitmap is null");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ status = pmo_psoc_get_ref(psoc);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("pmo cannot get the reference out of psoc");
+ return status;
+ }
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ if (psoc_ctx->get_pause_bitmap == handler)
+ psoc_ctx->get_pause_bitmap = NULL;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+ pmo_psoc_put_ref(psoc);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_register_is_device_in_low_pwr_mode(struct wlan_objmgr_psoc *psoc,
+ pmo_is_device_in_low_pwr_mode handler)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx;
+ QDF_STATUS status;
+
+ if (!psoc) {
+ pmo_err("psoc is null");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ if (!handler) {
+ pmo_err("pmo_get_pause_bitmap is null");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ status = pmo_psoc_get_ref(psoc);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("pmo cannot get the reference out of psoc");
+ return status;
+ }
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ psoc_ctx->is_device_in_low_pwr_mode = handler;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+ pmo_psoc_put_ref(psoc);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS pmo_unregister_is_device_in_low_pwr_mode(
+ struct wlan_objmgr_psoc *psoc,
+ pmo_is_device_in_low_pwr_mode handler)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx;
+ QDF_STATUS status;
+
+ if (!psoc) {
+ pmo_err("psoc is null");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ if (!handler) {
+ pmo_err("pmo_get_pause_bitmap is null");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ status = pmo_psoc_get_ref(psoc);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("pmo cannot get the reference out of psoc");
+ return status;
+ }
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+ qdf_spin_lock_bh(&psoc_ctx->lock);
+ psoc_ctx->is_device_in_low_pwr_mode = NULL;
+ qdf_spin_unlock_bh(&psoc_ctx->lock);
+ pmo_psoc_put_ref(psoc);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+
diff --git a/components/pmo/dispatcher/src/wlan_pmo_tgt_arp.c b/components/pmo/dispatcher/src/wlan_pmo_tgt_arp.c
new file mode 100644
index 0000000..eafcbed
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_arp.c
@@ -0,0 +1,158 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Implements public API for pmo to interact with target/WMI
+ */
+
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_arp_public_struct.h"
+#include "wlan_pmo_ns_public_struct.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include "wlan_pmo_main.h"
+
+QDF_STATUS pmo_tgt_enable_arp_offload_req(struct wlan_objmgr_vdev *vdev,
+ uint8_t vdev_id)
+{
+ struct pmo_arp_offload_params *arp_offload_req = NULL;
+ struct pmo_ns_offload_params *ns_offload_req = NULL;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+ struct wlan_objmgr_psoc *psoc;
+ QDF_STATUS status;
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ PMO_ENTER();
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ psoc = pmo_vdev_get_psoc(vdev);
+
+ arp_offload_req = qdf_mem_malloc(sizeof(*arp_offload_req));
+ if (!arp_offload_req) {
+ pmo_err("unable to allocate arp_offload_req");
+ status = QDF_STATUS_E_NOMEM;
+ goto out;
+ }
+
+ ns_offload_req = qdf_mem_malloc(sizeof(*ns_offload_req));
+ if (!ns_offload_req) {
+ pmo_err("unable to allocate ns_offload_req");
+ status = QDF_STATUS_E_NOMEM;
+ goto out;
+ }
+
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ qdf_mem_copy(arp_offload_req, &vdev_ctx->vdev_arp_req,
+ sizeof(*arp_offload_req));
+ qdf_mem_copy(ns_offload_req, &vdev_ctx->vdev_ns_req,
+ sizeof(*ns_offload_req));
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ pmo_debug("ARP Offload vdev_id: %d enable: %d",
+ vdev_id,
+ arp_offload_req->enable);
+ pmo_debug("NS Offload vdev_id: %d enable: %d ns_count: %u",
+ vdev_id,
+ ns_offload_req->enable,
+ ns_offload_req->num_ns_offload_count);
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.send_arp_offload_req) {
+ pmo_err("send_arp_offload_req is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+ status = pmo_tx_ops.send_arp_offload_req(
+ vdev, arp_offload_req, ns_offload_req);
+ if (status != QDF_STATUS_SUCCESS)
+ pmo_err("Failed to send ARP offload");
+out:
+ if (arp_offload_req)
+ qdf_mem_free(arp_offload_req);
+ if (ns_offload_req)
+ qdf_mem_free(ns_offload_req);
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_tgt_disable_arp_offload_req(struct wlan_objmgr_vdev *vdev,
+ uint8_t vdev_id)
+{
+ struct pmo_arp_offload_params *arp_offload_req = NULL;
+ struct pmo_ns_offload_params *ns_offload_req = NULL;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+ struct wlan_objmgr_psoc *psoc;
+ QDF_STATUS status;
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ PMO_ENTER();
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ psoc = pmo_vdev_get_psoc(vdev);
+
+ arp_offload_req = qdf_mem_malloc(sizeof(*arp_offload_req));
+ if (!arp_offload_req) {
+ pmo_err("unable to allocate arp_offload_req");
+ status = QDF_STATUS_E_NOMEM;
+ goto out;
+ }
+
+ ns_offload_req = qdf_mem_malloc(sizeof(*ns_offload_req));
+ if (!ns_offload_req) {
+ pmo_err("unable to allocate ns_offload_req");
+ status = QDF_STATUS_E_NOMEM;
+ goto out;
+ }
+
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ qdf_mem_copy(arp_offload_req, &vdev_ctx->vdev_arp_req,
+ sizeof(*arp_offload_req));
+ qdf_mem_copy(ns_offload_req, &vdev_ctx->vdev_ns_req,
+ sizeof(*ns_offload_req));
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ pmo_debug("ARP Offload vdev_id: %d enable: %d",
+ vdev_id,
+ arp_offload_req->enable);
+ pmo_debug("NS Offload vdev_id: %d enable: %d ns_count: %u",
+ vdev_id,
+ ns_offload_req->enable,
+ ns_offload_req->num_ns_offload_count);
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.send_arp_offload_req) {
+ pmo_err("send_arp_offload_req is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+ status = pmo_tx_ops.send_arp_offload_req(
+ vdev, arp_offload_req, ns_offload_req);
+ if (status != QDF_STATUS_SUCCESS)
+ pmo_err("Failed to send ARP offload");
+
+out:
+ if (arp_offload_req)
+ qdf_mem_free(arp_offload_req);
+ if (ns_offload_req)
+ qdf_mem_free(ns_offload_req);
+ PMO_EXIT();
+
+ return status;
+}
+
diff --git a/components/pmo/dispatcher/src/wlan_pmo_tgt_gtk.c b/components/pmo/dispatcher/src/wlan_pmo_tgt_gtk.c
new file mode 100644
index 0000000..8f38278
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_gtk.c
@@ -0,0 +1,178 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Implements public API for PMO GTK offload feature to interact
+ * with target/wmi.
+ */
+
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_gtk_public_struct.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include "wlan_pmo_main.h"
+
+QDF_STATUS pmo_tgt_send_gtk_offload_req(struct wlan_objmgr_vdev *vdev,
+ struct pmo_gtk_req *gtk_req)
+{
+ struct pmo_gtk_req *op_gtk_req = NULL;
+ QDF_STATUS status;
+ struct wlan_objmgr_psoc *psoc;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ PMO_ENTER();
+ psoc = wlan_vdev_get_psoc(vdev);
+ if (!psoc) {
+ pmo_err("Failed to find psoc from from vdev:%p",
+ vdev);
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.send_gtk_offload_req) {
+ pmo_err("send_gtk_offload_req is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ op_gtk_req = qdf_mem_malloc(sizeof(*op_gtk_req));
+ if (!op_gtk_req) {
+ pmo_err("cannot allocate op_gtk_req ");
+ status = QDF_STATUS_E_NOMEM;
+ goto out;
+ }
+
+ if (gtk_req->flags == PMO_GTK_OFFLOAD_ENABLE) {
+ qdf_atomic_set(&vdev_ctx->gtk_err_enable, true);
+ qdf_mem_copy(op_gtk_req->kck, gtk_req->kck,
+ PMO_KCK_LEN);
+ qdf_mem_copy(op_gtk_req->kek, gtk_req->kek,
+ PMO_KEK_LEN);
+ qdf_mem_copy(&op_gtk_req->replay_counter,
+ >k_req->replay_counter, PMO_REPLAY_COUNTER_LEN);
+ } else {
+ qdf_atomic_set(&vdev_ctx->gtk_err_enable, false);
+ }
+
+ pmo_info("replay counter %llu", op_gtk_req->replay_counter);
+ op_gtk_req->flags = gtk_req->flags;
+ status = pmo_tx_ops.send_gtk_offload_req(vdev, op_gtk_req);
+ if (status != QDF_STATUS_SUCCESS)
+ pmo_err("Failed to send gtk offload req event");
+out:
+ if (op_gtk_req)
+ qdf_mem_free(op_gtk_req);
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_tgt_get_gtk_rsp(struct wlan_objmgr_vdev *vdev)
+{
+
+ struct wlan_objmgr_psoc *psoc;
+ QDF_STATUS status;
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ PMO_ENTER();
+ psoc = wlan_vdev_get_psoc(vdev);
+ if (!psoc) {
+ pmo_err("Failed to find psoc from from vdev:%p",
+ vdev);
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.send_get_gtk_rsp_cmd) {
+ pmo_err("send_get_gtk_rsp_cmd is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+ status = pmo_tx_ops.send_get_gtk_rsp_cmd(vdev);
+ if (status != QDF_STATUS_SUCCESS)
+ pmo_err("Failed to send_get_gtk_rsp_cmd event");
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_tgt_gtk_rsp_evt(struct wlan_objmgr_psoc *psoc,
+ struct pmo_gtk_rsp_params *rsp_param)
+{
+ QDF_STATUS status;
+ struct wlan_objmgr_vdev *vdev;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+
+ PMO_ENTER();
+ if (!rsp_param) {
+ pmo_err("gtk rsp param is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ vdev = pmo_psoc_get_vdev(psoc, rsp_param->vdev_id);
+ if (!vdev) {
+ pmo_err("vdev is null vdev_id:%d psoc:%p",
+ rsp_param->vdev_id, psoc);
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ status = pmo_vdev_get_ref(vdev);
+ if (QDF_IS_STATUS_ERROR(status))
+ goto out;
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ status = pmo_get_vdev_bss_peer_mac_addr(vdev, &rsp_param->bssid);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("cannot find peer mac address");
+ goto dec_ref;
+ }
+
+ /* update cached replay counter */
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ vdev_ctx->vdev_gtk_req.replay_counter = rsp_param->replay_counter;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ if (vdev_ctx->vdev_gtk_rsp_req.callback) {
+ pmo_info("callback:%p context:%p psoc:%p vdev_id:%d",
+ vdev_ctx->vdev_gtk_rsp_req.callback,
+ vdev_ctx->vdev_gtk_rsp_req.callback_context,
+ psoc, rsp_param->vdev_id);
+ vdev_ctx->vdev_gtk_rsp_req.callback(
+ vdev_ctx->vdev_gtk_rsp_req.callback_context,
+ rsp_param);
+ } else {
+ pmo_err("gtk rsp callback is null for vdev_id:%d psoc %p",
+ rsp_param->vdev_id,
+ psoc);
+ }
+
+dec_ref:
+ pmo_vdev_put_ref(vdev);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
diff --git a/components/pmo/dispatcher/src/wlan_pmo_tgt_hw_filter.c b/components/pmo/dispatcher/src/wlan_pmo_tgt_hw_filter.c
new file mode 100644
index 0000000..1d29826
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_hw_filter.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: Implements public API for pmo to interact with target/WMI
+ */
+
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_hw_filter_public_struct.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include "wlan_pmo_main.h"
+
+QDF_STATUS pmo_tgt_conf_hw_filter(struct wlan_objmgr_psoc *psoc,
+ struct pmo_hw_filter_params *req)
+{
+ QDF_STATUS status;
+ struct wlan_pmo_tx_ops ops;
+
+ PMO_ENTER();
+
+ pmo_debug("Configure hw filter; vdev_id:%u, mode:%d",
+ req->vdev_id, req->mode);
+
+ ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!ops.send_conf_hw_filter_req) {
+ pmo_err("send_conf_hw_filter_req is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto exit_with_status;
+ }
+
+ status = ops.send_conf_hw_filter_req(psoc, req);
+
+exit_with_status:
+ PMO_EXIT();
+
+ return status;
+}
+
diff --git a/components/pmo/dispatcher/src/wlan_pmo_tgt_lphb.c b/components/pmo/dispatcher/src/wlan_pmo_tgt_lphb.c
new file mode 100644
index 0000000..5dce758
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_lphb.c
@@ -0,0 +1,155 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Implements public API for pmo low power hear beat feature
+ * to interact with target/WMI.
+ */
+
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_lphb_public_struct.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include "wlan_pmo_main.h"
+
+QDF_STATUS pmo_tgt_send_lphb_enable(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_enable_req *ts_lphb_enable)
+{
+ QDF_STATUS status;
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ PMO_ENTER();
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.send_lphb_enable) {
+ pmo_err("send_lphb_enable is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+ status = pmo_tx_ops.send_lphb_enable(psoc, ts_lphb_enable);
+ if (status != QDF_STATUS_SUCCESS)
+ pmo_err("Failed to send lphb enable");
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_tgt_send_lphb_tcp_params(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_tcp_params *ts_lphb_tcp_param)
+{
+ QDF_STATUS status;
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ PMO_ENTER();
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.send_lphb_tcp_params) {
+ pmo_err("send_lphb_tcp_params is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+ status = pmo_tx_ops.send_lphb_tcp_params(psoc, ts_lphb_tcp_param);
+ if (status != QDF_STATUS_SUCCESS)
+ pmo_err("Failed to send lphb tcp params");
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_tgt_send_lphb_tcp_pkt_filter(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_tcp_filter_req *ts_lphb_tcp_filter)
+{
+ QDF_STATUS status;
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ PMO_ENTER();
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.send_lphb_tcp_filter_req) {
+ pmo_err("send_lphb_tcp_filter_req is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+ status = pmo_tx_ops.send_lphb_tcp_filter_req(psoc, ts_lphb_tcp_filter);
+ if (status != QDF_STATUS_SUCCESS)
+ pmo_err("Failed to send lphb tcp filter req");
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_tgt_send_lphb_udp_params(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_udp_params *ts_lphb_udp_param)
+{
+ QDF_STATUS status;
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ PMO_ENTER();
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.send_lphb_upd_params) {
+ pmo_err("send_lphb_upd_params is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+ status = pmo_tx_ops.send_lphb_upd_params(psoc, ts_lphb_udp_param);
+ if (status != QDF_STATUS_SUCCESS)
+ pmo_err("Failed to send lphb udp param");
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_tgt_send_lphb_udp_pkt_filter(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_udp_filter_req *ts_lphb_udp_filter)
+{
+ QDF_STATUS status;
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ PMO_ENTER();
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.send_lphb_udp_filter_req) {
+ pmo_err("send_lphb_udp_filter_req is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+ status = pmo_tx_ops.send_lphb_udp_filter_req(psoc, ts_lphb_udp_filter);
+ if (status != QDF_STATUS_SUCCESS)
+ pmo_err("Failed to send lphb udp filter req");
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_tgt_lphb_rsp_evt(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_rsp *rsp_param)
+{
+ struct pmo_psoc_priv_obj *psoc_ctx;
+
+ psoc_ctx = pmo_psoc_get_priv(psoc);
+ if (psoc_ctx->wow.lphb_cb && psoc_ctx->wow.lphb_cb_ctx) {
+ pmo_info("callback:%p context:%p psoc:%p",
+ psoc_ctx->wow.lphb_cb, psoc_ctx->wow.lphb_cb_ctx, psoc);
+ psoc_ctx->wow.lphb_cb(psoc_ctx->wow.lphb_cb_ctx, rsp_param);
+ } else {
+ pmo_err("lphb rsp callback/context is null for psoc %p",
+ psoc);
+ }
+
+ return QDF_STATUS_SUCCESS;
+}
+
diff --git a/components/pmo/dispatcher/src/wlan_pmo_tgt_mc_addr_filtering.c b/components/pmo/dispatcher/src/wlan_pmo_tgt_mc_addr_filtering.c
new file mode 100644
index 0000000..9cc0563
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_mc_addr_filtering.c
@@ -0,0 +1,83 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Implements public API for pmo to interact with target/WMI
+ */
+
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_mc_addr_filtering_public_struct.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include "wlan_pmo_main.h"
+
+QDF_STATUS pmo_tgt_set_mc_filter_req(struct wlan_objmgr_vdev *vdev,
+ struct qdf_mac_addr multicast_addr)
+{
+ QDF_STATUS status;
+ struct wlan_objmgr_psoc *psoc;
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ PMO_ENTER();
+
+ psoc = pmo_vdev_get_psoc(vdev);
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.send_set_mc_filter_req) {
+ pmo_err("send_add_clear_mcbc_filter_request is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ status = pmo_tx_ops.send_set_mc_filter_req(
+ vdev, multicast_addr);
+ if (status != QDF_STATUS_SUCCESS)
+ pmo_err("Failed to add/clear mc filter");
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_tgt_clear_mc_filter_req(struct wlan_objmgr_vdev *vdev,
+ struct qdf_mac_addr multicast_addr)
+{
+ QDF_STATUS status;
+ struct wlan_objmgr_psoc *psoc;
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ PMO_ENTER();
+
+ psoc = pmo_vdev_get_psoc(vdev);
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.send_clear_mc_filter_req) {
+ pmo_err("send_add_clear_mcbc_filter_request is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ status = pmo_tx_ops.send_clear_mc_filter_req(
+ vdev, multicast_addr);
+ if (status != QDF_STATUS_SUCCESS)
+ pmo_err("Failed to add/clear mc filter");
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+
diff --git a/components/pmo/dispatcher/src/wlan_pmo_tgt_ns.c b/components/pmo/dispatcher/src/wlan_pmo_tgt_ns.c
new file mode 100644
index 0000000..9757cad
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_ns.c
@@ -0,0 +1,159 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Implements public API for PMO NS offload feature to interact
+ * with target/wmi.
+ */
+
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_arp_public_struct.h"
+#include "wlan_pmo_ns_public_struct.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include "wlan_pmo_main.h"
+
+QDF_STATUS pmo_tgt_enable_ns_offload_req(struct wlan_objmgr_vdev *vdev,
+ uint8_t vdev_id)
+{
+ struct pmo_arp_offload_params *arp_offload_req = NULL;
+ struct pmo_ns_offload_params *ns_offload_req = NULL;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+ struct wlan_objmgr_psoc *psoc;
+ QDF_STATUS status;
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ PMO_ENTER();
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ psoc = pmo_vdev_get_psoc(vdev);
+
+ arp_offload_req = qdf_mem_malloc(sizeof(*arp_offload_req));
+ if (!arp_offload_req) {
+ pmo_err("unable to allocate arp_offload_req");
+ status = QDF_STATUS_E_NOMEM;
+ goto out;
+ }
+
+ ns_offload_req = qdf_mem_malloc(sizeof(*ns_offload_req));
+ if (!ns_offload_req) {
+ pmo_err("unable to allocate ns_offload_req");
+ status = QDF_STATUS_E_NOMEM;
+ goto out;
+ }
+
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ qdf_mem_copy(arp_offload_req, &vdev_ctx->vdev_arp_req,
+ sizeof(*arp_offload_req));
+ qdf_mem_copy(ns_offload_req, &vdev_ctx->vdev_ns_req,
+ sizeof(*ns_offload_req));
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ pmo_debug("ARP Offload vdev_id: %d enable: %d",
+ vdev_id,
+ arp_offload_req->enable);
+ pmo_debug("NS Offload vdev_id: %d enable: %d ns_count: %u",
+ vdev_id,
+ ns_offload_req->enable,
+ ns_offload_req->num_ns_offload_count);
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.send_ns_offload_req) {
+ pmo_err("send_ns_offload_req is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+ status = pmo_tx_ops.send_ns_offload_req(
+ vdev, arp_offload_req, ns_offload_req);
+ if (status != QDF_STATUS_SUCCESS)
+ pmo_err("Failed to send NS offload");
+
+out:
+ if (arp_offload_req)
+ qdf_mem_free(arp_offload_req);
+ if (ns_offload_req)
+ qdf_mem_free(ns_offload_req);
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_tgt_disable_ns_offload_req(struct wlan_objmgr_vdev *vdev,
+ uint8_t vdev_id)
+{
+ struct pmo_arp_offload_params *arp_offload_req = NULL;
+ struct pmo_ns_offload_params *ns_offload_req = NULL;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+ struct wlan_objmgr_psoc *psoc;
+ QDF_STATUS status;
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ PMO_ENTER();
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ psoc = pmo_vdev_get_psoc(vdev);
+
+ arp_offload_req = qdf_mem_malloc(sizeof(*arp_offload_req));
+ if (!arp_offload_req) {
+ pmo_err("unable to allocate arp_offload_req");
+ status = QDF_STATUS_E_NOMEM;
+ goto out;
+ }
+
+ ns_offload_req = qdf_mem_malloc(sizeof(*ns_offload_req));
+ if (!ns_offload_req) {
+ pmo_err("unable to allocate ns_offload_req");
+ status = QDF_STATUS_E_NOMEM;
+ goto out;
+ }
+
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ qdf_mem_copy(arp_offload_req, &vdev_ctx->vdev_arp_req,
+ sizeof(*arp_offload_req));
+ qdf_mem_copy(ns_offload_req, &vdev_ctx->vdev_ns_req,
+ sizeof(*ns_offload_req));
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ pmo_debug("ARP Offload vdev_id: %d enable: %d",
+ vdev_id,
+ arp_offload_req->enable);
+ pmo_debug("NS Offload vdev_id: %d enable: %d ns_count: %u",
+ vdev_id,
+ ns_offload_req->enable,
+ ns_offload_req->num_ns_offload_count);
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.send_ns_offload_req) {
+ pmo_err("send_ns_offload_req is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+ status = pmo_tx_ops.send_ns_offload_req(
+ vdev, arp_offload_req, ns_offload_req);
+ if (status != QDF_STATUS_SUCCESS)
+ pmo_err("Failed to send NS offload");
+
+out:
+ if (arp_offload_req)
+ qdf_mem_free(arp_offload_req);
+ if (ns_offload_req)
+ qdf_mem_free(ns_offload_req);
+ PMO_EXIT();
+
+ return status;
+}
+
diff --git a/components/pmo/dispatcher/src/wlan_pmo_tgt_pkt_filter.c b/components/pmo/dispatcher/src/wlan_pmo_tgt_pkt_filter.c
new file mode 100644
index 0000000..6b46ede
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_pkt_filter.c
@@ -0,0 +1,156 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Implements public API for pmo to interact with target/WMI
+ */
+
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_pkt_filter_public_struct.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include "wlan_pmo_main.h"
+
+QDF_STATUS pmo_tgt_set_pkt_filter(struct wlan_objmgr_vdev *vdev,
+ struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req,
+ uint8_t vdev_id)
+{
+ QDF_STATUS status;
+ struct pmo_rcv_pkt_fltr_cfg *request_buf = NULL;
+ struct wlan_objmgr_psoc *psoc;
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+ struct qdf_mac_addr peer_bssid;
+
+ PMO_ENTER();
+
+ psoc = wlan_vdev_get_psoc(vdev);
+ if (!psoc) {
+ pmo_err("psoc unavailable for vdev %p", vdev);
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ pmo_info("filter_type=%d, filter_id = %d",
+ pmo_set_pkt_fltr_req->filter_type,
+ pmo_set_pkt_fltr_req->filter_id);
+
+ request_buf = qdf_mem_malloc(sizeof(*request_buf));
+
+ if (request_buf == NULL) {
+ pmo_err("Not able to allocate memory for Receive Filter Set Filter request");
+ status = QDF_STATUS_E_NOMEM;
+ goto out;
+ }
+
+ status = pmo_get_vdev_bss_peer_mac_addr(vdev,
+ &peer_bssid);
+ if (status != QDF_STATUS_SUCCESS) {
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ qdf_mem_copy(request_buf, pmo_set_pkt_fltr_req, sizeof(*request_buf));
+
+ qdf_mem_copy(&request_buf->self_macaddr.bytes,
+ wlan_vdev_mlme_get_macaddr(vdev),
+ QDF_MAC_ADDR_SIZE);
+
+ qdf_copy_macaddr(&pmo_set_pkt_fltr_req->bssid,
+ &peer_bssid);
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.send_set_pkt_filter) {
+ pmo_err("send_set_pkt_filter is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ status = pmo_tx_ops.send_set_pkt_filter(vdev, request_buf);
+ if (status != QDF_STATUS_SUCCESS)
+ goto out;
+
+out:
+ if (request_buf)
+ qdf_mem_free(request_buf);
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_tgt_clear_pkt_filter(struct wlan_objmgr_vdev *vdev,
+ struct pmo_rcv_pkt_fltr_clear_param *pmo_clr_pkt_fltr_param,
+ uint8_t vdev_id)
+{
+ QDF_STATUS status;
+ struct pmo_rcv_pkt_fltr_clear_param *request_buf = NULL;
+ struct wlan_objmgr_psoc *psoc;
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+ struct qdf_mac_addr peer_bssid;
+
+ PMO_ENTER();
+
+ psoc = wlan_vdev_get_psoc(vdev);
+ if (!psoc) {
+ pmo_err("psoc unavailable for vdev %p", vdev);
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ pmo_info("filter_id = %d", pmo_clr_pkt_fltr_param->filter_id);
+
+ request_buf = qdf_mem_malloc(sizeof(*request_buf));
+
+ if (request_buf == NULL) {
+ pmo_err("Not able to allocate memory for Receive Filter Set Filter request");
+ status = QDF_STATUS_E_NOMEM;
+ goto out;
+ }
+
+ status = pmo_get_vdev_bss_peer_mac_addr(vdev,
+ &peer_bssid);
+ if (status != QDF_STATUS_SUCCESS) {
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ qdf_mem_copy(request_buf, pmo_clr_pkt_fltr_param, sizeof(*request_buf));
+
+ qdf_mem_copy(&request_buf->self_macaddr.bytes,
+ wlan_vdev_mlme_get_macaddr(vdev),
+ QDF_MAC_ADDR_SIZE);
+
+ qdf_copy_macaddr(&pmo_clr_pkt_fltr_param->bssid,
+ &peer_bssid);
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.send_clear_pkt_filter) {
+ pmo_err("send_clear_pkt_filter is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ status = pmo_tx_ops.send_clear_pkt_filter(vdev, request_buf);
+ if (status != QDF_STATUS_SUCCESS)
+ goto out;
+
+out:
+ if (request_buf)
+ qdf_mem_free(request_buf);
+ PMO_EXIT();
+
+ return status;
+}
+
diff --git a/components/pmo/dispatcher/src/wlan_pmo_tgt_static_config.c b/components/pmo/dispatcher/src/wlan_pmo_tgt_static_config.c
new file mode 100644
index 0000000..bd322f9
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_static_config.c
@@ -0,0 +1,127 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Implements public API for pmo to interact with target/WMI
+ */
+
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_wow.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include "wlan_pmo_main.h"
+
+QDF_STATUS pmo_tgt_send_enhance_multicast_offload_req(
+ struct wlan_objmgr_vdev *vdev,
+ uint8_t vdev_id,
+ uint8_t action)
+{
+ QDF_STATUS status;
+ struct wlan_objmgr_psoc *psoc;
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ PMO_ENTER();
+ psoc = pmo_vdev_get_psoc(vdev);
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.send_enhance_mc_offload_req) {
+ pmo_err("send_enhance_multicast_offload is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ status = pmo_tx_ops.send_enhance_mc_offload_req(vdev, action);
+ if (status != QDF_STATUS_SUCCESS)
+ pmo_err("Failed to config enhance multicast offload");
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_tgt_send_ra_filter_req(struct wlan_objmgr_vdev *vdev)
+{
+
+ QDF_STATUS status;
+ uint8_t default_pattern;
+ uint16_t ra_interval;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+ uint8_t vdev_id;
+ struct wlan_objmgr_psoc *psoc;
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ PMO_ENTER();
+
+ psoc = pmo_vdev_get_psoc(vdev);
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ vdev_id = pmo_vdev_get_id(vdev);
+ qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
+ ra_interval = vdev_ctx->pmo_psoc_ctx->psoc_cfg.ra_ratelimit_interval;
+ qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
+
+ pmo_debug("send RA rate limit [%d] to fw vdev = %d",
+ ra_interval, vdev_id);
+
+ default_pattern = pmo_get_and_increment_wow_default_ptrn(vdev_ctx);
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.send_ra_filter_req) {
+ pmo_err("send_ra_filter_cmd is null");
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ status = pmo_tx_ops.send_ra_filter_req(
+ vdev, default_pattern, ra_interval);
+ if (status != QDF_STATUS_SUCCESS) {
+ pmo_err("Failed to send RA rate limit to fw");
+ pmo_decrement_wow_default_ptrn(vdev_ctx);
+ }
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_tgt_send_action_frame_pattern_req(
+ struct wlan_objmgr_vdev *vdev,
+ struct pmo_action_wakeup_set_params *cmd)
+{
+ QDF_STATUS status;
+ struct wlan_objmgr_psoc *psoc;
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ PMO_ENTER();
+
+ psoc = pmo_vdev_get_psoc(vdev);
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.send_action_frame_pattern_req) {
+ pmo_err("send_add_action_frame_pattern_cmd is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ status = pmo_tx_ops.send_action_frame_pattern_req(vdev, cmd);
+ if (status != QDF_STATUS_SUCCESS)
+ pmo_err("Failed to add filter");
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
diff --git a/components/pmo/dispatcher/src/wlan_pmo_tgt_suspend_resume.c b/components/pmo/dispatcher/src/wlan_pmo_tgt_suspend_resume.c
new file mode 100644
index 0000000..13e89c5
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_suspend_resume.c
@@ -0,0 +1,215 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Implements public API for pmo to interact with target/WMI
+ */
+
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_wow.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include "wlan_pmo_main.h"
+
+QDF_STATUS pmo_tgt_vdev_update_param_req(struct wlan_objmgr_vdev *vdev,
+ enum pmo_vdev_param_id param_id, uint32_t param_value)
+{
+ QDF_STATUS status;
+ struct wlan_objmgr_psoc *psoc;
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ PMO_ENTER();
+
+ psoc = pmo_vdev_get_psoc(vdev);
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.send_vdev_param_update_req) {
+ pmo_err("send_vdev_param_update_req is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ status = pmo_tx_ops.send_vdev_param_update_req(vdev, param_id,
+ param_value);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_tgt_send_vdev_sta_ps_param(struct wlan_objmgr_vdev *vdev,
+ enum pmo_sta_powersave_param ps_param, uint32_t param_value)
+{
+ QDF_STATUS status;
+ struct wlan_objmgr_psoc *psoc;
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ PMO_ENTER();
+
+ psoc = pmo_vdev_get_psoc(vdev);
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.send_vdev_sta_ps_param_req) {
+ pmo_err("send_vdev_param_set_req is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ status = pmo_tx_ops.send_vdev_sta_ps_param_req(vdev, ps_param,
+ param_value);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+void pmo_tgt_psoc_update_wow_bus_suspend_state(struct wlan_objmgr_psoc *psoc,
+ uint8_t val)
+{
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.psoc_update_wow_bus_suspend) {
+ pmo_err("psoc_update_wow_bus_suspend is null");
+ return;
+ }
+ pmo_tx_ops.psoc_update_wow_bus_suspend(psoc, val);
+}
+
+int pmo_tgt_psoc_get_host_credits(struct wlan_objmgr_psoc *psoc)
+{
+
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.psoc_get_host_credits) {
+ pmo_err("psoc_get_host_credits is null");
+ return 0;
+ }
+
+ return pmo_tx_ops.psoc_get_host_credits(psoc);
+}
+
+int pmo_tgt_psoc_get_pending_cmnds(struct wlan_objmgr_psoc *psoc)
+{
+
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.psoc_get_pending_cmnds) {
+ pmo_err("psoc_get_pending_cmnds is null");
+ return -EAGAIN;
+ }
+
+ return pmo_tx_ops.psoc_get_pending_cmnds(psoc);
+}
+
+void pmo_tgt_update_target_suspend_flag(struct wlan_objmgr_psoc *psoc,
+ uint8_t val)
+{
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.update_target_suspend_flag) {
+ pmo_err("update_target_suspend_flag is null");
+ return;
+ }
+ pmo_tx_ops.update_target_suspend_flag(psoc, val);
+}
+
+QDF_STATUS pmo_tgt_psoc_send_wow_enable_req(struct wlan_objmgr_psoc *psoc,
+ struct pmo_wow_cmd_params *param)
+{
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.psoc_send_wow_enable_req) {
+ pmo_err("psoc_send_wow_enable_req is null");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ return pmo_tx_ops.psoc_send_wow_enable_req(psoc, param);
+}
+
+QDF_STATUS pmo_tgt_psoc_send_supend_req(struct wlan_objmgr_psoc *psoc,
+ struct pmo_suspend_params *param)
+{
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.psoc_send_supend_req) {
+ pmo_err("psoc_send_supend_req is null");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ return pmo_tx_ops.psoc_send_supend_req(psoc, param);
+}
+
+QDF_STATUS pmo_tgt_psoc_set_runtime_pm_inprogress(struct wlan_objmgr_psoc *psoc,
+ bool value)
+{
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.psoc_set_runtime_pm_in_progress) {
+ pmo_err("pmo ops is null");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ pmo_tx_ops.psoc_set_runtime_pm_in_progress(psoc, value);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+bool pmo_tgt_psoc_get_runtime_pm_in_progress(struct wlan_objmgr_psoc *psoc)
+{
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.psoc_get_runtime_pm_in_progress) {
+ pmo_err("psoc_get_runtime_pm_in_progress is null");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ return pmo_tx_ops.psoc_get_runtime_pm_in_progress(psoc);
+}
+
+QDF_STATUS pmo_tgt_psoc_send_host_wakeup_ind(struct wlan_objmgr_psoc *psoc)
+{
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.psoc_send_host_wakeup_ind) {
+ pmo_err("psoc_send_host_wakeup_ind is null");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ return pmo_tx_ops.psoc_send_host_wakeup_ind(psoc);
+}
+
+QDF_STATUS pmo_tgt_psoc_send_target_resume_req(struct wlan_objmgr_psoc *psoc)
+{
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.psoc_send_target_resume_req) {
+ pmo_err("send_target_resume_req is null");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ return pmo_tx_ops.psoc_send_target_resume_req(psoc);
+}
+
diff --git a/components/pmo/dispatcher/src/wlan_pmo_tgt_wow.c b/components/pmo/dispatcher/src/wlan_pmo_tgt_wow.c
new file mode 100644
index 0000000..c3e9826
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_tgt_wow.c
@@ -0,0 +1,121 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: Implements public API for pmo to interact with target/WMI
+ */
+
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_wow.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+#include "wlan_pmo_main.h"
+
+QDF_STATUS pmo_tgt_enable_wow_wakeup_event(
+ struct wlan_objmgr_vdev *vdev,
+ uint32_t *bitmap)
+{
+ QDF_STATUS status;
+ struct wlan_objmgr_psoc *psoc;
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ PMO_ENTER();
+
+ psoc = pmo_vdev_get_psoc(vdev);
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.send_enable_wow_wakeup_event_req) {
+ pmo_err("send_enable_wow_wakeup_event_req is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+ status = pmo_tx_ops.send_enable_wow_wakeup_event_req(vdev, bitmap);
+ if (status != QDF_STATUS_SUCCESS)
+ pmo_err("Failed to enable wow wakeup event");
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_tgt_disable_wow_wakeup_event(
+ struct wlan_objmgr_vdev *vdev,
+ uint32_t *bitmap)
+{
+ QDF_STATUS status;
+ struct wlan_objmgr_psoc *psoc;
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ PMO_ENTER();
+
+ psoc = pmo_vdev_get_psoc(vdev);
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.send_disable_wow_wakeup_event_req) {
+ pmo_err("send_disable_wow_wakeup_event_req is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+ status = pmo_tx_ops.send_disable_wow_wakeup_event_req(vdev, bitmap);
+ if (status != QDF_STATUS_SUCCESS)
+ pmo_err("Failed to disable wow wakeup event");
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
+QDF_STATUS pmo_tgt_send_wow_patterns_to_fw(
+ struct wlan_objmgr_vdev *vdev, uint8_t ptrn_id,
+ const uint8_t *ptrn, uint8_t ptrn_len,
+ uint8_t ptrn_offset, const uint8_t *mask,
+ uint8_t mask_len, bool user)
+{
+ QDF_STATUS status;
+ struct pmo_vdev_priv_obj *vdev_ctx;
+ struct wlan_objmgr_psoc *psoc;
+ struct wlan_pmo_tx_ops pmo_tx_ops;
+
+ PMO_ENTER();
+ psoc = pmo_vdev_get_psoc(vdev);
+
+ vdev_ctx = pmo_vdev_get_priv(vdev);
+
+ pmo_tx_ops = GET_PMO_TX_OPS_FROM_PSOC(psoc);
+ if (!pmo_tx_ops.send_add_wow_pattern) {
+ pmo_err("send_add_wow_pattern is null");
+ status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+ status = pmo_tx_ops.send_add_wow_pattern(
+ vdev, ptrn_id, ptrn,
+ ptrn_len, ptrn_offset, mask,
+ mask_len, user);
+ if (status != QDF_STATUS_SUCCESS) {
+ if (!user)
+ pmo_decrement_wow_default_ptrn(vdev_ctx);
+ pmo_err("Failed to sen wow pattern event");
+ goto out;
+ }
+
+ if (user)
+ pmo_increment_wow_user_ptrn(vdev_ctx);
+out:
+ PMO_EXIT();
+
+ return status;
+}
+
diff --git a/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c b/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c
new file mode 100644
index 0000000..c1a19cb
--- /dev/null
+++ b/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c
@@ -0,0 +1,342 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+ * DOC: public API related to the pmo called by north bound HDD/OSIF
+ */
+
+#include "wlan_pmo_ucfg_api.h"
+#include "wlan_pmo_arp.h"
+#include "wlan_pmo_ns.h"
+#include "wlan_pmo_gtk.h"
+#include "wlan_pmo_wow.h"
+#include "wlan_pmo_mc_addr_filtering.h"
+#include "wlan_pmo_main.h"
+#include "wlan_pmo_lphb.h"
+#include "wlan_pmo_suspend_resume.h"
+#include "wlan_pmo_pkt_filter.h"
+#include "wlan_pmo_hw_filter.h"
+
+QDF_STATUS pmo_ucfg_get_psoc_config(struct wlan_objmgr_psoc *psoc,
+ struct pmo_psoc_cfg *psoc_cfg)
+{
+ return pmo_core_get_psoc_config(psoc, psoc_cfg);
+}
+
+QDF_STATUS pmo_ucfg_update_psoc_config(struct wlan_objmgr_psoc *psoc,
+ struct pmo_psoc_cfg *psoc_cfg)
+{
+ return pmo_core_update_psoc_config(psoc, psoc_cfg);
+}
+
+bool pmo_ucfg_is_ap_mode_supports_arp_ns(struct wlan_objmgr_psoc *psoc,
+ enum tQDF_ADAPTER_MODE vdev_opmode)
+{
+ return pmo_core_is_ap_mode_supports_arp_ns(psoc, vdev_opmode);
+}
+
+bool pmo_ucfg_is_vdev_connected(struct wlan_objmgr_vdev *vdev)
+{
+ return pmo_core_is_vdev_connected(vdev);
+}
+
+bool pmo_ucfg_is_vdev_supports_offload(struct wlan_objmgr_vdev *vdev)
+{
+ return pmo_core_is_vdev_supports_offload(vdev);
+}
+
+void pmo_ucfg_enable_wakeup_event(struct wlan_objmgr_psoc *psoc,
+ uint32_t vdev_id, uint32_t *bitmap)
+{
+ pmo_core_enable_wakeup_event(psoc, vdev_id, bitmap);
+}
+
+void pmo_ucfg_disable_wakeup_event(struct wlan_objmgr_psoc *psoc,
+ uint32_t vdev_id, uint32_t bitmap)
+{
+ pmo_core_disable_wakeup_event(psoc, vdev_id, &bitmap);
+}
+
+QDF_STATUS pmo_ucfg_cache_arp_offload_req(struct pmo_arp_req *arp_req)
+{
+ return pmo_core_cache_arp_offload_req(arp_req);
+}
+
+QDF_STATUS pmo_ucfg_flush_arp_offload_req(struct wlan_objmgr_vdev *vdev)
+{
+ return pmo_core_flush_arp_offload_req(vdev);
+}
+
+QDF_STATUS pmo_ucfg_enable_arp_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+ enum pmo_offload_trigger trigger)
+{
+ return pmo_core_enable_arp_offload_in_fwr(vdev, trigger);
+}
+
+QDF_STATUS pmo_ucfg_disable_arp_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+ enum pmo_offload_trigger trigger)
+{
+ return pmo_core_disable_arp_offload_in_fwr(vdev, trigger);
+}
+
+QDF_STATUS pmo_ucfg_cache_ns_offload_req(struct pmo_ns_req *ns_req)
+{
+ return pmo_core_cache_ns_offload_req(ns_req);
+}
+
+QDF_STATUS pmo_ucfg_flush_ns_offload_req(struct wlan_objmgr_vdev *vdev)
+{
+ return pmo_core_flush_ns_offload_req(vdev);
+}
+
+QDF_STATUS pmo_ucfg_enable_ns_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+ enum pmo_offload_trigger trigger)
+{
+ return pmo_core_enable_ns_offload_in_fwr(vdev, trigger);
+}
+
+QDF_STATUS pmo_ucfg_disable_ns_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
+ enum pmo_offload_trigger trigger)
+{
+ return pmo_core_disable_ns_offload_in_fwr(vdev, trigger);
+}
+
+QDF_STATUS pmo_ucfg_cache_mc_addr_list(
+ struct pmo_mc_addr_list_params *mc_list_config)
+{
+ return pmo_core_cache_mc_addr_list(mc_list_config);
+}
+
+QDF_STATUS pmo_ucfg_flush_mc_addr_list(struct wlan_objmgr_psoc *psoc,
+ uint8_t vdev_id)
+{
+ return pmo_core_flush_mc_addr_list(psoc, vdev_id);
+}
+
+QDF_STATUS pmo_ucfg_enable_mc_addr_filtering_in_fwr(
+ struct wlan_objmgr_psoc *psoc,
+ uint8_t vdev_id,
+ enum pmo_offload_trigger trigger)
+{
+ return pmo_core_enable_mc_addr_filtering_in_fwr(psoc,
+ vdev_id, trigger);
+}
+
+QDF_STATUS pmo_ucfg_disable_mc_addr_filtering_in_fwr(
+ struct wlan_objmgr_psoc *psoc,
+ uint8_t vdev_id,
+ enum pmo_offload_trigger trigger)
+{
+ return pmo_core_disable_mc_addr_filtering_in_fwr(psoc,
+ vdev_id, trigger);
+}
+
+uint8_t pmo_ucfg_max_mc_addr_supported(struct wlan_objmgr_psoc *psoc)
+{
+ return pmo_core_max_mc_addr_supported(psoc);
+}
+
+QDF_STATUS pmo_ucfg_cache_gtk_offload_req(struct wlan_objmgr_vdev *vdev,
+ struct pmo_gtk_req *gtk_req)
+{
+ return pmo_core_cache_gtk_offload_req(vdev, gtk_req);
+}
+
+QDF_STATUS pmo_ucfg_flush_gtk_offload_req(struct wlan_objmgr_vdev *vdev)
+{
+ return pmo_core_flush_gtk_offload_req(vdev);
+}
+
+QDF_STATUS pmo_ucfg_enable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev)
+{
+ return pmo_core_enable_gtk_offload_in_fwr(vdev);
+}
+
+QDF_STATUS pmo_ucfg_disable_gtk_offload_in_fwr(struct wlan_objmgr_vdev *vdev)
+{
+ return pmo_core_disable_gtk_offload_in_fwr(vdev);
+}
+
+QDF_STATUS pmo_ucfg_set_pkt_filter(struct wlan_objmgr_psoc *psoc,
+ struct pmo_rcv_pkt_fltr_cfg *pmo_set_pkt_fltr_req,
+ uint8_t vdev_id)
+{
+ return pmo_core_set_pkt_filter(psoc, pmo_set_pkt_fltr_req, vdev_id);
+}
+
+QDF_STATUS pmo_ucfg_clear_pkt_filter(struct wlan_objmgr_psoc *psoc,
+ struct pmo_rcv_pkt_fltr_clear_param *pmo_clr_pkt_fltr_param,
+ uint8_t vdev_id)
+{
+ return pmo_core_clear_pkt_filter(psoc,
+ pmo_clr_pkt_fltr_param, vdev_id);
+}
+
+QDF_STATUS pmo_ucfg_get_gtk_rsp(struct wlan_objmgr_vdev *vdev,
+ struct pmo_gtk_rsp_req *gtk_rsp_req)
+{
+ return pmo_core_get_gtk_rsp(vdev, gtk_rsp_req);
+}
+
+void pmo_ucfg_update_extscan_in_progress(struct wlan_objmgr_vdev *vdev,
+ bool value)
+{
+ pmo_core_update_extscan_in_progress(vdev, value);
+}
+
+void pmo_ucfg_update_p2plo_in_progress(struct wlan_objmgr_vdev *vdev,
+ bool value)
+{
+ pmo_core_update_p2plo_in_progress(vdev, value);
+}
+
+QDF_STATUS pmo_ucfg_lphb_config_req(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_req *lphb_req, void *lphb_cb_ctx,
+ pmo_lphb_callback callback)
+{
+ return pmo_core_lphb_config_req(psoc, lphb_req, lphb_cb_ctx, callback);
+}
+
+void pmo_ucfg_update_alt_modulated_dtim_enable(struct wlan_objmgr_vdev *vdev,
+ bool value)
+{
+ pmo_core_update_alt_modulated_dtim_enable(vdev, value);
+}
+
+void pmo_ucfg_psoc_update_power_save_mode(struct wlan_objmgr_psoc *psoc,
+ uint8_t value)
+{
+ pmo_core_psoc_update_power_save_mode(psoc, value);
+}
+
+void pmo_ucfg_psoc_update_dp_handle(struct wlan_objmgr_psoc *psoc,
+ void *dp_handle)
+{
+ pmo_core_psoc_update_dp_handle(psoc, dp_handle);
+}
+
+void pmo_ucfg_vdev_update_dp_handle(struct wlan_objmgr_vdev *vdev,
+ void *dp_handle)
+{
+ pmo_core_vdev_update_dp_handle(vdev, dp_handle);
+}
+
+void pmo_ucfg_psoc_update_htc_handle(struct wlan_objmgr_psoc *psoc,
+ void *htc_handle)
+{
+ pmo_core_psoc_update_htc_handle(psoc, htc_handle);
+}
+
+void pmo_ucfg_psoc_set_hif_handle(struct wlan_objmgr_psoc *psoc,
+ void *hif_handle)
+{
+ pmo_core_psoc_set_hif_handle(psoc, hif_handle);
+}
+
+void pmo_ucfg_psoc_set_txrx_handle(struct wlan_objmgr_psoc *psoc,
+ void *txrx_handle)
+{
+ pmo_core_psoc_set_txrx_handle(psoc, txrx_handle);
+}
+
+void pmo_ucfg_psoc_handle_initial_wake_up(void *cb_ctx)
+{
+ return pmo_core_psoc_handle_initial_wake_up(cb_ctx);
+}
+
+QDF_STATUS pmo_ucfg_psoc_user_space_suspend_req(struct wlan_objmgr_psoc *psoc,
+ enum qdf_suspend_type type)
+{
+ return pmo_core_psoc_user_space_suspend_req(psoc, type);
+}
+
+
+QDF_STATUS pmo_ucfg_psoc_user_space_resume_req(struct wlan_objmgr_psoc *psoc,
+ enum qdf_suspend_type type)
+{
+ return pmo_core_psoc_user_space_resume_req(psoc, type);
+}
+
+QDF_STATUS pmo_ucfg_psoc_bus_suspend_req(struct wlan_objmgr_psoc *psoc,
+ enum qdf_suspend_type type,
+ struct pmo_wow_enable_params *wow_params)
+{
+ return pmo_core_psoc_bus_suspend_req(psoc, type, wow_params);
+}
+
+#ifdef FEATURE_RUNTIME_PM
+QDF_STATUS pmo_ucfg_psoc_bus_runtime_suspend(struct wlan_objmgr_psoc *psoc,
+ pmo_pld_auto_suspend_cb pld_cb)
+{
+ return pmo_core_psoc_bus_runtime_suspend(psoc, pld_cb);
+}
+
+QDF_STATUS pmo_ucfg_psoc_bus_runtime_resume(struct wlan_objmgr_psoc *psoc,
+ pmo_pld_auto_suspend_cb pld_cb)
+{
+ return pmo_core_psoc_bus_runtime_resume(psoc, pld_cb);
+}
+#endif
+
+QDF_STATUS pmo_ucfg_psoc_suspend_target(struct wlan_objmgr_psoc *psoc,
+ int disable_target_intr)
+{
+ return pmo_core_psoc_suspend_target(psoc, disable_target_intr);
+}
+
+QDF_STATUS pmo_ucfg_psoc_bus_resume_req(struct wlan_objmgr_psoc *psoc,
+ enum qdf_suspend_type type)
+{
+ return pmo_core_psoc_bus_resume_req(psoc, type);
+}
+
+bool pmo_ucfg_get_wow_bus_suspend(struct wlan_objmgr_psoc *psoc)
+{
+ return pmo_core_get_wow_bus_suspend(psoc);
+}
+
+int pmo_ucfg_psoc_is_target_wake_up_received(struct wlan_objmgr_psoc *psoc)
+{
+ return pmo_core_psoc_is_target_wake_up_received(psoc);
+}
+
+int pmo_ucfg_psoc_clear_target_wake_up(struct wlan_objmgr_psoc *psoc)
+{
+ return pmo_core_psoc_clear_target_wake_up(psoc);
+}
+
+void pmo_ucfg_psoc_target_suspend_acknowledge(void *context, bool wow_nack)
+{
+ pmo_core_psoc_target_suspend_acknowledge(context, wow_nack);
+}
+
+void pmo_ucfg_psoc_wakeup_host_event_received(struct wlan_objmgr_psoc *psoc)
+{
+ pmo_core_psoc_wakeup_host_event_received(psoc);
+}
+
+QDF_STATUS pmo_ucfg_enable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev)
+{
+ return pmo_core_enable_hw_filter_in_fwr(vdev);
+}
+
+QDF_STATUS pmo_ucfg_disable_hw_filter_in_fwr(struct wlan_objmgr_vdev *vdev)
+{
+ return pmo_core_disable_hw_filter_in_fwr(vdev);
+}
+
+
diff --git a/components/target_if/pmo/inc/target_if_pmo.h b/components/target_if/pmo/inc/target_if_pmo.h
new file mode 100644
index 0000000..cb3bea6
--- /dev/null
+++ b/components/target_if/pmo/inc/target_if_pmo.h
@@ -0,0 +1,407 @@
+/*
+* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+*
+* Permission to use, copy, modify, and/or distribute this software for
+* any purpose with or without fee is hereby granted, provided that the
+* above copyright notice and this permission notice appear in all
+* copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+* PERFORMANCE OF THIS SOFTWARE.
+*/
+/**
+* DOC: Declare various api/struct which shall be used
+* by pmo component for wmi cmd (tx path) and
+* event (rx) handling.
+*/
+
+#ifndef _TARGET_IF_PMO_H_
+#define _TARGET_IF_PMO_H_
+
+#include "target_if.h"
+#include "wlan_pmo_tgt_api.h"
+#include "wlan_pmo_obj_mgmt_public_struct.h"
+
+/**
+ * target_if_pmo_enable_wow_wakeup_event() - Enable wow wakeup events.
+ * @vdev:objmgr vdev handle
+ * @bitmap: Event bitmap
+ * @enable: enable/disable
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_enable_wow_wakeup_event(struct wlan_objmgr_vdev *vdev,
+ uint32_t *bitmap);
+
+/**
+ * target_if_pmo_disable_wow_wakeup_event() - Disable wow wakeup events.
+ * @vdev:objmgr vdev handle
+ * @bitmap: Event bitmap
+ * @enable: enable/disable
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_disable_wow_wakeup_event(
+ struct wlan_objmgr_vdev *vdev, uint32_t *bitmap);
+
+/**
+ * target_if_pmo_send_wow_patterns_to_fw() - Sends WOW patterns to FW.
+ * @vdev: objmgr vdev handle
+ * @ptrn_id: pattern id
+ * @ptrn: pattern
+ * @ptrn_len: pattern length
+ * @ptrn_offset: pattern offset
+ * @mask: mask
+ * @mask_len: mask length
+ * @user: true for user configured pattern and false for default pattern
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_send_wow_patterns_to_fw(struct wlan_objmgr_vdev *vdev,
+ uint8_t ptrn_id,
+ const uint8_t *ptrn, uint8_t ptrn_len,
+ uint8_t ptrn_offset, const uint8_t *mask,
+ uint8_t mask_len, bool user);
+
+/**
+ * target_if_pmo_send_enhance_mc_offload_req() - send enhance mc offload req
+ * @vdev: objmgr vdev
+ * @action: enable or disable enhance multicast offload
+ *
+ * Return: QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS target_if_pmo_send_enhance_mc_offload_req(
+ struct wlan_objmgr_vdev *vdev,
+ bool enable);
+
+/**
+ * target_if_pmo_set_mc_filter_req() - set mcast filter command to fw
+ * @vdev: objmgr vdev handle
+ * @multicastAddr: mcast address
+ *
+ * Return: 0 for success or error code
+ */
+QDF_STATUS target_if_pmo_set_mc_filter_req(struct wlan_objmgr_vdev *vdev,
+ struct qdf_mac_addr multicast_addr);
+
+/**
+ * target_if_pmo_clear_mc_filter_req() - clear mcast filter command to fw
+ * @vdev: objmgr vdev handle
+ * @multicastAddr: mcast address
+ *
+ * Return: 0 for success or error code
+ */
+QDF_STATUS target_if_pmo_clear_mc_filter_req(struct wlan_objmgr_vdev *vdev,
+ struct qdf_mac_addr multicast_addr);
+
+/**
+ * target_if_pmo_send_ra_filter_req() - set RA filter pattern in fw
+ * @vdev: objmgr vdev handle
+ * @default_pattern: default pattern id
+ * @rate_limit_interval: ra rate limit interval
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_send_ra_filter_req(struct wlan_objmgr_vdev *vdev,
+ uint8_t default_pattern, uint16_t rate_limit_interval);
+
+/**
+ * target_if_pmo_send_action_frame_patterns() - register action frame map to fw
+ * @handle: Pointer to wma handle
+ * @vdev_id: VDEV ID
+ *
+ * This is called to push action frames wow patterns from local
+ * cache to firmware.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS target_if_pmo_send_action_frame_patterns(
+ struct wlan_objmgr_vdev *vdev,
+ struct pmo_action_wakeup_set_params *ip_cmd);
+
+/**
+ * target_if_pmo_conf_hw_filter() - configure hardware filter in DTIM mode
+ * @psoc: the psoc containing the vdev to configure
+ * @req: the request parameters
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS target_if_pmo_conf_hw_filter(struct wlan_objmgr_psoc *psoc,
+ struct pmo_hw_filter_params *req);
+
+/**
+ * target_if_pmo_send_pkt_filter_req() - enable packet filter
+ * @vdev: objmgr vdev
+ * @rcv_filter_param: filter params
+ *
+ * This function enable packet filter
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS target_if_pmo_send_pkt_filter_req(struct wlan_objmgr_vdev *vdev,
+ struct pmo_rcv_pkt_fltr_cfg *rcv_filter_param);
+
+/**
+ * target_if_pmo_clear_pkt_filter_req() - disable packet filter
+ * @vdev: objmgr vdev
+ * @rcv_clear_param: filter params
+ *
+ * This function disable packet filter
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS target_if_pmo_clear_pkt_filter_req(struct wlan_objmgr_vdev *vdev,
+ struct pmo_rcv_pkt_fltr_clear_param *rcv_clear_param);
+
+/**
+ * target_if_pmo_send_arp_offload_req() - sends arp request to fwr
+ * @vdev: objmgr vdev
+ * @arp_offload_req: arp offload req
+ * @ns_offload_req: ns offload request
+ *
+ * This functions sends arp request to fwr.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS target_if_pmo_send_arp_offload_req(
+ struct wlan_objmgr_vdev *vdev,
+ struct pmo_arp_offload_params *arp_offload_req,
+ struct pmo_ns_offload_params *ns_offload_req);
+
+/**
+ * target_if_pmo_send_ns_offload_req() - sends ns request to fwr
+ * @vdev: objmgr vdev
+ * @arp_offload_req: arp offload req
+ * @ns_offload_req: ns offload request
+ *
+ * This functions sends ns request to fwr.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS target_if_pmo_send_ns_offload_req(
+ struct wlan_objmgr_vdev *vdev,
+ struct pmo_arp_offload_params *arp_offload_req,
+ struct pmo_ns_offload_params *ns_offload_req);
+
+/**
+ * target_if_pmo_send_gtk_offload_req() - send gtk offload request in fwr
+ * @vdev: objmgr vdev handle
+ * @gtk_offload_req: gtk offload request
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_send_gtk_offload_req(struct wlan_objmgr_vdev *vdev,
+ struct pmo_gtk_req *gtk_offload_req);
+
+/**
+ * target_if_pmo_send_gtk_response_req() - send gtk response request in fwr
+ * @vdev: objmgr vdev handle
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_send_gtk_response_req(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * target_if_pmo_gtk_offload_status_event() - GTK offload status event handler
+ * @scn_handle: scn handle
+ * @event: event buffer
+ * @len: buffer length
+ *
+ * Return: 0 for success or error code
+ */
+int target_if_pmo_gtk_offload_status_event(void *scn_handle,
+ uint8_t *event, uint32_t len);
+
+/**
+ * target_if_pmo_send_lphb_enable() - enable command of LPHB config req
+ * @psoc: objmgr psoc handle
+ * @ts_lphb_enable: lphb enable request which needs to configure in fwr
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_send_lphb_enable(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_enable_req *ts_lphb_enable);
+
+/**
+ * target_if_pmo_send_lphb_tcp_params() - set lphb tcp params config request
+ * @psoc: objmgr psoc handle
+ * @ts_lphb_tcp_param: lphb tcp params which needs to configure in fwr
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_send_lphb_tcp_params(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_tcp_params *ts_lphb_tcp_param);
+
+/**
+ * target_if_pmo_send_lphb_tcp_pkt_filter() - send lphb tcp packet filter req
+ * @psoc: objmgr psoc handle
+ * @ts_lphb_tcp_filter: lphb tcp filter request which needs to configure in fwr
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_send_lphb_tcp_pkt_filter(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_tcp_filter_req *ts_lphb_tcp_filter);
+
+/**
+ * target_if_pmo_send_lphb_udp_params() - Send udp param command of LPHB
+ * @psoc: objmgr psoc handle
+ * @ts_lphb_udp_param: lphb udp params which needs to configure in fwr
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_send_lphb_udp_params(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_udp_params *ts_lphb_udp_param);
+
+/**
+ * target_if_pmo_send_lphb_udp_pkt_filter() - Send lphb udp pkt filter cmd req
+ * @psoc: objmgr psoc handle
+ * @ts_lphb_udp_filter: lphb udp filter request which needs to configure in fwr
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_send_lphb_udp_pkt_filter(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_udp_filter_req *ts_lphb_udp_filter);
+
+/**
+ * target_if_pmo_lphb_evt_handler() - send LPHB indication to os if /HDD
+ * @psoc: objmgr psoc handle
+ * @event: lphb event buffer
+ *
+ * Return: QDF_STATUS_SUCCESS for success else error code
+ */
+QDF_STATUS target_if_pmo_lphb_evt_handler(struct wlan_objmgr_psoc *psoc,
+ uint8_t *event);
+
+/**
+ * target_if_pmo_send_vdev_update_param_req() - Send vdev param value to fwr
+ * @vdev: objmgr vdev
+ * @param_id: tell vdev param id which needs to be updated in fwr
+ * @param_value: vdev parameter value
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_send_vdev_update_param_req(
+ struct wlan_objmgr_vdev *vdev,
+ uint32_t param_id, uint32_t param_value);
+
+/**
+ * target_if_pmo_send_vdev_ps_param_req() - Send vdev ps param value to fwr
+ * @vdev: objmgr vdev
+ * @param_id: tell vdev param id which needs to be updated in fwr
+ * @param_value: vdev parameter value
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_send_vdev_ps_param_req(
+ struct wlan_objmgr_vdev *vdev,
+ uint32_t param_id,
+ uint32_t param_value);
+
+/**
+ * target_if_pmo_psoc_update_bus_suspend() - update wmi bus suspend flag
+ * @psoc: objmgr psoc
+ * @value: bus suspend value
+ *
+ * Return: None
+ */
+void target_if_pmo_psoc_update_bus_suspend(struct wlan_objmgr_psoc *psoc,
+ uint8_t value);
+
+/**
+ * target_if_pmo_psoc_get_host_credits() - get available host credits
+ * @psoc: objmgr psoc
+ *
+ * Return: return host credits
+ */
+int target_if_pmo_psoc_get_host_credits(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * target_if_pmo_psoc_get_pending_cmnds() - get wmi pending commands
+ * @psoc: objmgr psoc
+ *
+ * Return: return wmi pending commands
+ */
+int target_if_pmo_psoc_get_pending_cmnds(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * target_if_pmo_update_target_suspend_flag() - set wmi target suspend flag
+ * @psoc: objmgr psoc
+ * @value: value
+ *
+ * Return: return wmi pending commands
+ */
+void target_if_pmo_update_target_suspend_flag(struct wlan_objmgr_psoc *psoc,
+ uint8_t value);
+
+/**
+ * target_if_pmo_psoc_send_wow_enable_req() -send wow enable request
+ * @psoc: objmgr psoc
+ * @param: wow command params
+ *
+ * Return: return QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS target_if_pmo_psoc_send_wow_enable_req(struct wlan_objmgr_psoc *psoc,
+ struct pmo_wow_cmd_params *param);
+
+/**
+ * target_if_pmo_psoc_send_suspend_req() - fp to send suspend request
+ * @psoc: objmgr psoc
+ * @param: target suspend params
+ *
+ * Return: return QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS target_if_pmo_psoc_send_suspend_req(struct wlan_objmgr_psoc *psoc,
+ struct pmo_suspend_params *param);
+
+/**
+ * target_if_pmo_set_runtime_pm_in_progress() - set runtime pm status
+ * @psoc: objmgr psoc
+ * @value: set runtime pm status
+ *
+ * Return: none
+ */
+void target_if_pmo_set_runtime_pm_in_progress(struct wlan_objmgr_psoc *psoc,
+ bool value);
+
+/**
+ * target_if_pmo_get_runtime_pm_in_progress() - fp to get runtime pm status
+ * @psoc: objmgr psoc
+ *
+ * Return: true if runtime pm in progress else false
+ */
+bool target_if_pmo_get_runtime_pm_in_progress(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * target_if_pmo_psoc_send_host_wakeup_ind() - send host wake ind to fwr
+ * @psoc: objmgr psoc
+ *
+ * Return: return QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS target_if_pmo_psoc_send_host_wakeup_ind(
+ struct wlan_objmgr_psoc *psoc);
+
+/**
+ * target_if_pmo_psoc_send_target_resume_req() -send target resume request
+ * @psoc: objmgr psoc
+ *
+ * Return: return QDF_STATUS_SUCCESS on success else error code
+ */
+QDF_STATUS target_if_pmo_psoc_send_target_resume_req(
+ struct wlan_objmgr_psoc *psoc);
+
+/**
+ * target_if_pmo_register_tx_ops() - Register PMO component TX OPS
+ * @tx_ops: PMO if transmit ops
+ *
+ * Return: None
+ */
+void target_if_pmo_register_tx_ops(struct wlan_pmo_tx_ops *tx_ops);
+
+#endif
+
diff --git a/components/target_if/pmo/src/target_if_pmo_arp.c b/components/target_if/pmo/src/target_if_pmo_arp.c
new file mode 100644
index 0000000..b28b08a
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_arp.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/**
+ * DOC: target_if_pmo_arp.c
+ *
+ * Target interface file for pmo component to
+ * send arp offload related cmd and process event.
+ */
+
+#include "target_if.h"
+#include "target_if_pmo.h"
+#include "wmi_unified_api.h"
+
+QDF_STATUS target_if_pmo_send_arp_offload_req(
+ struct wlan_objmgr_vdev *vdev,
+ struct pmo_arp_offload_params *arp_offload_req,
+ struct pmo_ns_offload_params *ns_offload_req)
+{
+ uint8_t vdev_id;
+ struct wlan_objmgr_psoc *psoc;
+ QDF_STATUS status;
+
+ if (!vdev) {
+ target_if_err("vdev ptr passed is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ psoc = wlan_vdev_get_psoc(vdev);
+ vdev_id = wlan_vdev_get_id(vdev);
+ if (!psoc) {
+ target_if_err("psoc handle is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ status = wmi_unified_enable_arp_ns_offload_cmd(
+ GET_WMI_HDL_FROM_PSOC(psoc),
+ arp_offload_req,
+ ns_offload_req,
+ vdev_id);
+ if (status != QDF_STATUS_SUCCESS)
+ target_if_err("Failed to enable ARP NDP/NSffload");
+
+ return status;
+}
+
+
diff --git a/components/target_if/pmo/src/target_if_pmo_gtk.c b/components/target_if/pmo/src/target_if_pmo_gtk.c
new file mode 100644
index 0000000..5f67b9f
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_gtk.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/**
+ * DOC: target_if_pmo_gtk.c
+ *
+ * Target interface file for pmo component to
+ * send gtk offload related cmd and process event.
+ */
+
+#include "target_if.h"
+#include "target_if_pmo.h"
+#include "wmi_unified_api.h"
+
+QDF_STATUS target_if_pmo_send_gtk_offload_req(struct wlan_objmgr_vdev *vdev,
+ struct pmo_gtk_req *gtk_req)
+{
+ uint8_t vdev_id;
+ QDF_STATUS status;
+ uint32_t gtk_offload_opcode;
+ struct wlan_objmgr_psoc *psoc;
+
+ if (!vdev) {
+ target_if_err("vdev ptr passed is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ psoc = wlan_vdev_get_psoc(vdev);
+ vdev_id = wlan_vdev_get_id(vdev);
+ if (!psoc) {
+ target_if_err("psoc handle is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ if (gtk_req->flags == PMO_GTK_OFFLOAD_ENABLE)
+ gtk_offload_opcode = GTK_OFFLOAD_ENABLE_OPCODE;
+ else
+ gtk_offload_opcode = GTK_OFFLOAD_DISABLE_OPCODE;
+
+ status = wmi_unified_send_gtk_offload_cmd(
+ GET_WMI_HDL_FROM_PSOC(psoc),
+ vdev_id,
+ gtk_req,
+ gtk_req->flags,
+ gtk_offload_opcode);
+ if (status)
+ target_if_err("Failed to send gtk offload cmd to fw");
+
+ return status;
+}
+
+QDF_STATUS target_if_pmo_send_gtk_response_req(struct wlan_objmgr_vdev *vdev)
+{
+ uint8_t vdev_id;
+ struct wlan_objmgr_psoc *psoc;
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ uint32_t offload_req_opcode;
+
+ if (!vdev) {
+ target_if_err("vdev ptr passed is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ psoc = wlan_vdev_get_psoc(vdev);
+ vdev_id = wlan_vdev_get_id(vdev);
+ if (!psoc) {
+ target_if_err("psoc handle is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ /* Request for GTK offload status */
+ offload_req_opcode = GTK_OFFLOAD_REQUEST_STATUS_OPCODE;
+
+ /* send the wmi command */
+ status = wmi_unified_process_gtk_offload_getinfo_cmd(
+ GET_WMI_HDL_FROM_PSOC(psoc),
+ vdev_id, offload_req_opcode);
+
+ return status;
+}
+
+int target_if_pmo_gtk_offload_status_event(void *scn_handle,
+ uint8_t *event, uint32_t len)
+{
+ struct pmo_gtk_rsp_params *gtk_rsp_param;
+ struct wlan_objmgr_psoc *psoc;
+ QDF_STATUS ret;
+
+ TARGET_IF_ENTER();
+ psoc = target_if_get_psoc_from_scn_hdl(scn_handle);
+ if (!psoc) {
+ target_if_err("psoc ptr is NULL");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ gtk_rsp_param = qdf_mem_malloc(sizeof(*gtk_rsp_param));
+ if (!gtk_rsp_param) {
+ target_if_err("memory allocation failed");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ if (wmi_extract_gtk_rsp_event(GET_WMI_HDL_FROM_PSOC(psoc),
+ event, gtk_rsp_param, len) != QDF_STATUS_SUCCESS) {
+ target_if_err("Extraction of gtk rsp event failed");
+ qdf_mem_free(gtk_rsp_param);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = pmo_tgt_gtk_rsp_evt(psoc, (void *)gtk_rsp_param);
+ if (ret != QDF_STATUS_SUCCESS) {
+ target_if_err("Failed to rx_gtk_rsp_event");
+ ret = -EINVAL;
+ }
+ qdf_mem_free(gtk_rsp_param);
+out:
+ TARGET_IF_EXIT();
+
+ return ret;
+}
+
diff --git a/components/target_if/pmo/src/target_if_pmo_hw_filter.c b/components/target_if/pmo/src/target_if_pmo_hw_filter.c
new file mode 100644
index 0000000..8070a64
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_hw_filter.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/**
+ * DOC: target_if_pmo_non_arp_bcast_fltr.c
+ *
+ * Target interface file for pmo component to
+ * send non arp hw bcast filtering related cmd and process event.
+ */
+
+#include "target_if.h"
+#include "target_if_pmo.h"
+#include "wmi_unified_api.h"
+#include "wlan_pmo_hw_filter_public_struct.h"
+
+QDF_STATUS target_if_pmo_conf_hw_filter(struct wlan_objmgr_psoc *psoc,
+ struct pmo_hw_filter_params *req)
+{
+ QDF_STATUS status;
+
+ if (!psoc) {
+ target_if_err("psoc is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ status = wmi_unified_conf_hw_filter_cmd(
+ GET_WMI_HDL_FROM_PSOC(psoc),
+ req);
+
+ if (QDF_IS_STATUS_ERROR(status))
+ target_if_err("Failed to configure HW Filter");
+
+ return status;
+}
diff --git a/components/target_if/pmo/src/target_if_pmo_lphb.c b/components/target_if/pmo/src/target_if_pmo_lphb.c
new file mode 100644
index 0000000..8c630b8
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_lphb.c
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/**
+ * DOC: target_if_pmo_lphb.c
+ *
+ * Target interface file for pmo component to
+ * send lphb offload related cmd and process event.
+ */
+#ifdef FEATURE_WLAN_LPHB
+
+#include "target_if.h"
+#include "target_if_pmo.h"
+#include "wmi_unified_pmo_api.h"
+
+QDF_STATUS target_if_pmo_send_lphb_enable(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_enable_req *ts_lphb_enable)
+{
+ QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+ int status = 0;
+ wmi_hb_set_enable_cmd_fixed_param hb_enable_fp;
+
+ if (ts_lphb_enable == NULL) {
+ target_if_err("LPHB Enable configuration is NULL");
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ target_if_info("PMO_HB_SET_ENABLE enable=%d, item=%d, session=%d",
+ ts_lphb_enable->enable,
+ ts_lphb_enable->item, ts_lphb_enable->session);
+
+ if ((ts_lphb_enable->item != 1) && (ts_lphb_enable->item != 2)) {
+ target_if_err("LPHB configuration wrong item %d",
+ ts_lphb_enable->item);
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ /* fill in values */
+ hb_enable_fp.vdev_id = ts_lphb_enable->session;
+ hb_enable_fp.enable = ts_lphb_enable->enable;
+ hb_enable_fp.item = ts_lphb_enable->item;
+ hb_enable_fp.session = ts_lphb_enable->session;
+
+ status = wmi_unified_lphb_config_hbenable_cmd(
+ GET_WMI_HDL_FROM_PSOC(psoc),
+ &hb_enable_fp);
+ if (status != EOK) {
+ qdf_status = QDF_STATUS_E_FAILURE;
+ goto error;
+ }
+ return QDF_STATUS_SUCCESS;
+error:
+
+ return qdf_status;
+}
+
+QDF_STATUS target_if_pmo_send_lphb_tcp_params(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_tcp_params *ts_lphb_tcp_param)
+{
+ QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+ int status = 0;
+ wmi_hb_set_tcp_params_cmd_fixed_param hb_tcp_params_fp = {0};
+
+ if (ts_lphb_tcp_param == NULL) {
+ target_if_err("TCP params LPHB configuration is NULL");
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ target_if_info("PMO --> WMI_HB_SET_TCP_PARAMS srv_ip=%08x, "
+ "dev_ip=%08x, src_port=%d, dst_port=%d, timeout=%d, "
+ "session=%d, gateway_mac= %pM, time_period_sec=%d,"
+ "tcp_sn=%d", ts_lphb_tcp_param->srv_ip,
+ ts_lphb_tcp_param->dev_ip, ts_lphb_tcp_param->src_port,
+ ts_lphb_tcp_param->dst_port, ts_lphb_tcp_param->timeout,
+ ts_lphb_tcp_param->session,
+ ts_lphb_tcp_param->gateway_mac.bytes,
+ ts_lphb_tcp_param->time_period_sec, ts_lphb_tcp_param->tcp_sn);
+
+ /* fill in values */
+ hb_tcp_params_fp.vdev_id = ts_lphb_tcp_param->session;
+ hb_tcp_params_fp.srv_ip = ts_lphb_tcp_param->srv_ip;
+ hb_tcp_params_fp.dev_ip = ts_lphb_tcp_param->dev_ip;
+ hb_tcp_params_fp.seq = ts_lphb_tcp_param->tcp_sn;
+ hb_tcp_params_fp.src_port = ts_lphb_tcp_param->src_port;
+ hb_tcp_params_fp.dst_port = ts_lphb_tcp_param->dst_port;
+ hb_tcp_params_fp.interval = ts_lphb_tcp_param->time_period_sec;
+ hb_tcp_params_fp.timeout = ts_lphb_tcp_param->timeout;
+ hb_tcp_params_fp.session = ts_lphb_tcp_param->session;
+ WMI_CHAR_ARRAY_TO_MAC_ADDR(ts_lphb_tcp_param->gateway_mac.bytes,
+ &hb_tcp_params_fp.gateway_mac);
+
+ status = wmi_unified_lphb_config_tcp_params_cmd(
+ GET_WMI_HDL_FROM_PSOC(psoc),
+ &hb_tcp_params_fp);
+ if (status != EOK) {
+ qdf_status = QDF_STATUS_E_FAILURE;
+ goto error;
+ }
+
+ return QDF_STATUS_SUCCESS;
+error:
+ return qdf_status;
+}
+
+QDF_STATUS target_if_pmo_send_lphb_tcp_pkt_filter(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_tcp_filter_req *ts_lphb_tcp_filter)
+{
+ QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+ int status = 0;
+ wmi_hb_set_tcp_pkt_filter_cmd_fixed_param hb_tcp_filter_fp = {0};
+
+ if (ts_lphb_tcp_filter == NULL) {
+ target_if_err("TCP PKT FILTER LPHB configuration is NULL");
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ target_if_info("SET_TCP_PKT_FILTER length=%d, offset=%d, session=%d, "
+ "filter=%2x:%2x:%2x:%2x:%2x:%2x ...",
+ ts_lphb_tcp_filter->length, ts_lphb_tcp_filter->offset,
+ ts_lphb_tcp_filter->session, ts_lphb_tcp_filter->filter[0],
+ ts_lphb_tcp_filter->filter[1], ts_lphb_tcp_filter->filter[2],
+ ts_lphb_tcp_filter->filter[3], ts_lphb_tcp_filter->filter[4],
+ ts_lphb_tcp_filter->filter[5]);
+
+ /* fill in values */
+ hb_tcp_filter_fp.vdev_id = ts_lphb_tcp_filter->session;
+ hb_tcp_filter_fp.length = ts_lphb_tcp_filter->length;
+ hb_tcp_filter_fp.offset = ts_lphb_tcp_filter->offset;
+ hb_tcp_filter_fp.session = ts_lphb_tcp_filter->session;
+ memcpy((void *)&hb_tcp_filter_fp.filter,
+ (void *)&ts_lphb_tcp_filter->filter,
+ WMI_WLAN_HB_MAX_FILTER_SIZE);
+
+ status = wmi_unified_lphb_config_tcp_pkt_filter_cmd(
+ GET_WMI_HDL_FROM_PSOC(psoc),
+ &hb_tcp_filter_fp);
+ if (status != EOK) {
+ qdf_status = QDF_STATUS_E_FAILURE;
+ goto error;
+ }
+
+ return QDF_STATUS_SUCCESS;
+error:
+ return qdf_status;
+}
+
+QDF_STATUS target_if_pmo_send_lphb_udp_params(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_udp_params *ts_lphb_udp_param)
+{
+ QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+ int status = 0;
+ wmi_hb_set_udp_params_cmd_fixed_param hb_udp_params_fp = {0};
+
+ if (ts_lphb_udp_param == NULL) {
+ target_if_err("UDP param for LPHB configuration is NULL");
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ target_if_info("HB_SET_UDP_PARAMS srv_ip=%d, dev_ip=%d, src_port=%d, "
+ "dst_port=%d, interval=%d, timeout=%d, session=%d, "
+ "gateway_mac= %pM",
+ ts_lphb_udp_param->srv_ip, ts_lphb_udp_param->dev_ip,
+ ts_lphb_udp_param->src_port, ts_lphb_udp_param->dst_port,
+ ts_lphb_udp_param->interval, ts_lphb_udp_param->timeout,
+ ts_lphb_udp_param->session,
+ ts_lphb_udp_param->gateway_mac.bytes);
+
+ /* fill in values */
+ hb_udp_params_fp.vdev_id = ts_lphb_udp_param->session;
+ hb_udp_params_fp.srv_ip = ts_lphb_udp_param->srv_ip;
+ hb_udp_params_fp.dev_ip = ts_lphb_udp_param->dev_ip;
+ hb_udp_params_fp.src_port = ts_lphb_udp_param->src_port;
+ hb_udp_params_fp.dst_port = ts_lphb_udp_param->dst_port;
+ hb_udp_params_fp.interval = ts_lphb_udp_param->interval;
+ hb_udp_params_fp.timeout = ts_lphb_udp_param->timeout;
+ hb_udp_params_fp.session = ts_lphb_udp_param->session;
+ WMI_CHAR_ARRAY_TO_MAC_ADDR(ts_lphb_udp_param->gateway_mac.bytes,
+ &hb_udp_params_fp.gateway_mac);
+
+ status = wmi_unified_lphb_config_udp_params_cmd(
+ GET_WMI_HDL_FROM_PSOC(psoc),
+ &hb_udp_params_fp);
+ if (status != EOK) {
+ qdf_status = QDF_STATUS_E_FAILURE;
+ goto error;
+ }
+
+ return QDF_STATUS_SUCCESS;
+error:
+ return qdf_status;
+}
+
+/**
+ * target_if_pmo_lphb_send_udp_pkt_filter() - Send LPHB udp pkt filter req
+ * @psoc: objmgr psoc handle
+ * @ts_lphb_udp_filter: lphb udp filter request which needs to configure in fwr
+ *
+ * Return: QDF status
+ */
+QDF_STATUS target_if_pmo_send_lphb_udp_pkt_filter(struct wlan_objmgr_psoc *psoc,
+ struct pmo_lphb_udp_filter_req *ts_lphb_udp_filter)
+{
+ QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
+ int status = 0;
+ wmi_hb_set_udp_pkt_filter_cmd_fixed_param hb_udp_filter_fp = {0};
+
+ if (ts_lphb_udp_filter == NULL) {
+ target_if_err("LPHB UDP packet filter configuration is NULL");
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ target_if_info("SET_UDP_PKT_FILTER length=%d, offset=%d, session=%d, "
+ "filter=%2x:%2x:%2x:%2x:%2x:%2x ...",
+ ts_lphb_udp_filter->length, ts_lphb_udp_filter->offset,
+ ts_lphb_udp_filter->session, ts_lphb_udp_filter->filter[0],
+ ts_lphb_udp_filter->filter[1], ts_lphb_udp_filter->filter[2],
+ ts_lphb_udp_filter->filter[3], ts_lphb_udp_filter->filter[4],
+ ts_lphb_udp_filter->filter[5]);
+
+ /* fill in values */
+ hb_udp_filter_fp.vdev_id = ts_lphb_udp_filter->session;
+ hb_udp_filter_fp.length = ts_lphb_udp_filter->length;
+ hb_udp_filter_fp.offset = ts_lphb_udp_filter->offset;
+ hb_udp_filter_fp.session = ts_lphb_udp_filter->session;
+ qdf_mem_copy((void *)&hb_udp_filter_fp.filter,
+ (void *)&ts_lphb_udp_filter->filter,
+ WMI_WLAN_HB_MAX_FILTER_SIZE);
+
+ status = wmi_unified_lphb_config_udp_pkt_filter_cmd(
+ GET_WMI_HDL_FROM_PSOC(psoc),
+ &hb_udp_filter_fp);
+ if (status != EOK) {
+ qdf_status = QDF_STATUS_E_FAILURE;
+ goto error;
+ }
+
+ return QDF_STATUS_SUCCESS;
+error:
+ return qdf_status;
+}
+
+QDF_STATUS target_if_pmo_lphb_evt_handler(struct wlan_objmgr_psoc *psoc,
+ uint8_t *event)
+{
+ wmi_hb_ind_event_fixed_param *hb_fp;
+ struct pmo_lphb_rsp *slphb_indication = NULL;
+ QDF_STATUS qdf_status;
+
+ TARGET_IF_ENTER();
+ if (!psoc) {
+ target_if_err("psoc ptr is NULL");
+ qdf_status = QDF_STATUS_E_NULL_VALUE;
+ goto out;
+ }
+
+ hb_fp = (wmi_hb_ind_event_fixed_param *) event;
+ if (!hb_fp) {
+ target_if_err("Invalid wmi_hb_ind_event_fixed_param buffer");
+ qdf_status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ target_if_debug("lphb indication received with\n"
+ "vdev_id=%d, session=%d, reason=%d",
+ hb_fp->vdev_id, hb_fp->session, hb_fp->reason);
+
+ slphb_indication = (struct pmo_lphb_rsp *)qdf_mem_malloc(
+ sizeof(struct pmo_lphb_rsp));
+
+ if (!slphb_indication) {
+ target_if_err("Invalid LPHB indication buffer");
+ qdf_status = QDF_STATUS_E_NOMEM;
+ goto out;
+ }
+
+ slphb_indication->session_idx = hb_fp->session;
+ slphb_indication->protocol_type = hb_fp->reason;
+ slphb_indication->event_reason = hb_fp->reason;
+
+ qdf_status = pmo_tgt_lphb_rsp_evt(psoc, slphb_indication);
+ if (qdf_status != QDF_STATUS_SUCCESS)
+ target_if_err("Failed to lphb_rsp_event");
+out:
+ if (slphb_indication)
+ qdf_mem_free(slphb_indication);
+
+ return qdf_status;
+}
+#endif
+
diff --git a/components/target_if/pmo/src/target_if_pmo_main.c b/components/target_if/pmo/src/target_if_pmo_main.c
new file mode 100644
index 0000000..6e63d04
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_main.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/**
+ * DOC: Target interface file for pmo component to
+ * Implement api's which shall be used by pmo component
+ * in target if internally.
+ */
+
+#include "target_if_pmo.h"
+#include "wlan_pmo_common_public_struct.h"
+
+void target_if_pmo_register_tx_ops(struct wlan_pmo_tx_ops *pmo_tx_ops)
+{
+ if (!pmo_tx_ops) {
+ target_if_err("pmo_tx_ops is null");
+ return;
+ }
+
+ pmo_tx_ops->send_arp_offload_req =
+ target_if_pmo_send_arp_offload_req;
+ pmo_tx_ops->send_conf_hw_filter_req =
+ target_if_pmo_conf_hw_filter;
+ pmo_tx_ops->send_ns_offload_req =
+ target_if_pmo_send_ns_offload_req;
+ pmo_tx_ops->send_enable_wow_wakeup_event_req =
+ target_if_pmo_enable_wow_wakeup_event;
+ pmo_tx_ops->send_disable_wow_wakeup_event_req =
+ target_if_pmo_disable_wow_wakeup_event;
+ pmo_tx_ops->send_add_wow_pattern =
+ target_if_pmo_send_wow_patterns_to_fw;
+ pmo_tx_ops->send_enhance_mc_offload_req =
+ target_if_pmo_send_enhance_mc_offload_req;
+ pmo_tx_ops->send_set_mc_filter_req =
+ target_if_pmo_set_mc_filter_req;
+ pmo_tx_ops->send_clear_mc_filter_req =
+ target_if_pmo_clear_mc_filter_req;
+ pmo_tx_ops->send_ra_filter_req =
+ target_if_pmo_send_ra_filter_req;
+ pmo_tx_ops->send_gtk_offload_req =
+ target_if_pmo_send_gtk_offload_req;
+ pmo_tx_ops->send_get_gtk_rsp_cmd =
+ target_if_pmo_send_gtk_response_req;
+ pmo_tx_ops->send_action_frame_pattern_req =
+ target_if_pmo_send_action_frame_patterns;
+ pmo_tx_ops->send_lphb_enable =
+ target_if_pmo_send_lphb_enable;
+ pmo_tx_ops->send_lphb_tcp_params =
+ target_if_pmo_send_lphb_tcp_params;
+ pmo_tx_ops->send_lphb_tcp_filter_req =
+ target_if_pmo_send_lphb_tcp_pkt_filter;
+ pmo_tx_ops->send_lphb_upd_params =
+ target_if_pmo_send_lphb_udp_params;
+ pmo_tx_ops->send_lphb_udp_filter_req =
+ target_if_pmo_send_lphb_udp_pkt_filter;
+ pmo_tx_ops->send_vdev_param_update_req =
+ target_if_pmo_send_vdev_update_param_req;
+ pmo_tx_ops->send_vdev_sta_ps_param_req =
+ target_if_pmo_send_vdev_ps_param_req;
+ pmo_tx_ops->psoc_update_wow_bus_suspend =
+ target_if_pmo_psoc_update_bus_suspend;
+ pmo_tx_ops->psoc_get_host_credits =
+ target_if_pmo_psoc_get_host_credits;
+ pmo_tx_ops->psoc_get_pending_cmnds =
+ target_if_pmo_psoc_get_pending_cmnds;
+ pmo_tx_ops->update_target_suspend_flag =
+ target_if_pmo_update_target_suspend_flag;
+ pmo_tx_ops->psoc_send_wow_enable_req =
+ target_if_pmo_psoc_send_wow_enable_req;
+ pmo_tx_ops->psoc_send_supend_req =
+ target_if_pmo_psoc_send_suspend_req;
+ pmo_tx_ops->psoc_set_runtime_pm_in_progress =
+ target_if_pmo_set_runtime_pm_in_progress;
+ pmo_tx_ops->psoc_get_runtime_pm_in_progress =
+ target_if_pmo_get_runtime_pm_in_progress;
+ pmo_tx_ops->psoc_send_host_wakeup_ind =
+ target_if_pmo_psoc_send_host_wakeup_ind;
+ pmo_tx_ops->psoc_send_target_resume_req =
+ target_if_pmo_psoc_send_target_resume_req;
+ pmo_tx_ops->send_set_pkt_filter =
+ target_if_pmo_send_pkt_filter_req;
+ pmo_tx_ops->send_clear_pkt_filter =
+ target_if_pmo_clear_pkt_filter_req;
+
+}
+
diff --git a/components/target_if/pmo/src/target_if_pmo_mc_addr_filtering.c b/components/target_if/pmo/src/target_if_pmo_mc_addr_filtering.c
new file mode 100644
index 0000000..bd3b29b
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_mc_addr_filtering.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/**
+ * DOC: target_if_pmo_mc_addr_filtering.c
+ *
+ * Target interface file for pmo component to
+ * send mc address filtering offload related cmd and process event.
+ */
+
+
+#include "target_if.h"
+#include "target_if_pmo.h"
+#include "wmi_unified_api.h"
+
+QDF_STATUS target_if_pmo_set_mc_filter_req(
+ struct wlan_objmgr_vdev *vdev,
+ struct qdf_mac_addr multicast_addr)
+{
+ uint8_t vdev_id;
+ struct wlan_objmgr_psoc *psoc;
+ QDF_STATUS status;
+
+ if (!vdev) {
+ target_if_err("vdev ptr passed is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ psoc = wlan_vdev_get_psoc(vdev);
+ vdev_id = wlan_vdev_get_id(vdev);
+ if (!psoc) {
+ target_if_err("psoc handle is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ status = wmi_unified_add_clear_mcbc_filter_cmd(
+ GET_WMI_HDL_FROM_PSOC(psoc),
+ vdev_id,
+ multicast_addr, false);
+ if (status)
+ target_if_err("Failed to send add/clear mcbc filter cmd");
+
+ return status;
+}
+
+QDF_STATUS target_if_pmo_clear_mc_filter_req(
+ struct wlan_objmgr_vdev *vdev,
+ struct qdf_mac_addr multicast_addr)
+{
+ uint8_t vdev_id;
+ struct wlan_objmgr_psoc *psoc;
+ QDF_STATUS status;
+
+ if (!vdev) {
+ target_if_err("vdev ptr passed is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ psoc = wlan_vdev_get_psoc(vdev);
+ vdev_id = wlan_vdev_get_id(vdev);
+ if (!psoc) {
+ target_if_err("psoc handle is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ status = wmi_unified_add_clear_mcbc_filter_cmd(
+ GET_WMI_HDL_FROM_PSOC(psoc),
+ vdev_id,
+ multicast_addr, true);
+ if (status)
+ target_if_err("Failed to send add/clear mcbc filter cmd");
+
+ return status;
+
+}
+
+
diff --git a/components/target_if/pmo/src/target_if_pmo_ns.c b/components/target_if/pmo/src/target_if_pmo_ns.c
new file mode 100644
index 0000000..6b2946b
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_ns.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/**
+ * DOC: target_if_pmo_ns.c
+ *
+ * Target interface file for pmo component to
+ * send ns offload related cmd and process event.
+ */
+
+#include "target_if.h"
+#include "target_if_pmo.h"
+#include "wmi_unified_api.h"
+
+QDF_STATUS target_if_pmo_send_ns_offload_req(
+ struct wlan_objmgr_vdev *vdev,
+ struct pmo_arp_offload_params *arp_offload_req,
+ struct pmo_ns_offload_params *ns_offload_req)
+{
+ uint8_t vdev_id;
+ struct wlan_objmgr_psoc *psoc;
+ QDF_STATUS status;
+
+ if (!vdev) {
+ target_if_err("vdev ptr passed is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ psoc = wlan_vdev_get_psoc(vdev);
+ vdev_id = wlan_vdev_get_id(vdev);
+ if (!psoc) {
+ target_if_err("psoc handle is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ status = wmi_unified_enable_arp_ns_offload_cmd(
+ GET_WMI_HDL_FROM_PSOC(psoc),
+ arp_offload_req,
+ ns_offload_req,
+ vdev_id);
+ if (status != QDF_STATUS_SUCCESS)
+ target_if_err("Failed to enable ARP NDP/NSffload");
+
+ return status;
+}
+
diff --git a/components/target_if/pmo/src/target_if_pmo_pkt_filter.c b/components/target_if/pmo/src/target_if_pmo_pkt_filter.c
new file mode 100644
index 0000000..7907c7a
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_pkt_filter.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/**
+ * DOC: target_if_pmo_pkt_filter.c
+ *
+ * Target interface file for pmo component to
+ * send packet filter related cmd and process event.
+ */
+
+#include "target_if.h"
+#include "target_if_pmo.h"
+#include "wmi_unified_pmo_api.h"
+#include "wlan_pmo_pkt_filter_public_struct.h"
+
+QDF_STATUS target_if_pmo_send_pkt_filter_req(struct wlan_objmgr_vdev *vdev,
+ struct pmo_rcv_pkt_fltr_cfg *rcv_filter_param)
+{
+ uint8_t vdev_id;
+ struct wlan_objmgr_psoc *psoc;
+ QDF_STATUS status;
+
+ if (!vdev) {
+ target_if_err("vdev ptr passed is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ psoc = wlan_vdev_get_psoc(vdev);
+ vdev_id = wlan_vdev_get_id(vdev);
+ if (!psoc) {
+ target_if_err("psoc handle is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ /* send the command along with data */
+ status = wmi_unified_config_packet_filter_cmd(
+ GET_WMI_HDL_FROM_PSOC(psoc), vdev_id,
+ rcv_filter_param,
+ rcv_filter_param->filter_id, true);
+ if (status) {
+ target_if_err("Failed to send pkt_filter cmd");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ /* Enable packet filter */
+ status = wmi_unified_enable_disable_packet_filter_cmd(
+ GET_WMI_HDL_FROM_PSOC(psoc),
+ vdev_id, true);
+ if (status)
+ target_if_err("Failed to send packet filter wmi cmd to fw");
+
+ return status;
+}
+
+QDF_STATUS target_if_pmo_clear_pkt_filter_req(struct wlan_objmgr_vdev *vdev,
+ struct pmo_rcv_pkt_fltr_clear_param *rcv_clear_param)
+{
+ uint8_t vdev_id;
+ struct wlan_objmgr_psoc *psoc;
+ QDF_STATUS status;
+
+ if (!vdev) {
+ target_if_err("vdev ptr passed is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ psoc = wlan_vdev_get_psoc(vdev);
+ vdev_id = wlan_vdev_get_id(vdev);
+ if (!psoc) {
+ target_if_err("psoc handle is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ /* send the command along with data */
+ status = wmi_unified_config_packet_filter_cmd(
+ GET_WMI_HDL_FROM_PSOC(psoc), vdev_id,
+ NULL, rcv_clear_param->filter_id, false);
+
+ if (status)
+ target_if_err("Failed to clear filter cmd");
+
+ return status;
+}
diff --git a/components/target_if/pmo/src/target_if_pmo_static_config.c b/components/target_if/pmo/src/target_if_pmo_static_config.c
new file mode 100644
index 0000000..8207e36
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_static_config.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/**
+ * DOC: target_if_pmo_static.c
+ *
+ * Target interface file for pmo component to
+ * send wow related cmd and process event.
+ */
+
+
+#include "target_if.h"
+#include "target_if_pmo.h"
+#include "wmi_unified_api.h"
+
+QDF_STATUS target_if_pmo_send_ra_filter_req(struct wlan_objmgr_vdev *vdev,
+ uint8_t default_pattern, uint16_t rate_limit_interval)
+{
+ uint8_t vdev_id;
+ struct wlan_objmgr_psoc *psoc;
+ QDF_STATUS status;
+
+ if (!vdev) {
+ target_if_err("vdev ptr passed is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ psoc = wlan_vdev_get_psoc(vdev);
+ vdev_id = wlan_vdev_get_id(vdev);
+ if (!psoc) {
+ target_if_err("psoc handle is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ status = wmi_unified_wow_sta_ra_filter_cmd(
+ GET_WMI_HDL_FROM_PSOC(psoc), vdev_id,
+ default_pattern, rate_limit_interval);
+ if (status)
+ target_if_err("Failed to send RA rate limit to fw");
+
+ return status;
+}
+
+QDF_STATUS target_if_pmo_send_action_frame_patterns(
+ struct wlan_objmgr_vdev *vdev,
+ struct pmo_action_wakeup_set_params *ip_cmd)
+{
+ uint8_t vdev_id;
+ struct wlan_objmgr_psoc *psoc;
+ QDF_STATUS status;
+
+ if (!vdev) {
+ target_if_err("vdev ptr passed is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ psoc = wlan_vdev_get_psoc(vdev);
+ vdev_id = wlan_vdev_get_id(vdev);
+ if (!psoc) {
+ target_if_err("psoc handle is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ status = wmi_unified_action_frame_patterns_cmd(
+ GET_WMI_HDL_FROM_PSOC(psoc), ip_cmd);
+ if (status != QDF_STATUS_SUCCESS)
+ target_if_err("Failed to config wow action frame map, ret %d",
+ status);
+
+ return status;
+}
+
+QDF_STATUS target_if_pmo_send_enhance_mc_offload_req(
+ struct wlan_objmgr_vdev *vdev, bool enable)
+{
+ uint8_t vdev_id;
+ struct wlan_objmgr_psoc *psoc;
+ QDF_STATUS status;
+
+ if (!vdev) {
+ target_if_err("vdev ptr passed is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ psoc = wlan_vdev_get_psoc(vdev);
+ vdev_id = wlan_vdev_get_id(vdev);
+ if (!psoc) {
+ target_if_err("psoc handle is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ status = wmi_unified_enable_enhance_multicast_offload_cmd(
+ GET_WMI_HDL_FROM_PSOC(psoc), vdev_id, enable);
+ if (status)
+ target_if_err("Failed to config wow wakeup event");
+
+ return status;
+}
+
diff --git a/components/target_if/pmo/src/target_if_pmo_suspend_resume.c b/components/target_if/pmo/src/target_if_pmo_suspend_resume.c
new file mode 100644
index 0000000..fbbd638
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_suspend_resume.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/**
+ * DOC: target_if_pmo_static.c
+ *
+ * Target interface file for pmo component to
+ * send suspend / resume related cmd and process event.
+ */
+
+
+#include "target_if.h"
+#include "target_if_pmo.h"
+#include "wmi_unified_api.h"
+
+#define TGT_WILDCARD_PDEV_ID 0x0
+
+QDF_STATUS target_if_pmo_send_vdev_update_param_req(
+ struct wlan_objmgr_vdev *vdev,
+ uint32_t param_id, uint32_t param_value)
+{
+ uint8_t vdev_id;
+ struct wlan_objmgr_psoc *psoc;
+ struct vdev_set_params param = {0};
+
+ if (!vdev) {
+ target_if_err("vdev ptr passed is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ psoc = wlan_vdev_get_psoc(vdev);
+ vdev_id = wlan_vdev_get_id(vdev);
+ if (!psoc) {
+ target_if_err("psoc handle is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ switch (param_id) {
+ case pmo_vdev_param_listen_interval:
+ param_id = WMI_VDEV_PARAM_LISTEN_INTERVAL;
+ break;
+ case pmo_vdev_param_dtim_policy:
+ param_id = WMI_VDEV_PARAM_DTIM_POLICY;
+ break;
+ default:
+ target_if_err("invalid vdev param id %d", param_id);
+ return QDF_STATUS_E_INVAL;
+ }
+
+ param.if_id = vdev_id;
+ param.param_id = param_id;
+ param.param_value = param_value;
+ target_if_info("set vdev param vdev_id: %d value: %d for param_id: %d",
+ vdev_id, param_value, param_id);
+ return wmi_unified_vdev_set_param_send(GET_WMI_HDL_FROM_PSOC(psoc),
+ ¶m);
+}
+
+QDF_STATUS target_if_pmo_send_vdev_ps_param_req(
+ struct wlan_objmgr_vdev *vdev,
+ uint32_t param_id,
+ uint32_t param_value)
+{
+ uint8_t vdev_id;
+ struct wlan_objmgr_psoc *psoc;
+ QDF_STATUS status;
+ struct sta_ps_params sta_ps_param = {0};
+
+ if (!vdev) {
+ target_if_err("vdev ptr passed is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ psoc = wlan_vdev_get_psoc(vdev);
+ vdev_id = wlan_vdev_get_id(vdev);
+ if (!psoc) {
+ target_if_err("psoc handle is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ switch (param_id) {
+ case pmo_sta_ps_enable_qpower:
+ param_id = WMI_STA_PS_ENABLE_QPOWER;
+ break;
+ default:
+ target_if_err("invalid vdev param id %d", param_id);
+ return QDF_STATUS_E_INVAL;
+ }
+
+ sta_ps_param.vdev_id = vdev_id;
+ sta_ps_param.param = param_id;
+ sta_ps_param.value = param_value;
+ target_if_info("set vdev param vdev_id: %d value: %d for param_id: %d",
+ vdev_id, param_value, param_id);
+
+ status = wmi_unified_sta_ps_cmd_send(GET_WMI_HDL_FROM_PSOC(psoc),
+ &sta_ps_param);
+ if (QDF_IS_STATUS_ERROR(status))
+ return status;
+
+ return status;
+
+}
+
+void target_if_pmo_psoc_update_bus_suspend(struct wlan_objmgr_psoc *psoc,
+ uint8_t value)
+{
+ wmi_set_is_wow_bus_suspended(GET_WMI_HDL_FROM_PSOC(psoc), value);
+}
+
+int target_if_pmo_psoc_get_host_credits(struct wlan_objmgr_psoc *psoc)
+{
+ return wmi_get_host_credits(GET_WMI_HDL_FROM_PSOC(psoc));
+}
+
+int target_if_pmo_psoc_get_pending_cmnds(struct wlan_objmgr_psoc *psoc)
+{
+ return wmi_get_pending_cmds(GET_WMI_HDL_FROM_PSOC(psoc));
+}
+
+void target_if_pmo_update_target_suspend_flag(struct wlan_objmgr_psoc *psoc,
+ uint8_t value)
+{
+ wmi_set_target_suspend(GET_WMI_HDL_FROM_PSOC(psoc), value);
+}
+
+QDF_STATUS target_if_pmo_psoc_send_wow_enable_req(
+ struct wlan_objmgr_psoc *psoc,
+ struct pmo_wow_cmd_params *param)
+{
+ return wmi_unified_wow_enable_send(GET_WMI_HDL_FROM_PSOC(psoc),
+ (struct wow_cmd_params *)param,
+ TGT_WILDCARD_PDEV_ID);
+}
+
+QDF_STATUS target_if_pmo_psoc_send_suspend_req(
+ struct wlan_objmgr_psoc *psoc,
+ struct pmo_suspend_params *param)
+{
+ return wmi_unified_suspend_send(GET_WMI_HDL_FROM_PSOC(psoc),
+ (struct suspend_params *) param,
+ TGT_WILDCARD_PDEV_ID);
+}
+
+void target_if_pmo_set_runtime_pm_in_progress(struct wlan_objmgr_psoc *psoc,
+ bool value)
+{
+ return wmi_set_runtime_pm_inprogress(GET_WMI_HDL_FROM_PSOC(psoc),
+ value);
+}
+
+bool target_if_pmo_get_runtime_pm_in_progress(
+ struct wlan_objmgr_psoc *psoc)
+{
+ return wmi_get_runtime_pm_inprogress(GET_WMI_HDL_FROM_PSOC(psoc));
+}
+
+QDF_STATUS target_if_pmo_psoc_send_host_wakeup_ind(
+ struct wlan_objmgr_psoc *psoc)
+{
+ return wmi_unified_host_wakeup_ind_to_fw_cmd(
+ GET_WMI_HDL_FROM_PSOC(psoc));
+}
+
+QDF_STATUS target_if_pmo_psoc_send_target_resume_req(
+ struct wlan_objmgr_psoc *psoc)
+{
+ return wmi_unified_resume_send(GET_WMI_HDL_FROM_PSOC(psoc),
+ TGT_WILDCARD_PDEV_ID);
+}
+
diff --git a/components/target_if/pmo/src/target_if_pmo_wow.c b/components/target_if/pmo/src/target_if_pmo_wow.c
new file mode 100644
index 0000000..828f0cf
--- /dev/null
+++ b/components/target_if/pmo/src/target_if_pmo_wow.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/**
+ * DOC: target_if_pmo_wow.c
+ *
+ * Target interface file for pmo component to
+ * send wow related cmd and process event.
+ */
+
+
+#include "target_if.h"
+#include "target_if_pmo.h"
+#include "wmi_unified_api.h"
+
+QDF_STATUS target_if_pmo_enable_wow_wakeup_event(struct wlan_objmgr_vdev *vdev,
+ uint32_t *bitmap)
+{
+ uint8_t vdev_id;
+ struct wlan_objmgr_psoc *psoc;
+ QDF_STATUS status;
+
+ if (!vdev) {
+ target_if_err("vdev ptr passed is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ psoc = wlan_vdev_get_psoc(vdev);
+ vdev_id = wlan_vdev_get_id(vdev);
+ if (!psoc) {
+ target_if_err("psoc handle is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ status = wmi_unified_add_wow_wakeup_event_cmd(
+ GET_WMI_HDL_FROM_PSOC(psoc), vdev_id, bitmap, true);
+ if (status)
+ target_if_err("Failed to config wow wakeup event");
+
+ return status;
+}
+
+QDF_STATUS target_if_pmo_disable_wow_wakeup_event(struct wlan_objmgr_vdev *vdev,
+ uint32_t *bitmap)
+{
+ uint8_t vdev_id;
+ struct wlan_objmgr_psoc *psoc;
+ QDF_STATUS status;
+
+ if (!vdev) {
+ target_if_err("vdev ptr passed is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ psoc = wlan_vdev_get_psoc(vdev);
+ vdev_id = wlan_vdev_get_id(vdev);
+ if (!psoc) {
+ target_if_err("psoc handle is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ status = wmi_unified_add_wow_wakeup_event_cmd(
+ GET_WMI_HDL_FROM_PSOC(psoc), vdev_id, bitmap, false);
+ if (status)
+ target_if_err("Failed to config wow wakeup event");
+
+ return status;
+}
+
+QDF_STATUS target_if_pmo_send_wow_patterns_to_fw(struct wlan_objmgr_vdev *vdev,
+ uint8_t ptrn_id,
+ const uint8_t *ptrn, uint8_t ptrn_len,
+ uint8_t ptrn_offset, const uint8_t *mask,
+ uint8_t mask_len, bool user)
+{
+ uint8_t vdev_id;
+ struct wlan_objmgr_psoc *psoc;
+ QDF_STATUS status;
+
+ if (!vdev) {
+ target_if_err("vdev ptr passed is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ psoc = wlan_vdev_get_psoc(vdev);
+ vdev_id = wlan_vdev_get_id(vdev);
+ if (!psoc) {
+ target_if_err("psoc handle is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ status = wmi_unified_wow_patterns_to_fw_cmd(
+ GET_WMI_HDL_FROM_PSOC(psoc),
+ vdev_id, ptrn_id, ptrn,
+ ptrn_len, ptrn_offset, mask,
+ mask_len, user, 0);
+
+ return status;
+}
+
diff --git a/core/cds/inc/cds_config.h b/core/cds/inc/cds_config.h
index 2ced690..e2cd107 100644
--- a/core/cds/inc/cds_config.h
+++ b/core/cds/inc/cds_config.h
@@ -36,11 +36,13 @@
*
* @DRIVER_TYPE_PRODUCTION: Driver used in the production
* @DRIVER_TYPE_MFG: Driver used in the Factory
+ * @DRIVER_TYPE_INVALID: Invalid and unrecognized type
*
*/
enum driver_type {
DRIVER_TYPE_PRODUCTION = 0,
DRIVER_TYPE_MFG = 1,
+ DRIVER_TYPE_INVALID = 0x7FFFFFFF
};
/**
diff --git a/core/cds/src/cds_reg_service.c b/core/cds/src/cds_reg_service.c
index 3b1dde0..9faf8e9 100644
--- a/core/cds/src/cds_reg_service.c
+++ b/core/cds/src/cds_reg_service.c
@@ -46,13 +46,13 @@
uint32_t flags = 0;
enum channel_state state;
struct ch_params ch_params;
+ int sec_channel;
state = wlan_reg_get_channel_state(pdev, chan);
if (state == CHANNEL_STATE_INVALID)
return flags;
if (state == CHANNEL_STATE_DFS) {
flags |= IEEE80211_CHAN_PASSIVE;
- flags |= IEEE80211_CHAN_DFS;
}
if (state == CHANNEL_STATE_DISABLE)
flags |= IEEE80211_CHAN_BLOCKED;
@@ -63,7 +63,9 @@
(bandwidth == CH_WIDTH_80MHZ)) {
bandwidth = CH_WIDTH_40MHZ;
}
- }
+ flags |= IEEE80211_CHAN_2GHZ;
+ } else
+ flags |= IEEE80211_CHAN_5GHZ;
switch (bandwidth) {
case CH_WIDTH_80P80MHZ:
@@ -95,8 +97,15 @@
ch_params.ch_width = bandwidth;
wlan_reg_set_channel_params(pdev, chan, 0, &ch_params);
+ if (ch_params.sec_ch_offset == LOW_PRIMARY_CH)
+ sec_channel = chan + 4;
+ else if (ch_params.sec_ch_offset == HIGH_PRIMARY_CH)
+ sec_channel = chan - 4;
+ else
+ sec_channel = 0;
+
if (wlan_reg_get_bonded_channel_state(pdev, chan, bandwidth,
- ch_params.sec_ch_offset) !=
+ sec_channel) !=
CHANNEL_STATE_INVALID) {
if (ch_params.sec_ch_offset == LOW_PRIMARY_CH) {
flags |= IEEE80211_CHAN_HT40PLUS;
@@ -124,6 +133,7 @@
(sub_20_channel_width ==
WLAN_SUB_20_CH_WIDTH_10))
flags |= IEEE80211_CHAN_HALF;
+ bandwidth = CH_WIDTH_5MHZ;
/* FALLTHROUGH */
case CH_WIDTH_5MHZ:
if ((wlan_reg_get_bonded_channel_state(pdev, chan, bandwidth,
diff --git a/core/dp/ol/inc/ol_txrx_ctrl_api.h b/core/dp/ol/inc/ol_txrx_ctrl_api.h
index fd6c498..de4fc9e 100644
--- a/core/dp/ol/inc/ol_txrx_ctrl_api.h
+++ b/core/dp/ol/inc/ol_txrx_ctrl_api.h
@@ -514,7 +514,7 @@
void ol_tx_register_flow_control(struct ol_txrx_pdev_t *pdev);
void ol_tx_deregister_flow_control(struct ol_txrx_pdev_t *pdev);
-void ol_tx_dump_flow_pool_info(void);
+void ol_tx_dump_flow_pool_info(void *);
void ol_tx_clear_flow_pool_stats(void);
void ol_tx_flow_pool_map_handler(uint8_t flow_id, uint8_t flow_type,
uint8_t flow_pool_id, uint16_t flow_pool_size);
@@ -557,7 +557,7 @@
static inline void ol_tx_deregister_flow_control(struct ol_txrx_pdev_t *pdev)
{
}
-static inline void ol_tx_dump_flow_pool_info(void)
+static inline void ol_tx_dump_flow_pool_info(void *ctx)
{
}
static inline void ol_tx_clear_flow_pool_stats(void)
diff --git a/core/dp/txrx/ol_tx.c b/core/dp/txrx/ol_tx.c
index 274af2b..4192c4d 100644
--- a/core/dp/txrx/ol_tx.c
+++ b/core/dp/txrx/ol_tx.c
@@ -1524,7 +1524,7 @@
1 /* error */);
if (tx_msdu_info->peer) {
/* remove the peer reference added above */
- ol_txrx_peer_unref_delete(tx_msdu_info->peer);
+ OL_TXRX_PEER_UNREF_DELETE(tx_msdu_info->peer);
}
return 1; /* can't accept the tx mgmt frame */
}
@@ -1549,7 +1549,7 @@
ol_tx_enqueue(vdev->pdev, txq, tx_desc, tx_msdu_info);
if (tx_msdu_info->peer) {
/* remove the peer reference added above */
- ol_txrx_peer_unref_delete(tx_msdu_info->peer);
+ OL_TXRX_PEER_UNREF_DELETE(tx_msdu_info->peer);
}
ol_tx_sched(vdev->pdev);
@@ -1739,7 +1739,7 @@
if (tx_msdu_info.peer) {
/* remove the peer reference
* added above */
- ol_txrx_peer_unref_delete(
+ OL_TXRX_PEER_UNREF_DELETE(
tx_msdu_info.peer);
}
goto MSDU_LOOP_BOTTOM;
@@ -1757,7 +1757,7 @@
ol_tx_desc_frame_free_nonstd(pdev,
tx_desc,
1);
- ol_txrx_peer_unref_delete(
+ OL_TXRX_PEER_UNREF_DELETE(
tx_msdu_info.peer);
msdu = next;
continue;
@@ -1773,7 +1773,7 @@
ol_tx_desc_frame_free_nonstd(
pdev,
tx_desc, 1);
- ol_txrx_peer_unref_delete(
+ OL_TXRX_PEER_UNREF_DELETE(
tx_msdu_info.peer);
msdu = next;
continue;
@@ -1822,7 +1822,7 @@
OL_TX_PEER_STATS_UPDATE(tx_msdu_info.peer,
msdu);
/* remove the peer reference added above */
- ol_txrx_peer_unref_delete(tx_msdu_info.peer);
+ OL_TXRX_PEER_UNREF_DELETE(tx_msdu_info.peer);
}
MSDU_LOOP_BOTTOM:
msdu = next;
diff --git a/core/dp/txrx/ol_tx_classify.c b/core/dp/txrx/ol_tx_classify.c
index 62c1e80..eb47024 100644
--- a/core/dp/txrx/ol_tx_classify.c
+++ b/core/dp/txrx/ol_tx_classify.c
@@ -357,7 +357,7 @@
peer = NULL;
} else {
if (peer)
- qdf_atomic_inc(&peer->ref_cnt);
+ OL_TXRX_PEER_INC_REF_CNT(peer);
}
}
if (!peer)
@@ -582,7 +582,7 @@
"%s: remove the peer for invalid peer_id %p\n",
__func__, peer);
/* remove the peer reference added above */
- ol_txrx_peer_unref_delete(peer);
+ OL_TXRX_PEER_UNREF_DELETE(peer);
tx_msdu_info->peer = NULL;
}
return NULL;
@@ -605,7 +605,7 @@
"%s: remove the peer reference %p\n",
__func__, peer);
/* remove the peer reference added above */
- ol_txrx_peer_unref_delete(tx_msdu_info->peer);
+ OL_TXRX_PEER_UNREF_DELETE(tx_msdu_info->peer);
/* Making peer NULL in case if multicast non STA mode */
tx_msdu_info->peer = NULL;
}
@@ -688,11 +688,7 @@
if (ol_txrx_peer_find_mac_addr_cmp(
mac_addr,
&peer->mac_addr) != 0) {
- rcnt = ol_txrx_peer_unref_delete(peer);
- QDF_TRACE(QDF_MODULE_ID_TXRX,
- QDF_TRACE_LEVEL_INFO_HIGH,
- "%s: peer %p peer->ref_cnt %d",
- __func__, peer, rcnt);
+ rcnt = OL_TXRX_PEER_UNREF_DELETE(peer);
peer = NULL;
}
}
diff --git a/core/dp/txrx/ol_tx_desc.c b/core/dp/txrx/ol_tx_desc.c
index ed587f0..f5ffd5f 100644
--- a/core/dp/txrx/ol_tx_desc.c
+++ b/core/dp/txrx/ol_tx_desc.c
@@ -767,6 +767,9 @@
if (tsoseg != NULL) {
txdesc = tsoseg->dbg.txdesc;
+ /* Don't validate if TX desc is NULL*/
+ if (!txdesc)
+ return 0;
if (txdesc->tso_desc != tsoseg)
qdf_tso_seg_dbg_bug("Owner sanity failed");
else
@@ -849,6 +852,7 @@
}
/* sanitize before free */
ol_tso_seg_dbg_sanitize(tso_seg);
+ qdf_tso_seg_dbg_setowner(tso_seg, NULL);
/*this tso seg is now a part of freelist*/
/* retain segment history, if debug is enabled */
qdf_tso_seg_dbg_zero(tso_seg);
diff --git a/core/dp/txrx/ol_tx_queue.c b/core/dp/txrx/ol_tx_queue.c
index 0014555..581ed49 100644
--- a/core/dp/txrx/ol_tx_queue.c
+++ b/core/dp/txrx/ol_tx_queue.c
@@ -111,13 +111,7 @@
for (i = 0; i < OL_TX_NUM_TIDS; i++) {
txq = &peer->txqs[i];
if (txq->frms) {
- qdf_atomic_inc(&peer->ref_cnt);
- QDF_TRACE(QDF_MODULE_ID_TXRX,
- QDF_TRACE_LEVEL_INFO_HIGH,
- "%s: peer %p peer->ref_cnt %d",
- __func__, peer,
- qdf_atomic_read
- (&peer->ref_cnt));
+ OL_TXRX_PEER_INC_REF_CNT(peer);
peers[peer_count++] = peer;
break;
}
@@ -135,7 +129,7 @@
}
ol_txrx_info(
"%s: Delete Peer %p\n", __func__, peer);
- ol_txrx_peer_unref_delete(peers[i]);
+ OL_TXRX_PEER_UNREF_DELETE(peers[i]);
}
} while (peer_count >= PEER_ARRAY_COUNT);
}
diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c
index 2e10de5..b984126 100644
--- a/core/dp/txrx/ol_txrx.c
+++ b/core/dp/txrx/ol_txrx.c
@@ -310,10 +310,7 @@
if (!peer)
return NULL;
*peer_id = peer->local_id;
- qdf_atomic_dec(&peer->ref_cnt);
- QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
- "%s: peer %p peer->ref_cnt %d", __func__, peer,
- qdf_atomic_read(&peer->ref_cnt));
+ OL_TXRX_PEER_DEC_REF_CNT(peer);
return peer;
}
@@ -369,11 +366,8 @@
if (!peer)
return NULL;
*peer_id = peer->local_id;
- qdf_atomic_dec(&peer->ref_cnt);
- QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
- "%s: peer %p peer->ref_cnt %d", __func__, peer,
- qdf_atomic_read(&peer->ref_cnt));
- return (void *)peer;
+ OL_TXRX_PEER_DEC_REF_CNT(peer);
+ return peer;
}
static uint16_t ol_txrx_local_peer_id(void *ppeer)
@@ -1813,7 +1807,7 @@
}
/* to get flow pool status before freeing descs */
- ol_tx_dump_flow_pool_info();
+ ol_tx_dump_flow_pool_info((void *)pdev);
for (i = 0; i < pdev->tx_desc.pool_size; i++) {
void *htt_tx_desc;
@@ -2505,7 +2499,7 @@
qdf_atomic_init(&peer->ref_cnt);
/* keep one reference for attach */
- qdf_atomic_inc(&peer->ref_cnt);
+ OL_TXRX_PEER_INC_REF_CNT(peer);
/*
* Set a flag to indicate peer create is pending in firmware and
@@ -2516,7 +2510,7 @@
*/
qdf_atomic_init(&peer->fw_create_pending);
qdf_atomic_set(&peer->fw_create_pending, 1);
- qdf_atomic_inc(&peer->ref_cnt);
+ OL_TXRX_PEER_INC_REF_CNT(peer);
peer->valid = 1;
qdf_timer_init(pdev->osdev, &peer->peer_unmap_timer,
@@ -2943,11 +2937,7 @@
"%s: no state change, returns directly\n",
__func__);
#endif
- peer_ref_cnt = ol_txrx_peer_unref_delete(peer);
- QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
- "%s: peer %p peer->ref_cnt %d",
- __func__, peer, peer_ref_cnt);
-
+ peer_ref_cnt = OL_TXRX_PEER_UNREF_DELETE(peer);
return QDF_STATUS_SUCCESS;
}
@@ -2977,15 +2967,12 @@
ol_txrx_peer_tid_unpause(peer, tid);
}
}
- peer_ref_cnt = ol_txrx_peer_unref_delete(peer);
- QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
- "%s: peer %p peer->ref_cnt %d",
- __func__, peer, peer_ref_cnt);
+ peer_ref_cnt = OL_TXRX_PEER_UNREF_DELETE(peer);
/*
- * after ol_txrx_peer_unref_delete, peer object cannot be accessed
+ * after OL_TXRX_PEER_UNREF_DELETE, peer object cannot be accessed
* if the return code was 0
*/
- if (peer_ref_cnt)
+ if (peer_ref_cnt > 0)
/*
* Set the state after the Pause to avoid the race condiction
* with ADDBA check in tx path
@@ -3090,10 +3077,7 @@
break;
}
} /* switch */
- peer_ref_cnt = ol_txrx_peer_unref_delete(peer);
- QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
- "%s: peer %p peer->ref_cnt %d",
- __func__, peer, peer_ref_cnt);
+ peer_ref_cnt = OL_TXRX_PEER_UNREF_DELETE(peer);
}
uint8_t
@@ -3119,7 +3103,9 @@
return 0;
}
-int ol_txrx_peer_unref_delete(ol_txrx_peer_handle peer)
+int ol_txrx_peer_unref_delete(ol_txrx_peer_handle peer,
+ const char *fname,
+ int line)
{
int rc;
struct ol_txrx_vdev_t *vdev;
@@ -3285,8 +3271,8 @@
} else {
qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
- "%s: peer %p peer->ref_cnt = %d",
- __func__, peer, rc);
+ "ref delete(%s): peer %p peer->ref_cnt = %d",
+ fname, peer, rc);
}
return rc;
@@ -3347,8 +3333,26 @@
}
+void peer_unmap_timer_work_function(void *param)
+{
+ WMA_LOGE("Enter: %s", __func__);
+ /*
+ * wma_peer_debug_dump() will be replaced with a new routine.
+ * Add the equivalent of wma_peer_debug_dump() when available.
+ */
+ if (cds_is_self_recovery_enabled()) {
+ if (!cds_is_driver_recovering())
+ cds_trigger_recovery(false);
+ else
+ WMA_LOGE("%s: Recovery is in progress, ignore!",
+ __func__);
+ } else {
+ QDF_BUG(0);
+ }
+}
+
/**
- * peer_unmap_timer() - peer unmap timer function
+ * peer_unmap_timer_handler() - peer unmap timer function
* @data: peer object pointer
*
* Return: none
@@ -3356,6 +3360,7 @@
void peer_unmap_timer_handler(void *data)
{
ol_txrx_peer_handle peer = (ol_txrx_peer_handle)data;
+ ol_txrx_pdev_handle txrx_pdev = cds_get_context(QDF_MODULE_ID_TXRX);
ol_txrx_err("all unmap events not received for peer %p, ref_cnt %d",
peer, qdf_atomic_read(&peer->ref_cnt));
@@ -3365,10 +3370,10 @@
peer->mac_addr.raw[2], peer->mac_addr.raw[3],
peer->mac_addr.raw[4], peer->mac_addr.raw[5]);
if (!cds_is_driver_recovering()) {
- /*
- * Add the equivalent of wma_peer_debug_dump() when available.
- */
- QDF_BUG(0);
+ qdf_create_work(0, &txrx_pdev->peer_unmap_timer_work,
+ peer_unmap_timer_work_function,
+ NULL);
+ qdf_sched_work(0, &txrx_pdev->peer_unmap_timer_work);
} else {
ol_txrx_err("Recovery is in progress, ignore!");
}
@@ -3449,7 +3454,7 @@
* PEER_UNMAP message arrives to remove the other
* reference, added by the PEER_MAP message.
*/
- ol_txrx_peer_unref_delete(peer);
+ OL_TXRX_PEER_UNREF_DELETE(peer);
}
/**
@@ -3477,7 +3482,7 @@
qdf_spin_unlock_bh(&pdev->peer_map_unmap_lock);
/*
- * Set ref_cnt = 1 so that ol_txrx_peer_unref_delete() called by
+ * Set ref_cnt = 1 so that OL_TXRX_PEER_UNREF_DELETE() called by
* ol_txrx_peer_detach() will actually delete this peer entry properly.
*/
qdf_spin_lock_bh(&pdev->peer_ref_mutex);
@@ -3497,7 +3502,7 @@
ol_txrx_info_high(
"%s: Delete extra reference %p", __func__, peer);
/* release the extra reference */
- ol_txrx_peer_unref_delete(peer);
+ OL_TXRX_PEER_UNREF_DELETE(peer);
}
return peer;
}
@@ -4580,7 +4585,7 @@
ol_txrx_stats_display_tso(pdev);
break;
case CDP_DUMP_TX_FLOW_POOL_INFO:
- ol_tx_dump_flow_pool_info();
+ ol_tx_dump_flow_pool_info((void *)pdev);
break;
case CDP_TXRX_DESC_STATS:
qdf_nbuf_tx_desc_count_display();
@@ -4993,7 +4998,8 @@
*
* Return: QDF status
*/
-static QDF_STATUS ol_txrx_register_pause_cb(ol_tx_pause_callback_fp pause_cb)
+static QDF_STATUS ol_txrx_register_pause_cb(struct cdp_soc_t *soc,
+ tx_pause_callback pause_cb)
{
struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
@@ -5362,7 +5368,7 @@
#ifdef QCA_LL_TX_FLOW_CONTROL_V2
.register_pause_cb = ol_txrx_register_pause_cb,
.set_desc_global_pool_size = ol_tx_set_desc_global_pool_size,
- .dump_flow_pool_info = ol_tx_dump_flow_pool_info
+ .dump_flow_pool_info = ol_tx_dump_flow_pool_info,
#endif /* QCA_LL_TX_FLOW_CONTROL_V2 */
};
diff --git a/core/dp/txrx/ol_txrx.h b/core/dp/txrx/ol_txrx.h
index de60f40..f4c9927 100644
--- a/core/dp/txrx/ol_txrx.h
+++ b/core/dp/txrx/ol_txrx.h
@@ -39,8 +39,13 @@
* only for forwarding path.
*/
#define OL_TX_NON_FWD_RESERVE 100
+#define OL_TXRX_PEER_UNREF_DELETE(peer) \
+ ol_txrx_peer_unref_delete(peer, __func__, __LINE__);
-int ol_txrx_peer_unref_delete(struct ol_txrx_peer_t *peer);
+int ol_txrx_peer_unref_delete(ol_txrx_peer_handle peer,
+ const char *fname,
+ int line);
+
/**
* ol_tx_desc_pool_size_hl() - allocate tx descriptor pool size for HL systems
@@ -123,6 +128,7 @@
uint8_t *peer_id);
void htt_pkt_log_init(struct cdp_pdev *pdev_handle, void *scn);
+void peer_unmap_timer_work_function(void *);
void peer_unmap_timer_handler(void *data);
#endif /* _OL_TXRX__H_ */
diff --git a/core/dp/txrx/ol_txrx_flow_control.c b/core/dp/txrx/ol_txrx_flow_control.c
index 0373352..405ed38 100644
--- a/core/dp/txrx/ol_txrx_flow_control.c
+++ b/core/dp/txrx/ol_txrx_flow_control.c
@@ -128,8 +128,10 @@
break;
qdf_spin_unlock_bh(&pdev->tx_desc.flow_pool_list_lock);
ol_txrx_info("flow pool list is not empty %d!!!\n", i++);
+
if (i == 1)
- ol_tx_dump_flow_pool_info();
+ ol_tx_dump_flow_pool_info((void *)pdev);
+
ol_tx_dec_pool_ref(pool, true);
qdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock);
}
@@ -274,13 +276,12 @@
*
* Return: none
*/
-void ol_tx_dump_flow_pool_info(void)
+void ol_tx_dump_flow_pool_info(void *ctx)
{
- struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+ struct ol_txrx_pdev_t *pdev = ctx;
struct ol_tx_flow_pool_t *pool = NULL, *pool_prev = NULL;
struct ol_tx_flow_pool_t tmp_pool;
-
ol_txrx_info("Global Pool");
if (!pdev) {
ol_txrx_err("ERROR: pdev NULL");
diff --git a/core/dp/txrx/ol_txrx_peer_find.c b/core/dp/txrx/ol_txrx_peer_find.c
index ad21218..914bf81 100644
--- a/core/dp/txrx/ol_txrx_peer_find.c
+++ b/core/dp/txrx/ol_txrx_peer_find.c
@@ -69,6 +69,26 @@
return log2;
}
+/**
+ * __ol_txrx_peer_change_ref_cnt() - change peer ref count by the input value
+ * @peer: pointer to peer structure
+ * @change: value to add to the peer->ref_cnt, can be negative
+ * @fname: name of the calling function
+ * @line: line number of the calling function
+ *
+ * Return: the QDF_STATUS return from hdd_execute_config_command
+ */
+void __ol_txrx_peer_change_ref_cnt(struct ol_txrx_peer_t *peer,
+ int change,
+ const char *fname,
+ int line)
+{
+ qdf_atomic_add(change, &peer->ref_cnt);
+ QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
+ "[%s][%d]: peer %p peer->ref_cnt changed by(%d) to %d",
+ fname, line, peer, change, qdf_atomic_read(&peer->ref_cnt));
+}
+
/*=== function definitions for peer MAC addr --> peer object hash table =====*/
/*
@@ -178,15 +198,9 @@
if (ol_txrx_peer_find_mac_addr_cmp(mac_addr, &peer->mac_addr) ==
0 && (check_valid == 0 || peer->valid)
&& peer->vdev == vdev) {
- /*
- * found it - increment the ref count before releasing
- * the lock
- */
- qdf_atomic_inc(&peer->ref_cnt);
- QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
- "%s: peer %p peer->ref_cnt %d",
- __func__, peer,
- qdf_atomic_read(&peer->ref_cnt));
+
+ /* found it */
+ OL_TXRX_PEER_INC_REF_CNT(peer);
qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
return peer;
}
@@ -216,16 +230,9 @@
TAILQ_FOREACH(peer, &pdev->peer_hash.bins[index], hash_list_elem) {
if (ol_txrx_peer_find_mac_addr_cmp(mac_addr, &peer->mac_addr) ==
0 && (check_valid == 0 || peer->valid)) {
- /*
- * found it - increment the ref count before
- * releasing the lock
- */
- qdf_atomic_inc(&peer->ref_cnt);
+ /* found it */
+ OL_TXRX_PEER_INC_REF_CNT(peer);
qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
- QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
- "%s: peer %p peer->ref_cnt %d",
- __func__, peer,
- qdf_atomic_read(&peer->ref_cnt));
return peer;
}
}
@@ -286,16 +293,11 @@
/*
* Artificially adjust the peer's ref count to
* 1, so it will get deleted by
- * ol_txrx_peer_unref_delete.
+ * OL_TXRX_PEER_UNREF_DELETE.
*/
qdf_atomic_init(&peer->ref_cnt); /* set to 0 */
- qdf_atomic_inc(&peer->ref_cnt); /* incr to 1 */
- QDF_TRACE(QDF_MODULE_ID_TXRX,
- QDF_TRACE_LEVEL_INFO_HIGH,
- "%s: Delete Peer %p ref_cnt %d\n",
- __func__, peer,
- qdf_atomic_read(&peer->ref_cnt));
- ol_txrx_peer_unref_delete(peer);
+ OL_TXRX_PEER_INC_REF_CNT(peer); /* incr to 1 */
+ OL_TXRX_PEER_UNREF_DELETE(peer);
}
}
}
@@ -345,6 +347,8 @@
struct ol_txrx_peer_t *peer;
int status;
int i;
+ uint32_t peer_id_ref_cnt;
+ uint32_t peer_ref_cnt;
/* check if there's already a peer object with this MAC address */
peer =
@@ -395,18 +399,17 @@
* was sent to firmware.
*/
qdf_atomic_set(&peer->fw_create_pending, 0);
- ol_txrx_peer_unref_delete(peer);
+ OL_TXRX_PEER_UNREF_DELETE(peer);
}
qdf_spin_unlock(&pdev->peer_map_unmap_lock);
- QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+ peer_id_ref_cnt = qdf_atomic_read(&pdev->
+ peer_id_to_obj_map[peer_id].peer_id_ref_cnt);
+ peer_ref_cnt = qdf_atomic_read(&peer->ref_cnt);
+ QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
"%s: peer %p ID %d peer_id[%d] peer_id_ref_cnt %d peer->ref_cnt %d",
- __func__, peer, peer_id, i,
- qdf_atomic_read(&pdev->
- peer_id_to_obj_map[peer_id].
- peer_id_ref_cnt),
- qdf_atomic_read(&peer->ref_cnt));
+ __func__, peer, peer_id, i, peer_id_ref_cnt, peer_ref_cnt);
if (status) {
/* TBDXXX: assert for now */
@@ -591,7 +594,7 @@
* Remove a reference to the peer.
* If there are no more references, delete the peer object.
*/
- ol_txrx_peer_unref_delete(peer);
+ OL_TXRX_PEER_UNREF_DELETE(peer);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"%s: Remove the ID %d reference to peer %p peer_id_ref_cnt %d",
@@ -633,7 +636,7 @@
peer_id, peer_id_ref_cnt, i);
/*
* Transfer peer_id_ref_cnt into del_peer_id_ref_cnt so that
- * ol_txrx_peer_unref_delete will decrement del_peer_id_ref_cnt
+ * OL_TXRX_PEER_UNREF_DELETE will decrement del_peer_id_ref_cnt
* and any map events will increment peer_id_ref_cnt. Otherwise
* accounting will be messed up.
*
@@ -660,13 +663,8 @@
*/
if (vdev->last_real_peer
&& vdev->last_real_peer->peer_ids[0] != HTT_INVALID_PEER_ID) {
- qdf_atomic_inc(&vdev->last_real_peer->ref_cnt);
+ OL_TXRX_PEER_INC_REF_CNT(vdev->last_real_peer);
peer = vdev->last_real_peer;
- QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
- "%s: peer %p peer->ref_cnt %d",
- __func__, peer,
- qdf_atomic_read
- (&peer->ref_cnt));
} else {
peer = NULL;
}
diff --git a/core/dp/txrx/ol_txrx_peer_find.h b/core/dp/txrx/ol_txrx_peer_find.h
index 5e826af..df717a5 100644
--- a/core/dp/txrx/ol_txrx_peer_find.h
+++ b/core/dp/txrx/ol_txrx_peer_find.h
@@ -36,6 +36,17 @@
#include <cdp_txrx_cmn.h> /* ol_txrx_pdev_t, etc. */
#include <ol_txrx_internal.h> /* TXRX_ASSERT */
+
+#define OL_TXRX_PEER_INC_REF_CNT(peer) \
+ __ol_txrx_peer_change_ref_cnt(peer, 1, __func__, __LINE__);
+
+#define OL_TXRX_PEER_DEC_REF_CNT(peer) \
+ __ol_txrx_peer_change_ref_cnt(peer, (-1), __func__, __LINE__);
+
+void __ol_txrx_peer_change_ref_cnt(struct ol_txrx_peer_t *peer,
+ int change,
+ const char *fname,
+ int line);
int ol_txrx_peer_find_attach(struct ol_txrx_pdev_t *pdev);
void ol_txrx_peer_find_detach(struct ol_txrx_pdev_t *pdev);
@@ -107,10 +118,8 @@
void ol_txrx_peer_find_hash_erase(struct ol_txrx_pdev_t *pdev);
struct ol_txrx_peer_t *ol_txrx_assoc_peer_find(struct ol_txrx_vdev_t *vdev);
-
void ol_txrx_peer_remove_obj_map_entries(ol_txrx_pdev_handle pdev,
struct ol_txrx_peer_t *peer);
-
#if defined(TXRX_DEBUG_LEVEL) && TXRX_DEBUG_LEVEL > 5
void ol_txrx_peer_find_display(ol_txrx_pdev_handle pdev, int indent);
#else
diff --git a/core/dp/txrx/ol_txrx_types.h b/core/dp/txrx/ol_txrx_types.h
index 969c01d..b9e48c6 100644
--- a/core/dp/txrx/ol_txrx_types.h
+++ b/core/dp/txrx/ol_txrx_types.h
@@ -48,7 +48,7 @@
#include "ol_htt_tx_api.h"
#include "ol_htt_rx_api.h"
#include "ol_txrx_ctrl_api.h" /* WLAN_MAX_STA_COUNT */
-#include "ol_txrx_osif_api.h" /* ol_rx_callback_fp */
+#include "ol_txrx_osif_api.h" /* ol_rx_callback */
#include "cdp_txrx_flow_ctrl_v2.h"
#include "cdp_txrx_peer_ops.h"
@@ -971,13 +971,14 @@
int tid_to_ac[OL_TX_NUM_TIDS + OL_TX_VDEV_NUM_QUEUES];
uint8_t ocb_peer_valid;
struct ol_txrx_peer_t *ocb_peer;
- ol_tx_pause_callback_fp pause_cb;
+ tx_pause_callback pause_cb;
struct {
void (*lro_flush_cb)(void *);
qdf_atomic_t lro_dev_cnt;
} lro_info;
struct ol_txrx_peer_t *self_peer;
+ qdf_work_t peer_unmap_timer_work;
};
struct ol_txrx_vdev_t {
diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h
index 5375635..7c512b9 100644
--- a/core/hdd/inc/wlan_hdd_cfg.h
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -5798,6 +5798,29 @@
#define CFG_RATE_FOR_TX_MGMT_5G_MAX (WNI_CFG_RATE_FOR_TX_MGMT_5G_STAMAX)
#define CFG_RATE_FOR_TX_MGMT_5G_DEFAULT (WNI_CFG_RATE_FOR_TX_MGMT_5G_STADEF)
+/*
+ * <ini>
+ * gPreventLinkDown - Enable to prevent bus link from going down
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * Enable to prevent bus link from going down. Useful for platforms that do not
+ * (yet) support link down suspend cases.
+ *
+ * Related: N/A
+ *
+ * Supported Feature: Suspend/Resume
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_PREVENT_LINK_DOWN_NAME "gPreventLinkDown"
+#define CFG_PREVENT_LINK_DOWN_MIN (0)
+#define CFG_PREVENT_LINK_DOWN_MAX (1)
+#define CFG_PREVENT_LINK_DOWN_DEFAULT (0)
+
#ifdef FEATURE_WLAN_TDLS
/*
* <ini>
@@ -10457,6 +10480,70 @@
#define CFG_ITO_REPEAT_COUNT_MAX (5)
#define CFG_ITO_REPEAT_COUNT_DEFAULT (0)
/*
+ * <ini>
+ * groam_disallow_duration -disallow duration before roaming
+ * @Min: 0
+ * @Max: 3600
+ * @Default: 30
+ *
+ * This ini is used to configure how long LCA[Last Connected AP] AP will
+ * be disallowed before it can be a roaming candidate again, in units of
+ * seconds.
+ *
+ * Related: LFR
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_ROAM_DISALLOW_DURATION_NAME "groam_disallow_duration"
+#define CFG_ROAM_DISALLOW_DURATION_MIN (0)
+#define CFG_ROAM_DISALLOW_DURATION_MAX (3600)
+#define CFG_ROAM_DISALLOW_DURATION_DEFAULT (30)
+
+/*
+ * <ini>
+ * grssi_channel_penalization - RSSI penalization
+ * @Min: 0
+ * @Max: 15
+ * @Default: 5
+ *
+ * This ini is used to configure RSSI that will be penalized if candidate(s)
+ * are found to be in the same channel as disallowed AP's, in units of db.
+ *
+ * Related: LFR
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_ROAM_RSSI_CHANNEL_PENALIZATION_NAME "grssi_channel_penalization"
+#define CFG_ROAM_RSSI_CHANNEL_PENALIZATION_MIN (0)
+#define CFG_ROAM_RSSI_CHANNEL_PENALIZATION_MAX (15)
+#define CFG_ROAM_RSSI_CHANNEL_PENALIZATION_DEFAULT (5)
+
+/*
+ * <ini>
+ * groam_num_disallowed_aps - Max number of AP's to maintain in LCA list
+ * @Min: 0
+ * @Max: 8
+ * @Default: 3
+ *
+ * This ini is used to set the maximum number of AP's to be maintained
+ * in LCA [Last Connected AP] list.
+ *
+ * Related: LFR
+ *
+ * Usage: Internal
+ *
+ * </ini>
+ */
+#define CFG_ROAM_NUM_DISALLOWED_APS_NAME "groam_num_disallowed_aps"
+#define CFG_ROAM_NUM_DISALLOWED_APS_MIN (0)
+#define CFG_ROAM_NUM_DISALLOWED_APS_MAX (8)
+#define CFG_ROAM_NUM_DISALLOWED_APS_DEFAULT (3)
+
+/*
* Type declarations
*/
@@ -10784,6 +10871,7 @@
uint8_t enable_tx_ldpc;
uint8_t enable_rx_ldpc;
bool enable5gEBT;
+ bool prevent_link_down;
#ifdef FEATURE_WLAN_TDLS
bool fEnableTDLSSupport;
bool fEnableTDLSImplicitTrigger;
@@ -11200,6 +11288,11 @@
uint16_t num_11b_tx_chains;
uint16_t num_11ag_tx_chains;
uint8_t ito_repeat_count;
+
+ /* LCA(Last connected AP) disallow configs */
+ uint32_t disallow_duration;
+ uint32_t rssi_channel_penalization;
+ uint32_t num_disallowed_aps;
};
#define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var))
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index 822e49e..4a1cb2b 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -92,6 +92,14 @@
#define NUM_TX_QUEUES 4
#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
+#define HDD_NL80211_BAND_2GHZ NL80211_BAND_2GHZ
+#define HDD_NL80211_BAND_5GHZ NL80211_BAND_5GHZ
+#else
+#define HDD_NL80211_BAND_2GHZ IEEE80211_BAND_2GHZ
+#define HDD_NL80211_BAND_5GHZ IEEE80211_BAND_5GHZ
+#endif
+
/** Length of the TX queue for the netdev */
#define HDD_NETDEV_TX_QUEUE_LEN (3000)
@@ -288,6 +296,7 @@
#define HDD_SESSION_ID_INVALID 0xFF
#define SCAN_REJECT_THRESHOLD_TIME 300000 /* Time is in msec, equal to 5 mins */
+#define SCAN_REJECT_THRESHOLD 15
/* Default Psoc id */
#define DEFAULT_PSOC_ID 1
@@ -1619,6 +1628,7 @@
uint8_t last_scan_reject_session_id;
enum scan_reject_states last_scan_reject_reason;
unsigned long last_scan_reject_timestamp;
+ uint8_t scan_reject_cnt;
bool dfs_cac_offload;
bool reg_offload;
#ifdef FEATURE_WLAN_CH_AVOID
@@ -1635,6 +1645,8 @@
/* the context that is capturing tsf */
hdd_adapter_t *cap_tsf_context;
#endif
+ uint8_t bt_a2dp_active:1;
+ uint8_t bt_vo_active:1;
};
/**
diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c
index c76fd7f..3a24594 100644
--- a/core/hdd/src/wlan_hdd_assoc.c
+++ b/core/hdd/src/wlan_hdd_assoc.c
@@ -165,31 +165,30 @@
/**
* hdd_conn_set_connection_state() - set connection state
- * @pAdapter: pointer to the adapter
- * @connState: connection state
+ * @adapter: pointer to the adapter
+ * @conn_state: connection state
*
* This function updates the global HDD station context connection state.
*
* Return: none
*/
-void hdd_conn_set_connection_state(hdd_adapter_t *pAdapter,
- eConnectionState connState)
+void hdd_conn_set_connection_state(hdd_adapter_t *adapter,
+ eConnectionState conn_state)
{
- hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
- hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+ hdd_station_ctx_t *hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+ hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
/* save the new connection state */
- hdd_debug("%pS Changed connectionState Changed from oldState:%d to State:%d",
- (void *)_RET_IP_, pHddStaCtx->conn_info.connState,
- connState);
+ hdd_debug("%pS Changed conn state from old:%d to new:%d for dev %s",
+ (void *)_RET_IP_, hdd_sta_ctx->conn_info.connState,
+ conn_state, adapter->dev->name);
- hdd_tsf_notify_wlan_state_change(pAdapter,
- pHddStaCtx->conn_info.connState,
- connState);
- pHddStaCtx->conn_info.connState = connState;
+ hdd_tsf_notify_wlan_state_change(adapter,
+ hdd_sta_ctx->conn_info.connState,
+ conn_state);
+ hdd_sta_ctx->conn_info.connState = conn_state;
- /* Check is pending ROC request or not when connection state changed */
- schedule_delayed_work(&pHddCtx->roc_req_work, 0);
+ schedule_delayed_work(&hdd_ctx->roc_req_work, 0);
}
/**
@@ -2113,8 +2112,11 @@
QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
buf_ssid_ie, ssid_ie_len);
final_req_ie = qdf_mem_malloc(IW_GENERIC_IE_MAX);
- if (final_req_ie == NULL)
+ if (final_req_ie == NULL) {
+ if (bss)
+ cfg80211_put_bss(pAdapter->wdev.wiphy, bss);
goto done;
+ }
buf_ptr = final_req_ie;
qdf_mem_copy(buf_ptr, buf_ssid_ie, ssid_ie_len);
buf_ptr += ssid_ie_len;
@@ -2471,7 +2473,9 @@
pHddStaCtx->conn_info.connState)) &&
((eCSR_ROAM_RESULT_ASSOCIATED == roamResult) ||
(eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus))) {
- hdd_info("Disconnect from HDD in progress");
+ hdd_info("hddDisconInProgress state=%d, result=%d, status=%d",
+ pHddStaCtx->conn_info.connState,
+ roamResult, roamStatus);
hddDisconInProgress = true;
}
@@ -3204,10 +3208,10 @@
if (chan_no <= 14)
freq = ieee80211_channel_to_frequency(chan_no,
- NL80211_BAND_2GHZ);
+ HDD_NL80211_BAND_2GHZ);
else
freq = ieee80211_channel_to_frequency(chan_no,
- NL80211_BAND_5GHZ);
+ HDD_NL80211_BAND_5GHZ);
chan = ieee80211_get_channel(pAdapter->wdev.wiphy, freq);
@@ -3347,8 +3351,8 @@
if (MAX_PEERS == empty_slots) {
/* Last peer departed, set the IBSS state appropriately */
- pHddStaCtx->conn_info.connState =
- eConnectionState_IbssDisconnected;
+ hdd_conn_set_connection_state(pAdapter,
+ eConnectionState_IbssDisconnected);
hdd_debug("Last IBSS Peer Departed!!!");
}
/* Find next active staId, to have a valid sta trigger for TL. */
@@ -3445,7 +3449,7 @@
hdd_debug("MIC MAC " MAC_ADDRESS_STR,
MAC_ADDR_ARRAY(msg.src_addr.sa_data));
- if (pRoamInfo->u.pMICFailureInfo->multicast == eSIR_TRUE)
+ if (pRoamInfo->u.pMICFailureInfo->multicast == true)
msg.flags = IW_MICFAILURE_GROUP;
else
msg.flags = IW_MICFAILURE_PAIRWISE;
@@ -3459,7 +3463,7 @@
taMacAddr,
((pRoamInfo->u.pMICFailureInfo->
multicast ==
- eSIR_TRUE) ?
+ true) ?
NL80211_KEYTYPE_GROUP :
NL80211_KEYTYPE_PAIRWISE),
pRoamInfo->u.pMICFailureInfo->
diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c
index 07c7036..0a29fc0 100644
--- a/core/hdd/src/wlan_hdd_cfg.c
+++ b/core/hdd/src/wlan_hdd_cfg.c
@@ -2197,6 +2197,13 @@
CFG_PPS_ENABLE_5G_EBT_FEATURE_MIN,
CFG_PPS_ENABLE_5G_EBT_FEATURE_MAX),
+ REG_VARIABLE(CFG_PREVENT_LINK_DOWN_NAME, WLAN_PARAM_Integer,
+ struct hdd_config, prevent_link_down,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_PREVENT_LINK_DOWN_DEFAULT,
+ CFG_PREVENT_LINK_DOWN_MIN,
+ CFG_PREVENT_LINK_DOWN_MAX),
+
#ifdef FEATURE_WLAN_TDLS
REG_VARIABLE(CFG_TDLS_SUPPORT_ENABLE, WLAN_PARAM_Integer,
struct hdd_config, fEnableTDLSSupport,
@@ -4463,6 +4470,27 @@
CFG_ITO_REPEAT_COUNT_MIN,
CFG_ITO_REPEAT_COUNT_MAX),
+ REG_VARIABLE(CFG_ROAM_DISALLOW_DURATION_NAME, WLAN_PARAM_Integer,
+ struct hdd_config, disallow_duration,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_ROAM_DISALLOW_DURATION_DEFAULT,
+ CFG_ROAM_DISALLOW_DURATION_MIN,
+ CFG_ROAM_DISALLOW_DURATION_MAX),
+
+ REG_VARIABLE(CFG_ROAM_RSSI_CHANNEL_PENALIZATION_NAME,
+ WLAN_PARAM_Integer, struct hdd_config,
+ rssi_channel_penalization,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_ROAM_RSSI_CHANNEL_PENALIZATION_DEFAULT,
+ CFG_ROAM_RSSI_CHANNEL_PENALIZATION_MIN,
+ CFG_ROAM_RSSI_CHANNEL_PENALIZATION_MAX),
+
+ REG_VARIABLE(CFG_ROAM_NUM_DISALLOWED_APS_NAME, WLAN_PARAM_Integer,
+ struct hdd_config, num_disallowed_aps,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_ROAM_NUM_DISALLOWED_APS_DEFAULT,
+ CFG_ROAM_NUM_DISALLOWED_APS_MIN,
+ CFG_ROAM_NUM_DISALLOWED_APS_MAX),
};
@@ -6004,6 +6032,15 @@
hdd_debug("Name = [%s] value = [%u]",
CFG_ITO_REPEAT_COUNT_NAME,
pHddCtx->config->ito_repeat_count);
+ hdd_debug("Name = [%s] Value = [%u]",
+ CFG_ROAM_DISALLOW_DURATION_NAME,
+ pHddCtx->config->disallow_duration);
+ hdd_debug("Name = [%s] Value = [%u]",
+ CFG_ROAM_RSSI_CHANNEL_PENALIZATION_NAME,
+ pHddCtx->config->rssi_channel_penalization);
+ hdd_debug("Name = [%s] Value = [%u]",
+ CFG_ROAM_NUM_DISALLOWED_APS_NAME,
+ pHddCtx->config->num_disallowed_aps);
}
@@ -7238,6 +7275,27 @@
return status;
}
/**
+ * hdd_to_csr_wmm_mode() - Utility function to convert HDD to CSR WMM mode
+ *
+ * @enum hdd_wmm_user_mode - hdd WMM user mode
+ *
+ * Return: CSR WMM mode
+ */
+static eCsrRoamWmmUserModeType
+hdd_to_csr_wmm_mode(enum hdd_wmm_user_mode mode)
+{
+ switch (mode) {
+ case HDD_WMM_USER_MODE_QBSS_ONLY:
+ return eCsrRoamWmmQbssOnly;
+ case HDD_WMM_USER_MODE_NO_QOS:
+ return eCsrRoamWmmNoQos;
+ case HDD_WMM_USER_MODE_AUTO:
+ default:
+ return eCsrRoamWmmAuto;
+ }
+}
+
+/**
* hdd_set_sme_config() -initializes the sme configuration parameters
*
* @pHddCtx: the pointer to hdd context
@@ -7321,7 +7379,8 @@
#endif
smeConfig->csrConfig.Is11eSupportEnabled = pConfig->b80211eIsEnabled;
- smeConfig->csrConfig.WMMSupportMode = pConfig->WmmMode;
+ smeConfig->csrConfig.WMMSupportMode =
+ hdd_to_csr_wmm_mode(pConfig->WmmMode);
smeConfig->rrmConfig.rrm_enabled = pConfig->fRrmEnable;
smeConfig->rrmConfig.max_randn_interval = pConfig->nRrmRandnIntvl;
@@ -7604,6 +7663,13 @@
smeConfig->csrConfig.pkt_err_disconn_th =
pHddCtx->config->pkt_err_disconn_th;
+ smeConfig->csrConfig.disallow_duration =
+ pHddCtx->config->disallow_duration;
+ smeConfig->csrConfig.rssi_channel_penalization =
+ pHddCtx->config->rssi_channel_penalization;
+ smeConfig->csrConfig.num_disallowed_aps =
+ pHddCtx->config->num_disallowed_aps;
+
smeConfig->csrConfig.is_force_1x1 =
pHddCtx->config->is_force_1x1;
smeConfig->csrConfig.num_11b_tx_chains =
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index cd80c13..2276153 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -112,6 +112,44 @@
#include "wlan_utility.h"
#include "wlan_reg_ucfg_api.h"
+/* define short names for get station info attributes */
+#ifndef LINK_INFO_STANDARD_NL80211_ATTR
+#define LINK_INFO_STANDARD_NL80211_ATTR \
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_LINK_STANDARD_NL80211_ATTR
+#endif
+#ifndef AP_INFO_STANDARD_NL80211_ATTR
+#define AP_INFO_STANDARD_NL80211_ATTR \
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AP_STANDARD_NL80211_ATTR
+#endif
+#ifndef INFO_ROAM_COUNT
+#define INFO_ROAM_COUNT \
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ROAM_COUNT
+#endif
+#ifndef INFO_AKM
+#define INFO_AKM \
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AKM
+#endif
+#ifndef WLAN802_11_MODE
+#define WLAN802_11_MODE \
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_802_11_MODE
+#endif
+#ifndef AP_INFO_HS20_INDICATION
+#define AP_INFO_HS20_INDICATION \
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AP_HS20_INDICATION
+#endif
+#ifndef HT_OPERATION
+#define HT_OPERATION \
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_HT_OPERATION
+#endif
+#ifndef VHT_OPERATION
+#define VHT_OPERATION \
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_VHT_OPERATION
+#endif
+#ifndef INFO_ASSOC_FAIL_REASON
+#define INFO_ASSOC_FAIL_REASON \
+ QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ASSOC_FAIL_REASON
+#endif
+
#define g_mode_rates_size (12)
#define a_mode_rates_size (8)
#define GET_IE_LEN_IN_BSS_DESC(lenInBss) (lenInBss + sizeof(lenInBss) - \
@@ -130,7 +168,7 @@
#define IBSS_CFG_PROTECTION_ENABLE_MASK 0x8282
#define HDD2GHZCHAN(freq, chan, flag) { \
- .band = NL80211_BAND_2GHZ, \
+ .band = HDD_NL80211_BAND_2GHZ, \
.center_freq = (freq), \
.hw_value = (chan), \
.flags = (flag), \
@@ -139,7 +177,7 @@
}
#define HDD5GHZCHAN(freq, chan, flag) { \
- .band = NL80211_BAND_5GHZ, \
+ .band = HDD_NL80211_BAND_5GHZ, \
.center_freq = (freq), \
.hw_value = (chan), \
.flags = (flag), \
@@ -277,7 +315,7 @@
static struct ieee80211_supported_band wlan_hdd_band_2_4_ghz = {
.channels = NULL,
.n_channels = ARRAY_SIZE(hdd_channels_2_4_ghz),
- .band = NL80211_BAND_2GHZ,
+ .band = HDD_NL80211_BAND_2GHZ,
.bitrates = g_mode_rates,
.n_bitrates = g_mode_rates_size,
.ht_cap.ht_supported = 1,
@@ -296,7 +334,7 @@
static struct ieee80211_supported_band wlan_hdd_band_5_ghz = {
.channels = NULL,
.n_channels = ARRAY_SIZE(hdd_channels_5_ghz),
- .band = NL80211_BAND_5GHZ,
+ .band = HDD_NL80211_BAND_5GHZ,
.bitrates = a_mode_rates,
.n_bitrates = a_mode_rates_size,
.ht_cap.ht_supported = 1,
@@ -1706,6 +1744,8 @@
sap_config->acs_cfg.is_ht_enabled,
sap_config->acs_cfg.is_vht_enabled,
hdd_ctx->config->enable_sub_20_channel_width);
+ if (icv->flags & IEEE80211_CHAN_PASSIVE)
+ icv->flagext |= IEEE80211_CHAN_DFS;
hdd_info("freq %d flags %d flagext %d ieee %d maxreg %d maxpw %d minpw %d regClass %d antenna %d seg0 %d seg1 %d",
icv->freq, icv->flags,
@@ -1863,12 +1903,12 @@
int i, temp_count = 0;
int acs_list_count = sap_config->acs_cfg.ch_list_count;
/* Get scan band */
- if ((sap_config->acs_cfg.hw_mode == QCA_ACS_MODE_IEEE80211B) ||
- (sap_config->acs_cfg.hw_mode == QCA_ACS_MODE_IEEE80211G)) {
+ if ((sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211B) ||
+ (sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211G)) {
*band = eCSR_BAND_24;
- } else if (sap_config->acs_cfg.hw_mode == QCA_ACS_MODE_IEEE80211A) {
+ } else if (sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211A) {
*band = eCSR_BAND_5G;
- } else if (sap_config->acs_cfg.hw_mode == QCA_ACS_MODE_IEEE80211ANY) {
+ } else if (sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211ANY) {
*band = eCSR_BAND_ALL;
}
/* Auto is not supported currently */
@@ -1956,7 +1996,7 @@
hdd_update_reg_chan_info(adapter, channel_count, channel_list);
hdd_get_freq_list(channel_list, freq_list, channel_count);
/* Get phymode */
- phy_mode = sme_get_phy_mode(WLAN_HDD_GET_HAL_CTX(adapter));
+ phy_mode = adapter->sessionCtx.ap.sapConfig.acs_cfg.hw_mode;
skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
&(adapter->wdev),
@@ -2161,6 +2201,7 @@
goto out;
}
hw_mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]);
+ /* This value will be overwritten in wlan_hdd_set_acs_ch_range */
sap_config->acs_cfg.hw_mode = hw_mode;
if (tb[QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED])
@@ -2175,6 +2216,7 @@
else
ht40_enabled = 0;
+ hdd_debug("ht40_enabled %d", ht40_enabled);
if (tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_ENABLED])
vht_enabled =
nla_get_flag(tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_ENABLED]);
@@ -2203,6 +2245,7 @@
ch_width = 20;
}
+ hdd_debug("channel width =%d", ch_width);
if (ch_width == 80)
sap_config->acs_cfg.ch_width = CH_WIDTH_80MHZ;
else if (ch_width == 40)
@@ -2277,28 +2320,34 @@
pcl_channels_weight_list[i]);
}
+ wlan_hdd_set_acs_ch_range(sap_config, ht_enabled, vht_enabled);
/* ACS override for android */
+
+ sap_config->acs_cfg.band = hw_mode;
if (hdd_ctx->config->sap_p2p_11ac_override && ht_enabled &&
!hdd_ctx->config->sap_force_11n_for_11ac) {
- hdd_debug("ACS Config override for 11AC");
+ hdd_debug("ACS Config override for 11AC vhtChannelWidth %d",
+ hdd_ctx->config->vhtChannelWidth);
vht_enabled = 1;
sap_config->acs_cfg.hw_mode = eCSR_DOT11_MODE_11ac;
sap_config->acs_cfg.ch_width =
hdd_ctx->config->vhtChannelWidth;
+ ch_width = 80;
/* No VHT80 in 2.4G so perform ACS accordingly */
if (sap_config->acs_cfg.end_ch <= 14 &&
sap_config->acs_cfg.ch_width == eHT_CHANNEL_WIDTH_80MHZ) {
sap_config->acs_cfg.ch_width = eHT_CHANNEL_WIDTH_40MHZ;
ch_width = 40;
+ hdd_debug("resetting to 40Mhz in 2.4Ghz");
}
}
- wlan_hdd_set_acs_ch_range(sap_config, ht_enabled, vht_enabled);
- hdd_debug("ACS Config for wlan%d: HW_MODE: %d ACS_BW: %d HT: %d VHT: %d START_CH: %d END_CH: %d",
- adapter->dev->ifindex, sap_config->acs_cfg.hw_mode,
+ hdd_debug("ACS Config for %s: HW_MODE: %d ACS_BW: %d HT: %d VHT: %d START_CH: %d END_CH: %d band %d",
+ adapter->dev->name, sap_config->acs_cfg.hw_mode,
ch_width, ht_enabled, vht_enabled,
- sap_config->acs_cfg.start_ch, sap_config->acs_cfg.end_ch);
+ sap_config->acs_cfg.start_ch, sap_config->acs_cfg.end_ch,
+ sap_config->acs_cfg.band);
sap_config->acs_cfg.is_ht_enabled = ht_enabled;
sap_config->acs_cfg.is_vht_enabled = vht_enabled;
@@ -2325,7 +2374,6 @@
} else {
/* Check if vendor specific acs is enabled */
if (hdd_ctx->config->vendor_acs_support) {
- sap_config->acs_cfg.hw_mode = hw_mode;
hdd_create_acs_timer(adapter);
hdd_update_acs_timer_reason(adapter,
QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT);
@@ -2636,6 +2684,7 @@
#endif
fset |= WIFI_FEATURE_RSSI_MONITOR;
fset |= WIFI_FEATURE_TX_TRANSMIT_POWER;
+ fset |= WIFI_FEATURE_SET_TX_POWER_LIMIT;
if (hdd_link_layer_stats_supported())
fset |= WIFI_FEATURE_LINK_LAYER_STATS;
@@ -2793,6 +2842,15 @@
return ret;
}
+#define MAX_CONCURRENT_MATRIX \
+ QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
+#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
+ QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
+static const struct nla_policy
+wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
+ [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
+};
+
/**
* __wlan_hdd_cfg80211_get_concurrency_matrix() - to retrieve concurrency matrix
* @wiphy: pointer phy adapter
@@ -2811,7 +2869,7 @@
{
uint32_t feature_set_matrix[CDS_MAX_FEATURE_SET] = {0};
uint8_t i, feature_sets, max_feature_sets;
- struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
+ struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
struct sk_buff *reply_skb;
hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
int ret;
@@ -2827,19 +2885,18 @@
if (ret)
return ret;
- if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
- data, data_len, NULL)) {
+ if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
+ wlan_hdd_get_concurrency_matrix_policy)) {
hdd_err("Invalid ATTR");
return -EINVAL;
}
/* Parse and fetch max feature set */
- if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
+ if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
hdd_err("Attr max feature set size failed");
return -EINVAL;
}
- max_feature_sets = nla_get_u32(tb[
- QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
+ max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
hdd_debug("Max feature set size: %d", max_feature_sets);
/* Fill feature combination matrix */
@@ -2877,6 +2934,9 @@
return cfg80211_vendor_cmd_reply(reply_skb);
}
+#undef MAX_CONCURRENT_MATRIX
+#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
+
/**
* wlan_hdd_cfg80211_get_concurrency_matrix() - get concurrency matrix
* @wiphy: pointer to wireless wiphy structure.
@@ -3011,6 +3071,12 @@
hdd_debug("dbs_capability is %d", dbs_capability);
if (nla_put_u32(skb,
+ QCA_WLAN_VENDOR_ATTR_CONCURRENCY_CAPA,
+ dbs_capability))
+ goto nla_put_failure;
+
+
+ if (nla_put_u32(skb,
QCA_WLAN_VENDOR_ATTR_MAX_CONCURRENT_CHANNELS_2_4_BAND,
MAX_CONCURRENT_CHAN_ON_24G))
goto nla_put_failure;
@@ -6628,11 +6694,11 @@
if (pcl[i] <= ARRAY_SIZE(hdd_channels_2_4_ghz))
freq_list[i] =
ieee80211_channel_to_frequency(pcl[i],
- NL80211_BAND_2GHZ);
+ HDD_NL80211_BAND_2GHZ);
else
freq_list[i] =
ieee80211_channel_to_frequency(pcl[i],
- NL80211_BAND_5GHZ);
+ HDD_NL80211_BAND_5GHZ);
}
/* send the freq_list back to supplicant */
@@ -8183,6 +8249,7 @@
hdd_err("Failed to get channel list");
return -EINVAL;
}
+
for (i = 0; i < chan_count; i++) {
if (*channel_count < QDF_MAX_NUM_CHAN) {
if ((eCSR_BAND_24 == band) &&
@@ -8492,7 +8559,7 @@
status = wlan_hdd_cfg80211_start_bss(pre_cac_adapter, NULL,
PRE_CAC_SSID, qdf_str_len(PRE_CAC_SSID),
- eHIDDEN_SSID_NOT_IN_USE, false, false);
+ NL80211_HIDDEN_SSID_NOT_IN_USE, false, false);
if (QDF_IS_STATUS_ERROR(status)) {
hdd_err("start bss failed");
goto stop_close_pre_cac_adapter;
@@ -8540,6 +8607,8 @@
static const struct nla_policy
wlan_hdd_sap_config_policy[QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_MAX + 1] = {
[QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL] = {.type = NLA_U8 },
+ [QCA_WLAN_VENDOR_ATTR_SAP_MANDATORY_FREQUENCY_LIST] = {
+ .type = NLA_NESTED },
};
static const struct nla_policy
@@ -9847,10 +9916,10 @@
int ret = 0;
switch (nl80211_value) {
- case NL80211_BAND_2GHZ:
+ case HDD_NL80211_BAND_2GHZ:
*wmi_value = WMI_SAR_2G_ID;
break;
- case NL80211_BAND_5GHZ:
+ case HDD_NL80211_BAND_5GHZ:
*wmi_value = WMI_SAR_5G_ID;
break;
default:
@@ -10356,6 +10425,47 @@
return ret;
}
+
+void hdd_bt_activity_cb(void *context, uint32_t bt_activity)
+{
+ hdd_context_t *hdd_ctx = (hdd_context_t *)context;
+ int status;
+
+ status = wlan_hdd_validate_context(hdd_ctx);
+ if (0 != status)
+ return;
+
+ if (bt_activity == WLAN_COEX_EVENT_BT_A2DP_PROFILE_ADD)
+ hdd_ctx->bt_a2dp_active = 1;
+ else if (bt_activity == WLAN_COEX_EVENT_BT_A2DP_PROFILE_REMOVE)
+ hdd_ctx->bt_a2dp_active = 0;
+ else if (bt_activity == WLAN_COEX_EVENT_BT_VOICE_PROFILE_ADD)
+ hdd_ctx->bt_vo_active = 1;
+ else if (bt_activity == WLAN_COEX_EVENT_BT_VOICE_PROFILE_REMOVE)
+ hdd_ctx->bt_vo_active = 0;
+ else
+ return;
+
+ hdd_info("a2dp_active:%d vo_active:%d", hdd_ctx->bt_a2dp_active,
+ hdd_ctx->bt_vo_active);
+}
+
+
+/**
+ * wlan_hdd_is_bt_in_progress() - check if bt activity is in progress
+ * @hdd_ctx : HDD context
+ *
+ * Return: true if BT activity is in progress else false
+ */
+static inline bool wlan_hdd_is_bt_in_progress(hdd_context_t *hdd_ctx)
+{
+ if (hdd_ctx->bt_a2dp_active || hdd_ctx->bt_vo_active)
+ return true;
+
+ return false;
+}
+
+
const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = {
{
.info.vendor_id = QCA_NL80211_VENDOR_ID,
@@ -11107,7 +11217,8 @@
hdd_ctx->hdd_pdev,
band->channels[j].hw_value);
- if (NL80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) {
+ if (HDD_NL80211_BAND_2GHZ == i &&
+ eCSR_BAND_5G == eBand) {
/* 5G only */
#ifdef WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY
/* Enable Social channels for P2P */
@@ -11122,7 +11233,7 @@
band->channels[j].flags |=
IEEE80211_CHAN_DISABLED;
continue;
- } else if (NL80211_BAND_5GHZ == i &&
+ } else if (HDD_NL80211_BAND_5GHZ == i &&
eCSR_BAND_24 == eBand) {
/* 2G only */
band->channels[j].flags |=
@@ -11265,14 +11376,14 @@
* wiphy flags don't get reset because of static memory.
* It's better not to store channel in static memory.
*/
- wiphy->bands[NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_ghz;
- wiphy->bands[NL80211_BAND_2GHZ]->channels =
+ wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_ghz;
+ wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
qdf_mem_malloc(sizeof(hdd_channels_2_4_ghz));
- if (wiphy->bands[NL80211_BAND_2GHZ]->channels == NULL) {
+ if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels == NULL) {
hdd_err("Not enough memory to allocate channels");
return -ENOMEM;
}
- qdf_mem_copy(wiphy->bands[NL80211_BAND_2GHZ]->channels,
+ qdf_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
&hdd_channels_2_4_ghz[0],
sizeof(hdd_channels_2_4_ghz));
if ((hdd_is_5g_supported(pHddCtx)) &&
@@ -11280,17 +11391,17 @@
(eHDD_DOT11_MODE_11g != pCfg->dot11Mode) &&
(eHDD_DOT11_MODE_11b_ONLY != pCfg->dot11Mode) &&
(eHDD_DOT11_MODE_11g_ONLY != pCfg->dot11Mode))) {
- wiphy->bands[NL80211_BAND_5GHZ] = &wlan_hdd_band_5_ghz;
- wiphy->bands[NL80211_BAND_5GHZ]->channels =
+ wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_ghz;
+ wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
qdf_mem_malloc(sizeof(hdd_channels_5_ghz));
- if (wiphy->bands[NL80211_BAND_5GHZ]->channels == NULL) {
+ if (wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels == NULL) {
hdd_err("Not enough memory to allocate channels");
qdf_mem_free(wiphy->
- bands[NL80211_BAND_2GHZ]->channels);
- wiphy->bands[NL80211_BAND_2GHZ]->channels = NULL;
+ bands[HDD_NL80211_BAND_2GHZ]->channels);
+ wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
return -ENOMEM;
}
- qdf_mem_copy(wiphy->bands[NL80211_BAND_5GHZ]->channels,
+ qdf_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
&hdd_channels_5_ghz[0],
sizeof(hdd_channels_5_ghz));
}
@@ -11303,7 +11414,7 @@
for (j = 0; j < wiphy->bands[i]->n_channels; j++) {
struct ieee80211_supported_band *band = wiphy->bands[i];
- if (NL80211_BAND_2GHZ == i &&
+ if (HDD_NL80211_BAND_2GHZ == i &&
eCSR_BAND_5G == pCfg->nBandCapability) {
/* 5G only */
#ifdef WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY
@@ -11317,7 +11428,7 @@
band->channels[j].flags |=
IEEE80211_CHAN_DISABLED;
continue;
- } else if (NL80211_BAND_5GHZ == i &&
+ } else if (HDD_NL80211_BAND_5GHZ == i &&
eCSR_BAND_24 == pCfg->nBandCapability) {
/* 2G only */
band->channels[j].flags |=
@@ -11418,21 +11529,21 @@
ht_cap_info = (tSirMacHTCapabilityInfo *)&val16;
if (ht_cap_info->txSTBC == true) {
- if (NULL != hdd_ctx->wiphy->bands[NL80211_BAND_2GHZ])
- hdd_ctx->wiphy->bands[NL80211_BAND_2GHZ]->ht_cap.cap |=
+ if (NULL != hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ])
+ hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ]->ht_cap.cap |=
IEEE80211_HT_CAP_TX_STBC;
- if (NULL != hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ])
- hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ]->ht_cap.cap |=
+ if (NULL != hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ])
+ hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ]->ht_cap.cap |=
IEEE80211_HT_CAP_TX_STBC;
}
if (!sme_is_feature_supported_by_fw(DOT11AC)) {
- hdd_ctx->wiphy->bands[NL80211_BAND_2GHZ]->
+ hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ]->
vht_cap.vht_supported = 0;
- hdd_ctx->wiphy->bands[NL80211_BAND_2GHZ]->vht_cap.cap = 0;
- hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ]->
+ hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ]->vht_cap.cap = 0;
+ hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ]->
vht_cap.vht_supported = 0;
- hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap.cap = 0;
+ hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ]->vht_cap.cap = 0;
}
}
@@ -13354,15 +13465,15 @@
}
if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_ghz) &&
- (wiphy->bands[NL80211_BAND_2GHZ] != NULL)) {
+ (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL)) {
freq =
ieee80211_channel_to_frequency(chan_no,
- NL80211_BAND_2GHZ);
+ HDD_NL80211_BAND_2GHZ);
} else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_ghz))
- && (wiphy->bands[NL80211_BAND_5GHZ] != NULL)) {
+ && (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL)) {
freq =
ieee80211_channel_to_frequency(chan_no,
- NL80211_BAND_5GHZ);
+ HDD_NL80211_BAND_5GHZ);
} else {
hdd_err("Invalid channel: %d", chan_no);
qdf_mem_free(mgmt);
@@ -15381,7 +15492,8 @@
wlan_hdd_netif_queue_control(pAdapter,
WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, WLAN_CONTROL_PATH);
hdd_debug("Set HDD connState to eConnectionState_Disconnecting");
- pHddStaCtx->conn_info.connState = eConnectionState_Disconnecting;
+ hdd_conn_set_connection_state(pAdapter, eConnectionState_Disconnecting);
+
INIT_COMPLETION(pAdapter->disconnect_comp_var);
/* issue disconnect */
diff --git a/core/hdd/src/wlan_hdd_cfg80211.h b/core/hdd/src/wlan_hdd_cfg80211.h
index ff9893d..3bc3667 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.h
+++ b/core/hdd/src/wlan_hdd_cfg80211.h
@@ -167,6 +167,9 @@
#define WIFI_FEATURE_CONFIG_NDO 0x200000 /* ND offload configure */
#define WIFI_FEATURE_TX_TRANSMIT_POWER 0x400000 /* Tx transmit power levels */
+/* Support Tx Power Limit setting */
+#define WIFI_FEATURE_SET_TX_POWER_LIMIT 0x4000000
+
/* Add more features here */
#define WIFI_TDLS_SUPPORT BIT(0)
#define WIFI_TDLS_EXTERNAL_CONTROL_SUPPORT BIT(1)
@@ -563,4 +566,13 @@
*/
int wlan_hdd_merge_avoid_freqs(tHddAvoidFreqList *destFreqList,
tHddAvoidFreqList *srcFreqList);
+
+/**
+ * hdd_bt_activity_cb() - callback function to receive bt activity
+ * @context: HDD context
+ * @bt_activity: specifies the kind of bt activity
+ *
+ * Return: none
+ */
+void hdd_bt_activity_cb(void *context, uint32_t bt_activity);
#endif
diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c
index d18c628..06b6ede 100644
--- a/core/hdd/src/wlan_hdd_driver_ops.c
+++ b/core/hdd/src/wlan_hdd_driver_ops.c
@@ -230,6 +230,9 @@
goto err_hif_close;
}
+ if (hdd_ctx->config->prevent_link_down)
+ hif_vote_link_up(hif_ctx);
+
status = hif_enable(hif_ctx, dev, bdev, bid, bus_type,
(reinit == true) ? HIF_ENABLE_TYPE_REINIT :
HIF_ENABLE_TYPE_PROBE);
@@ -486,6 +489,13 @@
return;
}
+ if (!hif_ctx) {
+ hdd_err("Failed to get HIF context, ignore SSR shutdown");
+ return;
+ }
+ /* mask the host controller interrupts */
+ hif_mask_interrupt_call(hif_ctx);
+
if (cds_is_load_or_unload_in_progress()) {
hdd_err("Load/unload in progress, ignore SSR shutdown");
return;
@@ -498,10 +508,7 @@
hdd_err("Host is not ready for SSR, attempting anyway");
if (!QDF_IS_EPPING_ENABLED(cds_get_conparam())) {
- if (!hif_ctx)
- hdd_err("Invalid hif ctx!");
- else
- hif_disable_isr(hif_ctx);
+ hif_disable_isr(hif_ctx);
hdd_wlan_shutdown();
}
}
diff --git a/core/hdd/src/wlan_hdd_ftm.c b/core/hdd/src/wlan_hdd_ftm.c
index 4546e60..67c9b30 100644
--- a/core/hdd/src/wlan_hdd_ftm.c
+++ b/core/hdd/src/wlan_hdd_ftm.c
@@ -186,7 +186,8 @@
switch (pqcmbr_data->cmd) {
case ATH_XIOCTL_UNIFIED_UTF_CMD: {
pqcmbr_data->copy_to_user = 0;
- if (pqcmbr_data->length) {
+ if (pqcmbr_data->length &&
+ pqcmbr_data->length <= sizeof(pqcmbr_data->buf)) {
if (wlan_hdd_ftm_testmode_cmd(pqcmbr_data->buf,
pqcmbr_data->
length)
diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c
index 950bd02..f3e2cfc 100644
--- a/core/hdd/src/wlan_hdd_hostapd.c
+++ b/core/hdd/src/wlan_hdd_hostapd.c
@@ -1420,12 +1420,23 @@
}
break;
case eSAP_DFS_RADAR_DETECT:
+ {
+ int i;
+ tsap_Config_t *sap_config =
+ &pHostapdAdapter->sessionCtx.ap.sapConfig;
+
hdd_dfs_indicate_radar(pHddCtx);
wlan_hdd_send_svc_nlink_msg(pHddCtx->radio_index,
WLAN_SVC_DFS_RADAR_DETECT_IND,
&dfs_info,
sizeof(struct wlan_dfs_info));
pHddCtx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE;
+ for (i = 0; i < sap_config->channel_info_count; i++) {
+ if (sap_config->channel_info[i].ieee_chan_number
+ == dfs_info.channel)
+ sap_config->channel_info[i].flags |=
+ IEEE80211_CHAN_RADAR_DFS;
+ }
if (QDF_STATUS_SUCCESS !=
hdd_send_radar_event(pHddCtx, eSAP_DFS_RADAR_DETECT,
dfs_info, &pHostapdAdapter->wdev)) {
@@ -1434,6 +1445,7 @@
hdd_debug("Sent radar detected to user space");
}
break;
+ }
case eSAP_DFS_RADAR_DETECT_DURING_PRE_CAC:
hdd_debug("notification for radar detect during pre cac:%d",
pHostapdAdapter->sessionId);
@@ -1484,7 +1496,7 @@
hdd_debug("MIC MAC " MAC_ADDRESS_STR,
MAC_ADDR_ARRAY(msg.src_addr.sa_data));
if (pSapEvent->sapevt.sapStationMICFailureEvent.
- multicast == eSAP_TRUE)
+ multicast == true)
msg.flags = IW_MICFAILURE_GROUP;
else
msg.flags = IW_MICFAILURE_PAIRWISE;
@@ -1501,7 +1513,7 @@
((pSapEvent->sapevt.
sapStationMICFailureEvent.
multicast ==
- eSAP_TRUE) ?
+ true) ?
NL80211_KEYTYPE_GROUP :
NL80211_KEYTYPE_PAIRWISE),
pSapEvent->sapevt.
@@ -2604,6 +2616,10 @@
case QCSAP_IOCTL_SET_FW_CRASH_INJECT:
hdd_err("WE_SET_FW_CRASH_INJECT: %d %d",
value[1], value[2]);
+ if (value[1] == 3) {
+ cds_trigger_recovery(false);
+ return 0;
+ }
ret = wma_cli_set2_command(adapter->sessionId,
GEN_PARAM_CRASH_INJECT,
value[1], value[2],
@@ -8066,7 +8082,7 @@
return ret;
}
-static int hdd_destroy_acs_timer(hdd_adapter_t *adapter)
+int hdd_destroy_acs_timer(hdd_adapter_t *adapter)
{
QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
diff --git a/core/hdd/src/wlan_hdd_hostapd.h b/core/hdd/src/wlan_hdd_hostapd.h
index 557c620..c5c6a01 100644
--- a/core/hdd/src/wlan_hdd_hostapd.h
+++ b/core/hdd/src/wlan_hdd_hostapd.h
@@ -152,6 +152,8 @@
struct net_device *dev,
struct cfg80211_beacon_data *params);
+int hdd_destroy_acs_timer(hdd_adapter_t *adapter);
+
QDF_STATUS wlan_hdd_config_acs(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter);
void hdd_sap_indicate_disconnect_for_sta(hdd_adapter_t *adapter);
void hdd_sap_destroy_events(hdd_adapter_t *adapter);
diff --git a/core/hdd/src/wlan_hdd_ipa.c b/core/hdd/src/wlan_hdd_ipa.c
index 78d7aa8..e513a06 100644
--- a/core/hdd/src/wlan_hdd_ipa.c
+++ b/core/hdd/src/wlan_hdd_ipa.c
@@ -91,6 +91,8 @@
#define HDD_IPA_MAX_PENDING_EVENT_COUNT 20
+#define IPA_WLAN_RX_SOFTIRQ_THRESH 16
+
enum hdd_ipa_uc_op_code {
HDD_IPA_UC_OPCODE_TX_SUSPEND = 0,
HDD_IPA_UC_OPCODE_TX_RESUME = 1,
@@ -4076,6 +4078,40 @@
"RM CONS resource delete failed %d", ret);
}
+#ifdef QCA_CONFIG_SMP
+static int hdd_ipa_aggregated_rx_ind(qdf_nbuf_t skb)
+{
+ return netif_rx_ni(skb);
+}
+#else
+static int hdd_ipa_aggregated_rx_ind(qdf_nbuf_t skb)
+{
+ struct iphdr *ip_h;
+ static atomic_t softirq_mitigation_cntr =
+ ATOMIC_INIT(IPA_WLAN_RX_SOFTIRQ_THRESH);
+ int result;
+
+ ip_h = (struct iphdr *)(skb->data);
+ if ((skb->protocol == htons(ETH_P_IP)) &&
+ (ip_h->protocol == IPPROTO_ICMP)) {
+ result = netif_rx_ni(skb);
+ } else {
+ /* Call netif_rx_ni for every IPA_WLAN_RX_SOFTIRQ_THRESH packets
+ * to avoid excessive softirq's.
+ */
+ if (atomic_dec_and_test(&softirq_mitigation_cntr)) {
+ result = netif_rx_ni(skb);
+ atomic_set(&softirq_mitigation_cntr,
+ IPA_WLAN_RX_SOFTIRQ_THRESH);
+ } else {
+ result = netif_rx(skb);
+ }
+ }
+
+ return result;
+}
+#endif
+
/**
* hdd_ipa_send_skb_to_network() - Send skb to kernel
* @skb: network buffer
@@ -4089,6 +4125,7 @@
static void hdd_ipa_send_skb_to_network(qdf_nbuf_t skb,
hdd_adapter_t *adapter)
{
+ int result;
struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
unsigned int cpu_index;
@@ -4114,7 +4151,8 @@
cpu_index = wlan_hdd_get_cpu();
++adapter->hdd_stats.hddTxRxStats.rxPackets[cpu_index];
- if (netif_rx_ni(skb) == NET_RX_SUCCESS)
+ result = hdd_ipa_aggregated_rx_ind(skb);
+ if (result == NET_RX_SUCCESS)
++adapter->hdd_stats.hddTxRxStats.rxDelivered[cpu_index];
else
++adapter->hdd_stats.hddTxRxStats.rxRefused[cpu_index];
diff --git a/core/hdd/src/wlan_hdd_lro.c b/core/hdd/src/wlan_hdd_lro.c
index a2635db..c043b2b 100644
--- a/core/hdd/src/wlan_hdd_lro.c
+++ b/core/hdd/src/wlan_hdd_lro.c
@@ -154,10 +154,6 @@
}
ctx = wlan_hdd_get_lro_ctx(skb);
-
- QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
- "%s %d: ctx %p\n", __func__, __LINE__, ctx);
-
if (ctx == NULL) {
hdd_err("LRO mgr is NULL, vdev could be going down");
return status;
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index 620fb41..267a229 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -120,6 +120,7 @@
#include "os_if_nan.h"
#include "nan_public_structs.h"
#include "wlan_reg_ucfg_api.h"
+#include "wlan_hdd_rx_monitor.h"
#ifdef CNSS_GENL
#include <net/cnss_nl.h>
@@ -488,6 +489,8 @@
/* variable to hold the insmod parameters */
static int con_mode;
+static int con_mode_ftm;
+
/* Variable to hold connection mode including module parameter con_mode */
static int curr_con_mode;
@@ -1058,7 +1061,7 @@
struct hdd_config *pconfig = hdd_ctx->config;
struct wiphy *wiphy = hdd_ctx->wiphy;
struct ieee80211_supported_band *band_5g =
- wiphy->bands[NL80211_BAND_5GHZ];
+ wiphy->bands[HDD_NL80211_BAND_5GHZ];
uint32_t temp = 0;
uint32_t ch_width = eHT_CHANNEL_WIDTH_80MHZ;
@@ -1701,6 +1704,10 @@
ENTER_DEV(dev);
hdd_mon_mode_ether_setup(dev);
ret = hdd_set_mon_rx_cb(dev);
+
+ if (!ret)
+ ret = hdd_enable_monitor_mode(dev);
+
return ret;
}
@@ -3134,7 +3141,8 @@
if (!rc) {
hdd_err("timed out waiting for open sme session: %ld", rc);
errno = -ETIMEDOUT;
- goto objmgr_vdev_destroy;
+ set_bit(SME_SESSION_OPENED, &adapter->event_flags);
+ goto hdd_vdev_destroy;
}
/* firmware ready for component communication, raise vdev_ready event */
@@ -3188,10 +3196,7 @@
hdd_err("failed to register wireless extensions: %d", status);
goto error_register_wext;
}
-
- /* Set the Connection State to Not Connected */
- hdd_debug("Set HDD connState to eConnectionState_NotConnected");
- pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
+ hdd_conn_set_connection_state(adapter, eConnectionState_NotConnected);
qdf_mem_set(pHddStaCtx->conn_info.staId,
sizeof(pHddStaCtx->conn_info.staId), HDD_WLAN_INVALID_STA_ID);
@@ -4122,6 +4127,7 @@
hdd_deregister_tx_flow_control(adapter);
+ hdd_destroy_acs_timer(adapter);
mutex_lock(&hdd_ctx->sap_lock);
if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
QDF_STATUS status;
@@ -4307,14 +4313,18 @@
clear_bit(WMM_INIT_DONE, &adapter->event_flags);
}
- /*
- * If adapter is SAP, set session ID to invalid since SAP
- * session will be cleanup during SSR.
- */
- if (adapter->device_mode == QDF_SAP_MODE)
+ if (adapter->device_mode == QDF_SAP_MODE) {
+ /*
+ * If adapter is SAP, set session ID to invalid
+ * since SAP session will be cleanup during SSR.
+ */
wlansap_set_invalid_session(
WLAN_HDD_GET_SAP_CTX_PTR(adapter));
+ wlansap_cleanup_cac_timer(
+ WLAN_HDD_GET_SAP_CTX_PTR(adapter));
+ }
+
/* Delete peers if any for STA and P2P client modes */
if (adapter->device_mode == QDF_STA_MODE ||
adapter->device_mode == QDF_P2P_CLIENT_MODE) {
@@ -4579,10 +4589,10 @@
if (chan_no <= 14)
freq = ieee80211_channel_to_frequency(chan_no,
- NL80211_BAND_2GHZ);
+ HDD_NL80211_BAND_2GHZ);
else
freq = ieee80211_channel_to_frequency(chan_no,
- NL80211_BAND_5GHZ);
+ HDD_NL80211_BAND_5GHZ);
chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
bss = hdd_cfg80211_get_bss(padapter->wdev.wiphy, chan, bssid,
@@ -4636,6 +4646,8 @@
hdd_wmm_init(adapter);
+ adapter->scan_info.mScanPending = false;
+
switch (adapter->device_mode) {
case QDF_STA_MODE:
case QDF_P2P_CLIENT_MODE:
@@ -4647,7 +4659,6 @@
hdd_init_station_mode(adapter);
/* Open the gates for HDD to receive Wext commands */
adapter->isLinkUpSvcNeeded = false;
- adapter->scan_info.mScanPending = false;
/* Indicate disconnect event to supplicant
* if associated previously
@@ -9053,6 +9064,9 @@
if (ret)
goto cds_disable;
+ if (hdd_enable_egap(hdd_ctx))
+ hdd_debug("enhance green ap is not enabled");
+
return 0;
cds_disable:
@@ -9495,9 +9509,6 @@
memdump_init();
hdd_driver_memdump_init();
- if (hdd_enable_egap(hdd_ctx))
- hdd_debug("enhance green ap is not enabled");
-
if (hdd_ctx->config->fIsImpsEnabled)
hdd_set_idle_ps_config(hdd_ctx, true);
@@ -9545,7 +9556,8 @@
sme_cli_set_command(0, (int)WMI_PDEV_PARAM_ABG_MODE_TX_CHAIN_NUM,
num_abg_tx_chains, PDEV_CMD);
- qdf_mc_timer_start(&hdd_ctx->iface_change_timer,
+ if (QDF_GLOBAL_FTM_MODE != hdd_get_conparam())
+ qdf_mc_timer_start(&hdd_ctx->iface_change_timer,
hdd_ctx->config->iface_change_wait_time);
hdd_start_complete(0);
@@ -9689,6 +9701,11 @@
if (!QDF_IS_STATUS_SUCCESS(status))
hdd_err("set congestion callback failed");
+ status = sme_set_bt_activity_info_cb(hdd_ctx->hHal,
+ hdd_bt_activity_cb);
+ if (!QDF_IS_STATUS_SUCCESS(status))
+ hdd_err("set bt activity info callback failed");
+
EXIT();
return ret;
@@ -10709,6 +10726,26 @@
}
/**
+ * component_init - API to init cld component's
+ *
+ * Return: None
+ */
+static void component_init(void)
+{
+ pmo_init();
+}
+
+/**
+ * component_deinit - API to deinit cld component's
+ *
+ * Return: None
+ */
+static void component_deinit(void)
+{
+ pmo_deinit();
+}
+
+/**
* __hdd_module_init - Module init helper
*
* Module init helper function used by both module and static driver.
@@ -10741,6 +10778,9 @@
dispatcher_init();
+ /* Ensure to call post objmgr init */
+ component_init();
+
qdf_wake_lock_create(&wlan_wake_lock, "wlan");
hdd_set_conparam((uint32_t) con_mode);
@@ -10809,6 +10849,9 @@
qdf_wake_lock_destroy(&wlan_wake_lock);
+ /* Ensure to call prior to objmgr deinit */
+ component_deinit();
+
dispatcher_deinit();
hdd_deinit();
pld_deinit();
@@ -11247,6 +11290,24 @@
return ret;
}
+static int con_mode_handler_ftm(const char *kmessage,
+ struct kernel_param *kp)
+{
+ int ret;
+
+ ret = param_set_int(kmessage, kp);
+
+ if (con_mode_ftm != QDF_GLOBAL_FTM_MODE) {
+ pr_err("Only FTM mode supported!");
+ return -ENOTSUPP;
+ }
+
+ hdd_set_conparam(con_mode_ftm);
+ con_mode = con_mode_ftm;
+
+ return ret;
+}
+
/**
* hdd_get_conparam() - driver exit point
*
@@ -12089,6 +12150,9 @@
module_param_call(con_mode, con_mode_handler, param_get_int, &con_mode,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+module_param_call(con_mode_ftm, con_mode_handler_ftm, param_get_int,
+ &con_mode_ftm, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+
module_param_call(fwpath, fwpath_changed_handler, param_get_string, &fwpath,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
diff --git a/core/hdd/src/wlan_hdd_nan_datapath.c b/core/hdd/src/wlan_hdd_nan_datapath.c
index 3b3c1ea..23eae3c 100644
--- a/core/hdd/src/wlan_hdd_nan_datapath.c
+++ b/core/hdd/src/wlan_hdd_nan_datapath.c
@@ -292,20 +292,21 @@
{
hdd_adapter_t *adapter;
uint8_t i, attempts, max_attempt = 16;
- struct qdf_mac_addr bcast_mac_addr = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
for (attempts = 0; attempts < max_attempt; attempts++) {
cds_rand_get_bytes(0, (uint8_t *)mac_addr, sizeof(*mac_addr));
- WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(mac_addr->bytes);
+
+ /*
+ * Reset multicast bit (bit-0) and set locally-administered bit
+ */
+ mac_addr->bytes[0] = 0x2;
+
/*
* to avoid potential conflict with FW's generated NMI mac addr,
* host sets LSB if 6th byte to 0
*/
mac_addr->bytes[5] &= 0xFE;
- if (!qdf_mem_cmp(mac_addr, &bcast_mac_addr, sizeof(*mac_addr)))
- continue;
-
for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
if (!qdf_mem_cmp(hdd_ctx->config->intfMacAddr[i].bytes,
mac_addr, sizeof(*mac_addr)))
@@ -1250,8 +1251,8 @@
hdd_ctx->sta_to_adapter[new_peer_ind->sta_id] = adapter;
/* perform following steps for first new peer ind */
if (ndp_ctx->active_ndp_peers == 1) {
- hdd_info("Set ctx connection state to connected");
- sta_ctx->conn_info.connState = eConnectionState_NdiConnected;
+ hdd_conn_set_connection_state(adapter,
+ eConnectionState_NdiConnected);
hdd_wmm_connect(adapter, &roam_info, eCSR_BSS_TYPE_NDI);
wlan_hdd_netif_queue_control(adapter,
WLAN_WAKE_ALL_NETIF_QUEUE, WLAN_CONTROL_PATH);
@@ -1280,7 +1281,6 @@
if (--ndp_ctx->active_ndp_peers == 0) {
hdd_info("No more ndp peers.");
- sta_ctx->conn_info.connState = eConnectionState_NdiDisconnected;
hdd_conn_set_connection_state(adapter,
eConnectionState_NdiDisconnected);
hdd_info("Stop netif tx queues.");
diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c
index caa94c5..176b573 100644
--- a/core/hdd/src/wlan_hdd_power.c
+++ b/core/hdd/src/wlan_hdd_power.c
@@ -1406,6 +1406,7 @@
pHddCtx->last_scan_reject_session_id = 0xFF;
pHddCtx->last_scan_reject_reason = 0;
pHddCtx->last_scan_reject_timestamp = 0;
+ pHddCtx->scan_reject_cnt = 0;
hdd_set_roaming_in_progress(false);
complete(&pAdapter->roaming_comp_var);
diff --git a/core/hdd/src/wlan_hdd_regulatory.c b/core/hdd/src/wlan_hdd_regulatory.c
index 6749e1d..e647029 100644
--- a/core/hdd/src/wlan_hdd_regulatory.c
+++ b/core/hdd/src/wlan_hdd_regulatory.c
@@ -259,9 +259,9 @@
* disable 2.4 Ghz channels that dont have 20 mhz bw
*/
for (chan_num = 0;
- chan_num < wiphy->bands[NL80211_BAND_2GHZ]->n_channels;
+ chan_num < wiphy->bands[HDD_NL80211_BAND_2GHZ]->n_channels;
chan_num++) {
- chan = &(wiphy->bands[NL80211_BAND_2GHZ]->channels[chan_num]);
+ chan = &(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels[chan_num]);
if (chan->flags & IEEE80211_CHAN_NO_20MHZ)
chan->flags |= IEEE80211_CHAN_DISABLED;
}
@@ -489,11 +489,11 @@
static void hdd_set_dfs_region(hdd_context_t *hdd_ctx,
enum dfs_reg dfs_reg)
{
- wlan_reg_set_dfs_region(hdd_ctx->hdd_psoc, dfs_reg);
+ wlan_reg_set_dfs_region(hdd_ctx->hdd_pdev, dfs_reg);
}
#else
static void hdd_set_dfs_region(hdd_context_t *hdd_ctx,
- enum dfs_region dfs_reg)
+ enum dfs_region dfs_reg)
{
/* remap the ctl code to dfs region code */
@@ -550,7 +550,7 @@
cds_fill_and_send_ctl_to_fw(reg_info);
hdd_set_dfs_region(hdd_ctx, DFS_FCC_REG);
- wlan_reg_get_dfs_region(hdd_ctx->hdd_psoc, &dfs_reg);
+ wlan_reg_get_dfs_region(hdd_ctx->hdd_pdev, &dfs_reg);
reg_program_config_vars(hdd_ctx, &config_vars);
ucfg_reg_set_config_vars(hdd_ctx->hdd_psoc, config_vars);
@@ -715,11 +715,11 @@
if (('K' == request->alpha2[0]) &&
('R' == request->alpha2[1]))
- request->dfs_region = DFS_KR_REG;
+ request->dfs_region = (enum nl80211_dfs_regions) DFS_KR_REG;
if (('C' == request->alpha2[0]) &&
('N' == request->alpha2[1]))
- request->dfs_region = DFS_CN_REG;
+ request->dfs_region = (enum nl80211_dfs_regions) DFS_CN_REG;
/* first check if this callback is in response to the driver callback */
@@ -774,7 +774,7 @@
cds_fill_and_send_ctl_to_fw(&hdd_ctx->reg);
hdd_set_dfs_region(hdd_ctx, request->dfs_region);
- wlan_reg_get_dfs_region(hdd_ctx->hdd_psoc, &dfs_reg);
+ wlan_reg_get_dfs_region(hdd_ctx->hdd_pdev, &dfs_reg);
reg_program_config_vars(hdd_ctx, &config_vars);
ucfg_reg_set_config_vars(hdd_ctx->hdd_psoc, config_vars);
diff --git a/core/hdd/src/wlan_hdd_rx_monitor.c b/core/hdd/src/wlan_hdd_rx_monitor.c
index 8fcbe6f..7ba0396 100644
--- a/core/hdd/src/wlan_hdd_rx_monitor.c
+++ b/core/hdd/src/wlan_hdd_rx_monitor.c
@@ -118,3 +118,26 @@
{
txrx->rx.mon = rx_monitor_cb;
}
+
+/**
+ * hdd_enable_monitor_mode() - Enable monitor mode
+ * @dev: Pointer to the net_device structure
+ *
+ * This function invokes cdp interface API to enable
+ * monitor mode configuration on the hardware. In this
+ * case sends HTT messages to FW to setup hardware rings
+ *
+ * Return: 0 for success; non-zero for failure
+ */
+int hdd_enable_monitor_mode(struct net_device *dev)
+{
+ void *soc = cds_get_context(QDF_MODULE_ID_SOC);
+ void *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+ hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+
+ ENTER_DEV(dev);
+
+ return cdp_set_monitor_mode(soc,
+ (struct cdp_vdev *)cdp_get_vdev_from_vdev_id(soc,
+ (struct cdp_pdev *)pdev, adapter->sessionId), false);
+}
diff --git a/core/hdd/src/wlan_hdd_rx_monitor.h b/core/hdd/src/wlan_hdd_rx_monitor.h
index 161b8a1..415b523 100644
--- a/core/hdd/src/wlan_hdd_rx_monitor.h
+++ b/core/hdd/src/wlan_hdd_rx_monitor.h
@@ -37,12 +37,18 @@
void hdd_rx_monitor_callback(ol_osif_vdev_handle vdev,
qdf_nbuf_t mpdu,
void *rx_status);
+
+int hdd_enable_monitor_mode(struct net_device *dev);
#else
-static void hdd_monitor_set_rx_monitor_cb(struct ol_txrx_ops *txrx,
+static inline void hdd_monitor_set_rx_monitor_cb(struct ol_txrx_ops *txrx,
ol_txrx_rx_mon_fp rx_monitor_cb){ }
-static void hdd_rx_monitor_callback(ol_osif_vdev_handle vdev,
+static inline void hdd_rx_monitor_callback(ol_osif_vdev_handle vdev,
qdf_nbuf_t mpdu,
void *rx_status){ }
+static inline int hdd_enable_monitor_mode(struct net_device *dev)
+{
+ return -ENOSYS;
+}
#endif /* CONFIG_LITHIUM */
#endif /* __WLAN_HDD_RX_MONITOR_H */
diff --git a/core/hdd/src/wlan_hdd_scan.c b/core/hdd/src/wlan_hdd_scan.c
index aaeccef..fbb1e01 100644
--- a/core/hdd/src/wlan_hdd_scan.c
+++ b/core/hdd/src/wlan_hdd_scan.c
@@ -505,19 +505,16 @@
uint32_t size = 0;
ret = wlan_hdd_validate_context(hddctx);
- if (0 != ret)
+ if (ret) {
+ hdd_err("Invalid hdd_ctx; Drop results for scanId %d", scanId);
return QDF_STATUS_E_INVAL;
+ }
hdd_debug("called with hal = %p, pContext = %p, ID = %d, status = %d",
halHandle, pContext, (int)scanId, (int)status);
pScanInfo->mScanPendingCounter = 0;
- if (pScanInfo->mScanPending != true) {
- QDF_ASSERT(pScanInfo->mScanPending);
- goto allow_suspend;
- }
-
if (QDF_STATUS_SUCCESS !=
wlan_hdd_scan_request_dequeue(hddctx, scanId, &req, &source,
&scan_time)) {
@@ -926,16 +923,21 @@
pHddCtx->last_scan_reject_session_id = curr_session_id;
pHddCtx->last_scan_reject_reason = curr_reason;
pHddCtx->last_scan_reject_timestamp =
- jiffies_to_msecs(jiffies);
+ jiffies_to_msecs(jiffies) +
+ SCAN_REJECT_THRESHOLD_TIME;
+ pHddCtx->scan_reject_cnt = 0;
} else {
- hdd_debug("curr_session id %d curr_reason %d time delta %lu",
- curr_session_id, curr_reason,
- (jiffies_to_msecs(jiffies) -
- pHddCtx->last_scan_reject_timestamp));
- if ((jiffies_to_msecs(jiffies) -
- pHddCtx->last_scan_reject_timestamp) >=
- SCAN_REJECT_THRESHOLD_TIME) {
+ pHddCtx->scan_reject_cnt++;
+ hdd_debug("curr_session id %d curr_reason %d count %d threshold time has elapsed? %d",
+ curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
+ qdf_system_time_after(jiffies_to_msecs(jiffies),
+ pHddCtx->last_scan_reject_timestamp));
+ if ((pHddCtx->scan_reject_cnt >=
+ SCAN_REJECT_THRESHOLD) &&
+ qdf_system_time_after(jiffies_to_msecs(jiffies),
+ pHddCtx->last_scan_reject_timestamp)) {
pHddCtx->last_scan_reject_timestamp = 0;
+ pHddCtx->scan_reject_cnt = 0;
if (pHddCtx->config->enable_fatal_event) {
cds_flush_logs(WLAN_LOG_TYPE_FATAL,
WLAN_LOG_INDICATOR_HOST_DRIVER,
@@ -957,6 +959,7 @@
pHddCtx->last_scan_reject_timestamp = 0;
pHddCtx->last_scan_reject_session_id = 0xFF;
pHddCtx->last_scan_reject_reason = 0;
+ pHddCtx->scan_reject_cnt = 0;
/* Check whether SAP scan can be skipped or not */
if (pAdapter->device_mode == QDF_SAP_MODE &&
diff --git a/core/hdd/src/wlan_hdd_stats.c b/core/hdd/src/wlan_hdd_stats.c
index b29e56b..f96a2e0 100644
--- a/core/hdd/src/wlan_hdd_stats.c
+++ b/core/hdd/src/wlan_hdd_stats.c
@@ -1855,16 +1855,18 @@
hdd_populate_wifi_signal_info(struct sir_wifi_peer_signal_stats *peer_signal,
struct sk_buff *skb)
{
- uint32_t i;
+ uint32_t i, chain_count;
struct nlattr *chains, *att;
/* There might be no signal info for a peer */
if (!peer_signal)
return 0;
+ chain_count = peer_signal->num_chain < WIFI_MAX_CHAINS ?
+ peer_signal->num_chain : WIFI_MAX_CHAINS;
if (nla_put_u32(skb,
QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_ANT_NUM,
- WIFI_MAX_CHAINS)) {
+ chain_count)) {
hdd_err("QCA_WLAN_VENDOR_ATTR put fail");
return -EINVAL;
}
@@ -1876,7 +1878,7 @@
return -EINVAL;
}
- for (i = 0; i < WIFI_MAX_CHAINS; i++) {
+ for (i = 0; i < chain_count; i++) {
chains = nla_nest_start(skb, i);
if (!chains) {
@@ -1884,12 +1886,23 @@
return -EINVAL;
}
+ hdd_debug("SNR=%d, NF=%d, Rx=%d, Tx=%d",
+ peer_signal->per_ant_snr[i],
+ peer_signal->nf[i],
+ peer_signal->per_ant_rx_mpdus[i],
+ peer_signal->per_ant_tx_mpdus[i]);
if (nla_put_u32(skb,
QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_SNR,
peer_signal->per_ant_snr[i]) ||
nla_put_u32(skb,
QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_NF,
- peer_signal->nf[i])) {
+ peer_signal->nf[i]) ||
+ nla_put_u32(skb,
+ QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU,
+ peer_signal->per_ant_rx_mpdus[i]) ||
+ nla_put_u32(skb,
+ QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MPDU,
+ peer_signal->per_ant_tx_mpdus[i])) {
hdd_err("QCA_WLAN_VENDOR_ATTR put fail");
return -EINVAL;
}
diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c
index beaee5f..eb6e24a 100644
--- a/core/hdd/src/wlan_hdd_wext.c
+++ b/core/hdd/src/wlan_hdd_wext.c
@@ -5006,8 +5006,7 @@
SME_SUMMARY_STATS |
SME_GLOBAL_CLASSA_STATS |
SME_GLOBAL_CLASSD_STATS,
- hdd_statistics_cb, 0,
- false,
+ hdd_statistics_cb,
pHddStaCtx->conn_info.staId[0],
pAdapter, pAdapter->sessionId);
@@ -6165,8 +6164,6 @@
hstatus = sme_get_statistics(WLAN_HDD_GET_HAL_CTX(pAdapter),
eCSR_HDD, SME_GLOBAL_CLASSA_STATS,
hdd_get_class_a_statistics_cb,
- 0, /* not periodic */
- false, /* non-cached results */
pHddStaCtx->conn_info.staId[0],
cookie, pAdapter->sessionId);
if (QDF_STATUS_SUCCESS != hstatus) {
@@ -6283,8 +6280,6 @@
SME_GLOBAL_CLASSA_STATS |
SME_PER_CHAIN_RSSI_STATS,
hdd_get_station_statistics_cb,
- 0, /* not periodic */
- false, /* non-cached results */
pHddStaCtx->conn_info.staId[0],
cookie,
pAdapter->sessionId);
@@ -7574,10 +7569,10 @@
return -EIO;
}
if (phddctx->config->nChannelBondingMode5GHz)
- phddctx->wiphy->bands[NL80211_BAND_5GHZ]->ht_cap.cap
+ phddctx->wiphy->bands[HDD_NL80211_BAND_5GHZ]->ht_cap.cap
|= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
else
- phddctx->wiphy->bands[NL80211_BAND_5GHZ]->ht_cap.cap
+ phddctx->wiphy->bands[HDD_NL80211_BAND_5GHZ]->ht_cap.cap
&= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
hdd_debug("New_Phymode= %d ch_bonding=%d band=%d VHT_ch_width=%u",
@@ -11670,7 +11665,7 @@
pmo_set_pkt_fltr_req =
qdf_mem_malloc(sizeof(*pmo_set_pkt_fltr_req));
if (!pmo_set_pkt_fltr_req) {
- pmo_err("unable to allocate pmo_set_pkt_fltr_req");
+ hdd_err("unable to allocate pmo_set_pkt_fltr_req");
return QDF_STATUS_E_NOMEM;
}
@@ -11683,7 +11678,7 @@
}
pmo_set_pkt_fltr_req->num_params = request->num_params;
pmo_set_pkt_fltr_req->coalesce_time = 0;
- pmo_set_pkt_fltr_req->filter_type = HDD_RCV_FILTER_SET;
+ pmo_set_pkt_fltr_req->filter_type = PMO_RCV_FILTER_TYPE_FILTER_PKT;
for (i = 0; i < request->num_params; i++) {
pmo_set_pkt_fltr_req->params_data[i].protocol_layer =
request->params_data[i].protocol_layer;
@@ -11930,7 +11925,7 @@
SME_SUMMARY_STATS |
SME_GLOBAL_CLASSA_STATS |
SME_GLOBAL_CLASSD_STATS,
- hdd_statistics_cb, 0, false,
+ hdd_statistics_cb,
(WLAN_HDD_GET_STATION_CTX_PTR
(pAdapter))->conn_info.staId[0],
pAdapter, pAdapter->sessionId);
@@ -11954,7 +11949,7 @@
SME_SUMMARY_STATS |
SME_GLOBAL_CLASSA_STATS |
SME_GLOBAL_CLASSD_STATS,
- NULL, 0, false,
+ NULL,
(WLAN_HDD_GET_STATION_CTX_PTR
(pAdapter))->conn_info.
staId[0], pAdapter,
@@ -12702,6 +12697,10 @@
value[1], value[2]);
pr_err("SSR is triggered by iwpriv CRASH_INJECT: %d %d\n",
value[1], value[2]);
+ if (value[1] == 3) {
+ cds_trigger_recovery(false);
+ return 0;
+ }
ret = wma_cli_set2_command(pAdapter->sessionId,
GEN_PARAM_CRASH_INJECT,
value[1], value[2], GEN_CMD);
diff --git a/core/mac/inc/ani_system_defs.h b/core/mac/inc/ani_system_defs.h
index 4d5796e..2e228a5 100644
--- a/core/mac/inc/ani_system_defs.h
+++ b/core/mac/inc/ani_system_defs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -63,12 +63,6 @@
#define true 1
#endif
-typedef enum eAniBool {
- eSIR_FALSE,
- eSIR_TRUE,
- eSIR_DONOT_USE_BOOL = SIR_MAX_ENUM_SIZE
-} tAniBool;
-
/* / Authentication type enum used with peer */
typedef enum eAniAuthType {
eSIR_OPEN_SYSTEM,
@@ -180,7 +174,7 @@
tSirMacAddr srcMacAddr; /* address used to compute MIC */
tSirMacAddr taMacAddr; /* transmitter address */
tSirMacAddr dstMacAddr;
- tAniBool multicast;
+ bool multicast;
uint8_t IV1; /* first byte of IV */
uint8_t keyId; /* second byte of IV */
uint8_t TSC[SIR_CIPHER_SEQ_CTR_SIZE]; /* sequence number */
diff --git a/core/mac/inc/mac_init_api.h b/core/mac/inc/mac_init_api.h
index a439d19..6004c1e 100644
--- a/core/mac/inc/mac_init_api.h
+++ b/core/mac/inc/mac_init_api.h
@@ -42,9 +42,9 @@
#include "sir_types.h"
tSirRetStatus mac_start(tHalHandle hHal, void *pHalMacStartParams);
-tSirRetStatus mac_stop(tHalHandle hHal, tHalStopType stopType);
+QDF_STATUS mac_stop(tHalHandle hHal, tHalStopType stopType);
tSirRetStatus mac_open(struct wlan_objmgr_psoc *psoc, tHalHandle *pHalHandle,
tHddHandle hHdd, struct cds_config_info *cds_cfg);
-tSirRetStatus mac_close(tHalHandle hHal);
+QDF_STATUS mac_close(tHalHandle hHal);
#endif /* __MAC_INIT_API_H */
diff --git a/core/mac/inc/qwlan_version.h b/core/mac/inc/qwlan_version.h
index 50d421a..93f29c1 100644
--- a/core/mac/inc/qwlan_version.h
+++ b/core/mac/inc/qwlan_version.h
@@ -41,9 +41,9 @@
#define QWLAN_VERSION_MAJOR 5
#define QWLAN_VERSION_MINOR 2
#define QWLAN_VERSION_PATCH 0
-#define QWLAN_VERSION_EXTRA "Z"
-#define QWLAN_VERSION_BUILD 33
+#define QWLAN_VERSION_EXTRA "I"
+#define QWLAN_VERSION_BUILD 35
-#define QWLAN_VERSIONSTR "5.2.0.33Z"
+#define QWLAN_VERSIONSTR "5.2.0.35I"
#endif /* QWLAN_VERSION_H */
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index 55a6a4b..e30acfd 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -1166,15 +1166,15 @@
tAniEdType MgmtEncryptionType;
#endif
- tAniBool is11Rconnection;
+ bool is11Rconnection;
#ifdef FEATURE_WLAN_ESE
- tAniBool isESEFeatureIniEnabled;
- tAniBool isESEconnection;
+ bool isESEFeatureIniEnabled;
+ bool isESEconnection;
tESETspecInfo eseTspecInfo;
#endif
- tAniBool isFastTransitionEnabled;
- tAniBool isFastRoamIniFeatureEnabled;
+ bool isFastTransitionEnabled;
+ bool isFastRoamIniFeatureEnabled;
uint8_t txLdpcIniFeatureEnabled;
tSirHTConfig htConfig;
@@ -1190,11 +1190,11 @@
bool send_smps_action;
uint8_t max_amsdu_num;
- tAniBool isWMEenabled;
- tAniBool isQosEnabled;
- tAniBool isOSENConnection;
+ bool isWMEenabled;
+ bool isQosEnabled;
+ bool isOSENConnection;
struct rrm_config_param rrm_config;
- tAniBool spectrumMgtIndicator;
+ bool spectrumMgtIndicator;
tSirMacPowerCapInfo powerCap;
tSirSupChnl supportedChannels;
bool enable_bcast_probe_rsp;
@@ -1287,6 +1287,12 @@
enum phy_ch_width ch_width;
} tSirSmeChanInfo, *tpSirSmeChanInfo;
+enum sir_sme_phy_mode {
+ SIR_SME_PHY_MODE_LEGACY = 0,
+ SIR_SME_PHY_MODE_HT = 1,
+ SIR_SME_PHY_MODE_VHT = 2
+};
+
/* / Definition for Association indication from peer */
/* / MAC ---> */
typedef struct sSirSmeAssocInd {
@@ -1310,11 +1316,11 @@
/* powerCap & supportedChannels are present only when */
/* spectrumMgtIndicator flag is set */
- tAniBool spectrumMgtIndicator;
+ bool spectrumMgtIndicator;
tSirMacPowerCapInfo powerCap;
tSirSupChnl supportedChannels;
- tAniBool wmmEnabledSta; /* if present - STA is WMM enabled */
- tAniBool reassocReq;
+ bool wmmEnabledSta; /* if present - STA is WMM enabled */
+ bool reassocReq;
/* Required for indicating the frames to upper layer */
uint32_t beaconLength;
uint8_t *beaconPtr;
@@ -1324,6 +1330,17 @@
/* Timing measurement capability */
uint8_t timingMeasCap;
tSirSmeChanInfo chan_info;
+ bool ampdu;
+ bool sgi_enable;
+ bool tx_stbc;
+ bool rx_stbc;
+ tSirMacHTChannelWidth ch_width;
+ enum sir_sme_phy_mode mode;
+ uint8_t max_supp_idx;
+ uint8_t max_ext_idx;
+ uint8_t max_mcs_idx;
+ uint8_t rx_mcs_map;
+ uint8_t tx_mcs_map;
} tSirSmeAssocInd, *tpSirSmeAssocInd;
/* / Definition for Association confirm */
@@ -1563,7 +1580,7 @@
struct qdf_mac_addr peer_macaddr;
tAniStaStatStruct perStaStats; /* STA stats */
uint16_t staId;
-} qdf_packed tSirSmeDisassocRsp, *tpSirSmeDisassocRsp;
+} tSirSmeDisassocRsp, *tpSirSmeDisassocRsp;
/* / Definition for Disassociation indication from peer */
typedef struct sSirSmeDisassocInd {
@@ -1897,8 +1914,8 @@
uint16_t msgType; /* message type is same as the request type */
uint16_t msgLen; /* length of the entire request */
uint8_t countryCode[WNI_CFG_COUNTRY_CODE_LEN]; /* 3 char country code */
- tAniBool countryFromUserSpace;
- tAniBool sendRegHint; /* true if we want to send hint to NL80211 */
+ bool countryFromUserSpace;
+ bool sendRegHint; /* true if we want to send hint to NL80211 */
void *changeCCCallback;
void *pDevContext; /* device context */
void *p_cds_context; /* cds context */
@@ -2983,6 +3000,20 @@
uint32_t unused:30;
};
+/**
+ * struct lca_disallow_config_params - LCA[Last Connected AP]
+ * disallow config params
+ * @disallow_duration: LCA AP disallowed duration
+ * @rssi_channel_penalization: RSSI channel Penalization
+ * @num_disallowed_aps: Maximum number of AP's in LCA list
+ *
+ */
+struct lca_disallow_config_params{
+ uint32_t disallow_duration;
+ uint32_t rssi_channel_penalization;
+ uint32_t num_disallowed_aps;
+};
+
typedef struct sSirRoamOffloadScanReq {
uint16_t message_type;
uint16_t length;
@@ -3040,6 +3071,7 @@
int8_t early_stop_scan_max_threshold;
enum wmi_dwelltime_adaptive_mode roamscan_adaptive_dwell_mode;
tSirAddie assoc_ie;
+ struct lca_disallow_config_params lca_config_params;
} tSirRoamOffloadScanReq, *tpSirRoamOffloadScanReq;
typedef struct sSirRoamOffloadScanRsp {
@@ -5225,6 +5257,9 @@
* @peer_id: peer ID
* @per_ant_snr: per antenna SNR
* @nf: peer background noise
+ * @per_ant_rx_mpdus: MPDUs received per antenna
+ * @per_ant_tx_mpdus: MPDUs transferred per antenna
+ * @num_chain: valid chain count
*/
struct sir_wifi_peer_signal_stats {
uint32_t vdev_id;
@@ -5235,6 +5270,10 @@
/* Background noise */
int32_t nf[WIFI_MAX_CHAINS];
+
+ int32_t per_ant_rx_mpdus[WIFI_MAX_CHAINS];
+ int32_t per_ant_tx_mpdus[WIFI_MAX_CHAINS];
+ int32_t num_chain;
};
#define WIFI_VDEV_NUM 4
diff --git a/core/mac/inc/sir_mac_prot_def.h b/core/mac/inc/sir_mac_prot_def.h
index 508f0d6..60b8417 100644
--- a/core/mac/inc/sir_mac_prot_def.h
+++ b/core/mac/inc/sir_mac_prot_def.h
@@ -560,7 +560,7 @@
#define SIR_MAC_MAX_NUMBER_OF_RATES 12
#define SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS 4
#define SIR_MAC_KEY_LENGTH 13 /* WEP Maximum key length size */
-#define SIR_MAC_AUTH_CHALLENGE_LENGTH 128
+#define SIR_MAC_AUTH_CHALLENGE_LENGTH 253
#define SIR_MAC_WEP_IV_LENGTH 4
#define SIR_MAC_WEP_ICV_LENGTH 4
diff --git a/core/mac/inc/wni_api.h b/core/mac/inc/wni_api.h
index 7c95510..8f9d7cb 100644
--- a/core/mac/inc/wni_api.h
+++ b/core/mac/inc/wni_api.h
@@ -261,6 +261,7 @@
eWMI_SME_LL_STATS_IND,
eWNI_SME_DFS_CAC_COMPLETE,
eWNI_SME_UPDATE_CONFIG,
+ eWNI_SME_BT_ACTIVITY_INFO_IND,
eWNI_SME_MSG_TYPES_END
};
diff --git a/core/mac/src/cfg/cfgUtil/dot11f.frms b/core/mac/src/cfg/cfgUtil/dot11f.frms
index e4b4773..6923da0 100644
--- a/core/mac/src/cfg/cfgUtil/dot11f.frms
+++ b/core/mac/src/cfg/cfgUtil/dot11f.frms
@@ -3634,6 +3634,7 @@
OPTIE vendor_he_op;
OPTIE bss_color_change;
OPTIE mu_edca_param_set;
+ OPTIE MBO_IE;
} // End frame AssocResponse.
FRAME ReAssocRequest // 7.2.3.6
@@ -3712,6 +3713,7 @@
OPTIE vendor_he_op;
OPTIE bss_color_change;
OPTIE mu_edca_param_set;
+ OPTIE MBO_IE;
} // End frame ReAssocResponse.
FRAME ProbeRequest // 7.2.3.8
diff --git a/core/mac/src/dph/dph_hash_table.c b/core/mac/src/dph/dph_hash_table.c
index 3ebcb6a..3fd4940 100644
--- a/core/mac/src/dph/dph_hash_table.c
+++ b/core/mac/src/dph/dph_hash_table.c
@@ -240,7 +240,7 @@
{
uint32_t val;
- tpDphHashNode pStaDs;
+ tpDphHashNode pStaDs, pnext;
uint16_t staIdx = STA_INVALID_IDX;
if (assocId >= pDphHashTable->size) {
@@ -250,10 +250,11 @@
pStaDs = get_node(pMac, (uint8_t) assocId, pDphHashTable);
staIdx = pStaDs->staIndex;
+ pnext = pStaDs->next;
- /* Clear the STA node except for the next pointer (last 4 bytes) */
- qdf_mem_set((uint8_t *) pStaDs,
- sizeof(tDphHashNode) - sizeof(tpDphHashNode), 0);
+ /* Clear the STA node except for the next pointer */
+ qdf_mem_set((uint8_t *)pStaDs, sizeof(tDphHashNode), 0);
+ pStaDs->next = pnext;
/* Initialize the assocId */
pStaDs->assocId = assocId;
diff --git a/core/mac/src/include/dot11f.h b/core/mac/src/include/dot11f.h
index 3885b4b..8ee738c 100644
--- a/core/mac/src/include/dot11f.h
+++ b/core/mac/src/include/dot11f.h
@@ -35,7 +35,7 @@
*
*
* This file was automatically generated by 'framesc'
- * Thu Jul 6 16:41:06 2017 from the following file(s):
+ * Fri Jul 14 12:29:59 2017 from the following file(s):
*
* dot11f.frms
*
@@ -9291,6 +9291,7 @@
tDot11fIEvendor_he_op vendor_he_op;
tDot11fIEbss_color_change bss_color_change;
tDot11fIEmu_edca_param_set mu_edca_param_set;
+ tDot11fIEMBO_IE MBO_IE;
} tDot11fAssocResponse;
#define DOT11F_ASSOCRESPONSE (4)
@@ -10218,6 +10219,7 @@
tDot11fIEvendor_he_op vendor_he_op;
tDot11fIEbss_color_change bss_color_change;
tDot11fIEmu_edca_param_set mu_edca_param_set;
+ tDot11fIEMBO_IE MBO_IE;
} tDot11fReAssocResponse;
#define DOT11F_REASSOCRESPONSE (27)
diff --git a/core/mac/src/pe/include/lim_session.h b/core/mac/src/pe/include/lim_session.h
index c8fe42c..ee757fe 100644
--- a/core/mac/src/pe/include/lim_session.h
+++ b/core/mac/src/pe/include/lim_session.h
@@ -55,7 +55,7 @@
tpAniSirGlobal pMac;
uint8_t sessionID;
tLimMlmStates limPrevMlmState; /* Previous MLM State */
- tLimSmeStates limMlmState; /* MLM State */
+ tLimMlmStates limMlmState; /* MLM State */
} tComebackTimerInfo;
#endif /* WLAN_FEATURE_11W */
/*--------------------------------------------------------------------------
@@ -292,14 +292,14 @@
int8_t maxTxPower; /* MIN (Regulatory and local power constraint) */
enum tQDF_ADAPTER_MODE pePersona;
int8_t txMgmtPower;
- tAniBool is11Rconnection;
+ bool is11Rconnection;
#ifdef FEATURE_WLAN_ESE
- tAniBool isESEconnection;
+ bool isESEconnection;
tEsePEContext eseContext;
#endif
- tAniBool isFastTransitionEnabled;
- tAniBool isFastRoamIniFeatureEnabled;
+ bool isFastTransitionEnabled;
+ bool isFastRoamIniFeatureEnabled;
tSirNoAParam p2pNoA;
tSirP2PNoaAttr p2pGoPsUpdate;
uint32_t defaultAuthFailureTimeout;
diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c
index b8041c9..9356f4f 100644
--- a/core/mac/src/pe/lim/lim_api.c
+++ b/core/mac/src/pe/lim/lim_api.c
@@ -479,7 +479,7 @@
*/
tSirRetStatus lim_start(tpAniSirGlobal pMac)
{
- tSirResultCodes retCode = eSIR_SUCCESS;
+ tSirRetStatus retCode = eSIR_SUCCESS;
pe_debug("enter");
@@ -1354,34 +1354,34 @@
* @param pBeacon - Parsed Beacon Frame structure
* @param pSession - Pointer to the PE session
*
- * @return eSIR_TRUE if encryption type is matched; eSIR_FALSE otherwise
+ * @return true if encryption type is matched; false otherwise
*/
-static tAniBool lim_ibss_enc_type_matched(tpSchBeaconStruct pBeacon,
+static bool lim_ibss_enc_type_matched(tpSchBeaconStruct pBeacon,
tpPESession pSession)
{
if (!pBeacon || !pSession)
- return eSIR_FALSE;
+ return false;
/* Open case */
if (pBeacon->capabilityInfo.privacy == 0
&& pSession->encryptType == eSIR_ED_NONE)
- return eSIR_TRUE;
+ return true;
/* WEP case */
if (pBeacon->capabilityInfo.privacy == 1 && pBeacon->wpaPresent == 0
&& pBeacon->rsnPresent == 0
&& (pSession->encryptType == eSIR_ED_WEP40
|| pSession->encryptType == eSIR_ED_WEP104))
- return eSIR_TRUE;
+ return true;
/* WPA-None case */
if (pBeacon->capabilityInfo.privacy == 1 && pBeacon->wpaPresent == 1
&& pBeacon->rsnPresent == 0
&& ((pSession->encryptType == eSIR_ED_CCMP) ||
(pSession->encryptType == eSIR_ED_TKIP)))
- return eSIR_TRUE;
+ return true;
- return eSIR_FALSE;
+ return false;
}
/**
@@ -1424,7 +1424,7 @@
lim_cmp_ssid(&pBeacon->ssId, psessionEntry) ||
(psessionEntry->currentOperChannel != pBeacon->channelNumber))
retCode = eSIR_LIM_IGNORE_BEACON;
- else if (lim_ibss_enc_type_matched(pBeacon, psessionEntry) != eSIR_TRUE) {
+ else if (lim_ibss_enc_type_matched(pBeacon, psessionEntry) != true) {
pe_debug("peer privacy: %d peer wpa: %d peer rsn: %d self encType: %d",
pBeacon->capabilityInfo.privacy,
pBeacon->wpaPresent, pBeacon->rsnPresent,
@@ -1985,6 +1985,15 @@
bss_desc_ptr->timeStamp[1] = parsed_frm_ptr->timeStamp[1];
qdf_mem_copy(&bss_desc_ptr->capabilityInfo,
&bcn_proberesp_ptr[SIR_MAC_HDR_LEN_3A + SIR_MAC_B_PR_CAPAB_OFFSET], 2);
+
+ if (qdf_is_macaddr_zero((struct qdf_mac_addr *)mac_hdr->bssId)) {
+ pe_debug("bssid is 0 in beacon/probe update it with bssId %pM in sync ind",
+ roam_offload_synch_ind_ptr->bssid.bytes);
+ qdf_mem_copy(mac_hdr->bssId,
+ roam_offload_synch_ind_ptr->bssid.bytes,
+ sizeof(tSirMacAddr));
+ }
+
qdf_mem_copy((uint8_t *) &bss_desc_ptr->bssId,
(uint8_t *) mac_hdr->bssId,
sizeof(tSirMacAddr));
diff --git a/core/mac/src/pe/lim/lim_link_monitoring_algo.c b/core/mac/src/pe/lim/lim_link_monitoring_algo.c
index 95d4390..1734eee 100644
--- a/core/mac/src/pe/lim/lim_link_monitoring_algo.c
+++ b/core/mac/src/pe/lim/lim_link_monitoring_algo.c
@@ -231,7 +231,7 @@
pe_err("Do not process in limMlmState %s(%x) limSmeState %s(%x)",
lim_mlm_state_str(session_entry->limMlmState),
session_entry->limMlmState,
- lim_mlm_state_str(session_entry->limSmeState),
+ lim_sme_state_str(session_entry->limSmeState),
session_entry->limSmeState);
qdf_mem_free(msg);
return;
diff --git a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c
index 970533b..9c39b71 100644
--- a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c
+++ b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c
@@ -2110,6 +2110,50 @@
return;
}
+static uint8_t lim_get_max_rate_idx(tSirMacRateSet *rateset)
+{
+ uint8_t maxidx;
+ int i;
+
+ maxidx = rateset->rate[0] & 0x7f;
+ for (i = 1; i < rateset->numRates; i++) {
+ if ((rateset->rate[i] & 0x7f) > maxidx)
+ maxidx = rateset->rate[i] & 0x7f;
+ }
+
+ return maxidx;
+}
+
+static void fill_mlm_assoc_ind_vht(tpSirAssocReq assocreq,
+ tpDphHashNode stads,
+ tpLimMlmAssocInd assocind)
+{
+ if (stads->mlmStaContext.vhtCapability) {
+ /* ampdu */
+ assocind->ampdu = true;
+
+ /* sgi */
+ if (assocreq->VHTCaps.shortGI80MHz ||
+ assocreq->VHTCaps.shortGI160and80plus80MHz)
+ assocind->sgi_enable = true;
+
+ /* stbc */
+ assocind->tx_stbc = assocreq->VHTCaps.txSTBC;
+ assocind->rx_stbc = assocreq->VHTCaps.rxSTBC;
+
+ /* ch width */
+ assocind->ch_width = stads->vhtSupportedChannelWidthSet ?
+ eHT_CHANNEL_WIDTH_80MHZ :
+ stads->htSupportedChannelWidthSet ?
+ eHT_CHANNEL_WIDTH_40MHZ : eHT_CHANNEL_WIDTH_20MHZ;
+
+ /* mode */
+ assocind->mode = SIR_SME_PHY_MODE_VHT;
+ assocind->rx_mcs_map = assocreq->VHTCaps.rxMCSMap & 0xff;
+ assocind->tx_mcs_map = assocreq->VHTCaps.txMCSMap & 0xff;
+ }
+}
+
/**
* lim_send_mlm_assoc_ind() - Sends assoc indication to SME
* @mac_ctx: Global Mac context
@@ -2130,6 +2174,7 @@
uint32_t phy_mode;
uint8_t sub_type;
uint8_t *wpsie = NULL;
+ uint8_t maxidx, i;
uint32_t tmp;
/* Get a copy of the already parsed Assoc Request */
@@ -2192,7 +2237,7 @@
/* Fill in 802.11h related info */
if (assoc_req->powerCapabilityPresent
&& assoc_req->supportedChannelsPresent) {
- assoc_ind->spectrumMgtIndicator = eSIR_TRUE;
+ assoc_ind->spectrumMgtIndicator = true;
assoc_ind->powerCap.minTxPower =
assoc_req->powerCapability.minTxPower;
assoc_ind->powerCap.maxTxPower =
@@ -2200,7 +2245,7 @@
lim_convert_supported_channels(mac_ctx, assoc_ind,
assoc_req);
} else {
- assoc_ind->spectrumMgtIndicator = eSIR_FALSE;
+ assoc_ind->spectrumMgtIndicator = false;
}
/* This check is to avoid extra Sec IEs present incase of WPS */
@@ -2295,6 +2340,57 @@
assoc_ind->chan_info.nss = sta_ds->nss;
assoc_ind->chan_info.rate_flags =
lim_get_max_rate_flags(mac_ctx, sta_ds);
+ assoc_ind->ampdu = false;
+ assoc_ind->sgi_enable = false;
+ assoc_ind->tx_stbc = false;
+ assoc_ind->rx_stbc = false;
+ assoc_ind->ch_width = eHT_CHANNEL_WIDTH_20MHZ;
+ assoc_ind->mode = SIR_SME_PHY_MODE_LEGACY;
+ assoc_ind->max_supp_idx = 0xff;
+ assoc_ind->max_ext_idx = 0xff;
+ assoc_ind->max_mcs_idx = 0xff;
+ assoc_ind->rx_mcs_map = 0xff;
+ assoc_ind->tx_mcs_map = 0xff;
+
+ if (assoc_req->supportedRates.numRates)
+ assoc_ind->max_supp_idx =
+ lim_get_max_rate_idx(
+ &assoc_req->supportedRates);
+ if (assoc_req->extendedRates.numRates)
+ assoc_ind->max_ext_idx =
+ lim_get_max_rate_idx(
+ &assoc_req->extendedRates);
+
+ if (sta_ds->mlmStaContext.htCapability) {
+ /* ampdu */
+ assoc_ind->ampdu = true;
+
+ /* sgi */
+ if (sta_ds->htShortGI20Mhz || sta_ds->htShortGI40Mhz)
+ assoc_ind->sgi_enable = true;
+
+ /* stbc */
+ assoc_ind->tx_stbc = assoc_req->HTCaps.txSTBC;
+ assoc_ind->rx_stbc = assoc_req->HTCaps.rxSTBC;
+
+ /* ch width */
+ assoc_ind->ch_width =
+ sta_ds->htSupportedChannelWidthSet ?
+ eHT_CHANNEL_WIDTH_40MHZ :
+ eHT_CHANNEL_WIDTH_20MHZ;
+
+ /* mode */
+ assoc_ind->mode = SIR_SME_PHY_MODE_HT;
+ maxidx = 0;
+ for (i = 0; i < 8; i++) {
+ if (assoc_req->HTCaps.supportedMCSSet[0] &
+ (1 << i))
+ maxidx = i;
+ }
+ assoc_ind->max_mcs_idx = maxidx;
+ }
+ fill_mlm_assoc_ind_vht(assoc_req, sta_ds, assoc_ind);
+
/* updates VHT information in assoc indication */
lim_fill_assoc_ind_vht_info(mac_ctx, session_entry, assoc_req,
assoc_ind);
diff --git a/core/mac/src/pe/lim/lim_process_auth_frame.c b/core/mac/src/pe/lim/lim_process_auth_frame.c
index 71bd8a0..090f982 100644
--- a/core/mac/src/pe/lim/lim_process_auth_frame.c
+++ b/core/mac/src/pe/lim/lim_process_auth_frame.c
@@ -281,7 +281,7 @@
if (sta_ds_ptr) {
tLimMlmDisassocReq *pMlmDisassocReq = NULL;
tLimMlmDeauthReq *pMlmDeauthReq = NULL;
- tAniBool isConnected = eSIR_TRUE;
+ bool isConnected = true;
pMlmDisassocReq =
mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
@@ -294,7 +294,7 @@
MAC_ADDR_ARRAY(
pMlmDisassocReq->peer_macaddr.bytes));
lim_process_disassoc_ack_timeout(mac_ctx);
- isConnected = eSIR_FALSE;
+ isConnected = false;
}
pMlmDeauthReq =
mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
@@ -307,7 +307,7 @@
MAC_ADDR_ARRAY(
pMlmDeauthReq->peer_macaddr.bytes));
lim_process_deauth_ack_timeout(mac_ctx);
- isConnected = eSIR_FALSE;
+ isConnected = false;
}
/*
diff --git a/core/mac/src/pe/lim/lim_process_message_queue.c b/core/mac/src/pe/lim/lim_process_message_queue.c
index 2dcbe8b..f63f074 100644
--- a/core/mac/src/pe/lim/lim_process_message_queue.c
+++ b/core/mac/src/pe/lim/lim_process_message_queue.c
@@ -878,7 +878,7 @@
tpSirMacMgmtHdr pHdr = NULL;
tpPESession psessionEntry = NULL;
uint8_t sessionId;
- tAniBool isFrmFt = false;
+ bool isFrmFt = false;
*pDeferMsg = false;
lim_get_b_dfrom_rx_packet(pMac, limMsg->bodyptr,
diff --git a/core/mac/src/pe/lim/lim_process_mlm_req_messages.c b/core/mac/src/pe/lim/lim_process_mlm_req_messages.c
index 030e1fd..7b0d693 100644
--- a/core/mac/src/pe/lim/lim_process_mlm_req_messages.c
+++ b/core/mac/src/pe/lim/lim_process_mlm_req_messages.c
@@ -489,7 +489,7 @@
if (NULL == addbss_param) {
pe_err("Unable to allocate memory during ADD_BSS");
/* Respond to SME with LIM_MLM_START_CNF */
- return eSIR_MEM_ALLOC_FAILED;
+ return eSIR_SME_RESOURCES_UNAVAILABLE;
}
/* Fill in tAddBssParams members */
diff --git a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c
index b0cf987..209e209 100644
--- a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c
+++ b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c
@@ -756,7 +756,7 @@
/* Copy the new TITAN capabilities */
sme_assoc_ind->spectrumMgtIndicator = assoc_ind->spectrumMgtIndicator;
- if (assoc_ind->spectrumMgtIndicator == eSIR_TRUE) {
+ if (assoc_ind->spectrumMgtIndicator == true) {
sme_assoc_ind->powerCap.minTxPower =
assoc_ind->powerCap.minTxPower;
sme_assoc_ind->powerCap.maxTxPower =
@@ -772,6 +772,17 @@
sizeof(tSirSmeChanInfo));
/* Fill in WmmInfo */
sme_assoc_ind->wmmEnabledSta = assoc_ind->WmmStaInfoPresent;
+ sme_assoc_ind->ampdu = assoc_ind->ampdu;
+ sme_assoc_ind->sgi_enable = assoc_ind->sgi_enable;
+ sme_assoc_ind->tx_stbc = assoc_ind->tx_stbc;
+ sme_assoc_ind->rx_stbc = assoc_ind->rx_stbc;
+ sme_assoc_ind->ch_width = assoc_ind->ch_width;
+ sme_assoc_ind->mode = assoc_ind->mode;
+ sme_assoc_ind->max_supp_idx = assoc_ind->max_supp_idx;
+ sme_assoc_ind->max_ext_idx = assoc_ind->max_ext_idx;
+ sme_assoc_ind->max_mcs_idx = assoc_ind->max_mcs_idx;
+ sme_assoc_ind->rx_mcs_map = assoc_ind->rx_mcs_map;
+ sme_assoc_ind->tx_mcs_map = assoc_ind->tx_mcs_map;
}
/**
@@ -3205,7 +3216,7 @@
case SIR_SCAN_EVENT_START_FAILED:
if (ROC_SCAN_REQUESTOR_ID == pScanEvent->requestor) {
lim_send_sme_roc_rsp(pMac, eWNI_SME_REMAIN_ON_CHN_RSP,
- QDF_STATUS_SUCCESS,
+ eSIR_SME_SUCCESS,
pScanEvent->sessionId,
pScanEvent->scanId);
qdf_mem_free(pMac->lim.gpLimRemainOnChanReq);
@@ -3233,7 +3244,7 @@
if (pMac->lim.gpLimRemainOnChanReq) {
lim_send_sme_roc_rsp(pMac,
eWNI_SME_REMAIN_ON_CHN_RDY_IND,
- QDF_STATUS_SUCCESS,
+ eSIR_SME_SUCCESS,
pScanEvent->sessionId,
pScanEvent->scanId);
} else {
diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
index 2ae9522..b425330 100644
--- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c
+++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
@@ -3505,7 +3505,7 @@
sta_ds->mlmStaContext.subType,
true, sta_ds->mlmStaContext.authType,
sta_ds->assocId, true,
- eSIR_MAC_UNSPEC_FAILURE_STATUS,
+ eSIR_SME_UNEXPECTED_REQ_RESULT_CODE,
session_entry);
}
end:
@@ -3569,10 +3569,7 @@
if (!LIM_IS_STA_ROLE(psessionEntry)) {
pe_err("AddTs received on AP - ignoring");
- lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
- psessionEntry, pSirAddts->req.tspec,
- smesessionId, smetransactionId);
- return;
+ goto send_failure_addts_rsp;
}
pStaDs =
@@ -3581,19 +3578,13 @@
if (pStaDs == NULL) {
pe_err("Cannot find AP context for addts req");
- lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
- psessionEntry, pSirAddts->req.tspec,
- smesessionId, smetransactionId);
- return;
+ goto send_failure_addts_rsp;
}
if ((!pStaDs->valid) || (pStaDs->mlmStaContext.mlmState !=
eLIM_MLM_LINK_ESTABLISHED_STATE)) {
pe_err("AddTs received in invalid MLM state");
- lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
- psessionEntry, pSirAddts->req.tspec,
- smesessionId, smetransactionId);
- return;
+ goto send_failure_addts_rsp;
}
pSirAddts->req.wsmTspecPresent = 0;
@@ -3610,20 +3601,14 @@
pSirAddts->req.lleTspecPresent = 1;
else {
pe_warn("ADDTS_REQ ignore - qos is disabled");
- lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
- psessionEntry, pSirAddts->req.tspec,
- smesessionId, smetransactionId);
- return;
+ goto send_failure_addts_rsp;
}
if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
(psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE)) {
pe_err("AddTs received in invalid LIMsme state (%d)",
psessionEntry->limSmeState);
- lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
- psessionEntry, pSirAddts->req.tspec,
- smesessionId, smetransactionId);
- return;
+ goto send_failure_addts_rsp;
}
if (pMac->lim.gLimAddtsSent) {
@@ -3632,10 +3617,7 @@
pMac->lim.gLimAddtsReq.req.tspec.tsinfo.traffic.tsid,
pMac->lim.gLimAddtsReq.req.tspec.tsinfo.traffic.
userPrio);
- lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
- psessionEntry, pSirAddts->req.tspec,
- smesessionId, smetransactionId);
- return;
+ goto send_failure_addts_rsp;
}
sir_copy_mac_addr(peerMac, psessionEntry->bssId);
@@ -3656,21 +3638,21 @@
eSIR_SUCCESS) {
pe_err("Unable to get Cfg param %d (Addts Rsp Timeout)",
WNI_CFG_ADDTS_RSP_TIMEOUT);
- return;
+ goto send_failure_addts_rsp;
}
timeout = SYS_MS_TO_TICKS(timeout);
if (tx_timer_change(&pMac->lim.limTimers.gLimAddtsRspTimer, timeout, 0)
!= TX_SUCCESS) {
pe_err("AddtsRsp timer change failed!");
- return;
+ goto send_failure_addts_rsp;
}
pMac->lim.gLimAddtsRspTimerCount++;
if (tx_timer_change_context(&pMac->lim.limTimers.gLimAddtsRspTimer,
pMac->lim.gLimAddtsRspTimerCount) !=
TX_SUCCESS) {
pe_err("AddtsRsp timer change failed!");
- return;
+ goto send_failure_addts_rsp;
}
MTRACE(mac_trace
(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId,
@@ -3681,9 +3663,14 @@
if (tx_timer_activate(&pMac->lim.limTimers.gLimAddtsRspTimer) !=
TX_SUCCESS) {
pe_err("AddtsRsp timer activation failed!");
- return;
+ goto send_failure_addts_rsp;
}
return;
+
+send_failure_addts_rsp:
+ lim_send_sme_addts_rsp(pMac, pSirAddts->rspReqd, eSIR_FAILURE,
+ psessionEntry, pSirAddts->req.tspec,
+ smesessionId, smetransactionId);
}
static void __lim_process_sme_delts_req(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
@@ -5823,7 +5810,7 @@
switch_mode = 1;
if (LIM_IS_AP_ROLE(session_entry)) {
- for (i = 0; i < mac_ctx->lim.maxStation; i++) {
+ for (i = 0; i <= mac_ctx->lim.maxStation; i++) {
psta =
session_entry->dph.dphHashTable.pDphNodeArray + i;
if (psta && psta->added)
diff --git a/core/mac/src/pe/lim/lim_process_tdls.c b/core/mac/src/pe/lim/lim_process_tdls.c
index f1103f7..85d5e9b 100644
--- a/core/mac/src/pe/lim/lim_process_tdls.c
+++ b/core/mac/src/pe/lim/lim_process_tdls.c
@@ -2416,8 +2416,6 @@
tDot11fIEVHTCaps *pVhtCaps_txbf = NULL;
tDot11fIEVHTCaps vhtCap;
uint8_t cbMode;
- tpDphHashNode pSessStaDs = NULL;
- uint16_t aid;
if (pTdlsAddStaReq->tdlsAddOper == TDLS_OPER_ADD) {
populate_dot11f_ht_caps(pMac, psessionEntry, &htCap);
@@ -2516,8 +2514,6 @@
else
pStaDs->htSecondaryChannelOffset = cbMode;
}
- pSessStaDs = dph_lookup_hash_entry(pMac, psessionEntry->bssId, &aid,
- &psessionEntry->dph.dphHashTable);
/* Lets enable QOS parameter */
pStaDs->qosMode = (pTdlsAddStaReq->capability & CAPABILITIES_QOS_OFFSET)
|| pTdlsAddStaReq->htcap_present;
diff --git a/core/mac/src/pe/lim/lim_security_utils.c b/core/mac/src/pe/lim/lim_security_utils.c
index 68416e9..28f31a6 100644
--- a/core/mac/src/pe/lim/lim_security_utils.c
+++ b/core/mac/src/pe/lim/lim_security_utils.c
@@ -562,7 +562,7 @@
* @return None
*/
-void lim_compute_crc32(uint8_t *pDest, uint8_t *pSrc, uint8_t len)
+void lim_compute_crc32(uint8_t *pDest, uint8_t *pSrc, uint16_t len)
{
uint32_t crc;
int i;
diff --git a/core/mac/src/pe/lim/lim_security_utils.h b/core/mac/src/pe/lim/lim_security_utils.h
index 47175b8..3dc6a93 100644
--- a/core/mac/src/pe/lim/lim_security_utils.h
+++ b/core/mac/src/pe/lim/lim_security_utils.h
@@ -60,7 +60,7 @@
uint8_t lim_delete_open_auth_pre_auth_node(tpAniSirGlobal mac_ctx);
/* Encryption/Decryption related functions */
-void lim_compute_crc32(uint8_t *, uint8_t *, uint8_t);
+void lim_compute_crc32(uint8_t *, uint8_t *, uint16_t);
void lim_rc4(uint8_t *, uint8_t *, uint8_t *, uint32_t, uint16_t);
void lim_encrypt_auth_frame(tpAniSirGlobal, uint8_t, uint8_t *, uint8_t *,
uint8_t *, uint32_t);
diff --git a/core/mac/src/pe/lim/lim_send_frames_host_roam.c b/core/mac/src/pe/lim/lim_send_frames_host_roam.c
index b3d109d..655c533 100644
--- a/core/mac/src/pe/lim/lim_send_frames_host_roam.c
+++ b/core/mac/src/pe/lim/lim_send_frames_host_roam.c
@@ -142,7 +142,7 @@
LIM_BSS_CAPS_GET(WSM, pe_session->limReassocBssQosCaps);
if (pe_session->lim11hEnable &&
- pe_session->pLimReAssocReq->spectrumMgtIndicator == eSIR_TRUE) {
+ pe_session->pLimReAssocReq->spectrumMgtIndicator == true) {
power_caps_populated = true;
populate_dot11f_power_caps(mac_ctx, &frm.PowerCaps,
@@ -604,7 +604,7 @@
LIM_BSS_CAPS_GET(WSM, psessionEntry->limReassocBssQosCaps);
if (psessionEntry->lim11hEnable &&
- psessionEntry->pLimReAssocReq->spectrumMgtIndicator == eSIR_TRUE) {
+ psessionEntry->pLimReAssocReq->spectrumMgtIndicator == true) {
PowerCapsPopulated = true;
populate_dot11f_power_caps(pMac, &frm.PowerCaps, LIM_REASSOC,
psessionEntry);
diff --git a/core/mac/src/pe/lim/lim_send_management_frames.c b/core/mac/src/pe/lim/lim_send_management_frames.c
index 9117329..7944fbc 100644
--- a/core/mac/src/pe/lim/lim_send_management_frames.c
+++ b/core/mac/src/pe/lim/lim_send_management_frames.c
@@ -1636,6 +1636,7 @@
if (NULL == pe_session) {
pe_err("pe_session is NULL");
+ qdf_mem_free(mlm_assoc_req);
return;
}
@@ -1644,6 +1645,7 @@
/* check this early to avoid unncessary operation */
if (NULL == pe_session->pLimJoinReq) {
pe_err("pe_session->pLimJoinReq is NULL");
+ qdf_mem_free(mlm_assoc_req);
return;
}
add_ie_len = pe_session->pLimJoinReq->addIEAssoc.length;
@@ -1652,6 +1654,7 @@
frm = qdf_mem_malloc(sizeof(tDot11fAssocRequest));
if (NULL == frm) {
pe_err("Unable to allocate memory");
+ qdf_mem_free(mlm_assoc_req);
return;
}
qdf_mem_set((uint8_t *) frm, sizeof(tDot11fAssocRequest), 0);
@@ -1713,7 +1716,7 @@
LIM_BSS_CAPS_GET(WSM, pe_session->limCurrentBssQosCaps);
if (pe_session->lim11hEnable &&
- pe_session->pLimJoinReq->spectrumMgtIndicator == eSIR_TRUE) {
+ pe_session->pLimJoinReq->spectrumMgtIndicator == true) {
power_caps = true;
populate_dot11f_power_caps(mac_ctx, &frm->PowerCaps,
@@ -1947,8 +1950,7 @@
lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_CNF,
(uint32_t *) &assoc_cnf);
- qdf_mem_free(frm);
- return;
+ goto end;
}
/* Paranoia: */
qdf_mem_set(frame, bytes, 0);
@@ -1963,8 +1965,7 @@
if (DOT11F_FAILED(status)) {
pe_err("Assoc request pack failure (0x%08x)", status);
cds_packet_free((void *)packet);
- qdf_mem_free(frm);
- return;
+ goto end;
} else if (DOT11F_WARNED(status)) {
pe_warn("Assoc request pack warning (0x%08x)", status);
}
@@ -2024,9 +2025,8 @@
pe_err("Failed to send Association Request (%X)!",
qdf_status);
/* Pkt will be freed up by the callback */
- qdf_mem_free(frm);
- return;
}
+end:
/* Free up buffer allocated for mlm_assoc_req */
qdf_mem_free(mlm_assoc_req);
mlm_assoc_req = NULL;
diff --git a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
index 338ecb6..330974a 100644
--- a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
+++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
@@ -2314,6 +2314,12 @@
}
pe_debug("new ch width: %d space: %d",
session_entry->gLimChannelSwitch.ch_width, chan_space);
+ if ((session_entry->currentOperChannel == csa_params->channel) &&
+ (session_entry->ch_width ==
+ session_entry->gLimChannelSwitch.ch_width)) {
+ pe_debug("Ignore CSA, no change in ch and bw");
+ goto err;
+ }
lim_prepare_for11h_channel_switch(mac_ctx, session_entry);
csa_offload_ind = qdf_mem_malloc(sizeof(tSmeCsaOffloadInd));
diff --git a/core/mac/src/pe/lim/lim_types.h b/core/mac/src/pe/lim/lim_types.h
index 9c50a84..4cfa3d7 100644
--- a/core/mac/src/pe/lim/lim_types.h
+++ b/core/mac/src/pe/lim/lim_types.h
@@ -253,12 +253,12 @@
tSirWAPIie wapiIE;
tSirAddie addIE; /* additional IE received from the peer, which possibly includes WSC IE and/or P2P IE. */
tSirMacCapabilityInfo capabilityInfo;
- tAniBool spectrumMgtIndicator;
+ bool spectrumMgtIndicator;
tSirMacPowerCapInfo powerCap;
tSirSupChnl supportedChannels;
uint8_t sessionId;
- tAniBool WmmStaInfoPresent;
+ bool WmmStaInfoPresent;
/* Required for indicating the frames to upper layer */
uint32_t beaconLength;
@@ -266,6 +266,17 @@
uint32_t assocReqLength;
uint8_t *assocReqPtr;
tSirSmeChanInfo chan_info;
+ bool ampdu;
+ bool sgi_enable;
+ bool tx_stbc;
+ bool rx_stbc;
+ tSirMacHTChannelWidth ch_width;
+ enum sir_sme_phy_mode mode;
+ uint8_t max_supp_idx;
+ uint8_t max_ext_idx;
+ uint8_t max_mcs_idx;
+ uint8_t rx_mcs_map;
+ uint8_t tx_mcs_map;
} tLimMlmAssocInd, *tpLimMlmAssocInd;
typedef struct sLimMlmReassocReq {
@@ -292,11 +303,11 @@
tSirWAPIie wapiIE;
tSirAddie addIE; /* additional IE received from the peer, which can be WSC IE and/or P2P IE. */
tSirMacCapabilityInfo capabilityInfo;
- tAniBool spectrumMgtIndicator;
+ bool spectrumMgtIndicator;
tSirMacPowerCapInfo powerCap;
tSirSupChnl supportedChannels;
- tAniBool WmmStaInfoPresent;
+ bool WmmStaInfoPresent;
/* Required for indicating the frames to upper layer */
uint32_t beaconLength;
diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c
index 2c9a435..e94c931 100644
--- a/core/mac/src/pe/lim/lim_utils.c
+++ b/core/mac/src/pe/lim/lim_utils.c
@@ -4930,7 +4930,7 @@
* @param channel - New channel to which we are expected to move
* @return None
*/
-tAniBool lim_is_channel_valid_for_channel_switch(tpAniSirGlobal pMac, uint8_t channel)
+bool lim_is_channel_valid_for_channel_switch(tpAniSirGlobal pMac, uint8_t channel)
{
uint8_t index;
uint32_t validChannelListLen = WNI_CFG_VALID_CHANNEL_LIST_LEN;
@@ -4941,16 +4941,16 @@
(uint32_t *) &validChannelListLen) !=
eSIR_SUCCESS) {
pe_err("could not retrieve valid channel list");
- return eSIR_FALSE;
+ return false;
}
for (index = 0; index < validChannelListLen; index++) {
if (validChannelList[index] == channel)
- return eSIR_TRUE;
+ return true;
}
/* channel does not belong to list of valid channels */
- return eSIR_FALSE;
+ return false;
}
/**------------------------------------------------------
diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h
index 645059d..17c9187 100644
--- a/core/mac/src/pe/lim/lim_utils.h
+++ b/core/mac/src/pe/lim/lim_utils.h
@@ -247,7 +247,7 @@
void lim_cancel_dot11h_channel_switch(tpAniSirGlobal pMac,
tpPESession psessionEntry);
void lim_cancel_dot11h_quiet(tpAniSirGlobal pMac, tpPESession psessionEntry);
-tAniBool lim_is_channel_valid_for_channel_switch(tpAniSirGlobal pMac,
+bool lim_is_channel_valid_for_channel_switch(tpAniSirGlobal pMac,
uint8_t channel);
void lim_frame_transmission_control(tpAniSirGlobal pMac, tLimQuietTxMode type,
tLimControlTx mode);
diff --git a/core/mac/src/sys/legacy/src/system/src/mac_init_api.c b/core/mac/src/sys/legacy/src/system/src/mac_init_api.c
index 3d4a6ee..e6b7458 100644
--- a/core/mac/src/sys/legacy/src/system/src/mac_init_api.c
+++ b/core/mac/src/sys/legacy/src/system/src/mac_init_api.c
@@ -83,13 +83,13 @@
\return tSirRetStatus
-------------------------------------------------------------*/
-tSirRetStatus mac_stop(tHalHandle hHal, tHalStopType stopType)
+QDF_STATUS mac_stop(tHalHandle hHal, tHalStopType stopType)
{
tpAniSirGlobal pMac = (tpAniSirGlobal) hHal;
pe_stop(pMac);
cfg_cleanup(pMac);
- return eSIR_SUCCESS;
+ return QDF_STATUS_SUCCESS;
}
/** -------------------------------------------------------------
@@ -157,13 +157,13 @@
\return none
-------------------------------------------------------------*/
-tSirRetStatus mac_close(tHalHandle hHal)
+QDF_STATUS mac_close(tHalHandle hHal)
{
tpAniSirGlobal pMac = (tpAniSirGlobal) hHal;
if (!pMac)
- return eSIR_FAILURE;
+ return QDF_STATUS_E_FAILURE;
pe_close(pMac);
@@ -177,5 +177,5 @@
wlan_objmgr_psoc_release_ref(pMac->psoc, WLAN_LEGACY_MAC_ID);
pMac->psoc = NULL;
- return eSIR_SUCCESS;
+ return QDF_STATUS_SUCCESS;
}
diff --git a/core/mac/src/sys/legacy/src/utils/src/dot11f.c b/core/mac/src/sys/legacy/src/utils/src/dot11f.c
index 4b6623e..a6051e5 100644
--- a/core/mac/src/sys/legacy/src/utils/src/dot11f.c
+++ b/core/mac/src/sys/legacy/src/utils/src/dot11f.c
@@ -33,7 +33,7 @@
*
*
* This file was automatically generated by 'framesc'
- * Thu Jul 6 16:41:06 2017 from the following file(s):
+ * Fri Jul 14 12:29:59 2017 from the following file(s):
*
* dot11f.frms
*
@@ -7370,6 +7370,9 @@
offsetof(tDot11fIEmu_edca_param_set, present), 0, "mu_edca_param_set",
0, 19, 19, SigIemu_edca_param_set, {0, 19, 116, 4, 0},
4, DOT11F_EID_MU_EDCA_PARAM_SET, 0, 0, },
+ { offsetof(tDot11fAssocResponse, MBO_IE), offsetof(tDot11fIEMBO_IE,
+ present), 0, "MBO_IE", 0, 6, 295, SigIeMBO_IE, {80, 111, 154, 22, 0},
+ 4, DOT11F_EID_MBO_IE, 0, 0, },
{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
uint32_t dot11f_unpack_assoc_response(tpAniSirGlobal pCtx,
@@ -9150,6 +9153,9 @@
offsetof(tDot11fIEmu_edca_param_set, present), 0, "mu_edca_param_set",
0, 19, 19, SigIemu_edca_param_set, {0, 19, 116, 4, 0},
4, DOT11F_EID_MU_EDCA_PARAM_SET, 0, 0, },
+ { offsetof(tDot11fReAssocResponse, MBO_IE), offsetof(tDot11fIEMBO_IE,
+ present), 0, "MBO_IE", 0, 6, 295, SigIeMBO_IE, {80, 111, 154, 22, 0},
+ 4, DOT11F_EID_MBO_IE, 0, 0, },
{0, 0, 0, NULL, 0, 0, 0, 0, {0, 0, 0, 0, 0}, 0, 0xff, 0, },};
uint32_t dot11f_unpack_re_assoc_response(tpAniSirGlobal pCtx,
diff --git a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c
index 5744ae9..79cd5ef 100644
--- a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c
+++ b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c
@@ -414,6 +414,8 @@
CASE_RETURN_STRING(eWNI_SME_DEFAULT_SCAN_IE);
CASE_RETURN_STRING(eWNI_SME_ROAM_SCAN_OFFLOAD_REQ);
CASE_RETURN_STRING(eWNI_SME_LOST_LINK_INFO_IND);
+ CASE_RETURN_STRING(eWNI_SME_GET_PEER_INFO_IND);
+ CASE_RETURN_STRING(eWNI_SME_GET_PEER_INFO_EXT_IND);
CASE_RETURN_STRING(eWNI_SME_RSO_CMD_STATUS_IND);
CASE_RETURN_STRING(eWNI_SME_MSG_TYPES_END);
default:
diff --git a/core/pld/inc/pld_common.h b/core/pld/inc/pld_common.h
index 30abc28..ad20d09 100644
--- a/core/pld/inc/pld_common.h
+++ b/core/pld/inc/pld_common.h
@@ -33,6 +33,10 @@
#include <linux/pm.h>
#include <osapi_linux.h>
+#ifdef CONFIG_CNSS_UTILS
+#include <net/cnss_utils.h>
+#endif
+
#define PLD_IMAGE_FILE "athwlan.bin"
#define PLD_UTF_FIRMWARE_FILE "utf.bin"
#define PLD_BOARD_DATA_FILE "fakeboar.bin"
@@ -366,14 +370,150 @@
u32 target_type, u32 target_version);
void pld_is_pci_link_down(struct device *dev);
int pld_shadow_control(struct device *dev, bool enable);
-int pld_set_wlan_unsafe_channel(struct device *dev, u16 *unsafe_ch_list,
- u16 ch_count);
-int pld_get_wlan_unsafe_channel(struct device *dev, u16 *unsafe_ch_list,
- u16 *ch_count, u16 buf_len);
-int pld_wlan_set_dfs_nol(struct device *dev, void *info, u16 info_len);
-int pld_wlan_get_dfs_nol(struct device *dev, void *info, u16 info_len);
void pld_schedule_recovery_work(struct device *dev,
enum pld_recovery_reason reason);
+#ifdef CONFIG_CNSS_UTILS
+/**
+ * pld_set_wlan_unsafe_channel() - Set unsafe channel
+ * @dev: device
+ * @unsafe_ch_list: unsafe channel list
+ * @ch_count: number of channel
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+static inline int pld_set_wlan_unsafe_channel(struct device *dev,
+ u16 *unsafe_ch_list,
+ u16 ch_count)
+{
+ return cnss_utils_set_wlan_unsafe_channel(dev, unsafe_ch_list,
+ ch_count);
+}
+/**
+ * pld_get_wlan_unsafe_channel() - Get unsafe channel
+ * @dev: device
+ * @unsafe_ch_list: buffer to unsafe channel list
+ * @ch_count: number of channel
+ * @buf_len: buffer length
+ *
+ * Return WLAN unsafe channel to the buffer.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+static inline int pld_get_wlan_unsafe_channel(struct device *dev,
+ u16 *unsafe_ch_list,
+ u16 *ch_count, u16 buf_len)
+{
+ return cnss_utils_get_wlan_unsafe_channel(dev, unsafe_ch_list,
+ ch_count, buf_len);
+}
+/**
+ * pld_wlan_set_dfs_nol() - Set DFS info
+ * @dev: device
+ * @info: DFS info
+ * @info_len: info length
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+static inline int pld_wlan_set_dfs_nol(struct device *dev, void *info,
+ u16 info_len)
+{
+ return cnss_utils_wlan_set_dfs_nol(dev, info, info_len);
+}
+/**
+ * pld_wlan_get_dfs_nol() - Get DFS info
+ * @dev: device
+ * @info: buffer to DFS info
+ * @info_len: info length
+ *
+ * Return DFS info to the buffer.
+ *
+ * Return: 0 for success
+ * Non zero failure code for errors
+ */
+static inline int pld_wlan_get_dfs_nol(struct device *dev,
+ void *info, u16 info_len)
+{
+ return cnss_utils_wlan_get_dfs_nol(dev, info, info_len);
+}
+/**
+ * pld_get_wlan_mac_address() - API to query MAC address from Platform
+ * Driver
+ * @dev: Device Structure
+ * @num: Pointer to number of MAC address supported
+ *
+ * Platform Driver can have MAC address stored. This API needs to be used
+ * to get those MAC address
+ *
+ * Return: Pointer to the list of MAC address
+ */
+static inline uint8_t *pld_get_wlan_mac_address(struct device *dev,
+ uint32_t *num)
+{
+ return cnss_utils_get_wlan_mac_address(dev, num);
+}
+/**
+ * pld_increment_driver_load_cnt() - Maintain driver load count
+ * @dev: device
+ *
+ * This function maintain a count which get increase whenever wiphy
+ * is registered
+ *
+ * Return: void
+ */
+static inline void pld_increment_driver_load_cnt(struct device *dev)
+{
+ cnss_utils_increment_driver_load_cnt(dev);
+}
+/**
+ * pld_get_driver_load_cnt() - get driver load count
+ * @dev: device
+ *
+ * This function provide total wiphy registration count from starting
+ *
+ * Return: driver load count
+ */
+static inline int pld_get_driver_load_cnt(struct device *dev)
+{
+ return cnss_utils_get_driver_load_cnt(dev);
+}
+#else
+static inline int pld_set_wlan_unsafe_channel(struct device *dev,
+ u16 *unsafe_ch_list,
+ u16 ch_count)
+{
+ return -EINVAL;
+}
+static inline int pld_get_wlan_unsafe_channel(struct device *dev,
+ u16 *unsafe_ch_list,
+ u16 *ch_count, u16 buf_len)
+{
+ return -EINVAL;
+}
+static inline int pld_wlan_set_dfs_nol(struct device *dev,
+ void *info, u16 info_len)
+{
+ return -EINVAL;
+}
+static inline int pld_wlan_get_dfs_nol(struct device *dev,
+ void *info, u16 info_len)
+{
+ return -EINVAL;
+}
+static inline uint8_t *pld_get_wlan_mac_address(struct device *dev,
+ uint32_t *num)
+{
+ *num = 0;
+ return NULL;
+}
+static inline void pld_increment_driver_load_cnt(struct device *dev) {}
+static inline int pld_get_driver_load_cnt(struct device *dev)
+{
+ return -EINVAL;
+}
+#endif
int pld_wlan_pm_control(struct device *dev, bool vote);
void *pld_get_virt_ramdump_mem(struct device *dev, unsigned long *size);
void pld_device_crashed(struct device *dev);
@@ -418,7 +558,6 @@
void pld_get_msi_address(struct device *dev, uint32_t *msi_addr_low,
uint32_t *msi_addr_high);
unsigned int pld_socinfo_get_serial_number(struct device *dev);
-uint8_t *pld_get_wlan_mac_address(struct device *dev, uint32_t *num);
int pld_is_qmi_disable(struct device *dev);
int pld_force_assert_target(struct device *dev);
diff --git a/core/pld/src/pld_common.c b/core/pld/src/pld_common.c
index 382a59c..eaa37b6 100644
--- a/core/pld/src/pld_common.c
+++ b/core/pld/src/pld_common.c
@@ -543,140 +543,6 @@
}
/**
- * pld_set_wlan_unsafe_channel() - Set unsafe channel
- * @dev: device
- * @unsafe_ch_list: unsafe channel list
- * @ch_count: number of channel
- *
- * Return: 0 for success
- * Non zero failure code for errors
- */
-int pld_set_wlan_unsafe_channel(struct device *dev,
- u16 *unsafe_ch_list, u16 ch_count)
-{
- int ret = 0;
-
- switch (pld_get_bus_type(dev)) {
- case PLD_BUS_TYPE_PCIE:
- ret = pld_pcie_set_wlan_unsafe_channel(unsafe_ch_list,
- ch_count);
- break;
- case PLD_BUS_TYPE_SNOC:
- ret = pld_snoc_set_wlan_unsafe_channel(unsafe_ch_list,
- ch_count);
- break;
- case PLD_BUS_TYPE_SDIO:
- /* To do get unsafe channel via cnss sdio API */
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-/**
- * pld_get_wlan_unsafe_channel() - Get unsafe channel
- * @dev: device
- * @unsafe_ch_list: buffer to unsafe channel list
- * @ch_count: number of channel
- * @buf_len: buffer length
- *
- * Return WLAN unsafe channel to the buffer.
- *
- * Return: 0 for success
- * Non zero failure code for errors
- */
-int pld_get_wlan_unsafe_channel(struct device *dev, u16 *unsafe_ch_list,
- u16 *ch_count, u16 buf_len)
-{
- int ret = 0;
-
- switch (pld_get_bus_type(dev)) {
- case PLD_BUS_TYPE_PCIE:
- ret = pld_pcie_get_wlan_unsafe_channel(unsafe_ch_list,
- ch_count, buf_len);
- break;
- case PLD_BUS_TYPE_SNOC:
- ret = pld_snoc_get_wlan_unsafe_channel(unsafe_ch_list,
- ch_count, buf_len);
- break;
- case PLD_BUS_TYPE_SDIO:
- /* To do get unsafe channel via cnss sdio API */
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-/**
- * pld_wlan_set_dfs_nol() - Set DFS info
- * @dev: device
- * @info: DFS info
- * @info_len: info length
- *
- * Return: 0 for success
- * Non zero failure code for errors
- */
-int pld_wlan_set_dfs_nol(struct device *dev, void *info, u16 info_len)
-{
- int ret = 0;
-
- switch (pld_get_bus_type(dev)) {
- case PLD_BUS_TYPE_PCIE:
- ret = pld_pcie_wlan_set_dfs_nol(info, info_len);
- break;
- case PLD_BUS_TYPE_SNOC:
- ret = pld_snoc_wlan_set_dfs_nol(info, info_len);
- break;
- case PLD_BUS_TYPE_SDIO:
- /* To do get nol via cnss sdio API */
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-/**
- * pld_wlan_get_dfs_nol() - Get DFS info
- * @dev: device
- * @info: buffer to DFS info
- * @info_len: info length
- *
- * Return DFS info to the buffer.
- *
- * Return: 0 for success
- * Non zero failure code for errors
- */
-int pld_wlan_get_dfs_nol(struct device *dev, void *info, u16 info_len)
-{
- int ret = 0;
-
- switch (pld_get_bus_type(dev)) {
- case PLD_BUS_TYPE_PCIE:
- ret = pld_pcie_wlan_get_dfs_nol(info, info_len);
- break;
- case PLD_BUS_TYPE_SNOC:
- ret = pld_snoc_wlan_get_dfs_nol(info, info_len);
- break;
- case PLD_BUS_TYPE_SDIO:
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-/**
* pld_schedule_recovery_work() - Schedule recovery work
* @dev: device
* @reason: recovery reason
@@ -1630,40 +1496,6 @@
return ret;
}
-/*
- * pld_get_wlan_mac_address() - API to query MAC address from Platform
- * Driver
- * @dev: Device Structure
- * @num: Pointer to number of MAC address supported
- *
- * Platform Driver can have MAC address stored. This API needs to be used
- * to get those MAC address
- *
- * Return: Pointer to the list of MAC address
- */
-uint8_t *pld_get_wlan_mac_address(struct device *dev, uint32_t *num)
-{
- enum pld_bus_type type = pld_get_bus_type(dev);
-
- switch (type) {
- case PLD_BUS_TYPE_PCIE:
- return pld_pcie_get_wlan_mac_address(dev, num);
- case PLD_BUS_TYPE_SDIO:
- return pld_sdio_get_wlan_mac_address(dev, num);
- case PLD_BUS_TYPE_SNOC:
- return pld_snoc_get_wlan_mac_address(dev, num);
- case PLD_BUS_TYPE_USB:
- pr_err("Not supported on type %d\n", type);
- break;
- default:
- pr_err("Invalid device type\n");
- break;
- }
-
- *num = 0;
- return NULL;
-}
-
/**
* pld_is_qmi_disable() - Check QMI support is present or not
* @dev: device
@@ -1713,8 +1545,9 @@
case PLD_BUS_TYPE_SNOC:
ret = pld_snoc_force_assert_target(dev);
break;
-
case PLD_BUS_TYPE_PCIE:
+ ret = pld_pcie_force_assert_target(dev);
+ break;
case PLD_BUS_TYPE_SDIO:
ret = -EINVAL;
break;
diff --git a/core/pld/src/pld_pcie.h b/core/pld/src/pld_pcie.h
index 95481e9..186dfb4 100644
--- a/core/pld/src/pld_pcie.h
+++ b/core/pld/src/pld_pcie.h
@@ -238,7 +238,10 @@
{
return 0;
}
-
+static inline int pld_pcie_force_assert_target(struct device *dev)
+{
+ return -EINVAL;
+}
static inline uint8_t *pld_pcie_get_wlan_mac_address(struct device *dev,
uint32_t *num)
{
@@ -356,7 +359,10 @@
{
return cnss_power_down(dev);
}
-
+static inline int pld_pcie_force_assert_target(struct device *dev)
+{
+ return cnss_force_fw_assert(dev);
+}
static inline uint8_t *pld_pcie_get_wlan_mac_address(struct device *dev,
uint32_t *num)
{
diff --git a/core/sap/dfs/inc/dfs.h b/core/sap/dfs/inc/dfs.h
index a074f70..b0a034c 100644
--- a/core/sap/dfs/inc/dfs.h
+++ b/core/sap/dfs/inc/dfs.h
@@ -342,7 +342,7 @@
uint8_t dfs_phyerr_eventq_serial_num;
uint8_t peak_mag;
STAILQ_ENTRY(dfs_event) re_list;
-} qdf_packed;
+};
#ifdef WIN32
#pragma pack(pop, dfs_event)
#endif
@@ -496,7 +496,7 @@
uint32_t nol_timeout_ms; /* NOL timeout value in msec */
os_timer_t nol_timer; /* per element NOL timer */
struct dfs_nolelem *nol_next; /* next element pointer */
-} qdf_packed;
+};
#ifdef WIN32
#pragma pack(pop, dfs_nolelem)
#endif
diff --git a/core/sap/inc/sap_api.h b/core/sap/inc/sap_api.h
index 987bdd6..1412220 100644
--- a/core/sap/inc/sap_api.h
+++ b/core/sap/inc/sap_api.h
@@ -201,12 +201,6 @@
eSAP_USR_INITATED_DISASSOC
} eSapDisassocReason;
-/*Handle bool over here*/
-typedef enum {
- eSAP_FALSE,
- eSAP_TRUE,
-} eSapBool;
-
typedef enum {
eSAP_DFS_NOL_CLEAR,
eSAP_DFS_NOL_RANDOMIZE,
@@ -293,6 +287,17 @@
uint8_t *assocRespPtr;
uint8_t timingMeasCap;
tSirSmeChanInfo chan_info;
+ bool ampdu;
+ bool sgi_enable;
+ bool tx_stbc;
+ bool rx_stbc;
+ tSirMacHTChannelWidth ch_width;
+ enum sir_sme_phy_mode mode;
+ uint8_t max_supp_idx;
+ uint8_t max_ext_idx;
+ uint8_t max_mcs_idx;
+ uint8_t rx_mcs_map;
+ uint8_t tx_mcs_map;
} tSap_StationAssocReassocCompleteEvent;
typedef struct sap_StationDisassocCompleteEvent_s {
@@ -313,7 +318,7 @@
struct qdf_mac_addr srcMacAddr; /* address used to compute MIC */
struct qdf_mac_addr staMac; /* taMacAddr transmitter address */
struct qdf_mac_addr dstMacAddr;
- eSapBool multicast;
+ bool multicast;
uint8_t IV1; /* first byte of IV */
uint8_t keyId; /* second byte of IV */
uint8_t TSC[SIR_CIPHER_SEQ_CTR_SIZE]; /* sequence number */
@@ -517,6 +522,7 @@
uint8_t ht_sec_ch;
uint8_t vht_seg0_center_ch;
uint8_t vht_seg1_center_ch;
+ uint32_t band;
};
/*
@@ -1060,6 +1066,18 @@
* Return: None
*/
void sap_dfs_set_current_channel(void *sap_ctx);
+
+/**
+ * wlansap_cleanup_cac_timer() - Force cleanup DFS CAC timer
+ * @sap_ctx: sap context
+ *
+ * Force cleanup DFS CAC timer when reset all adapters. It will not
+ * check concurrency SAP since just called when reset all adapters.
+ *
+ * Return: None
+ */
+void wlansap_cleanup_cac_timer(void *sap_ctx);
+
#ifdef __cplusplus
}
#endif
diff --git a/core/sap/src/sap_api_link_cntl.c b/core/sap/src/sap_api_link_cntl.c
index cb0c236..9ca306c 100644
--- a/core/sap/src/sap_api_link_cntl.c
+++ b/core/sap/src/sap_api_link_cntl.c
@@ -568,7 +568,7 @@
* beacon template will be cleared by now. A new beacon template
* with no CSA IE will be sent to firmware.
*/
- dfs_beacon_start_req = eSAP_TRUE;
+ dfs_beacon_start_req = true;
sap_ctx->pre_cac_complete = false;
*ret_status = sme_roam_start_beacon_req(hHal, sap_ctx->bssid,
dfs_beacon_start_req);
diff --git a/core/sap/src/sap_ch_select.c b/core/sap/src/sap_ch_select.c
index eb8022f..0535060 100644
--- a/core/sap/src/sap_ch_select.c
+++ b/core/sap/src/sap_ch_select.c
@@ -587,7 +587,7 @@
if (pSpectCh == NULL) {
QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
"In %s, QDF_MALLOC_ERR", __func__);
- return eSAP_FALSE;
+ return false;
}
/* Initialize the pointers in the DfsParams to the allocated memory */
@@ -658,12 +658,12 @@
if (true == chSafe) {
pSpectCh->chNum = *pChans;
- pSpectCh->valid = eSAP_TRUE;
+ pSpectCh->valid = true;
pSpectCh->rssiAgr = SOFTAP_MIN_RSSI; /* Initialise for all channels */
pSpectCh->channelWidth = SOFTAP_HT20_CHANNELWIDTH; /* Initialise 20MHz for all the Channels */
}
}
- return eSAP_TRUE;
+ return true;
}
/*==========================================================================
@@ -2084,12 +2084,12 @@
static bool sap_filter_over_lap_ch(ptSapContext pSapCtx, uint16_t chNum)
{
if (pSapCtx->enableOverLapCh)
- return eSAP_TRUE;
+ return true;
else if ((chNum == CHANNEL_1) ||
(chNum == CHANNEL_6) || (chNum == CHANNEL_11))
- return eSAP_TRUE;
+ return true;
- return eSAP_FALSE;
+ return false;
}
#ifdef FEATURE_WLAN_CH_AVOID
@@ -2238,7 +2238,7 @@
}
/* Initialize the structure pointed by spect_info */
- if (sap_chan_sel_init(hal, spect_info, sap_ctx) != eSAP_TRUE) {
+ if (sap_chan_sel_init(hal, spect_info, sap_ctx) != true) {
QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
FL("Ch Select initialization failed"));
return SAP_CHANNEL_NOT_SELECTED;
diff --git a/core/sap/src/sap_fsm.c b/core/sap/src/sap_fsm.c
index 760d1a3..5cfd69c 100644
--- a/core/sap/src/sap_fsm.c
+++ b/core/sap/src/sap_fsm.c
@@ -1257,7 +1257,7 @@
}
mac = PMAC_STRUCT(hal);
- wlan_reg_get_dfs_region(mac->psoc, dfs_region);
+ wlan_reg_get_dfs_region(mac->pdev, dfs_region);
if (mac->sap.SapDfsInfo.ignore_cac) {
*cac_duration_ms = 0;
QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG,
@@ -1266,17 +1266,6 @@
}
*cac_duration_ms = DEFAULT_CAC_TIMEOUT;
- QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
- FL("sapdfs: dfs_region=%d, chwidth=%d, seg0=%d, seg1=%d"),
- *dfs_region, ch_params->ch_width,
- ch_params->center_freq_seg0, ch_params->center_freq_seg1);
-
- if (*dfs_region != DFS_ETSI_REG) {
- QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
- FL("sapdfs: defult cac duration"));
- return;
- }
-
if (sap_is_channel_bonding_etsi_weather_channel(sap_ctx)) {
*cac_duration_ms = ETSI_WEATHER_CH_CAC_TIMEOUT;
QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
@@ -2462,6 +2451,17 @@
reassoc_complete->wmmEnabled = csr_roaminfo->wmmEnabledSta;
reassoc_complete->status = (eSapStatus) context;
reassoc_complete->timingMeasCap = csr_roaminfo->timingMeasCap;
+ reassoc_complete->ampdu = csr_roaminfo->ampdu;
+ reassoc_complete->sgi_enable = csr_roaminfo->sgi_enable;
+ reassoc_complete->tx_stbc = csr_roaminfo->tx_stbc;
+ reassoc_complete->rx_stbc = csr_roaminfo->rx_stbc;
+ reassoc_complete->ch_width = csr_roaminfo->ch_width;
+ reassoc_complete->mode = csr_roaminfo->mode;
+ reassoc_complete->max_supp_idx = csr_roaminfo->max_supp_idx;
+ reassoc_complete->max_ext_idx = csr_roaminfo->max_ext_idx;
+ reassoc_complete->max_mcs_idx = csr_roaminfo->max_mcs_idx;
+ reassoc_complete->rx_mcs_map = csr_roaminfo->rx_mcs_map;
+ reassoc_complete->tx_mcs_map = csr_roaminfo->tx_mcs_map;
break;
case eSAP_STA_DISASSOC_EVENT:
@@ -3708,8 +3708,6 @@
pconfig_params->RSNWPAReqIELength);
profile->nRSNReqIELength = pconfig_params->RSNWPAReqIELength;
}
- /* Turn off CB mode */
- profile->CBMode = eCSR_CB_OFF;
/* set the phyMode to accept anything */
/* Best means everything because it covers all the things we support */
@@ -3837,7 +3835,7 @@
}
}
-eSapBool
+bool
sap_search_mac_list(struct qdf_mac_addr *macList,
uint8_t num_mac, uint8_t *peerMac,
uint8_t *index)
@@ -3849,7 +3847,7 @@
if ((NULL == macList) || (num_mac > MAX_ACL_MAC_ADDRESS)) {
QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
FL("either buffer is NULL or size = %d is more."), num_mac);
- return eSAP_FALSE;
+ return false;
}
while (nStart <= nEnd) {
@@ -3869,7 +3867,7 @@
QDF_TRACE_LEVEL_INFO_HIGH, "index %d",
*index);
}
- return eSAP_TRUE;
+ return true;
}
if (nRes < 0)
nStart = nMiddle + 1;
@@ -3879,7 +3877,7 @@
QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
"search not succ");
- return eSAP_FALSE;
+ return false;
}
void sap_add_mac_to_acl(struct qdf_mac_addr *macList,
@@ -4101,9 +4099,9 @@
* - DFS scan enabled and chan not in CHANNEL_STATE_DISABLE
* - DFS scan disable but chan in CHANNEL_STATE_ENABLE
*/
- if (!(((eSAP_TRUE == mac_ctx->scan.fEnableDFSChnlScan) &&
+ if (!(((true == mac_ctx->scan.fEnableDFSChnlScan) &&
wlan_reg_get_channel_state(mac_ctx->pdev, loop_count)) ||
- ((eSAP_FALSE == mac_ctx->scan.fEnableDFSChnlScan) &&
+ ((false == mac_ctx->scan.fEnableDFSChnlScan) &&
(CHANNEL_STATE_ENABLE ==
wlan_reg_get_channel_state(mac_ctx->pdev, loop_count)))))
continue;
@@ -4212,7 +4210,7 @@
* if the radar is found in the STARTED state
*/
if (eSAP_STARTED == sap_ctx->sapsMachine)
- mac->sap.SapDfsInfo.csaIERequired = eSAP_TRUE;
+ mac->sap.SapDfsInfo.csaIERequired = true;
if (sap_ctx->csr_roamProfile.disableDFSChSwitch)
return sap_ctx->channel;
diff --git a/core/sap/src/sap_internal.h b/core/sap/src/sap_internal.h
index 02b4b79..0116e47 100644
--- a/core/sap/src/sap_internal.h
+++ b/core/sap/src/sap_internal.h
@@ -368,7 +368,7 @@
void
sap_print_acl(struct qdf_mac_addr *macList, uint8_t size);
-eSapBool
+bool
sap_search_mac_list(struct qdf_mac_addr *macList, uint8_t num_mac,
uint8_t *peerMac, uint8_t *index);
diff --git a/core/sap/src/sap_module.c b/core/sap/src/sap_module.c
index c8d92bc..2c810ea 100644
--- a/core/sap/src/sap_module.c
+++ b/core/sap/src/sap_module.c
@@ -1300,7 +1300,7 @@
wlansap_modify_acl
(void *ctx,
uint8_t *peer_sta_mac, eSapACLType list_type, eSapACLCmdType cmd) {
- eSapBool sta_white_list = eSAP_FALSE, sta_black_list = eSAP_FALSE;
+ bool sta_white_list = false, sta_black_list = false;
uint8_t staWLIndex, staBLIndex;
ptSapContext sap_ctx = CDS_GET_SAP_CB(ctx);
@@ -2976,7 +2976,7 @@
return QDF_STATUS_E_FAULT;
}
- wlan_reg_get_dfs_region(pMac->psoc, &dfs_region);
+ wlan_reg_get_dfs_region(pMac->pdev, &dfs_region);
/*
* Set the JAPAN W53 restriction only if the current
@@ -3072,7 +3072,7 @@
return QDF_STATUS_E_FAULT;
}
- wlan_reg_get_dfs_region(pMac->psoc, &dfs_region);
+ wlan_reg_get_dfs_region(pMac->pdev, &dfs_region);
/*
* The Indoor/Outdoor only random channel selection
@@ -3745,3 +3745,26 @@
return QDF_STATUS_SUCCESS;
}
+
+void wlansap_cleanup_cac_timer(void *sap_ctx)
+{
+ tHalHandle hal;
+ ptSapContext psap_ctx;
+ tpAniSirGlobal pmac;
+
+ if (!sap_ctx)
+ return;
+
+ psap_ctx = CDS_GET_SAP_CB(sap_ctx);
+ hal = CDS_GET_HAL_CB(psap_ctx->p_cds_gctx);
+ pmac = PMAC_STRUCT(hal);
+ if (pmac->sap.SapDfsInfo.is_dfs_cac_timer_running) {
+ qdf_mc_timer_stop(&pmac->sap.SapDfsInfo.
+ sap_dfs_cac_timer);
+ pmac->sap.SapDfsInfo.is_dfs_cac_timer_running = 0;
+ qdf_mc_timer_destroy(
+ &pmac->sap.SapDfsInfo.sap_dfs_cac_timer);
+ QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
+ FL("sapdfs, force cleanup running dfs cac timer"));
+ }
+}
diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h
index 81a9f1b..cec91f0 100644
--- a/core/sme/inc/csr_api.h
+++ b/core/sme/inc/csr_api.h
@@ -527,6 +527,7 @@
/* comment inside indicates what roaming callback gets */
typedef enum {
eCSR_ROAM_RESULT_NONE,
+ eCSR_ROAM_RESULT_SUCCESS = eCSR_ROAM_RESULT_NONE,
/*
* If roamStatus is eCSR_ROAM_ASSOCIATION_COMPLETION,
* tCsrRoamInfo's pBssDesc may pass back
@@ -922,7 +923,6 @@
uint8_t MFPCapable;
#endif
tCsrKeys Keys;
- eCsrCBChoice CBMode;
tCsrChannelInfo ChannelInfo;
uint8_t operationChannel;
struct ch_params ch_params;
@@ -1012,7 +1012,6 @@
tCsrEncryptionList EncryptionInfo;
eCsrEncryptionType mcEncryptionType;
tCsrEncryptionList mcEncryptionInfo;
- eCsrCBChoice CBMode;
uint8_t operationChannel;
uint32_t vht_channel_width;
uint16_t beaconInterval;
@@ -1320,6 +1319,9 @@
bool is_force_1x1;
uint16_t num_11b_tx_chains;
uint16_t num_11ag_tx_chains;
+ uint32_t disallow_duration;
+ uint32_t rssi_channel_penalization;
+ uint32_t num_disallowed_aps;
} tCsrConfigParam;
/* Tush */
@@ -1448,6 +1450,17 @@
tDot11fIEVHTOperation vht_operation;
tDot11fIEHTInfo ht_operation;
bool reassoc;
+ bool ampdu;
+ bool sgi_enable;
+ bool tx_stbc;
+ bool rx_stbc;
+ tSirMacHTChannelWidth ch_width;
+ enum sir_sme_phy_mode mode;
+ uint8_t max_supp_idx;
+ uint8_t max_ext_idx;
+ uint8_t max_mcs_idx;
+ uint8_t rx_mcs_map;
+ uint8_t tx_mcs_map;
} tCsrRoamInfo;
typedef struct tagCsrFreqScanInfo {
@@ -1475,6 +1488,17 @@
uint8_t timingMeasCap;
tSirSmeChanInfo chan_info;
uint8_t target_channel;
+ bool ampdu;
+ bool sgi_enable;
+ bool tx_stbc;
+ tSirMacHTChannelWidth ch_width;
+ enum sir_sme_phy_mode mode;
+ bool rx_stbc;
+ uint8_t max_supp_idx;
+ uint8_t max_ext_idx;
+ uint8_t max_mcs_idx;
+ uint8_t rx_mcs_map;
+ uint8_t tx_mcs_map;
} tSirSmeAssocIndToUpperLayerCnf, *tpSirSmeAssocIndToUpperLayerCnf;
typedef struct tagCsrSummaryStatsInfo {
diff --git a/core/sme/inc/csr_internal.h b/core/sme/inc/csr_internal.h
index 095f90d..f0edfd7 100644
--- a/core/sme/inc/csr_internal.h
+++ b/core/sme/inc/csr_internal.h
@@ -624,6 +624,9 @@
bool is_force_1x1;
uint16_t num_11b_tx_chains;
uint16_t num_11ag_tx_chains;
+ uint32_t disallow_duration;
+ uint32_t rssi_channel_penalization;
+ uint32_t num_disallowed_aps;
} tCsrConfig;
typedef struct tagCsrChannelPowerInfo {
@@ -768,24 +771,17 @@
typedef struct tagCsrPeStatsReqInfo {
tListElem link; /* list links */
uint32_t statsMask;
- uint32_t periodicity;
bool rspPending;
- qdf_mc_timer_t hPeStatsTimer;
- bool timerRunning;
uint8_t staId;
uint8_t numClient;
tpAniSirGlobal pMac;
- /* To remember if the peStats timer is stopped successfully or not */
- bool timerStopFailed;
uint8_t sessionId;
-
} tCsrPeStatsReqInfo;
typedef struct tagCsrStatsClientReqInfo {
tListElem link; /* list links */
eCsrStatsRequesterType requesterId;
tCsrStatsCallback callback;
- uint32_t periodicity;
void *pContext;
uint32_t statsMask;
tCsrPeStatsReqInfo *pPeStaEntry;
@@ -797,9 +793,6 @@
} tCsrStatsClientReqInfo;
typedef struct tagCsrTlStatsReqInfo {
- uint32_t periodicity;
- bool timerRunning;
- qdf_mc_timer_t hTlStatsTimer;
uint8_t numClient;
} tCsrTlStatsReqInfo;
@@ -1209,8 +1202,7 @@
QDF_STATUS csr_get_statistics(tpAniSirGlobal pMac,
eCsrStatsRequesterType requesterId,
uint32_t statsMask, tCsrStatsCallback callback,
- uint32_t periodicity, bool cache, uint8_t staId,
- void *pContext, uint8_t sessionId);
+ uint8_t staId, void *pContext, uint8_t sessionId);
QDF_STATUS csr_get_rssi(tpAniSirGlobal pMac, tCsrRssiCallback callback,
uint8_t staId, struct qdf_mac_addr bssId, int8_t lastRSSI,
void *pContext, void *p_cds_context);
diff --git a/core/sme/inc/csr_neighbor_roam.h b/core/sme/inc/csr_neighbor_roam.h
index cf9b257..dff1bd9 100644
--- a/core/sme/inc/csr_neighbor_roam.h
+++ b/core/sme/inc/csr_neighbor_roam.h
@@ -170,6 +170,7 @@
uint8_t currentRoamBmissFinalBcnt;
uint8_t currentRoamBeaconRssiWeight;
uint8_t last_sent_cmd;
+ bool b_roam_scan_offload_started;
} tCsrNeighborRoamControlInfo, *tpCsrNeighborRoamControlInfo;
/* All the necessary Function declarations are here */
diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h
index b395657..fece2e1 100644
--- a/core/sme/inc/sme_api.h
+++ b/core/sme/inc/sme_api.h
@@ -348,8 +348,7 @@
QDF_STATUS sme_get_statistics(tHalHandle hHal,
eCsrStatsRequesterType requesterId,
uint32_t statsMask, tCsrStatsCallback callback,
- uint32_t periodicity, bool cache, uint8_t staId,
- void *pContext, uint8_t sessionId);
+ uint8_t staId, void *pContext, uint8_t sessionId);
QDF_STATUS sme_get_rssi(tHalHandle hHal,
tCsrRssiCallback callback,
uint8_t staId, struct qdf_mac_addr bssId, int8_t lastRSSI,
@@ -444,8 +443,8 @@
uint8_t *pCountry,
void *pContext,
void *p_cds_context,
- tAniBool countryFromUserSpace,
- tAniBool sendRegHint);
+ bool countryFromUserSpace,
+ bool sendRegHint);
QDF_STATUS sme_generic_change_country_code(tHalHandle hHal,
uint8_t *pCountry);
QDF_STATUS sme_tx_fail_monitor_start_stop_ind(tHalHandle hHal,
@@ -1618,4 +1617,47 @@
*/
int sme_cli_set_command(int vdev_id, int param_id, int sval, int vpdev);
+/**
+ * sme_set_bt_activity_info_cb - set the callback handler for bt events
+ * @hal: handle returned by mac_open
+ * @cb: callback handler
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS sme_set_bt_activity_info_cb(tHalHandle hal,
+ void (*cb)(void *, uint32_t profile_info));
+
+/**
+ * sme_get_peer_info() - sme api to get peer info
+ * @hal: hal handle for getting global mac struct
+ * @req: peer info request struct send to wma
+ * @context: context of callback function
+ * @callbackfn: hdd callback function when receive response
+ *
+ * This function will send WMA_GET_PEER_INFO to WMA
+ *
+ * Return: QDF_STATUS_SUCCESS or non-zero on failure
+ */
+QDF_STATUS sme_get_peer_info(tHalHandle hal,
+ struct sir_peer_info_req req,
+ void *context,
+ void (*callbackfn)(struct sir_peer_info_resp *param,
+ void *pcontext));
+
+/**
+ * sme_get_peer_info_ext() - sme api to get peer ext info
+ * @hal: hal handle for getting global mac struct
+ * @req: peer ext info request struct send to wma
+ * @context: context of callback function
+ * @callbackfn: hdd callback function when receive response
+ *
+ * This function will send WMA_GET_PEER_INFO_EXT to WMA
+ *
+ * Return: QDF_STATUS_SUCCESS or non-zero on failure
+ */
+QDF_STATUS sme_get_peer_info_ext(tHalHandle hal,
+ struct sir_peer_info_ext_req *req,
+ void *context,
+ void (*callbackfn)(struct sir_peer_info_ext_resp *param,
+ void *pcontext));
#endif /* #if !defined( __SME_API_H ) */
diff --git a/core/sme/inc/sme_internal.h b/core/sme/inc/sme_internal.h
index 7a13c60..585cced 100644
--- a/core/sme/inc/sme_internal.h
+++ b/core/sme/inc/sme_internal.h
@@ -197,6 +197,14 @@
void (*pLinkSpeedIndCb)(tSirLinkSpeedInfo *indParam,
void *pDevContext);
void *pLinkSpeedCbContext;
+ /* get peer info callback */
+ void (*pget_peer_info_ind_cb)(struct sir_peer_info_resp *param,
+ void *pcontext);
+ void *pget_peer_info_cb_context;
+ /* get extended peer info callback */
+ void (*pget_peer_info_ext_ind_cb)(struct sir_peer_info_ext_resp *param,
+ void *pcontext);
+ void *pget_peer_info_ext_cb_context;
#ifdef FEATURE_WLAN_EXTSCAN
void (*pExtScanIndCb)(void *, const uint16_t, void *);
#endif /* FEATURE_WLAN_EXTSCAN */
@@ -252,6 +260,7 @@
void (*stats_ext2_cb)(void *, struct sir_sme_rx_aggr_hole_ind *);
void (*chip_power_save_fail_cb)(void *,
struct chip_pwr_save_fail_detected_params *);
+ void (*bt_activity_info_cb)(void *context, uint32_t bt_activity);
} tSmeStruct, *tpSmeStruct;
#endif /* #if !defined( __SMEINTERNAL_H ) */
diff --git a/core/sme/inc/sme_qos_internal.h b/core/sme/inc/sme_qos_internal.h
index 109fd50..9c66feb 100644
--- a/core/sme/inc/sme_qos_internal.h
+++ b/core/sme/inc/sme_qos_internal.h
@@ -123,17 +123,6 @@
------------------------------------------------------------------------*/
QDF_STATUS sme_qos_validate_params(tpAniSirGlobal pMac,
tSirBssDescription *pBssDesc);
-/**
- * sme_qos_remove_addts_delts_cmd - Remove addts/delts command
- * @mac_ctx: Pointer to the global MAC structure.
- * @session_id: Session id
- *
- * This function is used to remove addts/delts command
- * during csr roam sync callback.
- *
- * Return: void
- */
-void sme_qos_remove_addts_delts_cmd(tpAniSirGlobal mac_ctx, uint8_t session_id);
QDF_STATUS sme_qos_csr_event_ind(tpAniSirGlobal pMac,
uint8_t sessionId,
sme_qos_csr_event_indType ind, void *pEvent_info);
diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c
index 6925da8..617e8a6 100644
--- a/core/sme/src/common/sme_api.c
+++ b/core/sme/src/common/sme_api.c
@@ -1823,7 +1823,7 @@
QDF_STATUS sme_set_ese_beacon_request(tHalHandle hHal, const uint8_t sessionId,
const tCsrEseBeaconReq *pEseBcnReq)
{
- QDF_STATUS status = eSIR_SUCCESS;
+ QDF_STATUS status;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
tpSirBeaconReportReqInd pSmeBcnReportReq = NULL;
tCsrEseBeaconReqParams *pBeaconReq = NULL;
@@ -2413,6 +2413,18 @@
}
break;
#endif
+ case eWNI_SME_GET_PEER_INFO_IND:
+ if (pMac->sme.pget_peer_info_ind_cb)
+ pMac->sme.pget_peer_info_ind_cb(pMsg->bodyptr,
+ pMac->sme.pget_peer_info_cb_context);
+ qdf_mem_free(pMsg->bodyptr);
+ break;
+ case eWNI_SME_GET_PEER_INFO_EXT_IND:
+ if (pMac->sme.pget_peer_info_ext_ind_cb)
+ pMac->sme.pget_peer_info_ext_ind_cb(pMsg->bodyptr,
+ pMac->sme.pget_peer_info_ext_cb_context);
+ qdf_mem_free(pMsg->bodyptr);
+ break;
case eWNI_SME_CSA_OFFLOAD_EVENT:
if (pMsg->bodyptr) {
csr_scan_flush_bss_entry(pMac, pMsg->bodyptr);
@@ -2638,7 +2650,11 @@
pMsg->bodyptr);
qdf_mem_free(pMsg->bodyptr);
break;
-
+ case eWNI_SME_BT_ACTIVITY_INFO_IND:
+ if (pMac->sme.bt_activity_info_cb)
+ pMac->sme.bt_activity_info_cb(pMac->hHdd,
+ pMsg->bodyval);
+ break;
default:
if ((pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN)
@@ -4226,6 +4242,7 @@
qdf_mem_copy(&pParam->rrmConfig,
&pMac->rrm.rrmSmeContext.rrmConfig,
sizeof(pMac->rrm.rrmSmeContext.rrmConfig));
+ pParam->snr_monitor_enabled = pMac->snr_monitor_enabled;
sme_release_global_lock(&pMac->sme);
}
@@ -4583,8 +4600,9 @@
if (eSIR_SUCCESS != ret_code) {
sme_err("Posting WMA_WOWL_ADD_BCAST_PTRN failed, reason: %X",
ret_code);
+ return QDF_STATUS_E_FAILURE;
}
- return ret_code;
+ return QDF_STATUS_SUCCESS;
}
/**
@@ -4622,8 +4640,10 @@
if (eSIR_SUCCESS != ret_code) {
sme_err("Posting WMA_WOWL_DEL_BCAST_PTRN failed, reason: %X",
ret_code);
+ return QDF_STATUS_E_FAILURE;
}
- return ret_code;
+
+ return QDF_STATUS_SUCCESS;
}
/**
@@ -4904,9 +4924,6 @@
\param statsMask - The different category/categories of stats requester
is looking for
\param callback - SME sends back the requested stats using the callback
- \param periodicity - If requester needs periodic update in millisec, 0 means
- it's an one time request
- \param cache - If requester is happy with cached stats
\param staId - The station ID for which the stats is requested for
\param pContext - user context to be passed back along with the callback
\param sessionId - sme session interface
@@ -4915,20 +4932,16 @@
QDF_STATUS sme_get_statistics(tHalHandle hHal,
eCsrStatsRequesterType requesterId,
uint32_t statsMask, tCsrStatsCallback callback,
- uint32_t periodicity, bool cache, uint8_t staId,
- void *pContext, uint8_t sessionId)
+ uint8_t staId, void *pContext, uint8_t sessionId)
{
QDF_STATUS status = QDF_STATUS_E_FAILURE;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
- MTRACE(qdf_trace(QDF_MODULE_ID_SME,
- TRACE_CODE_SME_RX_HDD_GET_STATS, NO_SESSION,
- periodicity));
status = sme_acquire_global_lock(&pMac->sme);
if (QDF_IS_STATUS_SUCCESS(status)) {
status =
- csr_get_statistics(pMac, requesterId, statsMask, callback,
- periodicity, cache, staId, pContext,
+ csr_get_statistics(pMac, requesterId, statsMask,
+ callback, staId, pContext,
sessionId);
sme_release_global_lock(&pMac->sme);
}
@@ -5062,8 +5075,8 @@
uint8_t *pCountry,
void *pContext,
void *p_cds_context,
- tAniBool countryFromUserSpace,
- tAniBool sendRegHint)
+ bool countryFromUserSpace,
+ bool sendRegHint)
{
QDF_STATUS status = QDF_STATUS_E_FAILURE;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
@@ -7975,27 +7988,29 @@
}
-/*--------------------------------------------------------------------------
- \brief sme_stop_roaming() - Stop roaming for a given sessionId
- This is a synchronous call
- \param hHal - The handle returned by mac_open
- \param sessionId - Session Identifier
- \return QDF_STATUS_SUCCESS on success
- Other status on failure
- \sa
- --------------------------------------------------------------------------*/
-QDF_STATUS sme_stop_roaming(tHalHandle hHal, uint8_t sessionId, uint8_t reason)
+/**
+ * sme_stop_roaming() - Stop roaming for a given sessionId
+ * This is a synchronous call
+ *
+ * @hHal - The handle returned by mac_open
+ * @sessionId - Session Identifier
+ *
+ * Return QDF_STATUS_SUCCESS on success
+ * Other status on failure
+ */
+QDF_STATUS sme_stop_roaming(tHalHandle hal, uint8_t session_id, uint8_t reason)
{
struct scheduler_msg wma_msg = {0};
tSirRetStatus status;
tSirRoamOffloadScanReq *req;
- tpAniSirGlobal mac_ctx = PMAC_STRUCT(hHal);
+ tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+ tpCsrNeighborRoamControlInfo roam_info;
- if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId)) {
+ if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
sme_err("incorrect session/vdev ID");
return QDF_STATUS_E_INVAL;
}
-
+ roam_info = &mac_ctx->roam.neighborRoamInfo[session_id];
req = qdf_mem_malloc(sizeof(*req));
if (!req) {
sme_err("failed to allocated memory");
@@ -8007,8 +8022,8 @@
req->reason = REASON_ROAM_STOP_ALL;
else
req->reason = REASON_ROAM_SYNCH_FAILED;
- req->sessionId = sessionId;
- if (csr_neighbor_middle_of_roaming(mac_ctx, sessionId))
+ req->sessionId = session_id;
+ if (csr_neighbor_middle_of_roaming(mac_ctx, session_id))
req->middle_of_roaming = 1;
else
csr_roam_reset_roam_params(mac_ctx);
@@ -8019,10 +8034,12 @@
status = wma_post_ctrl_msg(mac_ctx, &wma_msg);
if (eSIR_SUCCESS != status) {
sme_err("WMA_ROAM_SCAN_OFFLOAD_REQ failed, session_id: %d",
- sessionId);
+ session_id);
qdf_mem_free(req);
return QDF_STATUS_E_FAULT;
}
+ roam_info->b_roam_scan_offload_started = false;
+ roam_info->last_sent_cmd = ROAM_SCAN_OFFLOAD_STOP;
return QDF_STATUS_SUCCESS;
}
@@ -9681,6 +9698,100 @@
return status;
}
+QDF_STATUS sme_get_peer_info(tHalHandle hal, struct sir_peer_info_req req,
+ void *context,
+ void (*callbackfn)(struct sir_peer_info_resp *param,
+ void *pcontext))
+{
+
+ QDF_STATUS status;
+ QDF_STATUS qdf_status;
+ tpAniSirGlobal mac = PMAC_STRUCT(hal);
+ struct scheduler_msg message;
+
+ status = sme_acquire_global_lock(&mac->sme);
+ if (QDF_STATUS_SUCCESS == status) {
+ if (NULL == callbackfn) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ "%s: Indication Call back is NULL",
+ __func__);
+ sme_release_global_lock(&mac->sme);
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ mac->sme.pget_peer_info_ind_cb = callbackfn;
+ mac->sme.pget_peer_info_cb_context = context;
+
+ /* serialize the req through MC thread */
+ message.bodyptr = qdf_mem_malloc(sizeof(req));
+ if (NULL == message.bodyptr) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ "%s: Memory allocation failed.", __func__);
+ sme_release_global_lock(&mac->sme);
+ return QDF_STATUS_E_NOMEM;
+ }
+ qdf_mem_copy(message.bodyptr, &req, sizeof(req));
+ message.type = WMA_GET_PEER_INFO;
+ qdf_status = scheduler_post_msg(QDF_MODULE_ID_WMA, &message);
+ if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ "%s: Post get peer info msg fail", __func__);
+ qdf_mem_free(message.bodyptr);
+ status = QDF_STATUS_E_FAILURE;
+ }
+ sme_release_global_lock(&mac->sme);
+ }
+ return status;
+}
+
+QDF_STATUS sme_get_peer_info_ext(tHalHandle hal,
+ struct sir_peer_info_ext_req *req,
+ void *context,
+ void (*callbackfn)(struct sir_peer_info_ext_resp *param,
+ void *pcontext))
+{
+ QDF_STATUS status;
+ QDF_STATUS qdf_status;
+ tpAniSirGlobal mac = PMAC_STRUCT(hal);
+ struct scheduler_msg message;
+
+ status = sme_acquire_global_lock(&mac->sme);
+ if (QDF_STATUS_SUCCESS == status) {
+ if (NULL == callbackfn) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ "%s: Indication Call back is NULL",
+ __func__);
+ sme_release_global_lock(&mac->sme);
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ mac->sme.pget_peer_info_ext_ind_cb = callbackfn;
+ mac->sme.pget_peer_info_ext_cb_context = context;
+
+ /* serialize the req through MC thread */
+ message.bodyptr =
+ qdf_mem_malloc(sizeof(struct sir_peer_info_ext_req));
+ if (NULL == message.bodyptr) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ "%s: Memory allocation failed.", __func__);
+ sme_release_global_lock(&mac->sme);
+ return QDF_STATUS_E_NOMEM;
+ }
+ qdf_mem_copy(message.bodyptr,
+ req,
+ sizeof(struct sir_peer_info_ext_req));
+ message.type = WMA_GET_PEER_INFO_EXT;
+ qdf_status = scheduler_post_msg(QDF_MODULE_ID_WMA, &message);
+ if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ "%s: Post get rssi msg fail", __func__);
+ qdf_mem_free(message.bodyptr);
+ status = QDF_STATUS_E_FAILURE;
+ }
+ sme_release_global_lock(&mac->sme);
+ }
+ return status;
+}
/*
* SME API to enable/disable WLAN driver initiated SSR
@@ -13451,7 +13562,7 @@
(scheduler_post_msg(QDF_MODULE_ID_WMA,
&message))) {
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
- "%s: Not able to post WMA_SET_DHCP_SERVER_OFFLOAD_CMD to WMA!",
+ "%s:WMA_SET_DHCP_SERVER_OFFLOAD_CMD failed",
__func__);
qdf_mem_free(pSmeDhcpSrvInfo);
status = QDF_STATUS_E_FAILURE;
@@ -16349,3 +16460,21 @@
{
return wma_cli_set_command(vdev_id, param_id, sval, vpdev);
}
+
+QDF_STATUS sme_set_bt_activity_info_cb(tHalHandle hal,
+ void (*cb)(void *, uint32_t bt_activity))
+{
+ QDF_STATUS status;
+ tpAniSirGlobal mac = PMAC_STRUCT(hal);
+
+ status = sme_acquire_global_lock(&mac->sme);
+ if (QDF_IS_STATUS_SUCCESS(status)) {
+ mac->sme.bt_activity_info_cb = cb;
+ sme_release_global_lock(&mac->sme);
+ sme_debug("bt activity info callback set");
+ } else {
+ sme_debug("sme_acquire_global_lock failed %d", status);
+ }
+
+ return status;
+}
diff --git a/core/sme/src/common/sme_power_save.c b/core/sme/src/common/sme_power_save.c
index ed87cd8..0d4b961 100644
--- a/core/sme/src/common/sme_power_save.c
+++ b/core/sme/src/common/sme_power_save.c
@@ -440,7 +440,7 @@
if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
sme_err("Invalid Session_id: %d", session_id);
- return eSIR_FAILURE;
+ return QDF_STATUS_E_INVAL;
}
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
FL("Power Save command %d"), command);
diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c
index 53efb0b..8820dc6 100644
--- a/core/sme/src/csr/csr_api_roam.c
+++ b/core/sme/src/csr/csr_api_roam.c
@@ -98,8 +98,6 @@
#define ROAMING_OFFLOAD_TIMER_STOP 2
#define CSR_ROAMING_OFFLOAD_TIMEOUT_PERIOD (5 * QDF_MC_TIMER_TO_SEC_UNIT)
-static bool b_roam_scan_offload_started;
-
/* Static Type declarations */
static tCsrRoamSession csr_roam_roam_session[CSR_ROAM_SESSION_MAX];
@@ -246,18 +244,9 @@
tDblLinkList *pStaList,
tCsrStatsClientReqInfo *
pStaEntry);
-static void csr_roam_stats_client_timer_handler(void *pv);
-tCsrPeStatsReqInfo *csr_roam_check_pe_stats_req_list(tpAniSirGlobal pMac,
- uint32_t statsMask,
- uint32_t periodicity,
- bool *pFound,
- uint8_t staId,
- uint8_t sessionId);
static void csr_roam_report_statistics(tpAniSirGlobal pMac, uint32_t statsMask,
tCsrStatsCallback callback, uint8_t staId,
void *pContext);
-static void csr_roam_tl_stats_timer_handler(void *pv);
-static void csr_roam_pe_stats_timer_handler(void *pv);
tListElem *csr_roam_check_client_req_list(tpAniSirGlobal pMac,
uint32_t statsMask);
static void csr_roam_remove_entry_from_pe_stats_req_list(tpAniSirGlobal pMac,
@@ -897,8 +886,6 @@
for (i = 0; i < CSR_ROAM_SESSION_MAX; i++)
status = csr_neighbor_roam_init(pMac, i);
pMac->roam.tlStatsReqInfo.numClient = 0;
- pMac->roam.tlStatsReqInfo.periodicity = 0;
- pMac->roam.tlStatsReqInfo.timerRunning = false;
/* init the link quality indication also */
pMac->roam.vccLinkQuality = eCSR_ROAM_LINK_QUAL_MIN_IND;
if (!QDF_IS_STATUS_SUCCESS(status)) {
@@ -938,14 +925,6 @@
pMac->roam.curSubState[sessionId] = eCSR_ROAM_SUBSTATE_NONE;
}
- /* When HAL resets all the context information
- * in HAL is lost, so we might need to send the
- * scan offload request again when it comes
- * out of reset for scan offload to be functional
- */
- if (HAL_STOP_TYPE_SYS_RESET == stopType)
- b_roam_scan_offload_started = false;
-
return QDF_STATUS_SUCCESS;
}
@@ -1083,13 +1062,6 @@
sme_err("cannot allocate memory for packetdump timer");
break;
}
- status = qdf_mc_timer_init(&pMac->roam.tlStatsReqInfo.
- hTlStatsTimer, QDF_TIMER_TYPE_SW,
- csr_roam_tl_stats_timer_handler, pMac);
- if (!QDF_IS_STATUS_SUCCESS(status)) {
- sme_err("cannot allocate memory for summary Statistics timer");
- return QDF_STATUS_E_FAILURE;
- }
} while (0);
return status;
}
@@ -1103,8 +1075,6 @@
qdf_mc_timer_stop(&pMac->roam.hTimerWaitForKey);
qdf_mc_timer_destroy(&pMac->roam.hTimerWaitForKey);
- qdf_mc_timer_stop(&pMac->roam.tlStatsReqInfo.hTlStatsTimer);
- qdf_mc_timer_destroy(&pMac->roam.tlStatsReqInfo.hTlStatsTimer);
qdf_mc_timer_stop(&pMac->roam.packetdump_timer);
qdf_mc_timer_destroy(&pMac->roam.packetdump_timer);
return QDF_STATUS_SUCCESS;
@@ -1176,7 +1146,6 @@
pProfile->mcEncryptionType = connected_prof->mcEncryptionType;
pProfile->BSSType = connected_prof->BSSType;
pProfile->operationChannel = connected_prof->operationChannel;
- pProfile->CBMode = connected_prof->CBMode;
qdf_mem_copy(&pProfile->bssid, &connected_prof->bssid,
sizeof(struct qdf_mac_addr));
qdf_mem_copy(&pProfile->SSID, &connected_prof->SSID,
@@ -2806,6 +2775,8 @@
pParam->sta_roam_policy_params.dfs_mode;
pMac->roam.configParam.sta_roam_policy.skip_unsafe_channels =
pParam->sta_roam_policy_params.skip_unsafe_channels;
+ pMac->roam.configParam.sta_roam_policy.sap_operating_band =
+ pParam->sta_roam_policy_params.sap_operating_band;
pMac->roam.configParam.tx_aggregation_size =
pParam->tx_aggregation_size;
@@ -2817,6 +2788,12 @@
pParam->qcn_ie_support;
pMac->roam.configParam.fils_max_chan_guard_time =
pParam->fils_max_chan_guard_time;
+ pMac->roam.configParam.disallow_duration =
+ pParam->disallow_duration;
+ pMac->roam.configParam.rssi_channel_penalization =
+ pParam->rssi_channel_penalization;
+ pMac->roam.configParam.num_disallowed_aps =
+ pParam->num_disallowed_aps;
csr_update_he_config_param(pMac, pParam);
}
@@ -3056,6 +3033,12 @@
pMac->roam.configParam.qcn_ie_support;
pParam->fils_max_chan_guard_time =
pMac->roam.configParam.fils_max_chan_guard_time;
+ pParam->disallow_duration =
+ pMac->roam.configParam.disallow_duration;
+ pParam->rssi_channel_penalization =
+ pMac->roam.configParam.rssi_channel_penalization;
+ pParam->num_disallowed_aps =
+ pMac->roam.configParam.num_disallowed_aps;
csr_get_he_config_param(pParam, pMac);
@@ -5876,8 +5859,13 @@
if (!QDF_IS_STATUS_SUCCESS(status)) {
sme_err("failed status %d", status);
csr_release_command(mac_ctx, cmd);
+ } else {
+ csr_neighbor_roam_state_transition(mac_ctx,
+ eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING,
+ session_id);
}
+
qdf_mem_free(pIes);
pIes = NULL;
}
@@ -7577,7 +7565,6 @@
if (pDstProfile->phyMode & eCSR_DOT11_MODE_11n)
pDstProfile->phyMode &= ~eCSR_DOT11_MODE_11n;
#endif /* FEATURE_WLAN_WAPI */
- pDstProfile->CBMode = pSrcProfile->CBMode;
pDstProfile->ch_params.ch_width = pSrcProfile->ch_params.ch_width;
pDstProfile->ch_params.center_freq_seg0 =
pSrcProfile->ch_params.center_freq_seg0;
@@ -7714,7 +7701,6 @@
pDstProfile->negotiatedMCEncryptionType =
pSrcProfile->mcEncryptionType;
pDstProfile->BSSType = pSrcProfile->BSSType;
- pDstProfile->CBMode = pSrcProfile->CBMode;
qdf_mem_copy(&pDstProfile->Keys, &pSrcProfile->Keys,
sizeof(pDstProfile->Keys));
if (pSrcProfile->MDID.mdiePresent) {
@@ -8643,12 +8629,6 @@
pConnectProfile->MFPCapable = pProfile->MFPCapable;
#endif
}
- if (pIes)
- pConnectProfile->CBMode = csr_get_cb_mode_from_ies(pMac,
- pSirBssDesc->channelId, pIes);
- else
- sme_err("IE unavailable to derive CB mode");
-
/* Save bssid */
pConnectProfile->operationChannel = pSirBssDesc->channelId;
pConnectProfile->beaconInterval = pSirBssDesc->beaconInterval;
@@ -9290,10 +9270,10 @@
if (pNeighborRoamInfo) {
qdf_mem_zero(&roamInfo, sizeof(tCsrRoamInfo));
csr_roam_call_callback(pMac,
- pSmeJoinRsp->sessionId,
- &roamInfo, roamId,
- eCSR_ROAM_FT_REASSOC_FAILED,
- eSIR_SME_SUCCESS);
+ pSmeJoinRsp->sessionId,
+ &roamInfo, roamId,
+ eCSR_ROAM_FT_REASSOC_FAILED,
+ eCSR_ROAM_RESULT_SUCCESS);
/*
* Since the above callback sends a disconnect
* to HDD, we should clean-up our state
@@ -9441,7 +9421,8 @@
/* Inform the upper layers that the reassoc failed */
qdf_mem_zero(roam_info, sizeof(tCsrRoamInfo));
csr_roam_call_callback(mac_ctx, session_id, roam_info, 0,
- eCSR_ROAM_FT_REASSOC_FAILED, eSIR_SME_SUCCESS);
+ eCSR_ROAM_FT_REASSOC_FAILED,
+ eCSR_ROAM_RESULT_SUCCESS);
/*
* Issue a disassoc request so that PE/LIM uses this to clean-up the FT
* session. Upon success, we would re-enter this routine after receiving
@@ -9871,6 +9852,17 @@
qdf_mem_copy(&pRoamInfo->chan_info,
&pUpperLayerAssocCnf->chan_info,
sizeof(tSirSmeChanInfo));
+ pRoamInfo->ampdu = pUpperLayerAssocCnf->ampdu;
+ pRoamInfo->sgi_enable = pUpperLayerAssocCnf->sgi_enable;
+ pRoamInfo->tx_stbc = pUpperLayerAssocCnf->tx_stbc;
+ pRoamInfo->tx_stbc = pUpperLayerAssocCnf->rx_stbc;
+ pRoamInfo->ch_width = pUpperLayerAssocCnf->ch_width;
+ pRoamInfo->mode = pUpperLayerAssocCnf->mode;
+ pRoamInfo->max_supp_idx = pUpperLayerAssocCnf->max_supp_idx;
+ pRoamInfo->max_ext_idx = pUpperLayerAssocCnf->max_ext_idx;
+ pRoamInfo->max_mcs_idx = pUpperLayerAssocCnf->max_mcs_idx;
+ pRoamInfo->rx_mcs_map = pUpperLayerAssocCnf->rx_mcs_map;
+ pRoamInfo->tx_mcs_map = pUpperLayerAssocCnf->tx_mcs_map;
if (CSR_IS_INFRA_AP(pRoamInfo->u.pConnectedProfile)) {
pMac->roam.roamSession[sessionId].connectState =
eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED;
@@ -14084,7 +14076,7 @@
uint8_t txBFCsnValue = 0;
tSirSmeJoinReq *csr_join_req;
tSirMacCapabilityInfo *pAP_capabilityInfo;
- tAniBool fTmp;
+ bool fTmp;
int8_t pwrLimit = 0;
struct ps_global_info *ps_global_info = &pMac->sme.ps_global_info;
struct ps_params *ps_param = &ps_global_info->ps_params[sessionId];
@@ -14694,9 +14686,9 @@
*/
if (csr_is11h_supported(pMac) && pAP_capabilityInfo->spectrumMgt
&& eSIR_11A_NW_TYPE == pBssDescription->nwType) {
- fTmp = (tAniBool) 1;
+ fTmp = true;
} else
- fTmp = (tAniBool) 0;
+ fTmp = false;
csr_join_req->spectrumMgtIndicator = fTmp;
csr_join_req->powerCap.minTxPower = MIN_TX_PWR_CAP;
@@ -15190,54 +15182,90 @@
else
statusCode = eSIR_SME_ASSOC_REFUSED;
qdf_mem_copy(pBuf, &statusCode, sizeof(tSirResultCodes));
- pBuf += sizeof(tSirResultCodes);
/* bssId */
- qdf_mem_copy((tSirMacAddr *) pBuf, pAssocInd->bssId,
- sizeof(tSirMacAddr));
- pBuf += sizeof(tSirMacAddr);
+ pBuf = (uint8_t *)&pMsg->bssId;
+ qdf_mem_copy((tSirMacAddr *)pBuf, pAssocInd->bssId,
+ sizeof(tSirMacAddr));
/* peerMacAddr */
- qdf_mem_copy((tSirMacAddr *) pBuf, pAssocInd->peerMacAddr,
- sizeof(tSirMacAddr));
- pBuf += sizeof(tSirMacAddr);
+ pBuf = (uint8_t *)&pMsg->peerMacAddr;
+ qdf_mem_copy((tSirMacAddr *)pBuf, pAssocInd->peerMacAddr,
+ sizeof(tSirMacAddr));
/* StaId */
+ pBuf = (uint8_t *)&pMsg->aid;
wTmp = pAssocInd->staId;
qdf_mem_copy(pBuf, &wTmp, sizeof(uint16_t));
- pBuf += sizeof(uint16_t);
/* alternateBssId */
- qdf_mem_copy((tSirMacAddr *) pBuf, pAssocInd->bssId,
- sizeof(tSirMacAddr));
- pBuf += sizeof(tSirMacAddr);
+ pBuf = (uint8_t *)&pMsg->alternateBssId;
+ qdf_mem_copy((tSirMacAddr *)pBuf, pAssocInd->bssId,
+ sizeof(tSirMacAddr));
/* alternateChannelId */
+ pBuf = (uint8_t *)&pMsg->alternateChannelId;
*pBuf = 11;
- pBuf += sizeof(uint8_t);
- /* Instead of copying roam Info, we just copy only WmmEnabled,
- * RsnIE information
+ /*
+ * Instead of copying roam Info,just copy WmmEnabled,
+ * RsnIE information.
+ * Wmm
*/
- /* Wmm */
+ pBuf = (uint8_t *)&pMsg->wmmEnabledSta;
*pBuf = pAssocInd->wmmEnabledSta;
- pBuf += sizeof(uint8_t);
/* RSN IE */
- qdf_mem_copy((tSirRSNie *) pBuf, &pAssocInd->rsnIE,
- sizeof(tSirRSNie));
- pBuf += sizeof(tSirRSNie);
+ pBuf = (uint8_t *)&pMsg->rsnIE;
+ qdf_mem_copy((tSirRSNie *)pBuf, &pAssocInd->rsnIE,
+ sizeof(tSirRSNie));
#ifdef FEATURE_WLAN_WAPI
/* WAPI IE */
- qdf_mem_copy((tSirWAPIie *) pBuf, &pAssocInd->wapiIE,
- sizeof(tSirWAPIie));
- pBuf += sizeof(tSirWAPIie);
+ pBuf = (uint8_t *)&pMsg->wapiIE;
+ qdf_mem_copy((tSirWAPIie *)pBuf, &pAssocInd->wapiIE,
+ sizeof(tSirWAPIie));
#endif
/* Additional IE */
- qdf_mem_copy((void *)pBuf, &pAssocInd->addIE,
- sizeof(tSirAddie));
- pBuf += sizeof(tSirAddie);
+ pBuf = (uint8_t *)&pMsg->addIE;
+ qdf_mem_copy((tSirAddie *)pBuf, &pAssocInd->addIE,
+ sizeof(tSirAddie));
/* reassocReq */
+ pBuf = (uint8_t *)&pMsg->reassocReq;
*pBuf = pAssocInd->reassocReq;
- pBuf += sizeof(uint8_t);
/* timingMeasCap */
+ pBuf = (uint8_t *)&pMsg->timingMeasCap;
*pBuf = pAssocInd->timingMeasCap;
- pBuf += sizeof(uint8_t);
+ /* chan_info */
+ pBuf = (uint8_t *)&pMsg->chan_info;
qdf_mem_copy((void *)pBuf, &pAssocInd->chan_info,
- sizeof(tSirSmeChanInfo));
+ sizeof(tSirSmeChanInfo));
+ /* ampdu */
+ pBuf = (uint8_t *)&pMsg->ampdu;
+ *((bool *)pBuf) = pAssocInd->ampdu;
+ /* sgi_enable */
+ pBuf = (uint8_t *)&pMsg->sgi_enable;
+ *((bool *)pBuf) = pAssocInd->sgi_enable;
+ /* tx stbc */
+ pBuf = (uint8_t *)&pMsg->tx_stbc;
+ *((bool *)pBuf) = pAssocInd->tx_stbc;
+ /* ch_width */
+ pBuf = (uint8_t *)&pMsg->ch_width;
+ *((tSirMacHTChannelWidth *)pBuf) = pAssocInd->ch_width;
+ /* mode */
+ pBuf = (uint8_t *)&pMsg->mode;
+ *((enum sir_sme_phy_mode *)pBuf) = pAssocInd->mode;
+ /* rx stbc */
+ pBuf = (uint8_t *)&pMsg->rx_stbc;
+ *((bool *)pBuf) = pAssocInd->rx_stbc;
+ /* max supported idx */
+ pBuf = (uint8_t *)&pMsg->max_supp_idx;
+ *pBuf = pAssocInd->max_supp_idx;
+ /* max extended idx */
+ pBuf = (uint8_t *)&pMsg->max_ext_idx;
+ *pBuf = pAssocInd->max_ext_idx;
+ /* max ht mcs idx */
+ pBuf = (uint8_t *)&pMsg->max_mcs_idx;
+ *pBuf = pAssocInd->max_mcs_idx;
+ /* vht rx mcs map */
+ pBuf = (uint8_t *)&pMsg->rx_mcs_map;
+ *pBuf = pAssocInd->rx_mcs_map;
+ /* vht tx mcs map */
+ pBuf = (uint8_t *)&pMsg->tx_mcs_map;
+ *pBuf = pAssocInd->tx_mcs_map;
+
msgQ.type = eWNI_SME_UPPER_LAYER_ASSOC_CNF;
msgQ.bodyptr = pMsg;
msgQ.bodyval = 0;
@@ -15886,7 +15914,7 @@
{
struct del_sta_self_params *del_sta_self_req;
struct scheduler_msg msg = {0};
- QDF_STATUS status = QDF_STATUS_E_FAILURE;
+ tSirRetStatus status;
del_sta_self_req = qdf_mem_malloc(sizeof(struct del_sta_self_params));
if (NULL == del_sta_self_req) {
@@ -15907,11 +15935,12 @@
sme_debug("sending WMA_DEL_STA_SELF_REQ");
status = wma_post_ctrl_msg(pMac, &msg);
- if (status != QDF_STATUS_SUCCESS) {
+ if (status != eSIR_SUCCESS) {
sme_err("wma_post_ctrl_msg failed");
qdf_mem_free(del_sta_self_req);
+ return QDF_STATUS_E_FAILURE;
}
- return status;
+ return QDF_STATUS_SUCCESS;
}
void csr_cleanup_session(tpAniSirGlobal pMac, uint32_t sessionId)
@@ -16144,109 +16173,6 @@
}
-static void csr_roam_tl_stats_timer_handler(void *pv)
-{
- tpAniSirGlobal pMac = PMAC_STRUCT(pv);
- QDF_STATUS status;
-
- pMac->roam.tlStatsReqInfo.timerRunning = false;
-
- sme_debug("TL stat timer is no-op. It needs to support multiple stations");
-
- if (!pMac->roam.tlStatsReqInfo.timerRunning) {
- if (pMac->roam.tlStatsReqInfo.periodicity) {
- /* start timer */
- status =
- qdf_mc_timer_start(&pMac->roam.tlStatsReqInfo.
- hTlStatsTimer,
- pMac->roam.tlStatsReqInfo.
- periodicity);
- if (!QDF_IS_STATUS_SUCCESS(status)) {
- sme_err("csr_roam_tl_stats_timer_handler:cannot start TlStatsTimer timer");
- return;
- }
- pMac->roam.tlStatsReqInfo.timerRunning = true;
- }
- }
-}
-
-static void csr_roam_pe_stats_timer_handler(void *pv)
-{
- tCsrPeStatsReqInfo *pPeStatsReqListEntry = (tCsrPeStatsReqInfo *) pv;
- QDF_STATUS status;
- tpAniSirGlobal pMac = pPeStatsReqListEntry->pMac;
- QDF_STATUS qdf_status;
-
- pPeStatsReqListEntry->timerRunning = false;
- if (pPeStatsReqListEntry->timerStopFailed == true) {
- /* If we entered here, meaning the timer could not be
- * successfully stopped in
- * csr_roam_remove_entry_from_pe_stats_req_list().
- * So do it here.
- * Destroy the timer
- */
- qdf_status = qdf_mc_timer_destroy(&pPeStatsReqListEntry->
- hPeStatsTimer);
- if (!QDF_IS_STATUS_SUCCESS(qdf_status))
- sme_err("csr_roam_pe_stats_timer_handler:failed to destroy hPeStatsTimer timer");
-
- /* Free the entry */
- qdf_mem_free(pPeStatsReqListEntry);
- pPeStatsReqListEntry = NULL;
- } else {
- if (!pPeStatsReqListEntry->rspPending) {
- status = csr_send_mb_stats_req_msg(pMac,
- pPeStatsReqListEntry->
- statsMask & ~(1 <<
- eCsrGlobalClassDStats),
- pPeStatsReqListEntry->staId,
- pPeStatsReqListEntry->
- sessionId);
- if (!QDF_IS_STATUS_SUCCESS(status))
- sme_err("csr_roam_pe_stats_timer_handler:failed to send down stats req to PE");
- else
- pPeStatsReqListEntry->rspPending = true;
- }
- /* send down a req */
- if (pPeStatsReqListEntry->periodicity &&
- (QDF_TIMER_STATE_STOPPED ==
- qdf_mc_timer_get_current_state(&pPeStatsReqListEntry->
- hPeStatsTimer))) {
- if (pPeStatsReqListEntry->periodicity <
- pMac->roam.configParam.
- statsReqPeriodicityInPS) {
- pPeStatsReqListEntry->periodicity =
- pMac->roam.configParam.
- statsReqPeriodicityInPS;
- }
- /* start timer */
- qdf_status =
- qdf_mc_timer_start(&pPeStatsReqListEntry->
- hPeStatsTimer,
- pPeStatsReqListEntry->
- periodicity);
- if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
- sme_err("csr_roam_pe_stats_timer_handler:cannot start hPeStatsTimer timer");
- return;
- }
- pPeStatsReqListEntry->timerRunning = true;
-
- }
-
- }
-}
-
-static void csr_roam_stats_client_timer_handler(void *pv)
-{
- tCsrStatsClientReqInfo *pStaEntry = (tCsrStatsClientReqInfo *) pv;
-
- if (QDF_TIMER_STATE_STOPPED ==
- qdf_mc_timer_get_current_state(&pStaEntry->timer)) {
- QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
- "roam stats client timer is stopped");
- }
-}
-
QDF_STATUS csr_send_mb_stats_req_msg(tpAniSirGlobal pMac, uint32_t statsMask,
uint8_t staId, uint8_t sessionId)
{
@@ -16456,8 +16382,6 @@
if ((pTempStaEntry->requesterId == pStaEntry->requesterId)
&& (pTempStaEntry->statsMask == pStaEntry->statsMask)) {
if (update) {
- pTempStaEntry->periodicity =
- pStaEntry->periodicity;
pTempStaEntry->callback = pStaEntry->callback;
pTempStaEntry->pContext = pStaEntry->pContext;
}
@@ -16503,8 +16427,9 @@
pStaEntry)
{
tCsrStatsClientReqInfo *pNewStaEntry = NULL;
- /* if same entity requested for same set of stats with different
- * periodicity & callback update it
+ /*
+ * if same entity requested for same set of stats with different
+ * callback update it
*/
if (NULL == csr_roam_checkn_update_client_req_list(pMac, pStaEntry,
true)) {
@@ -16517,7 +16442,6 @@
pNewStaEntry->callback = pStaEntry->callback;
pNewStaEntry->pContext = pStaEntry->pContext;
- pNewStaEntry->periodicity = pStaEntry->periodicity;
pNewStaEntry->requesterId = pStaEntry->requesterId;
pNewStaEntry->statsMask = pStaEntry->statsMask;
pNewStaEntry->pPeStaEntry = pStaEntry->pPeStaEntry;
@@ -16531,34 +16455,6 @@
return pNewStaEntry;
}
-static
-tCsrPeStatsReqInfo *csr_roam_insert_entry_into_pe_stats_req_list(
- tpAniSirGlobal pMac,
- tDblLinkList *pStaList,
- tCsrPeStatsReqInfo *
- pStaEntry)
-{
- tCsrPeStatsReqInfo *pNewStaEntry = NULL;
-
- pNewStaEntry = qdf_mem_malloc(sizeof(tCsrPeStatsReqInfo));
- if (NULL == pNewStaEntry) {
- sme_err("couldn't allocate memory for the entry");
- return NULL;
- }
-
- pNewStaEntry->hPeStatsTimer = pStaEntry->hPeStatsTimer;
- pNewStaEntry->numClient = pStaEntry->numClient;
- pNewStaEntry->periodicity = pStaEntry->periodicity;
- pNewStaEntry->statsMask = pStaEntry->statsMask;
- pNewStaEntry->pMac = pStaEntry->pMac;
- pNewStaEntry->staId = pStaEntry->staId;
- pNewStaEntry->timerRunning = pStaEntry->timerRunning;
- pNewStaEntry->rspPending = pStaEntry->rspPending;
-
- csr_ll_insert_tail(pStaList, &pNewStaEntry->link, LL_ACCESS_LOCK);
- return pNewStaEntry;
-}
-
QDF_STATUS csr_get_rssi(tpAniSirGlobal pMac,
tCsrRssiCallback callback,
uint8_t staId,
@@ -16624,6 +16520,7 @@
status = csr_roam_get_session_id_from_bssid(pMac, &bssId, &sessionId);
if (!QDF_IS_STATUS_SUCCESS(status)) {
+ qdf_mem_free(pMsg);
sme_err("Couldn't find session_id for given BSSID");
return status;
}
@@ -16680,19 +16577,6 @@
}
/* check if we need to stop the tl stats timer too */
mac_ctx->roam.tlStatsReqInfo.numClient--;
- if (!mac_ctx->roam.tlStatsReqInfo.numClient) {
- if (mac_ctx->roam.tlStatsReqInfo.timerRunning) {
- status = qdf_mc_timer_stop(
- &mac_ctx->roam.tlStatsReqInfo.hTlStatsTimer);
- if (!QDF_IS_STATUS_SUCCESS(status)) {
- sme_err(
- "cannot stop TlStatsTimer timer");
- return status;
- }
- }
- mac_ctx->roam.tlStatsReqInfo.periodicity = 0;
- mac_ctx->roam.tlStatsReqInfo.timerRunning = false;
- }
qdf_mc_timer_stop(&ptr_sta_entry->timer);
/* Destroy the qdf timer... */
status = qdf_mc_timer_destroy(&ptr_sta_entry->timer);
@@ -16708,16 +16592,13 @@
* csr_insert_stats_request_to_list() - inserts request to existing list
* @mac_ctx: mac global context
* @sta_entry: stats request entry
- * @periodicity: periodicity of stats
*
* Return: status of operation
*/
static QDF_STATUS
csr_insert_stats_request_to_list(tpAniSirGlobal mac_ctx,
- tCsrStatsClientReqInfo *sta_entry,
- uint32_t periodicity)
+ tCsrStatsClientReqInfo *sta_entry)
{
- QDF_STATUS status = QDF_STATUS_SUCCESS;
tCsrStatsClientReqInfo *ptr_sta_entry = csr_roam_insert_entry_into_list(
mac_ctx, &mac_ctx->roam.statsClientReqList,
sta_entry);
@@ -16725,79 +16606,6 @@
sme_err("Failed to insert req in statsClientReqList");
return QDF_STATUS_E_FAILURE;
}
- /* Init & start timer if needed */
- ptr_sta_entry->periodicity = periodicity;
- if (ptr_sta_entry->periodicity) {
- status = qdf_mc_timer_init(&ptr_sta_entry->timer,
- QDF_TIMER_TYPE_SW,
- csr_roam_stats_client_timer_handler,
- ptr_sta_entry);
- if (!QDF_IS_STATUS_SUCCESS(status)) {
- sme_err("cannot init StatsClient timer");
- return QDF_STATUS_E_FAILURE;
- }
- status = qdf_mc_timer_start(&ptr_sta_entry->timer,
- ptr_sta_entry->periodicity);
- if (!QDF_IS_STATUS_SUCCESS(status)) {
- sme_err("cannot start StatsClient timer");
- return QDF_STATUS_E_FAILURE;
- }
- }
- return status;
-}
-
-/**
- * csr_get_statistics_from_tl() - fetch stats from tl layer
- * @mac_ctx: mac global context
- * @cache: indicate if cached stats are required
- * @staId: station id
- * @periodicity: periodicity of stats
- *
- * Return: status of operation
- */
-static QDF_STATUS
-csr_get_statistics_from_tl(tpAniSirGlobal mac_ctx,
- bool cache,
- uint8_t staId,
- uint32_t periodicity)
-{
- QDF_STATUS status;
-
- if (cache && mac_ctx->roam.tlStatsReqInfo.numClient) {
- sme_err("Looking for cached stats from TL");
- mac_ctx->roam.tlStatsReqInfo.numClient++;
- return QDF_STATUS_SUCCESS;
- }
-
- /* update periodicity */
- if (mac_ctx->roam.tlStatsReqInfo.periodicity)
- mac_ctx->roam.tlStatsReqInfo.periodicity =
- QDF_MIN(periodicity,
- mac_ctx->roam.tlStatsReqInfo.periodicity);
- else
- mac_ctx->roam.tlStatsReqInfo.periodicity = periodicity;
-
- if (mac_ctx->roam.tlStatsReqInfo.periodicity
- < CSR_MIN_TL_STAT_QUERY_PERIOD) {
- mac_ctx->roam.tlStatsReqInfo.periodicity =
- CSR_MIN_TL_STAT_QUERY_PERIOD;
- }
-
- if (!mac_ctx->roam.tlStatsReqInfo.timerRunning) {
-
- if (mac_ctx->roam.tlStatsReqInfo.periodicity) {
- /* start timer */
- status = qdf_mc_timer_start(
- &mac_ctx->roam.tlStatsReqInfo.hTlStatsTimer,
- mac_ctx->roam.tlStatsReqInfo.periodicity);
- if (!QDF_IS_STATUS_SUCCESS(status)) {
- sme_err("cannot start TlStatsTimer timer");
- return QDF_STATUS_E_FAILURE;
- }
- mac_ctx->roam.tlStatsReqInfo.timerRunning = true;
- }
- }
- mac_ctx->roam.tlStatsReqInfo.numClient++;
return QDF_STATUS_SUCCESS;
}
@@ -16805,15 +16613,11 @@
eCsrStatsRequesterType requesterId,
uint32_t statsMask,
tCsrStatsCallback callback,
- uint32_t periodicity,
- bool cache,
uint8_t staId,
void *pContext,
uint8_t sessionId)
{
tCsrStatsClientReqInfo staEntry;
- tCsrPeStatsReqInfo *pPeStaEntry = NULL;
- bool found = false;
QDF_STATUS status = QDF_STATUS_SUCCESS;
bool insertInClientList = false;
uint32_t temp_mask = 0;
@@ -16837,77 +16641,38 @@
if ((statsMask) && (!callback))
return csr_deregister_client_request(pMac, &staEntry);
- if (cache && !periodicity) {
- /* return the cached stats */
- csr_roam_report_statistics(pMac, statsMask, callback, staId,
- pContext);
- return QDF_STATUS_SUCCESS;
- }
/* add the request in the client req list */
staEntry.callback = callback;
staEntry.pContext = pContext;
- staEntry.periodicity = periodicity;
staEntry.pPeStaEntry = NULL;
staEntry.staId = staId;
staEntry.pMac = pMac;
staEntry.timerExpired = false;
staEntry.sessionId = sessionId;
- /* if periodic report requested with non cached result from PE/TL */
- if (periodicity) {
- /* if looking for stats from PE */
- temp_mask = statsMask & ~(1 << eCsrGlobalClassDStats);
- if (temp_mask) {
- /* check if same req made already & waiting for rsp */
- pPeStaEntry = csr_roam_check_pe_stats_req_list(pMac,
- temp_mask, periodicity, &found,
- staId, sessionId);
- if (!pPeStaEntry)
- /* bail out, maxed out on num of req for PE */
- return QDF_STATUS_E_FAILURE;
- staEntry.pPeStaEntry = pPeStaEntry;
- }
+ temp_mask = statsMask & ~(1 << eCsrGlobalClassDStats);
+ if (temp_mask) {
+ /* send down a req */
+ status = csr_send_mb_stats_req_msg(pMac,
+ temp_mask, staId, sessionId);
+ if (!QDF_IS_STATUS_SUCCESS(status))
+ sme_err("failed to send down stats req");
/*
- * request stats from TL rightaway if requested by client,
- * update tlStatsReqInfo if needed
+ * so that when the stats rsp comes back from PE we
+ * respond to upper layer right away
*/
- temp_mask = statsMask & (1 << eCsrGlobalClassDStats);
- if (temp_mask) {
- status = csr_get_statistics_from_tl(pMac, cache, staId,
- periodicity);
- if (!QDF_IS_STATUS_SUCCESS(status))
- return status;
- }
+ staEntry.timerExpired = true;
insertInClientList = true;
}
- /* if one time report requested with non cached result from PE/TL */
- else if (!cache && !periodicity) {
- temp_mask = statsMask & ~(1 << eCsrGlobalClassDStats);
- if (temp_mask) {
- /* send down a req */
- status = csr_send_mb_stats_req_msg(pMac,
- temp_mask, staId, sessionId);
- if (!QDF_IS_STATUS_SUCCESS(status))
- sme_err(
- "failed to send down stats req");
- /*
- * so that when the stats rsp comes back from PE we
- * respond to upper layer right away
- */
- staEntry.timerExpired = true;
- insertInClientList = true;
- }
- /* if looking for stats from TL only */
- if (!insertInClientList) {
- /* return the stats */
- csr_roam_report_statistics(pMac, statsMask, callback,
- staId, pContext);
- return QDF_STATUS_SUCCESS;
- }
+ /* if looking for stats from TL only */
+ if (!insertInClientList) {
+ /* return the stats */
+ csr_roam_report_statistics(pMac, statsMask, callback,
+ staId, pContext);
+ return QDF_STATUS_SUCCESS;
}
if (insertInClientList)
- return csr_insert_stats_request_to_list(pMac, &staEntry,
- periodicity);
+ return csr_insert_stats_request_to_list(pMac, &staEntry);
return QDF_STATUS_SUCCESS;
}
@@ -17505,15 +17270,26 @@
mac_ctx->roam.configParam.early_stop_scan_min_threshold;
req_buf->early_stop_scan_max_threshold =
mac_ctx->roam.configParam.early_stop_scan_max_threshold;
- QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
- FL("HomeAwayTime=%d EarlyStopFeature Enable=%d, MinThresh=%d, MaxThresh=%d PMK len=%d"),
- req_buf->HomeAwayTime, req_buf->early_stop_scan_enable,
- req_buf->early_stop_scan_min_threshold,
- req_buf->early_stop_scan_max_threshold,
- req_buf->pmk_len);
req_buf->roamscan_adaptive_dwell_mode =
mac_ctx->roam.configParam.roamscan_adaptive_dwell_mode;
+ req_buf->lca_config_params.disallow_duration =
+ mac_ctx->roam.configParam.disallow_duration;
+ req_buf->lca_config_params.rssi_channel_penalization =
+ mac_ctx->roam.configParam.rssi_channel_penalization;
+ req_buf->lca_config_params.num_disallowed_aps =
+ mac_ctx->roam.configParam.num_disallowed_aps;
+
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
+ FL("HomeAwayTime=%d EarlyStopFeature Enable=%d, MinThresh=%d, MaxThresh=%d PMK len=%d disallow_dur=%d rssi_chan_pen=%d num_disallowed_aps=%d"),
+ req_buf->HomeAwayTime,
+ req_buf->early_stop_scan_enable,
+ req_buf->early_stop_scan_min_threshold,
+ req_buf->early_stop_scan_max_threshold,
+ req_buf->pmk_len,
+ req_buf->lca_config_params.disallow_duration,
+ req_buf->lca_config_params.rssi_channel_penalization,
+ req_buf->lca_config_params.num_disallowed_aps);
req_buf->RoamOffloadEnabled = csr_roamIsRoamOffloadEnabled(mac_ctx);
req_buf->RoamKeyMgmtOffloadEnabled = session->RoamKeyMgmtOffloadEnabled;
req_buf->pmkid_modes = session->pmkid_modes;
@@ -17578,24 +17354,24 @@
/*
* Below Table describe whether RSO command can be send down to fimrware or not.
* Host check it on the basis of previous RSO command sent down to firmware.
- *||==========================================================================||
- *|| New cmd | LAST SENT COMMAND ---> ||
- *||====|=====================================================================||
- *|| V | START | STOP | RESTART | UPDATE_CFG| ABORT_SCAN ||
- *|| -------------------------------------------------------------------------||
- *|| RSO_START | NO | YES | NO | NO | NO ||
- *|| RSO_STOP | YES | YES | YES | YES | YES ||
- *|| RSO_RESTART | YES | YES | NO | YES | YES ||
- *|| RSO_UPDATE_CFG | YES | NO | YES | YES | YES ||
- *|| RSO_ABORT_SCAN | YES | NO | YES | YES | YES ||
- *||==========================================================================||
+ * ||=========================================================================||
+ * || New cmd | LAST SENT COMMAND ---> ||
+ * ||====|====================================================================||
+ * || V | START | STOP | RESTART | UPDATE_CFG| ABORT_SCAN ||
+ * || ------------------------------------------------------------------------||
+ * || RSO_START | NO | YES | NO | YES | NO ||
+ * || RSO_STOP | YES | YES | YES | YES | YES ||
+ * || RSO_RESTART | YES | YES | NO | YES | YES ||
+ * || RSO_UPDATE_CFG | YES | NO | YES | YES | YES ||
+ * || RSO_ABORT_SCAN | YES | NO | YES | YES | YES ||
+ * ||=========================================================================||
**/
#define RSO_START_BIT (1<<ROAM_SCAN_OFFLOAD_START)
#define RSO_STOP_BIT (1<<ROAM_SCAN_OFFLOAD_STOP)
#define RSO_RESTART_BIT (1<<ROAM_SCAN_OFFLOAD_RESTART)
#define RSO_UPDATE_CFG_BIT (1<<ROAM_SCAN_OFFLOAD_UPDATE_CFG)
#define RSO_ABORT_SCAN_BIT (1<<ROAM_SCAN_OFFLOAD_ABORT_SCAN)
-#define RSO_START_ALLOW_MASK (RSO_STOP_BIT)
+#define RSO_START_ALLOW_MASK (RSO_STOP_BIT | RSO_UPDATE_CFG_BIT)
#define RSO_STOP_ALLOW_MASK (RSO_UPDATE_CFG_BIT | RSO_RESTART_BIT | \
RSO_STOP_BIT | RSO_START_BIT | RSO_ABORT_SCAN_BIT)
#define RSO_RESTART_ALLOW_MASK (RSO_UPDATE_CFG_BIT | RSO_START_BIT | \
@@ -17988,7 +17764,7 @@
return QDF_STATUS_E_FAILURE;
}
- if ((true == b_roam_scan_offload_started)
+ if ((true == roam_info->b_roam_scan_offload_started)
&& (ROAM_SCAN_OFFLOAD_START == command)) {
sme_err("Roam Scan Offload is already started");
return QDF_STATUS_E_FAILURE;
@@ -18142,9 +17918,9 @@
return QDF_STATUS_E_FAILURE;
}
if (ROAM_SCAN_OFFLOAD_START == command)
- b_roam_scan_offload_started = true;
+ roam_info->b_roam_scan_offload_started = true;
else if (ROAM_SCAN_OFFLOAD_STOP == command)
- b_roam_scan_offload_started = false;
+ roam_info->b_roam_scan_offload_started = false;
/* update the last sent cmd */
roam_info->last_sent_cmd = command;
@@ -18177,102 +17953,6 @@
}
#endif
-tCsrPeStatsReqInfo *csr_roam_check_pe_stats_req_list(tpAniSirGlobal pMac,
- uint32_t statsMask,
- uint32_t periodicity,
- bool *pFound,
- uint8_t staId,
- uint8_t sessionId)
-{
- bool found = false;
- QDF_STATUS status = QDF_STATUS_SUCCESS;
- tCsrPeStatsReqInfo staEntry;
- tCsrPeStatsReqInfo *pTempStaEntry = NULL;
- tListElem *pStaEntry = NULL;
- QDF_STATUS qdf_status;
- *pFound = false;
-
- pStaEntry = csr_roam_find_in_pe_stats_req_list(pMac, statsMask);
- if (pStaEntry) {
- pTempStaEntry =
- GET_BASE_ADDR(pStaEntry, tCsrPeStatsReqInfo, link);
- if (pTempStaEntry->periodicity) {
- pTempStaEntry->periodicity =
- QDF_MIN(periodicity,
- pTempStaEntry->periodicity);
- } else {
- pTempStaEntry->periodicity = periodicity;
- }
- pTempStaEntry->numClient++;
- found = true;
- } else {
- qdf_mem_set(&staEntry, sizeof(tCsrPeStatsReqInfo), 0);
- staEntry.numClient = 1;
- staEntry.periodicity = periodicity;
- staEntry.pMac = pMac;
- staEntry.rspPending = false;
- staEntry.staId = staId;
- staEntry.statsMask = statsMask;
- staEntry.timerRunning = false;
- staEntry.sessionId = sessionId;
- pTempStaEntry = csr_roam_insert_entry_into_pe_stats_req_list(
- pMac,
- &pMac->roam.
- peStatsReqList,
- &staEntry);
- if (!pTempStaEntry) {
- sme_err(
- "Failed to insert req in peStatsReqList");
- return NULL;
- }
- }
- pTempStaEntry->periodicity =
- pMac->roam.configParam.statsReqPeriodicityInPS;
-
- if (!pTempStaEntry->timerRunning) {
- /* send down a req in case of one time req, for periodic ones
- * wait for timer to expire
- */
- if (!pTempStaEntry->rspPending && !pTempStaEntry->periodicity) {
- status = csr_send_mb_stats_req_msg(pMac,
- statsMask & ~(1 <<
- eCsrGlobalClassDStats),
- staId, sessionId);
- if (!QDF_IS_STATUS_SUCCESS(status))
- sme_err("csr_roam_check_pe_stats_req_list:failed to send down stats req to PE");
- else
- pTempStaEntry->rspPending = true;
- }
- if (pTempStaEntry->periodicity) {
- if (!found) {
-
- qdf_status = qdf_mc_timer_init(&pTempStaEntry->
- hPeStatsTimer,
- QDF_TIMER_TYPE_SW,
- csr_roam_pe_stats_timer_handler,
- pTempStaEntry);
- if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
- sme_err("csr_roam_check_pe_stats_req_list:cannot init hPeStatsTimer timer");
- return NULL;
- }
- }
- /* start timer */
- sme_debug("csr_roam_check_pe_stats_req_list:peStatsTimer period %d",
- pTempStaEntry->periodicity);
- qdf_status = qdf_mc_timer_start(&pTempStaEntry->
- hPeStatsTimer,
- pTempStaEntry->periodicity);
- if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
- sme_err("csr_roam_check_pe_stats_req_list:cannot start hPeStatsTimer timer");
- return NULL;
- }
- pTempStaEntry->timerRunning = true;
- }
- }
- *pFound = found;
- return pTempStaEntry;
-}
-
/* pStaEntry is no longer invalid upon the return of this function. */
static void csr_roam_remove_stat_list_entry(tpAniSirGlobal pMac,
tListElem *pEntry)
@@ -18290,7 +17970,6 @@
{
tListElem *pEntry;
tCsrPeStatsReqInfo *pTempStaEntry;
- QDF_STATUS qdf_status;
pEntry = csr_ll_peek_head(&pMac->roam.peStatsReqList, LL_ACCESS_LOCK);
if (!pEntry) {
@@ -18307,42 +17986,10 @@
continue;
}
sme_debug("Match found");
- if (pTempStaEntry->timerRunning) {
- qdf_status = qdf_mc_timer_stop(
- &pTempStaEntry->hPeStatsTimer);
- /*
- * If we are not able to stop the timer here, just
- * remove the entry from the linked list. Destroy the
- * timer object and free the memory in the timer CB
- */
- if (qdf_status == QDF_STATUS_SUCCESS) {
- /* the timer is successfully stopped */
- pTempStaEntry->timerRunning = false;
- /* Destroy the timer */
- qdf_status = qdf_mc_timer_destroy(
- &pTempStaEntry->hPeStatsTimer);
- } else {
- /*
- * the timer could not be stopped. Hence destroy
- * and free the memory for the PE stat entry in
- * the timer CB.
- */
- pTempStaEntry->timerStopFailed = true;
- }
- if (!QDF_IS_STATUS_SUCCESS(qdf_status))
- sme_err("failed to stop/destroy timer");
- }
-
if (csr_ll_remove_entry(&pMac->roam.peStatsReqList, pEntry,
LL_ACCESS_LOCK)) {
- /*
- * Only free the memory if we could stop the timer
- * successfully
- */
- if (!pTempStaEntry->timerStopFailed) {
- qdf_mem_free(pTempStaEntry);
- pTempStaEntry = NULL;
- }
+ qdf_mem_free(pTempStaEntry);
+ pTempStaEntry = NULL;
break;
}
pEntry = csr_ll_next(&pMac->roam.peStatsReqList, pEntry,
@@ -18426,7 +18073,6 @@
tListElem *pPrevEntry = NULL;
tCsrStatsClientReqInfo *pTempStaEntry = NULL;
QDF_STATUS status = QDF_STATUS_SUCCESS;
- QDF_STATUS qdf_status;
pEntry = csr_ll_peek_head(&pMac->roam.statsClientReqList,
LL_ACCESS_LOCK);
@@ -18465,38 +18111,9 @@
}
/* check if we need to stop the tl stats timer too */
pMac->roam.tlStatsReqInfo.numClient--;
- if (!pMac->roam.tlStatsReqInfo.numClient) {
- if (pMac->roam.tlStatsReqInfo.timerRunning) {
- status =
- qdf_mc_timer_stop(&pMac->roam.
- tlStatsReqInfo.
- hTlStatsTimer);
- if (!QDF_IS_STATUS_SUCCESS(status))
- sme_err("csr_roam_dereg_statistics_req:cannot stop TlStatsTimer timer");
- /* we will continue */
- }
- pMac->roam.tlStatsReqInfo.periodicity = 0;
- pMac->roam.tlStatsReqInfo.timerRunning = false;
- }
- if (pTempStaEntry->periodicity) {
- /* While creating StaEntry in csr_get_statistics,
- * Initializing and starting timer only when periodicity
- * is set. So Stop and Destroy timer only when
- * periodicity is set.
- */
-
- qdf_mc_timer_stop(&pTempStaEntry->timer);
- /* Destroy the qdf timer... */
- qdf_status =
- qdf_mc_timer_destroy(&pTempStaEntry->timer);
- if (!QDF_IS_STATUS_SUCCESS(qdf_status))
- sme_err("csr_roam_dereg_statistics_req:failed to destroy Client req timer");
- }
-
pPrevEntry = pEntry;
- pEntry =
- csr_ll_next(&pMac->roam.statsClientReqList, pEntry,
- LL_ACCESS_NOLOCK);
+ pEntry = csr_ll_next(&pMac->roam.statsClientReqList, pEntry,
+ LL_ACCESS_NOLOCK);
}
/* the last one */
if (pPrevEntry) {
@@ -20201,24 +19818,24 @@
return QDF_STATUS_E_FAILURE;
}
csr_roam_call_callback(mac_ctx, session_id, NULL, 0,
- eCSR_ROAM_FT_START, eSIR_SME_SUCCESS);
+ eCSR_ROAM_FT_START, eCSR_ROAM_RESULT_SUCCESS);
return status;
case SIR_ROAMING_START:
csr_roam_roaming_offload_timer_action(mac_ctx,
CSR_ROAMING_OFFLOAD_TIMEOUT_PERIOD, session_id,
ROAMING_OFFLOAD_TIMER_START);
csr_roam_call_callback(mac_ctx, session_id, NULL, 0,
- eCSR_ROAM_START, eSIR_SME_SUCCESS);
+ eCSR_ROAM_START, eCSR_ROAM_RESULT_SUCCESS);
return status;
case SIR_ROAMING_ABORT:
csr_roam_roaming_offload_timer_action(mac_ctx,
0, session_id, ROAMING_OFFLOAD_TIMER_STOP);
csr_roam_call_callback(mac_ctx, session_id, NULL, 0,
- eCSR_ROAM_ABORT, eSIR_SME_SUCCESS);
+ eCSR_ROAM_ABORT, eCSR_ROAM_RESULT_SUCCESS);
return status;
case SIR_ROAM_SYNCH_NAPI_OFF:
csr_roam_call_callback(mac_ctx, session_id, NULL, 0,
- eCSR_ROAM_NAPI_OFF, eSIR_SME_SUCCESS);
+ eCSR_ROAM_NAPI_OFF, eCSR_ROAM_RESULT_SUCCESS);
return status;
case SIR_ROAMING_INVOKE_FAIL:
csr_roam_call_callback(mac_ctx, session_id, NULL, 0,
@@ -20440,7 +20057,6 @@
eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED;
sme_qos_csr_event_ind(mac_ctx, session_id,
SME_QOS_CSR_REASSOC_COMPLETE, &assoc_info);
- sme_qos_remove_addts_delts_cmd(mac_ctx, session_id);
roam_info->pBssDesc = bss_desc;
conn_profile->acm_mask = sme_qos_get_acm_mask(mac_ctx,
bss_desc, NULL);
diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c
index ea915e9..0748943 100644
--- a/core/sme/src/csr/csr_api_scan.c
+++ b/core/sme/src/csr/csr_api_scan.c
@@ -3380,13 +3380,14 @@
}
if (CSR_ROAM_SESSION_MAX == i) {
uint32_t len = QDF_MAC_ADDR_SIZE;
+ tSirRetStatus sir_status;
- status = wlan_cfg_get_str(pMac, WNI_CFG_STA_ID,
+ sir_status = wlan_cfg_get_str(pMac, WNI_CFG_STA_ID,
selfmac.bytes, &len);
- if (!QDF_IS_STATUS_SUCCESS(status)
+ if ((sir_status != eSIR_SUCCESS)
|| (len < QDF_MAC_ADDR_SIZE)) {
- sme_err("Can't get self MAC address: %d",
- status);
+ sme_err("Can't get self MAC: status:%d len:%d",
+ sir_status, len);
status = QDF_STATUS_E_FAILURE;
goto send_scan_req;
}
@@ -4603,18 +4604,20 @@
QDF_STATUS csr_get_country_code(tpAniSirGlobal pMac, uint8_t *pBuf,
uint8_t *pbLen)
{
- QDF_STATUS status = QDF_STATUS_E_INVAL;
+ tSirRetStatus status;
uint32_t len;
if (pBuf && pbLen && (*pbLen >= WNI_CFG_COUNTRY_CODE_LEN)) {
len = *pbLen;
status = wlan_cfg_get_str(pMac, WNI_CFG_COUNTRY_CODE, pBuf,
&len);
- if (QDF_IS_STATUS_SUCCESS(status))
+ if (status == eSIR_SUCCESS) {
*pbLen = (uint8_t) len;
+ return QDF_STATUS_SUCCESS;
+ }
}
- return status;
+ return QDF_STATUS_E_INVAL;
}
void csr_set_cfg_scan_control_list(tpAniSirGlobal pMac, uint8_t *countryCode,
diff --git a/core/sme/src/csr/csr_host_scan_roam.c b/core/sme/src/csr/csr_host_scan_roam.c
index 1ac0d18..2f1c656 100644
--- a/core/sme/src/csr/csr_host_scan_roam.c
+++ b/core/sme/src/csr/csr_host_scan_roam.c
@@ -616,7 +616,7 @@
qdf_mem_zero(&roam_info, sizeof(tCsrRoamInfo));
csr_roam_call_callback(mac_ctx, session_id, &roam_info, roamid,
- eCSR_ROAM_FT_START, eSIR_SME_SUCCESS);
+ eCSR_ROAM_FT_START, eCSR_ROAM_RESULT_SUCCESS);
qdf_mem_zero(&roam_info, sizeof(tCsrRoamInfo));
csr_neighbor_roam_state_transition(mac_ctx,
diff --git a/core/sme/src/csr/csr_neighbor_roam.c b/core/sme/src/csr/csr_neighbor_roam.c
index 61931cb..15b94e3 100644
--- a/core/sme/src/csr/csr_neighbor_roam.c
+++ b/core/sme/src/csr/csr_neighbor_roam.c
@@ -1420,6 +1420,7 @@
&pNeighborRoamInfo->FTRoamInfo.
preAuthDoneList);
csr_ll_close(&pNeighborRoamInfo->FTRoamInfo.preAuthDoneList);
+ pNeighborRoamInfo->b_roam_scan_offload_started = false;
csr_neighbor_roam_state_transition(pMac,
eCSR_NEIGHBOR_ROAM_STATE_CLOSED, sessionId);
diff --git a/core/sme/src/nan/nan_datapath_api.c b/core/sme/src/nan/nan_datapath_api.c
index f70d2bf..44b1e66 100644
--- a/core/sme/src/nan/nan_datapath_api.c
+++ b/core/sme/src/nan/nan_datapath_api.c
@@ -372,7 +372,6 @@
sizeof(connect_profile), 0);
connect_profile->AuthType = roam_profile->negotiatedAuthType;
connect_profile->AuthInfo = roam_profile->AuthType;
- connect_profile->CBMode = roam_profile->CBMode;
connect_profile->EncryptionType =
roam_profile->negotiatedUCEncryptionType;
connect_profile->EncryptionInfo = roam_profile->EncryptionType;
diff --git a/core/sme/src/p2p/p2p_api.c b/core/sme/src/p2p/p2p_api.c
index 710ec5d..3b99871 100644
--- a/core/sme/src/p2p/p2p_api.c
+++ b/core/sme/src/p2p/p2p_api.c
@@ -117,9 +117,12 @@
return status;
callback = pCommand->u.remainChlCmd.callback;
- if (callback)
+ if (callback && rsp) {
+ if (rsp->status != eSIR_SME_SUCCESS)
+ status = QDF_STATUS_E_FAILURE;
callback(pMac, pCommand->u.remainChlCmd.callbackCtx,
- rsp->status, rsp->scan_id);
+ status, rsp->scan_id);
+ }
fFound = csr_scan_active_ll_remove_entry(pMac, pEntry,
LL_ACCESS_LOCK);
diff --git a/core/sme/src/qos/sme_qos.c b/core/sme/src/qos/sme_qos.c
index 993eefb..b5bbe98 100644
--- a/core/sme/src/qos/sme_qos.c
+++ b/core/sme/src/qos/sme_qos.c
@@ -908,27 +908,6 @@
return status;
}
-void sme_qos_remove_addts_delts_cmd(tpAniSirGlobal mac_ctx, uint8_t session_id)
-{
- tListElem *entry;
- tSmeCmd *command;
-
- entry = csr_nonscan_active_ll_peek_head(mac_ctx, LL_ACCESS_LOCK);
- if (NULL == entry)
- return;
- command = GET_BASE_ADDR(entry, tSmeCmd, Link);
- if ((eSmeCommandAddTs == command->command ||
- eSmeCommandDelTs == command->command) &&
- command->sessionId == session_id) {
- if (csr_nonscan_active_ll_remove_entry(mac_ctx, entry,
- LL_ACCESS_LOCK)) {
- QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
- "%s: removed addts/delts command", __func__);
- qos_release_command(mac_ctx, command);
- }
- }
-}
-
/*--------------------------------------------------------------------------
\brief sme_qos_csr_event_ind() - The QoS sub-module in SME expects notifications
from CSR when certain events occur as mentioned in sme_qos_csr_event_indType.
@@ -2962,7 +2941,7 @@
pAddtsRsp->rc = eSIR_SUCCESS;
pAddtsRsp->sessionId = sessionId;
pAddtsRsp->rsp.dialogToken = 0;
- pAddtsRsp->rsp.status = eSIR_SUCCESS;
+ pAddtsRsp->rsp.status = eSIR_MAC_SUCCESS_STATUS;
pAddtsRsp->rsp.wmeTspecPresent = pTspec->present;
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
"%s: Copy Tspec to local data structure ac=%d, tspecIdx=%d",
@@ -6771,7 +6750,7 @@
if (!QDF_IS_STATUS_SUCCESS(lock_status)) {
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
"%s: %d: Unable to obtain lock", __func__, __LINE__);
- return SME_QOS_STATUS_RELEASE_FAILURE_RSP;
+ return QDF_STATUS_E_FAILURE;
}
/* Call the internal function for QoS release, adding a layer of abstraction */
status =
@@ -7538,10 +7517,8 @@
sme_qos_add_ts_req(pMac, (uint8_t) pCommand->sessionId,
&pCommand->u.qosCmd.tspecInfo,
pCommand->u.qosCmd.ac);
- if (QDF_IS_STATUS_SUCCESS(status)) {
+ if (QDF_IS_STATUS_SUCCESS(status))
fRemoveCmd = false;
- status = SME_QOS_STATUS_SETUP_REQ_PENDING_RSP;
- }
break;
case eSmeCommandDelTs:
status =
diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h
index 1ff0697..f0c79e7 100644
--- a/core/wma/inc/wma.h
+++ b/core/wma/inc/wma.h
@@ -40,6 +40,7 @@
#include "cfg_api.h"
#include "qdf_status.h"
#include "cds_sched.h"
+#include "cds_config.h"
#include "sir_mac_prot_def.h"
#include "wma_types.h"
#include <linux/workqueue.h>
@@ -520,18 +521,6 @@
typedef void (*tp_wma_packetdump_cb)(qdf_nbuf_t netbuf,
uint8_t status, uint8_t vdev_id, uint8_t type);
-/**
- * enum t_wma_drv_type - wma driver type
- * @WMA_DRIVER_TYPE_PRODUCTION: production driver type
- * @WMA_DRIVER_TYPE_MFG: manufacture driver type
- * @WMA_DRIVER_TYPE_INVALID: invalid driver type
- */
-typedef enum {
- WMA_DRIVER_TYPE_PRODUCTION = 0,
- WMA_DRIVER_TYPE_MFG = 1,
- WMA_DRIVER_TYPE_INVALID = 0x7FFFFFFF
-} t_wma_drv_type;
-
#ifdef FEATURE_WLAN_TDLS
/**
* enum t_wma_tdls_mode - TDLS mode
@@ -1364,7 +1353,7 @@
qdf_event_t recovery_event;
uint16_t max_station;
uint16_t max_bssid;
- t_wma_drv_type driver_type;
+ enum driver_type driver_type;
uint8_t myaddr[IEEE80211_ADDR_LEN];
uint8_t hwaddr[IEEE80211_ADDR_LEN];
wmi_abi_version target_abi_vers;
@@ -1571,7 +1560,7 @@
typedef struct {
void *pConfigBuffer;
uint16_t usConfigBufferLen;
- t_wma_drv_type driver_type;
+ enum driver_type driver_type;
void *pUserData;
void *pIndUserData;
} t_wma_start_req;
diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h
index 35cd3b5..f31ff21 100644
--- a/core/wma/inc/wma_internal.h
+++ b/core/wma/inc/wma_internal.h
@@ -721,7 +721,14 @@
int32_t wmi_unified_send_txbf(tp_wma_handle wma, tpAddStaParams params);
-void wma_update_txrx_chainmask(int num_rf_chains, int *cmd_value);
+/**
+ * wma_check_txrx_chainmask() - check txrx chainmask
+ * @num_rf_chains: number of rf chains
+ * @cmd_value: command value
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS wma_check_txrx_chainmask(int num_rf_chains, int cmd_value);
int wma_peer_state_change_event_handler(void *handle,
uint8_t *event_buff,
@@ -1254,4 +1261,17 @@
int wma_rx_aggr_failure_event_handler(void *handle, u_int8_t *event_buf,
u_int32_t len);
+/**
+ * wma_wlan_bt_activity_evt_handler - event handler to handle bt activity
+ * @handle: the WMA handle
+ * @event: buffer with the event parameters
+ * @len: length of the buffer
+ *
+ * This function receives BT activity event from firmware and passes the event
+ * information to upper layers
+ *
+ * Return: 0 on success
+ */
+int wma_wlan_bt_activity_evt_handler(void *handle, uint8_t *event,
+ uint32_t len);
#endif
diff --git a/core/wma/src/wma_data.c b/core/wma/src/wma_data.c
index 97eec99..d6bb573 100644
--- a/core/wma/src/wma_data.c
+++ b/core/wma/src/wma_data.c
@@ -913,27 +913,21 @@
}
/**
- * wma_update_txrx_chainmask() - update txrx chainmask
- * @num_rf_chains: number rf chains
+ * wma_check_txrx_chainmask() - check txrx chainmask
+ * @num_rf_chains: number of rf chains
* @cmd_value: command value
*
- * Return: none
+ * Return: QDF_STATUS_SUCCESS for success or error code
*/
-void wma_update_txrx_chainmask(int num_rf_chains, int *cmd_value)
+QDF_STATUS wma_check_txrx_chainmask(int num_rf_chains, int cmd_value)
{
- if (*cmd_value > WMA_MAX_RF_CHAINS(num_rf_chains)) {
- WMA_LOGE("%s: Chainmask value exceeds the maximum supported range setting it to maximum value.",
- __func__);
- WMA_LOGE("%s: Requested value %d Updated value %d",
- __func__, *cmd_value, WMA_MAX_RF_CHAINS(num_rf_chains));
- *cmd_value = WMA_MAX_RF_CHAINS(num_rf_chains);
- } else if (*cmd_value < WMA_MIN_RF_CHAINS) {
- WMA_LOGE("%s: Chainmask value is less than the minimum supported range setting it to minimum value.",
- __func__);
- WMA_LOGE("%s: Requested value %d Updated value %d",
- __func__, *cmd_value, WMA_MIN_RF_CHAINS);
- *cmd_value = WMA_MIN_RF_CHAINS;
+ if ((cmd_value > WMA_MAX_RF_CHAINS(num_rf_chains)) ||
+ (cmd_value < WMA_MIN_RF_CHAINS)) {
+ WMA_LOGE("%s: Requested value %d over the range",
+ __func__, cmd_value);
+ return QDF_STATUS_E_INVAL;
}
+ return QDF_STATUS_SUCCESS;
}
/**
@@ -968,7 +962,7 @@
event = param_buf->fixed_param;
vdev = wma_find_vdev_by_id(wma_handle, event->vdev_id);
if (NULL == vdev) {
- WMA_LOGP("%s: Couldn't find vdev for vdev_id: %d",
+ WMA_LOGD("%s: Couldn't find vdev for vdev_id: %d",
__func__, event->vdev_id);
return -EINVAL;
}
diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c
index c18df48..98b3a8b 100644
--- a/core/wma/src/wma_dev_if.c
+++ b/core/wma/src/wma_dev_if.c
@@ -650,8 +650,13 @@
if (!iface->handle) {
WMA_LOGE("handle of vdev_id %d is NULL vdev is already freed",
vdev_id);
- qdf_mem_free(pdel_sta_self_req_param);
- pdel_sta_self_req_param = NULL;
+ pdel_sta_self_req_param->status = status;
+ if (generateRsp) {
+ wma_send_del_sta_self_resp(pdel_sta_self_req_param);
+ } else {
+ qdf_mem_free(pdel_sta_self_req_param);
+ pdel_sta_self_req_param = NULL;
+ }
return status;
}
@@ -2025,7 +2030,7 @@
(self_sta_req->type == WMI_VDEV_TYPE_OCB) ||
(self_sta_req->type == WMI_VDEV_TYPE_MONITOR) ||
(self_sta_req->type == WMI_VDEV_TYPE_NDI)) {
- WMA_LOGA("Creating self peer %pM, vdev_id %hu",
+ WMA_LOGD("Creating self peer %pM, vdev_id %hu",
self_sta_req->self_mac_addr, self_sta_req->session_id);
status = wma_create_peer(wma_handle, txrx_pdev,
txrx_vdev_handle,
diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c
index a499028..bebac44 100644
--- a/core/wma/src/wma_features.c
+++ b/core/wma/src/wma_features.c
@@ -1306,8 +1306,7 @@
* basic sanity check: requested channel should not be 0
* and equal to home channel
*/
- if ((0 == csa_offload_event->channel) ||
- (cur_chan == csa_offload_event->channel)) {
+ if (0 == csa_offload_event->channel) {
WMA_LOGE("CSA Event with channel %d. Ignore !!",
csa_offload_event->channel);
qdf_mem_free(csa_offload_event);
@@ -5406,3 +5405,38 @@
return 0;
}
+
+int wma_wlan_bt_activity_evt_handler(void *handle, uint8_t *event, uint32_t len)
+{
+ wmi_coex_bt_activity_event_fixed_param *fixed_param;
+ WMI_WLAN_COEX_BT_ACTIVITY_EVENTID_param_tlvs *param_buf =
+ (WMI_WLAN_COEX_BT_ACTIVITY_EVENTID_param_tlvs *)event;
+ struct scheduler_msg sme_msg = {0};
+ QDF_STATUS qdf_status;
+
+ if (!param_buf) {
+ WMA_LOGE(FL("Invalid BT activity event buffer"));
+ return -EINVAL;
+ }
+
+ fixed_param = param_buf->fixed_param;
+ if (!fixed_param) {
+ WMA_LOGE(FL("Invalid BT activity event fixed param buffer"));
+ return -EINVAL;
+ }
+
+ WMA_LOGI(FL("Received BT activity event %u"),
+ fixed_param->coex_profile_evt);
+
+ sme_msg.type = eWNI_SME_BT_ACTIVITY_INFO_IND;
+ sme_msg.bodyptr = NULL;
+ sme_msg.bodyval = fixed_param->coex_profile_evt;
+
+ qdf_status = scheduler_post_msg(QDF_MODULE_ID_SME, &sme_msg);
+ if (QDF_IS_STATUS_ERROR(qdf_status)) {
+ WMA_LOGE(FL("Failed to post msg to SME"));
+ return -EINVAL;
+ }
+
+ return 0;
+}
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index 9c7f205..6a8e431 100644
--- a/core/wma/src/wma_main.c
+++ b/core/wma/src/wma_main.c
@@ -947,8 +947,13 @@
privcmd->param_value);
if ((privcmd->param_id == WMI_PDEV_PARAM_RX_CHAIN_MASK) ||
(privcmd->param_id == WMI_PDEV_PARAM_TX_CHAIN_MASK)) {
- wma_update_txrx_chainmask(wma->num_rf_chains,
- &privcmd->param_value);
+ if (QDF_STATUS_SUCCESS !=
+ wma_check_txrx_chainmask(
+ wma->num_rf_chains,
+ privcmd->param_value)) {
+ WMA_LOGD("Chainmask value is invalid");
+ return;
+ }
}
pdev_param.param_id = privcmd->param_id;
pdev_param.param_value = privcmd->param_value;
@@ -1732,7 +1737,7 @@
return;
}
- while (qdf_list_peek_front(&wma->vdev_resp_queue, &node1) ==
+ while (qdf_list_remove_front(&wma->vdev_resp_queue, &node1) ==
QDF_STATUS_SUCCESS) {
req_msg = qdf_container_of(node1, struct wma_target_req, node);
qdf_spin_unlock_bh(&wma->vdev_respq_lock);
@@ -1762,7 +1767,7 @@
}
while (QDF_STATUS_SUCCESS ==
- qdf_list_peek_front(&wma->wma_hold_req_queue, &node1)) {
+ qdf_list_remove_front(&wma->wma_hold_req_queue, &node1)) {
req_msg = qdf_container_of(node1, struct wma_target_req, node);
qdf_spin_unlock_bh(&wma->wma_hold_req_q_lock);
/* Cleanup timeout handler */
@@ -3343,6 +3348,16 @@
}
#endif
+ status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
+ WMI_WLAN_COEX_BT_ACTIVITY_EVENTID,
+ wma_wlan_bt_activity_evt_handler,
+ WMA_RX_SERIALIZER_CTX);
+ if (!QDF_IS_STATUS_SUCCESS(status)) {
+ WMA_LOGE("Failed to register coex bt activity event handler");
+ qdf_status = QDF_STATUS_E_FAILURE;
+ goto end;
+ }
+
end:
WMA_LOGD("%s: Exit", __func__);
return qdf_status;
diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c
index bf34359..2418d03 100644
--- a/core/wma/src/wma_mgmt.c
+++ b/core/wma/src/wma_mgmt.c
@@ -1839,6 +1839,11 @@
key_info->encType == eSIR_ED_WEP104)) {
wma_read_cfg_wepkey(wma_handle, key_info->key,
&def_key_idx, &key_info->numKeys);
+ } else if ((key_info->encType == eSIR_ED_WEP40) ||
+ (key_info->encType == eSIR_ED_WEP104)) {
+ struct wma_txrx_node *intf =
+ &wma_handle->interfaces[key_info->smesessionId];
+ key_params.def_key_idx = intf->wep_default_key_idx;
}
for (i = 0; i < key_info->numKeys; i++) {
diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c
index 242f8a2..8f54da2 100644
--- a/core/wma/src/wma_scan_roam.c
+++ b/core/wma/src/wma_scan_roam.c
@@ -1577,11 +1577,12 @@
{
int i;
QDF_STATUS status = QDF_STATUS_SUCCESS;
- uint32_t len = 0, num_bssid_black_list = 0, num_ssid_white_list = 0,
+ uint32_t num_bssid_black_list = 0, num_ssid_white_list = 0,
num_bssid_preferred_list = 0;
uint32_t op_bitmap = 0;
struct roam_ext_params *roam_params;
struct roam_scan_filter_params *params;
+ struct lca_disallow_config_params *lca_config_params;
params = qdf_mem_malloc(sizeof(struct roam_scan_filter_params));
if (params == NULL) {
@@ -1590,29 +1591,33 @@
}
roam_params = &roam_req->roam_params;
+ lca_config_params = &roam_req->lca_config_params;
if (roam_req->Command != ROAM_SCAN_OFFLOAD_STOP) {
switch (roam_req->reason) {
case REASON_ROAM_SET_BLACKLIST_BSSID:
op_bitmap |= 0x1;
num_bssid_black_list =
roam_params->num_bssid_avoid_list;
- len = num_bssid_black_list * sizeof(wmi_mac_addr);
- len += WMI_TLV_HDR_SIZE;
break;
case REASON_ROAM_SET_SSID_ALLOWED:
op_bitmap |= 0x2;
num_ssid_white_list =
roam_params->num_ssid_allowed_list;
- len = num_ssid_white_list * sizeof(wmi_ssid);
- len += WMI_TLV_HDR_SIZE;
break;
case REASON_ROAM_SET_FAVORED_BSSID:
op_bitmap |= 0x4;
num_bssid_preferred_list =
roam_params->num_bssid_favored;
- len = num_bssid_preferred_list * sizeof(wmi_mac_addr);
- len += WMI_TLV_HDR_SIZE;
- len += num_bssid_preferred_list * sizeof(A_UINT32);
+ break;
+ case REASON_CTX_INIT:
+ if (roam_req->Command == ROAM_SCAN_OFFLOAD_START) {
+ params->lca_disallow_config_present = true;
+ op_bitmap |= ROAM_FILTER_OP_BITMAP_LCA_DISALLOW;
+ } else {
+ WMA_LOGD("%s : Roam Filter need not be sent", __func__);
+ qdf_mem_free(params);
+ return QDF_STATUS_SUCCESS;
+ }
break;
default:
WMA_LOGD("%s : Roam Filter need not be sent", __func__);
@@ -1626,11 +1631,7 @@
*/
op_bitmap = 0x2 | 0x4;
num_ssid_white_list = roam_params->num_ssid_allowed_list;
- len = num_ssid_white_list * sizeof(wmi_ssid);
num_bssid_preferred_list = roam_params->num_bssid_favored;
- len += num_bssid_preferred_list * sizeof(wmi_mac_addr);
- len += num_bssid_preferred_list * sizeof(A_UINT32);
- len += (2 * WMI_TLV_HDR_SIZE);
}
/* fill in fixed values */
@@ -1639,7 +1640,6 @@
params->num_bssid_black_list = num_bssid_black_list;
params->num_ssid_white_list = num_ssid_white_list;
params->num_bssid_preferred_list = num_bssid_preferred_list;
- params->len = len;
qdf_mem_copy(params->bssid_avoid_list, roam_params->bssid_avoid_list,
MAX_BSSID_AVOID_LIST * sizeof(struct qdf_mac_addr));
@@ -1660,6 +1660,14 @@
qdf_mem_copy(params->bssid_favored_factor,
roam_params->bssid_favored_factor, MAX_BSSID_FAVORED);
+ if (params->lca_disallow_config_present) {
+ params->disallow_duration
+ = lca_config_params->disallow_duration;
+ params->rssi_channel_penalization
+ = lca_config_params->rssi_channel_penalization;
+ params->num_disallowed_aps
+ = lca_config_params->num_disallowed_aps;
+ }
status = wmi_unified_roam_scan_filter_cmd(wma_handle->wmi_handle,
params);
@@ -1858,6 +1866,33 @@
break;
case ROAM_SCAN_OFFLOAD_STOP:
+ /*
+ * If roam synch propagation is in progress and an user space
+ * disconnect is requested, then there is no need to send the
+ * RSO STOP to firmware, since the roaming is already complete.
+ * If the RSO STOP is sent to firmware, then an HO_FAIL will be
+ * generated and the expectation from firmware would be to
+ * clean up the peer context on the host and not send down any
+ * WMI PEER DELETE commands to firmware. But, if the user space
+ * disconnect gets processed first, then there is a chance to
+ * send down the PEER DELETE commands. Hence, if we do not
+ * receive the HO_FAIL, and we complete the roam sync
+ * propagation, then the host and firmware will be in sync with
+ * respect to the peer and then the user space disconnect can
+ * be handled gracefully in a normal way.
+ *
+ * Ensure to check the reason code since the RSO Stop might
+ * come when roam sync failed as well and at that point it
+ * should go through to the firmware and receive HO_FAIL
+ * and clean up.
+ */
+ if (wma_is_roam_synch_in_progress(wma_handle,
+ roam_req->sessionId) &&
+ roam_req->reason ==
+ REASON_ROAM_STOP_ALL) {
+ WMA_LOGD("Dont send RSO stop during roam sync");
+ break;
+ }
wma_handle->suitable_ap_hb_failure = false;
if (wma_handle->roam_offload_enabled) {
uint32_t mode;
@@ -2428,9 +2463,10 @@
wma->csr_roam_synch_cb((tpAniSirGlobal)wma->mac_context,
roam_synch_ind_ptr, NULL, SIR_ROAMING_ABORT);
roam_req = qdf_mem_malloc(sizeof(tSirRoamOffloadScanReq));
- if (roam_req) {
+ if (roam_req && synch_event) {
roam_req->Command = ROAM_SCAN_OFFLOAD_STOP;
roam_req->reason = REASON_ROAM_SYNCH_FAILED;
+ roam_req->sessionId = synch_event->vdev_id;
wma_process_roaming_config(wma, roam_req);
}
}
@@ -2967,7 +3003,7 @@
if (!QDF_IS_STATUS_SUCCESS(status))
WMA_LOGE("policy_mgr_get_current_hw_mode failed");
- if ((params->nss == 2) && !hw_mode.dbs_cap) {
+ if (params->nss == 2) {
req.preferred_rx_streams = 2;
req.preferred_tx_streams = 2;
} else {
diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c
index 1f7e307..7473d75 100644
--- a/core/wma/src/wma_utils.c
+++ b/core/wma/src/wma_utils.c
@@ -1064,9 +1064,26 @@
peer_stats[i].vdev_id = wmi_peer_signal->vdev_id;
peer_signal = &peer_stats[i].peer_signal_stats;
+ WMA_LOGD("%d antennas for peer %d",
+ wmi_peer_signal->num_chains_valid,
+ wmi_peer_signal->peer_id);
if (dst_len <= result_size) {
- qdf_mem_copy(peer_signal,
- &wmi_peer_signal->vdev_id, dst_len);
+ peer_signal->vdev_id = wmi_peer_signal->vdev_id;
+ peer_signal->peer_id = wmi_peer_signal->peer_id;
+ peer_signal->num_chain =
+ wmi_peer_signal->num_chains_valid;
+ qdf_mem_copy(peer_signal->per_ant_snr,
+ wmi_peer_signal->per_chain_snr,
+ sizeof(peer_signal->per_ant_snr));
+ qdf_mem_copy(peer_signal->nf,
+ wmi_peer_signal->per_chain_nf,
+ sizeof(peer_signal->nf));
+ qdf_mem_copy(peer_signal->per_ant_rx_mpdus,
+ wmi_peer_signal->per_antenna_rx_mpdus,
+ sizeof(peer_signal->per_ant_rx_mpdus));
+ qdf_mem_copy(peer_signal->per_ant_tx_mpdus,
+ wmi_peer_signal->per_antenna_tx_mpdus,
+ sizeof(peer_signal->per_ant_tx_mpdus));
result_size -= dst_len;
} else {
WMA_LOGE(FL("Invalid length of PEER signal."));
@@ -3637,6 +3654,7 @@
node->stats_rsp->statsMask, get_stats_param->sessionId);
cmd.session_id = get_stats_param->sessionId;
+ cmd.stats_mask = get_stats_param->statsMask;
if (wmi_unified_get_stats_cmd(wma_handle->wmi_handle, &cmd,
node->bssid)) {