/*
 * Copyright (C) 2012-2017 ARM Limited or its affiliates.
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

/**************************************************************
This file defines the driver FIPS internal function, used by the driver itself.
***************************************************************/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <crypto/des.h>

#include "ssi_config.h"
#include "ssi_driver.h"
#include "cc_hal.h"


#define FIPS_POWER_UP_TEST_CIPHER	1
#define FIPS_POWER_UP_TEST_CMAC		1
#define FIPS_POWER_UP_TEST_HASH		1
#define FIPS_POWER_UP_TEST_HMAC		1
#define FIPS_POWER_UP_TEST_CCM		1
#define FIPS_POWER_UP_TEST_GCM		1

static bool ssi_fips_support = 1;
module_param(ssi_fips_support, bool, 0644);
MODULE_PARM_DESC(ssi_fips_support, "FIPS supported flag: 0 - off , 1 - on (default)");

static void fips_dsr(unsigned long devarg);

struct ssi_fips_handle {
#ifdef COMP_IN_WQ
	struct workqueue_struct *workq;
	struct delayed_work fipswork;
#else
	struct tasklet_struct fipstask;
#endif
};


extern int ssi_fips_get_state(ssi_fips_state_t *p_state);
extern int ssi_fips_get_error(ssi_fips_error_t *p_err);
extern int ssi_fips_ext_set_state(ssi_fips_state_t state);
extern int ssi_fips_ext_set_error(ssi_fips_error_t err);

/* FIPS power-up tests */
extern ssi_fips_error_t ssi_cipher_fips_power_up_tests(struct ssi_drvdata *drvdata, void *cpu_addr_buffer, dma_addr_t dma_coherent_buffer);
extern ssi_fips_error_t ssi_cmac_fips_power_up_tests(struct ssi_drvdata *drvdata, void *cpu_addr_buffer, dma_addr_t dma_coherent_buffer);
extern ssi_fips_error_t ssi_hash_fips_power_up_tests(struct ssi_drvdata *drvdata, void *cpu_addr_buffer, dma_addr_t dma_coherent_buffer);
extern ssi_fips_error_t ssi_hmac_fips_power_up_tests(struct ssi_drvdata *drvdata, void *cpu_addr_buffer, dma_addr_t dma_coherent_buffer);
extern ssi_fips_error_t ssi_ccm_fips_power_up_tests(struct ssi_drvdata *drvdata, void *cpu_addr_buffer, dma_addr_t dma_coherent_buffer);
extern ssi_fips_error_t ssi_gcm_fips_power_up_tests(struct ssi_drvdata *drvdata, void *cpu_addr_buffer, dma_addr_t dma_coherent_buffer);
extern size_t ssi_fips_max_mem_alloc_size(void);


/* The function called once at driver entry point to check whether TEE FIPS error occured.*/
static enum ssi_fips_error ssi_fips_get_tee_error(struct ssi_drvdata *drvdata)
{
	uint32_t regVal;
	void __iomem *cc_base = drvdata->cc_base;

	regVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, GPR_HOST));
	if (regVal == (CC_FIPS_SYNC_TEE_STATUS | CC_FIPS_SYNC_MODULE_OK)) {
		return CC_REE_FIPS_ERROR_OK;
	} 
	return CC_REE_FIPS_ERROR_FROM_TEE;
}


/* 
 This function should push the FIPS REE library status towards the TEE library.
 By writing the error state to HOST_GPR0 register. The function is called from  						.
 driver entry point so no need to protect by mutex.
*/
static void ssi_fips_update_tee_upon_ree_status(struct ssi_drvdata *drvdata, ssi_fips_error_t err)
{
	void __iomem *cc_base = drvdata->cc_base;
	if (err == CC_REE_FIPS_ERROR_OK) {
		CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_GPR0), (CC_FIPS_SYNC_REE_STATUS|CC_FIPS_SYNC_MODULE_OK));
	} else {
		CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_GPR0), (CC_FIPS_SYNC_REE_STATUS|CC_FIPS_SYNC_MODULE_ERROR));
	}
}



