qcacld-3.0: Add support for FW Offload component

This is for adding support for FW offload component. It is responsible
to offload all the ini params that are needed by the firmware. To have
this component, the new files added are

components/fw_offload/dispatcher/inc/cfg_fwol.h
components/fw_offload/dispatcher/inc/wlan_fwol_ucfg_api.h
components/fw_offload/dispatcher/src/wlan_fwol_ucfg_api.c
components/fw_offload/core/inc/wlan_fw_offload_main.h
components/fw_offload/core/src/wlan_fw_offload_main.c
components/fw_offload/dispatcher/inc/wlan_fw_offload_public_struct.h

The fw_offload_main.h is to take care of the public APIs for the
component. The corresponding .c file implements the init/deinit of
the component. The fw_offload_public_struct.h is to define the public
structures needed. The ucfg files are for the APIs that can be called
from other components. The cfg_fwol stores the INIs and CFGs.

Change-Id: I4405b87e6dec15aa94146f8ec550078c3d03b1e6
CRs-Fixed: 2307837
diff --git a/Kbuild b/Kbuild
index 1ae06d6..f250033 100644
--- a/Kbuild
+++ b/Kbuild
@@ -832,6 +832,14 @@
 		$(IPA_DIR)/core/src/wlan_ipa_rm.o
 endif
 
+######## FWOL ##########
+FWOL_DIR := components/fw_offload
+FWOL_INC := -I$(WLAN_ROOT)/$(FWOL_DIR)/core/inc \
+		-I$(WLAN_ROOT)/$(FWOL_DIR)/dispatcher/inc
+
+FWOL_OBJS :=	$(FWOL_DIR)/core/src/wlan_fw_offload_main.o \
+		$(FWOL_DIR)/dispatcher/src/wlan_fwol_ucfg_api.o
+
 
 ######## MLME ##############
 MLME_DIR := components/mlme
@@ -1617,6 +1625,7 @@
 
 INCS +=		$(IPA_INC)
 INCS +=		$(MLME_INC)
+INCS +=		$(FWOL_INC)
 
 ifeq ($(CONFIG_REMOVE_PKT_LOG), n)
 INCS +=		$(PKTLOG_INC)
@@ -1698,6 +1707,7 @@
 OBJS +=		$(UMAC_SER_OBJS)
 OBJS +=		$(PLD_OBJS)
 OBJS +=		$(MLME_OBJS)
+OBJS +=		$(FWOL_OBJS)
 
 ifeq ($(CONFIG_WLAN_FEATURE_DSRC), y)
 OBJS +=		$(OCB_OBJS)
diff --git a/components/cfg/cfg_all.h b/components/cfg/cfg_all.h
index d86c3a4..86eb368 100644
--- a/components/cfg/cfg_all.h
+++ b/components/cfg/cfg_all.h
@@ -19,6 +19,7 @@
 #include "cfg_define.h"
 #include "cfg_converged.h"
 #include "cfg_mlme.h"
+#include "cfg_fwol.h"
 
 #ifdef CONVERGED_P2P_ENABLE
 #include "wlan_p2p_cfg.h"
@@ -41,6 +42,7 @@
 /* Maintain Alphabetic order here while adding components */
 #define CFG_ALL \
 	CFG_CONVERGED_ALL \
+	CFG_FWOL_ALL \
 	CFG_MLME_ALL \
 	CFG_NAN_ALL \
 	CFG_P2P_ALL \
