qcacld-3.0: Add WMA FIPS infrastructure

As part of the support for the FIPS certification feature add the
WMA infrastructure.

Change-Id: I7e113cee8ba9a08c2efd1141bef84e43d530cdcb
CRs-Fixed: 2065002
diff --git a/Kbuild b/Kbuild
index 9e04d6d..6bf4ffa 100644
--- a/Kbuild
+++ b/Kbuild
@@ -1359,6 +1359,9 @@
 ifeq ($(CONFIG_WLAN_FEATURE_DSRC), y)
 WMA_OBJS+=	$(WMA_SRC_DIR)/wma_ocb.o
 endif
+ifeq ($(CONFIG_WLAN_FEATURE_FIPS), y)
+WMA_OBJS+=	$(WMA_SRC_DIR)/wma_fips_api.o
+endif
 ifeq ($(CONFIG_MPC_UT_FRAMEWORK),y)
 WMA_OBJS +=	$(WMA_SRC_DIR)/wma_utils_ut.o
 endif
diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h
index 11b257c..e1bd679 100644
--- a/core/sme/inc/sme_api.h
+++ b/core/sme/inc/sme_api.h
@@ -45,6 +45,7 @@
 #include "cds_regdomain.h"
 #include "sme_internal.h"
 #include "wma_tgt_cfg.h"
+#include "wma_fips_public_structs.h"
 
 #include "sme_rrm_internal.h"
 #include "sir_types.h"
@@ -1322,6 +1323,28 @@
 		void *context);
 #endif
 