void ssi_fips_fini(struct ssi_drvdata *drvdata)
{
	struct ssi_fips_handle *fips_h = drvdata->fips_handle;

	if (fips_h == NULL)
		return; /* Not allocated */

#ifdef COMP_IN_WQ
	if (fips_h->workq != NULL) {
		flush_workqueue(fips_h->workq);
		destroy_workqueue(fips_h->workq);
	}
#else
	/* Kill tasklet */
	tasklet_kill(&fips_h->fipstask);
#endif
	memset(fips_h, 0, sizeof(struct ssi_fips_handle));
	kfree(fips_h);
	drvdata->fips_handle = NULL;
}

void fips_handler(struct ssi_drvdata *drvdata)
{
	struct ssi_fips_handle *fips_handle_ptr = 
						drvdata->fips_handle;
#ifdef COMP_IN_WQ
	queue_delayed_work(fips_handle_ptr->workq, &fips_handle_ptr->fipswork, 0);
#else
	tasklet_schedule(&fips_handle_ptr->fipstask);
#endif
}



#ifdef COMP_IN_WQ
static void fips_wq_handler(struct work_struct *work)
{
	struct ssi_drvdata *drvdata =
		container_of(work, struct ssi_drvdata, fipswork.work);

	fips_dsr((unsigned long)drvdata);
}
#endif

/* Deferred service handler, run as interrupt-fired tasklet */
static void fips_dsr(unsigned long devarg)
{
	struct ssi_drvdata *drvdata = (struct ssi_drvdata *)devarg;
	void __iomem *cc_base = drvdata->cc_base;
	uint32_t irq;
	uint32_t teeFipsError = 0;

	irq = (drvdata->irq & (SSI_GPR0_IRQ_MASK));

	if (irq & SSI_GPR0_IRQ_MASK) {
		teeFipsError = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, GPR_HOST));
		if (teeFipsError != (CC_FIPS_SYNC_TEE_STATUS | CC_FIPS_SYNC_MODULE_OK)) {
			ssi_fips_set_error(drvdata, CC_REE_FIPS_ERROR_FROM_TEE);
		} 
	}

	/* after verifing that there is nothing to do, Unmask AXI completion interrupt */
	CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR), 
		CC_HAL_READ_REGISTER(
		CC_REG_OFFSET(HOST_RGF, HOST_IMR)) & ~irq);
}