diff --git a/components/fw_offload/core/inc/wlan_fw_offload_main.h b/components/fw_offload/core/inc/wlan_fw_offload_main.h
new file mode 100644
index 0000000..a479691
--- /dev/null
+++ b/components/fw_offload/core/inc/wlan_fw_offload_main.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/**
+ * DOC: declare utility API related to the fw_offload component
+ * called by other components
+ */
+
+#ifndef _WLAN_FW_OFFLOAD_MAIN_H_
+#define _WLAN_FW_OFFLOAD_MAIN_H_
+
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_objmgr_global_obj.h>
+#include <wlan_cmn.h>
+
+#define fwol_alert(params...) QDF_TRACE_FATAL(QDF_MODULE_ID_FWOL, params)
+#define fwol_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_FWOL, params)
+#define fwol_warn(params...) QDF_TRACE_WARN(QDF_MODULE_ID_FWOL, params)
+#define fwol_info(params...) QDF_TRACE_INFO(QDF_MODULE_ID_FWOL, params)
+#define fwol_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_FWOL, params)
+
+/**
+ * struct wlan_fwol_cfg - fwol config items
+ */
+struct wlan_fwol_cfg {
+	/* Add CFG and INI items here */
+	int test;
+};
+
+/**
+ * struct wlan_fwol_psoc_obj - FW offload psoc priv object
+ * @cfg:     cfg items
+ */
+struct wlan_fwol_psoc_obj {
+	struct wlan_fwol_cfg cfg;
+};
+
+/**
+ * wlan_psoc_get_fwol_obj() - private API to get fwol object from psoc
+ * @psoc: psoc object
+ *
+ * Return: fwol object
+ */
+struct wlan_fwol_psoc_obj *fwol_get_psoc_obj(struct wlan_objmgr_psoc *psoc);
+
+/*
+ * fwol_cfg_on_psoc_enable() - Populate FWOL structure from CFG and INI
+ * @psoc: pointer to the psoc object
+ *
+ * Populate the FWOL CFG structure from CFG and INI values using CFG APIs
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS fwol_cfg_on_psoc_enable(struct wlan_objmgr_psoc *psoc);
+
+/*
+ * fwol_cfg_on_psoc_disable() - Clear the CFG structure on psoc disable
+ * @psoc: pointer to the psoc object
+ *
+ * Clear the FWOL CFG structure on psoc disable
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS fwol_cfg_on_psoc_disable(struct wlan_objmgr_psoc *psoc);
+#endif
diff --git a/components/fw_offload/core/src/wlan_fw_offload_main.c b/components/fw_offload/core/src/wlan_fw_offload_main.c
new file mode 100644
index 0000000..7c9cc28
--- /dev/null
+++ b/components/fw_offload/core/src/wlan_fw_offload_main.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/**
+ * DOC: define internal APIs related to the fwol component
+ */
+
+#include "wlan_fw_offload_main.h"
+#include "cfg_ucfg_api.h"
+
+struct wlan_fwol_psoc_obj *fwol_get_psoc_obj(struct wlan_objmgr_psoc *psoc)
+{
+	return wlan_objmgr_psoc_get_comp_private_obj(psoc,
+						     WLAN_UMAC_COMP_FWOL);
+}
+
+QDF_STATUS fwol_cfg_on_psoc_enable(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct wlan_fwol_psoc_obj *fwol_obj;
+	struct wlan_fwol_cfg *fwol_cfg;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj) {
+		fwol_err("Failed to get FWOL Obj");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	fwol_cfg = &fwol_obj->cfg;
+	/* Populate the CFG and INI here using CFG_GET */
+
+	return status;
+}
+
+QDF_STATUS fwol_cfg_on_psoc_disable(struct wlan_objmgr_psoc *psoc)
+{
+	/* Clear the CFG structure */
+	return QDF_STATUS_SUCCESS;
+}
diff --git a/components/fw_offload/dispatcher/inc/cfg_fwol.h b/components/fw_offload/dispatcher/inc/cfg_fwol.h
new file mode 100644
index 0000000..a6ee83b
--- /dev/null
+++ b/components/fw_offload/dispatcher/inc/cfg_fwol.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012 - 2018 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __CFG_FWOL_H
+#define __CFG_FWOL_H
+
+#include "cfg_define.h"
+#include "cfg_converged.h"
+#include "qdf_types.h"
+
+#define CFG_FWOL_ALL
+
+#endif /* __CFG_FWOL_H */
+
diff --git a/components/fw_offload/dispatcher/inc/wlan_fwol_ucfg_api.h b/components/fw_offload/dispatcher/inc/wlan_fwol_ucfg_api.h
new file mode 100644
index 0000000..418c451
--- /dev/null
+++ b/components/fw_offload/dispatcher/inc/wlan_fwol_ucfg_api.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/**
+ * DOC: declare internal API related to the fwol component
+ */
+
+#ifndef _WLAN_FWOL_UCFG_API_H_
+#define _WLAN_FWOL_UCFG_API_H_
+
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_objmgr_global_obj.h>
+#include <wlan_cmn.h>
+
+/**
+ * ucfg_fwol_psoc_open() - FWOL component Open
+ * @psoc: pointer to psoc object
+ *
+ * Open the FWOL component and initialize the FWOL structure
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS ucfg_fwol_psoc_open(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_fwol_psoc_close() - FWOL component close
+ * @psoc: pointer to psoc object
+ *
+ * Close the FWOL component and clear the FWOL structures
+ *
+ * Return: None
+ */
+void ucfg_fwol_psoc_close(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_fwol_init() - initialize fwol_ctx context.
+ *
+ * This function initializes the fwol context.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error
+ */
+QDF_STATUS ucfg_fwol_init(void);
+
+/**
+ * ucfg_fwol_deinit() - De initialize fwol_ctx context.
+ *
+ * This function De initializes fwol contex.
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success else return error
+ */
+void ucfg_fwol_deinit(void);
+
+#endif /* _WLAN_FWOL_UCFG_API_H_ */
diff --git a/components/fw_offload/dispatcher/src/wlan_fwol_ucfg_api.c b/components/fw_offload/dispatcher/src/wlan_fwol_ucfg_api.c
new file mode 100644
index 0000000..d9a5d3a
--- /dev/null
+++ b/components/fw_offload/dispatcher/src/wlan_fwol_ucfg_api.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/**
+ * DOC: define internal APIs related to the fwol component
+ */
+
+#include "cfg_ucfg_api.h"
+#include "wlan_fw_offload_main.h"
+#include "wlan_fwol_ucfg_api.h"
+
+QDF_STATUS ucfg_fwol_psoc_open(struct wlan_objmgr_psoc *psoc)
+{
+	QDF_STATUS status;
+
+	status = fwol_cfg_on_psoc_enable(psoc);
+	if (QDF_IS_STATUS_ERROR(status))
+		fwol_err("Failed to initialize FWOL CFG");
+
+	return status;
+}
+
+void ucfg_fwol_psoc_close(struct wlan_objmgr_psoc *psoc)
+{
+	/* Clear the FWOL CFG Structure */
+}
+
+/**
+ * fwol_psoc_object_created_notification(): fwol psoc create handler
+ * @psoc: psoc which is going to created by objmgr
+ * @arg: argument for vdev create handler
+ *
+ * Register this api with objmgr to detect psoc is created
+ *
+ * Return QDF_STATUS status in case of success else return error
+ */
+static QDF_STATUS
+fwol_psoc_object_created_notification(struct wlan_objmgr_psoc *psoc, void *arg)
+{
+	QDF_STATUS status;
+	struct wlan_fwol_psoc_obj *fwol_obj;
+
+	fwol_obj = qdf_mem_malloc(sizeof(*fwol_obj));
+	if (!fwol_obj)
+		return QDF_STATUS_E_NOMEM;
+
+	status = wlan_objmgr_psoc_component_obj_attach(psoc,
+						       WLAN_UMAC_COMP_FWOL,
+						       fwol_obj,
+						       QDF_STATUS_SUCCESS);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		fwol_err("Failed to attach psoc_ctx with psoc");
+		qdf_mem_free(fwol_obj);
+	}
+
+	return status;
+}
+
+/**
+ * fwol_psoc_object_destroyed_notification(): fwol psoc delete handler
+ * @psoc: psoc which is going to delete by objmgr
+ * @arg: argument for vdev delete handler
+ *
+ * Register this api with objmgr to detect psoc is deleted
+ *
+ * Return QDF_STATUS status in case of success else return error
+ */
+static QDF_STATUS fwol_psoc_object_destroyed_notification(
+		struct wlan_objmgr_psoc *psoc, void *arg)
+{
+	struct wlan_fwol_psoc_obj *fwol_obj;
+	QDF_STATUS status;
+
+	fwol_obj = fwol_get_psoc_obj(psoc);
+	if (!fwol_obj)
+		return QDF_STATUS_E_NOMEM;
+
+	status = wlan_objmgr_psoc_component_obj_detach(psoc,
+						       WLAN_UMAC_COMP_FWOL,
+						       fwol_obj);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		fwol_err("Failed to detach psoc_ctx from psoc");
+		return status;
+	}
+
+	qdf_mem_free(fwol_obj);
+
+	return status;
+}
+
+QDF_STATUS ucfg_fwol_init(void)
+{
+	QDF_STATUS status;
+
+	status = wlan_objmgr_register_psoc_create_handler(
+			WLAN_UMAC_COMP_FWOL,
+			fwol_psoc_object_created_notification,
+			NULL);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		fwol_err("unable to register psoc create handle");
+		return status;
+	}
+
+	status = wlan_objmgr_register_psoc_destroy_handler(
+			WLAN_UMAC_COMP_FWOL,
+			fwol_psoc_object_destroyed_notification,
+			NULL);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		fwol_err("unable to register psoc create handle");
+		wlan_objmgr_unregister_psoc_create_handler(
+			WLAN_UMAC_COMP_FWOL,
+			fwol_psoc_object_created_notification,
+			NULL);
+	}
+
+	return status;
+}
+
+void ucfg_fwol_deinit(void)
+{
+	QDF_STATUS status;
+
+	status = wlan_objmgr_unregister_psoc_destroy_handler(
+			WLAN_UMAC_COMP_FWOL,
+			fwol_psoc_object_destroyed_notification,
+			NULL);
+	if (QDF_IS_STATUS_ERROR(status))
+		fwol_err("unable to unregister psoc destroy handle");
+
+	status = wlan_objmgr_unregister_psoc_create_handler(
+			WLAN_UMAC_COMP_FWOL,
+			fwol_psoc_object_created_notification,
+			NULL);
+	if (QDF_IS_STATUS_ERROR(status))
+		fwol_err("unable to unregister psoc create handle");
+}
+
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index 146adf5..2064699 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -143,6 +143,7 @@
 #include <wlan_hdd_rssi_monitor.h>
 #include "wlan_mlme_ucfg_api.h"
 #include "wlan_mlme_public_struct.h"