+#ifdef WLAN_FEATURE_FIPS
+/**
+ * sme_fips_request() - Perform a FIPS certification operation
+ * @hal: Hal handle for the object being certified
+ * @param: The FIPS certification parameters
+ * @callback: Callback function to invoke with the results
+ * @context: Opaque context to pass back to caller in the callback
+ *
+ * Return: QDF_STATUS_SUCCESS if the request is successfully sent
+ * to firmware for processing, otherwise an error status.
+ */
+QDF_STATUS sme_fips_request(tHalHandle hal, struct fips_params *param,
+			    wma_fips_cb callback, void *context);
+#else
+static inline
+QDF_STATUS sme_fips_request(tHalHandle hal, struct fips_params *param,
+			    wma_fips_cb callback, void *context)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+#endif /* WLAN_FEATURE_FIPS */
+
 /**
  * sme_set_cts2self_for_p2p_go() - sme function to set ini parms to FW.
  * @hal:                    reference to the HAL
diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c
index 4210a4a..7bd6194 100644
--- a/core/sme/src/common/sme_api.c
+++ b/core/sme/src/common/sme_api.c
@@ -45,6 +45,7 @@
 #include "csr_internal.h"
 #include "wma_types.h"
 #include "wma_if.h"
+#include "wma_fips_api.h"
 #include "qdf_trace.h"
 #include "sme_trace.h"
 #include "qdf_types.h"
@@ -15756,6 +15757,22 @@
 }
 #endif
 
+#ifdef WLAN_FEATURE_FIPS
+QDF_STATUS sme_fips_request(tHalHandle hal, struct fips_params *param,
+			    wma_fips_cb callback, void *context)
+{
+	void *wma_handle;
+
+	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+	if (!wma_handle) {
+		sme_err("wma handle is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return wma_fips_request(wma_handle, param, callback, context);
+}
+#endif
+
 QDF_STATUS sme_set_cts2self_for_p2p_go(tHalHandle hal_handle)
 {
 	void *wma_handle;
diff --git a/core/wma/src/wma_fips_api.c b/core/wma/src/wma_fips_api.c
new file mode 100644
index 0000000..1654685
--- /dev/null
+++ b/core/wma/src/wma_fips_api.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: wma_fips_api.c
+ *
+ * WLAN Host Device Driver FIPS Certification Feature
+ */
+
+#include "wma.h"
+#include "wma_fips_api.h"
+#include "wmi_unified_api.h"
+
+static wma_fips_cb fips_callback;
+static void *fips_context;
+
+static int
+wma_fips_event_handler(void *handle, uint8_t *event, uint32_t len)
+{
+	tp_wma_handle wma_handle;
+	wmi_unified_t wmi_handle;
+	struct wmi_host_fips_event_param param;
+	wma_fips_cb callback;
+	QDF_STATUS status;
+
+	WMA_LOGI(FL("handle:%p event:%p len:%u"), handle, event, len);
+
+	wma_handle = handle;
+	if (!wma_handle) {
+		WMA_LOGE(FL("NULL wma_handle"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wmi_handle = wma_handle->wmi_handle;
+	if (!wmi_handle) {
+		WMA_LOGE(FL("NULL wmi_handle"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = wmi_extract_fips_event_data(wmi_handle, event, &param);
+
+	WMA_LOGI(FL("Received FIPS event, pdev:%u status:%u data_len:%u"),
+		 param.pdev_id, param.error_status, param.data_len);
+
+	/* make sure extraction error is propagated to upper layers */
+	if (QDF_IS_STATUS_ERROR(status))
+		param.error_status = FIPS_ERROR_OPER_TIMEOUT;
+
+	callback = fips_callback;
+	fips_callback = NULL;
+	if (callback)
+		callback(fips_context, &param);
+
+	return 0;
+}
+
+QDF_STATUS wma_fips_request(WMA_HANDLE handle,
+			    struct fips_params *param,
+			    wma_fips_cb callback,
+			    void *context)
+{
+	tp_wma_handle wma_handle = handle;
+	wmi_unified_t wmi_handle;
+	QDF_STATUS status;
+
+	if (!wma_handle) {
+		WMA_LOGE(FL("NULL wma_handle"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wmi_handle = wma_handle->wmi_handle;
+	if (!wmi_handle) {
+		WMA_LOGE(FL("NULL wmi_handle"));
+		return QDF_STATUS_E_INVAL;
+	}
+
+	fips_callback = callback;
+	fips_context = context;
+	status = wmi_unified_pdev_fips_cmd_send(wmi_handle, param);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMA_LOGE(FL("wmi_unified_pdev_fips_cmd_send() error: %u"),
+			 status);
+		fips_callback = NULL;
+	}
+
+	return status;
+}
+
+QDF_STATUS wma_fips_register_event_handlers(WMA_HANDLE handle)
+{
+	tp_wma_handle wma_handle = handle;
+
+	return wmi_unified_register_event_handler(wma_handle->wmi_handle,
+						  WMI_PDEV_FIPS_EVENTID,
+						  wma_fips_event_handler,
+						  WMA_RX_SERIALIZER_CTX);
+}
diff --git a/core/wma/src/wma_fips_api.h b/core/wma/src/wma_fips_api.h
new file mode 100644
index 0000000..5ca0efb
--- /dev/null
+++ b/core/wma/src/wma_fips_api.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __WMA_FIPS_API_H
+#define __WMA_FIPS_API_H
+
+#include "wma_api.h"
+#include "wmi_unified_api.h"
+#include "wma_fips_public_structs.h"
+
+#ifdef WLAN_FEATURE_FIPS
+/**
+ * wma_fips_request() - Perform a FIPS certification operation
+ * @handle: WMA handle of the object being certified
+ * @param: The FIPS certification parameters
+ * @callback: Callback function to invoke with the results
+ * @context: Opaque context to pass back to caller in the callback
+ *
+ * Return: QDF_STATUS_SUCCESS if the request is successfully sent
+ * to firmware for processing, otherwise an error status.
+ */
+QDF_STATUS wma_fips_request(WMA_HANDLE handle,
+			    struct fips_params *param,
+			    wma_fips_cb callback,
+			    void *context);
+
+/**
+ * wma_fips_register_event_handlers() - Register FIPS event handlers
+ * @handle: WMA handle of the object being initialized
+ *
+ * This function registers all WMI event handlers required by the FIPS
+ * feature.
+ *
+ * Return: QDF_STATUS_SUCCESS upon success, otherwise an error
+ */
+QDF_STATUS wma_fips_register_event_handlers(WMA_HANDLE handle);
+
+#else /* WLAN_FEATURE_FIPS */
+
+static inline
+QDF_STATUS wma_fips_request(WMA_HANDLE handle,
+			    const struct fips_params *param,
+			    wma_fips_cb callback,
+			    void *context)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline
+QDF_STATUS wma_fips_register_event_handlers(WMA_HANDLE wma_handle)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+#endif /* WLAN_FEATURE_FIPS */
+
+#endif /* __WMA_FIPS_API_H */
diff --git a/core/wma/src/wma_fips_public_structs.h b/core/wma/src/wma_fips_public_structs.h
new file mode 100644
index 0000000..13c5999
--- /dev/null
+++ b/core/wma/src/wma_fips_public_structs.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __WMA_FIPS_PUBLIC_STRUCTS_H
+#define __WMA_FIPS_PUBLIC_STRUCTS_H
+
+struct wmi_host_fips_event_param;
+
+/**
+ * typedef wma_fips_cb() - FIPS callback function
+ * @context: Opaque context provided by caller in FIPS request
+ * @param: FIPS event parameters
+ */
+typedef void (*wma_fips_cb)(void *context,
+			    struct wmi_host_fips_event_param *param);
+
+#endif /* __WMA_FIPS_PUBLIC_STRUCTS_H */
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index 301058f..9a891f9 100644
--- a/core/wma/src/wma_main.c
+++ b/core/wma/src/wma_main.c
@@ -78,6 +78,7 @@
 #include "cdp_txrx_flow_ctrl_v2.h"
 #include "cdp_txrx_ipa.h"
 #include "cdp_txrx_misc.h"
+#include "wma_fips_api.h"
 #include "wma_nan_datapath.h"
 #include "wlan_lmac_if_def.h"
 #include "wlan_lmac_if_api.h"
@@ -3062,7 +3063,6 @@
 
 	WMA_LOGD("%s: Enter", __func__);
 
-	WMA_LOGD("%s: Enter", __func__);
 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
 	/* validate the wma_handle */
 	if (NULL == wma_handle) {
@@ -3219,6 +3219,13 @@
 		goto end;
 	}
 
+	status = wma_fips_register_event_handlers(wma_handle);
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		WMA_LOGE("Failed to register FIPS event handler");
+		qdf_status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+
 	/* Initialize the get temperature event handler */
 	status = wmi_unified_register_event_handler(wma_handle->wmi_handle,
 					WMI_PDEV_TEMPERATURE_EVENTID,