ssi_fips_error_t cc_fips_run_power_up_tests(struct ssi_drvdata *drvdata)
{
	ssi_fips_error_t fips_error = CC_REE_FIPS_ERROR_OK;
	void * cpu_addr_buffer = NULL;
	dma_addr_t dma_handle;
	size_t alloc_buff_size = ssi_fips_max_mem_alloc_size();
	struct device *dev = &drvdata->plat_dev->dev;

	// allocate memory using dma_alloc_coherent - for phisical, consecutive and cache coherent buffer (memory map is not needed)
	// the return value is the virtual address - use it to copy data into the buffer
	// the dma_handle is the returned phy address - use it in the HW descriptor
	FIPS_DBG("dma_alloc_coherent \n");
	cpu_addr_buffer = dma_alloc_coherent(dev, alloc_buff_size, &dma_handle, GFP_KERNEL);
	if (cpu_addr_buffer == NULL) {
		return CC_REE_FIPS_ERROR_GENERAL;
	}
	FIPS_DBG("allocated coherent buffer - addr 0x%08X , size = %d \n", (size_t)cpu_addr_buffer, alloc_buff_size);

#if FIPS_POWER_UP_TEST_CIPHER
	FIPS_DBG("ssi_cipher_fips_power_up_tests ...\n");
	fips_error = ssi_cipher_fips_power_up_tests(drvdata, cpu_addr_buffer, dma_handle);
	FIPS_DBG("ssi_cipher_fips_power_up_tests - done. (fips_error = %d) \n", fips_error);
#endif
#if FIPS_POWER_UP_TEST_CMAC
	if (likely(fips_error == CC_REE_FIPS_ERROR_OK)) {
		FIPS_DBG("ssi_cmac_fips_power_up_tests ...\n");
		fips_error = ssi_cmac_fips_power_up_tests(drvdata, cpu_addr_buffer, dma_handle);
		FIPS_DBG("ssi_cmac_fips_power_up_tests - done. (fips_error = %d) \n", fips_error);
	}
#endif
#if FIPS_POWER_UP_TEST_HASH
	if (likely(fips_error == CC_REE_FIPS_ERROR_OK)) {
		FIPS_DBG("ssi_hash_fips_power_up_tests ...\n");
		fips_error = ssi_hash_fips_power_up_tests(drvdata, cpu_addr_buffer, dma_handle);
		FIPS_DBG("ssi_hash_fips_power_up_tests - done. (fips_error = %d) \n", fips_error);
	}
#endif
#if FIPS_POWER_UP_TEST_HMAC
	if (likely(fips_error == CC_REE_FIPS_ERROR_OK)) {
		FIPS_DBG("ssi_hmac_fips_power_up_tests ...\n");
		fips_error = ssi_hmac_fips_power_up_tests(drvdata, cpu_addr_buffer, dma_handle);
		FIPS_DBG("ssi_hmac_fips_power_up_tests - done. (fips_error = %d) \n", fips_error);
	}
#endif
#if FIPS_POWER_UP_TEST_CCM
	if (likely(fips_error == CC_REE_FIPS_ERROR_OK)) {
		FIPS_DBG("ssi_ccm_fips_power_up_tests ...\n");
		fips_error = ssi_ccm_fips_power_up_tests(drvdata, cpu_addr_buffer, dma_handle);
		FIPS_DBG("ssi_ccm_fips_power_up_tests - done. (fips_error = %d) \n", fips_error);
	}
#endif
#if FIPS_POWER_UP_TEST_GCM
	if (likely(fips_error == CC_REE_FIPS_ERROR_OK)) {
		FIPS_DBG("ssi_gcm_fips_power_up_tests ...\n");
		fips_error = ssi_gcm_fips_power_up_tests(drvdata, cpu_addr_buffer, dma_handle);
		FIPS_DBG("ssi_gcm_fips_power_up_tests - done. (fips_error = %d) \n", fips_error);
	}
#endif
	/* deallocate the buffer when all tests are done... */
	FIPS_DBG("dma_free_coherent \n");
	dma_free_coherent(dev, alloc_buff_size, cpu_addr_buffer, dma_handle);

	return fips_error;
}



/* The function checks if FIPS supported and FIPS error exists.* 
*  It should be used in every driver API.*/
int ssi_fips_check_fips_error(void)
{
	ssi_fips_state_t fips_state; 

	if (ssi_fips_get_state(&fips_state) != 0) {
		FIPS_LOG("ssi_fips_get_state FAILED, returning.. \n");
		return -ENOEXEC;
	}
	if (fips_state == CC_FIPS_STATE_ERROR) {
		FIPS_LOG("ssi_fips_get_state: fips_state is %d, returning.. \n", fips_state);
		return -ENOEXEC;
	}
	return 0;
}


/* The function sets the REE FIPS state.* 
*  It should be used while driver is being loaded .*/
int ssi_fips_set_state(ssi_fips_state_t state)
{
	return ssi_fips_ext_set_state(state);
}

/* The function sets the REE FIPS error, and pushes the error to TEE library. * 
*  It should be used when any of the KAT tests fails .*/
int ssi_fips_set_error(struct ssi_drvdata *p_drvdata, ssi_fips_error_t err)
{
	int rc = 0;
        ssi_fips_error_t current_err;

        FIPS_LOG("ssi_fips_set_error - fips_error = %d \n", err);

	// setting no error is not allowed
	if (err == CC_REE_FIPS_ERROR_OK) {
                return -ENOEXEC;
	} 
        // If error exists, do not set new error
        if (ssi_fips_get_error(&current_err) != 0) {
                return -ENOEXEC;
        }
        if (current_err != CC_REE_FIPS_ERROR_OK) {
                return -ENOEXEC;
        }
        // set REE internal error and state
	rc = ssi_fips_ext_set_error(err);
	if (rc != 0) {
                return -ENOEXEC;
	}
	rc = ssi_fips_ext_set_state(CC_FIPS_STATE_ERROR);
	if (rc != 0) {
                return -ENOEXEC;
	}

        // push error towards TEE libraray, if it's not TEE error
	if (err != CC_REE_FIPS_ERROR_FROM_TEE) {
		ssi_fips_update_tee_upon_ree_status(p_drvdata, err);
	}
	return rc;
}