+#include "wlan_fwol_ucfg_api.h"
 #ifdef CNSS_GENL
 #include <net/cnss_nl.h>
 #endif
@@ -304,6 +305,7 @@
 	[QDF_MODULE_ID_CONFIG] = {QDF_TRACE_LEVEL_ALL},
 	[QDF_MODULE_ID_MLME] = {QDF_TRACE_LEVEL_ALL},
 	[QDF_MODULE_ID_TARGET] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_FWOL] = {QDF_TRACE_LEVEL_ALL},
 };
 
 struct notifier_block hdd_netdev_notifier;
@@ -8830,6 +8832,7 @@
 	hdd_qdf_trace_enable(QDF_MODULE_ID_CP_STATS,
 				hdd_ctx->config->qdf_trace_enable_cp_stats);
 	hdd_qdf_trace_enable(QDF_MODULE_ID_MLME, 0xffff);
+	hdd_qdf_trace_enable(QDF_MODULE_ID_FWOL, 0xffff);
 
 	hdd_set_mtrace_for_each(hdd_ctx);
 
@@ -12539,8 +12542,9 @@
 static void component_init(void)
 {
 	ucfg_mlme_init();
-	pmo_init();
+	ucfg_fwol_init();
 	disa_init();
+	pmo_init();
 	ucfg_ocb_init();
 	ipa_init();
 	ucfg_action_oui_init();
@@ -12558,16 +12562,32 @@
 	ucfg_ocb_deinit();
 	pmo_deinit();
 	disa_deinit();
+	ucfg_fwol_deinit();
 	ucfg_mlme_deinit();
 }
 
 QDF_STATUS hdd_component_psoc_open(struct wlan_objmgr_psoc *psoc)
 {
-	return ucfg_mlme_psoc_open(psoc);
+	QDF_STATUS status;
+
+	status = ucfg_mlme_psoc_open(psoc);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	status = ucfg_fwol_psoc_open(psoc);
+	if (QDF_IS_STATUS_ERROR(status))
+		goto err;
+
+	return status;
+
+err:
+	ucfg_mlme_psoc_close(psoc);
+	return status;
 }
 
 void hdd_component_psoc_close(struct wlan_objmgr_psoc *psoc)
 {
+	ucfg_fwol_psoc_close(psoc);
 	ucfg_mlme_psoc_close(psoc);
 }