/* The function called once at driver entry point .*/
int ssi_fips_init(struct ssi_drvdata *p_drvdata)
{
	ssi_fips_error_t rc = CC_REE_FIPS_ERROR_OK;
	struct ssi_fips_handle *fips_h;

	FIPS_DBG("CC FIPS code ..  (fips=%d) \n", ssi_fips_support);

	fips_h = kzalloc(sizeof(struct ssi_fips_handle),GFP_KERNEL);
	if (fips_h == NULL) {
		ssi_fips_set_error(p_drvdata, CC_REE_FIPS_ERROR_GENERAL);
		return -ENOMEM;
	}

	p_drvdata->fips_handle = fips_h;

#ifdef COMP_IN_WQ
	SSI_LOG_DEBUG("Initializing fips workqueue\n");
	fips_h->workq = create_singlethread_workqueue("arm_cc7x_fips_wq");
	if (unlikely(fips_h->workq == NULL)) {
		SSI_LOG_ERR("Failed creating fips work queue\n");
		ssi_fips_set_error(p_drvdata, CC_REE_FIPS_ERROR_GENERAL);
		rc = -ENOMEM;
		goto ssi_fips_init_err;
	}
	INIT_DELAYED_WORK(&fips_h->fipswork, fips_wq_handler);
#else
	SSI_LOG_DEBUG("Initializing fips tasklet\n");
	tasklet_init(&fips_h->fipstask, fips_dsr, (unsigned long)p_drvdata);
#endif

	/* init fips driver data */
	rc = ssi_fips_set_state((ssi_fips_support == 0)? CC_FIPS_STATE_NOT_SUPPORTED : CC_FIPS_STATE_SUPPORTED);
	if (unlikely(rc != 0)) {
		ssi_fips_set_error(p_drvdata, CC_REE_FIPS_ERROR_GENERAL);
		rc = -EAGAIN;
		goto ssi_fips_init_err;
	}

	/* Run power up tests (before registration and operating the HW engines) */
	FIPS_DBG("ssi_fips_get_tee_error \n");
	rc = ssi_fips_get_tee_error(p_drvdata);
	if (unlikely(rc != CC_REE_FIPS_ERROR_OK)) {
		ssi_fips_set_error(p_drvdata, CC_REE_FIPS_ERROR_FROM_TEE);
		rc = -EAGAIN;
		goto ssi_fips_init_err;
	}

	FIPS_DBG("cc_fips_run_power_up_tests \n");
	rc = cc_fips_run_power_up_tests(p_drvdata);
	if (unlikely(rc != CC_REE_FIPS_ERROR_OK)) {
		ssi_fips_set_error(p_drvdata, rc);
		rc = -EAGAIN;
		goto ssi_fips_init_err;
	}
	FIPS_LOG("cc_fips_run_power_up_tests - done  ...  fips_error = %d \n", rc);

	/* when all tests passed, update TEE with fips OK status after power up tests */
	ssi_fips_update_tee_upon_ree_status(p_drvdata, CC_REE_FIPS_ERROR_OK);

	if (unlikely(rc != 0)) {
		rc = -EAGAIN;
		ssi_fips_set_error(p_drvdata, CC_REE_FIPS_ERROR_GENERAL);
		goto ssi_fips_init_err;
	}

	return 0;

ssi_fips_init_err:
	ssi_fips_fini(p_drvdata);
	return rc;
}

