/*
 * Cryptographic API.
 *
 * Support for SAHARA cryptographic accelerator.
 *
 * Copyright (c) 2014 Steffen Trumtrar <s.trumtrar@pengutronix.de>
 * Copyright (c) 2013 Vista Silicon S.L.
 * Author: Javier Martin <javier.martin@vista-silicon.com>
 *
 * 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.
 *
 * Based on omap-aes.c and tegra-aes.c
 */

#include <crypto/algapi.h>
#include <crypto/aes.h>
#include <crypto/hash.h>
#include <crypto/internal/hash.h>
#include <crypto/scatterwalk.h>
#include <crypto/sha.h>

#include <linux/clk.h>
#include <linux/crypto.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>

#define SHA_BUFFER_LEN		PAGE_SIZE
#define SAHARA_MAX_SHA_BLOCK_SIZE	SHA256_BLOCK_SIZE

#define SAHARA_NAME "sahara"
#define SAHARA_VERSION_3	3
#define SAHARA_VERSION_4	4
#define SAHARA_TIMEOUT_MS	1000
#define SAHARA_MAX_HW_DESC	2
#define SAHARA_MAX_HW_LINK	20

#define FLAGS_MODE_MASK		0x000f
#define FLAGS_ENCRYPT		BIT(0)
#define FLAGS_CBC		BIT(1)
#define FLAGS_NEW_KEY		BIT(3)

#define SAHARA_HDR_BASE			0x00800000
#define SAHARA_HDR_SKHA_ALG_AES	0
#define SAHARA_HDR_SKHA_OP_ENC		(1 << 2)
#define SAHARA_HDR_SKHA_MODE_ECB	(0 << 3)
#define SAHARA_HDR_SKHA_MODE_CBC	(1 << 3)
#define SAHARA_HDR_FORM_DATA		(5 << 16)
#define SAHARA_HDR_FORM_KEY		(8 << 16)
#define SAHARA_HDR_LLO			(1 << 24)
#define SAHARA_HDR_CHA_SKHA		(1 << 28)
#define SAHARA_HDR_CHA_MDHA		(2 << 28)
#define SAHARA_HDR_PARITY_BIT		(1 << 31)

#define SAHARA_HDR_MDHA_SET_MODE_MD_KEY	0x20880000
#define SAHARA_HDR_MDHA_SET_MODE_HASH	0x208D0000
#define SAHARA_HDR_MDHA_HASH		0xA0850000
#define SAHARA_HDR_MDHA_STORE_DIGEST	0x20820000
#define SAHARA_HDR_MDHA_ALG_SHA1	0
#define SAHARA_HDR_MDHA_ALG_MD5		1
#define SAHARA_HDR_MDHA_ALG_SHA256	2
#define SAHARA_HDR_MDHA_ALG_SHA224	3
#define SAHARA_HDR_MDHA_PDATA		(1 << 2)
#define SAHARA_HDR_MDHA_HMAC		(1 << 3)
#define SAHARA_HDR_MDHA_INIT		(1 << 5)
#define SAHARA_HDR_MDHA_IPAD		(1 << 6)
#define SAHARA_HDR_MDHA_OPAD		(1 << 7)
#define SAHARA_HDR_MDHA_SWAP		(1 << 8)
#define SAHARA_HDR_MDHA_MAC_FULL	(1 << 9)
#define SAHARA_HDR_MDHA_SSL		(1 << 10)

/* SAHARA can only process one request at a time */
#define SAHARA_QUEUE_LENGTH	1

#define SAHARA_REG_VERSION	0x00
#define SAHARA_REG_DAR		0x04
#define SAHARA_REG_CONTROL	0x08
#define		SAHARA_CONTROL_SET_THROTTLE(x)	(((x) & 0xff) << 24)
#define		SAHARA_CONTROL_SET_MAXBURST(x)	(((x) & 0xff) << 16)
#define		SAHARA_CONTROL_RNG_AUTORSD	(1 << 7)
#define		SAHARA_CONTROL_ENABLE_INT	(1 << 4)
#define SAHARA_REG_CMD		0x0C
#define		SAHARA_CMD_RESET		(1 << 0)
#define		SAHARA_CMD_CLEAR_INT		(1 << 8)
#define		SAHARA_CMD_CLEAR_ERR		(1 << 9)
#define		SAHARA_CMD_SINGLE_STEP		(1 << 10)
#define		SAHARA_CMD_MODE_BATCH		(1 << 16)
#define		SAHARA_CMD_MODE_DEBUG		(1 << 18)
#define	SAHARA_REG_STATUS	0x10
#define		SAHARA_STATUS_GET_STATE(x)	((x) & 0x7)
#define			SAHARA_STATE_IDLE	0
#define			SAHARA_STATE_BUSY	1
#define			SAHARA_STATE_ERR	2
#define			SAHARA_STATE_FAULT	3
#define			SAHARA_STATE_COMPLETE	4
#define			SAHARA_STATE_COMP_FLAG	(1 << 2)
#define		SAHARA_STATUS_DAR_FULL		(1 << 3)
#define		SAHARA_STATUS_ERROR		(1 << 4)
#define		SAHARA_STATUS_SECURE		(1 << 5)
#define		SAHARA_STATUS_FAIL		(1 << 6)
#define		SAHARA_STATUS_INIT		(1 << 7)
#define		SAHARA_STATUS_RNG_RESEED	(1 << 8)
#define		SAHARA_STATUS_ACTIVE_RNG	(1 << 9)
#define		SAHARA_STATUS_ACTIVE_MDHA	(1 << 10)
#define		SAHARA_STATUS_ACTIVE_SKHA	(1 << 11)
#define		SAHARA_STATUS_MODE_BATCH	(1 << 16)
#define		SAHARA_STATUS_MODE_DEDICATED	(1 << 17)
#define		SAHARA_STATUS_MODE_DEBUG	(1 << 18)
#define		SAHARA_STATUS_GET_ISTATE(x)	(((x) >> 24) & 0xff)
#define SAHARA_REG_ERRSTATUS	0x14
#define		SAHARA_ERRSTATUS_GET_SOURCE(x)	((x) & 0xf)
#define			SAHARA_ERRSOURCE_CHA	14
#define			SAHARA_ERRSOURCE_DMA	15
#define		SAHARA_ERRSTATUS_DMA_DIR	(1 << 8)
#define		SAHARA_ERRSTATUS_GET_DMASZ(x)(((x) >> 9) & 0x3)
#define		SAHARA_ERRSTATUS_GET_DMASRC(x) (((x) >> 13) & 0x7)
#define		SAHARA_ERRSTATUS_GET_CHASRC(x)	(((x) >> 16) & 0xfff)
#define		SAHARA_ERRSTATUS_GET_CHAERR(x)	(((x) >> 28) & 0x3)
#define SAHARA_REG_FADDR	0x18
#define SAHARA_REG_CDAR		0x1C
#define SAHARA_REG_IDAR		0x20

struct sahara_hw_desc {
	u32		hdr;
	u32		len1;
	dma_addr_t	p1;
	u32		len2;
	dma_addr_t	p2;
	dma_addr_t	next;
};

struct sahara_hw_link {
	u32		len;
	dma_addr_t	p;
	dma_addr_t	next;
};

struct sahara_ctx {
	unsigned long flags;

	/* AES-specific context */
	int keylen;
	u8 key[AES_KEYSIZE_128];
	struct crypto_ablkcipher *fallback;

	/* SHA-specific context */
	struct crypto_shash *shash_fallback;
};

struct sahara_aes_reqctx {
	unsigned long mode;
};

/*
 * struct sahara_sha_reqctx - private data per request
 * @buf: holds data for requests smaller than block_size
 * @rembuf: used to prepare one block_size-aligned request
 * @context: hw-specific context for request. Digest is extracted from this
 * @mode: specifies what type of hw-descriptor needs to be built
 * @digest_size: length of digest for this request
 * @context_size: length of hw-context for this request.
 *                Always digest_size + 4
 * @buf_cnt: number of bytes saved in buf
 * @sg_in_idx: number of hw links
 * @in_sg: scatterlist for input data
 * @in_sg_chain: scatterlists for chained input data
 * @in_sg_chained: specifies if chained scatterlists are used or not
 * @total: total number of bytes for transfer
 * @last: is this the last block
 * @first: is this the first block
 * @active: inside a transfer
 */
struct sahara_sha_reqctx {
	u8			buf[SAHARA_MAX_SHA_BLOCK_SIZE];
	u8			rembuf[SAHARA_MAX_SHA_BLOCK_SIZE];
	u8			context[SHA256_DIGEST_SIZE + 4];
	struct mutex		mutex;
	unsigned int		mode;
	unsigned int		digest_size;
	unsigned int		context_size;
	unsigned int		buf_cnt;
	unsigned int		sg_in_idx;
	struct scatterlist	*in_sg;
	struct scatterlist	in_sg_chain[2];
	bool			in_sg_chained;
	size_t			total;
	unsigned int		last;
	unsigned int		first;
	unsigned int		active;
};

struct sahara_dev {
	struct device		*device;
	unsigned int		version;
	void __iomem		*regs_base;
	struct clk		*clk_ipg;
	struct clk		*clk_ahb;
	struct mutex		queue_mutex;
	struct task_struct	*kthread;
	struct completion	dma_completion;

	struct sahara_ctx	*ctx;
	spinlock_t		lock;
	struct crypto_queue	queue;
	unsigned long		flags;

	struct sahara_hw_desc	*hw_desc[SAHARA_MAX_HW_DESC];
	dma_addr_t		hw_phys_desc[SAHARA_MAX_HW_DESC];

	u8			*key_base;
	dma_addr_t		key_phys_base;

	u8			*iv_base;
	dma_addr_t		iv_phys_base;

	u8			*context_base;
	dma_addr_t		context_phys_base;

	struct sahara_hw_link	*hw_link[SAHARA_MAX_HW_LINK];
	dma_addr_t		hw_phys_link[SAHARA_MAX_HW_LINK];

	size_t			total;
	struct scatterlist	*in_sg;
	unsigned int		nb_in_sg;
	struct scatterlist	*out_sg;
	unsigned int		nb_out_sg;

	u32			error;
};

static struct sahara_dev *dev_ptr;

static inline void sahara_write(struct sahara_dev *dev, u32 data, u32 reg)
{
	writel(data, dev->regs_base + reg);
}

static inline unsigned int sahara_read(struct sahara_dev *dev, u32 reg)
{
	return readl(dev->regs_base + reg);
}

static u32 sahara_aes_key_hdr(struct sahara_dev *dev)
{
	u32 hdr = SAHARA_HDR_BASE | SAHARA_HDR_SKHA_ALG_AES |
			SAHARA_HDR_FORM_KEY | SAHARA_HDR_LLO |
			SAHARA_HDR_CHA_SKHA | SAHARA_HDR_PARITY_BIT;

	if (dev->flags & FLAGS_CBC) {
		hdr |= SAHARA_HDR_SKHA_MODE_CBC;
		hdr ^= SAHARA_HDR_PARITY_BIT;
	}

	if (dev->flags & FLAGS_ENCRYPT) {
		hdr |= SAHARA_HDR_SKHA_OP_ENC;
		hdr ^= SAHARA_HDR_PARITY_BIT;
	}

	return hdr;
}

static u32 sahara_aes_data_link_hdr(struct sahara_dev *dev)
{
	return SAHARA_HDR_BASE | SAHARA_HDR_FORM_DATA |
			SAHARA_HDR_CHA_SKHA | SAHARA_HDR_PARITY_BIT;
}

static int sahara_sg_length(struct scatterlist *sg,
			    unsigned int total)
{
	int sg_nb;
	unsigned int len;
	struct scatterlist *sg_list;

	sg_nb = 0;
	sg_list = sg;

	while (total) {
		len = min(sg_list->length, total);

		sg_nb++;
		total -= len;

		sg_list = sg_next(sg_list);
		if (!sg_list)
			total = 0;
	}

	return sg_nb;
}

static char *sahara_err_src[16] = {
	"No error",
	"Header error",
	"Descriptor length error",
	"Descriptor length or pointer error",
	"Link length error",
	"Link pointer error",
	"Input buffer error",
	"Output buffer error",
	"Output buffer starvation",
	"Internal state fault",
	"General descriptor problem",
	"Reserved",
	"Descriptor address error",
	"Link address error",
	"CHA error",
	"DMA error"
};

static char *sahara_err_dmasize[4] = {
	"Byte transfer",
	"Half-word transfer",
	"Word transfer",
	"Reserved"
};

static char *sahara_err_dmasrc[8] = {
	"No error",
	"AHB bus error",
	"Internal IP bus error",
	"Parity error",
	"DMA crosses 256 byte boundary",
	"DMA is busy",
	"Reserved",
	"DMA HW error"
};

static char *sahara_cha_errsrc[12] = {
	"Input buffer non-empty",
	"Illegal address",
	"Illegal mode",
	"Illegal data size",
	"Illegal key size",
	"Write during processing",
	"CTX read during processing",
	"HW error",
	"Input buffer disabled/underflow",
	"Output buffer disabled/overflow",
	"DES key parity error",
	"Reserved"
};

static char *sahara_cha_err[4] = { "No error", "SKHA", "MDHA", "RNG" };

static void sahara_decode_error(struct sahara_dev *dev, unsigned int error)
{
	u8 source = SAHARA_ERRSTATUS_GET_SOURCE(error);
	u16 chasrc = ffs(SAHARA_ERRSTATUS_GET_CHASRC(error));

	dev_err(dev->device, "%s: Error Register = 0x%08x\n", __func__, error);

	dev_err(dev->device, "	- %s.\n", sahara_err_src[source]);

	if (source == SAHARA_ERRSOURCE_DMA) {
		if (error & SAHARA_ERRSTATUS_DMA_DIR)
			dev_err(dev->device, "		* DMA read.\n");
		else
			dev_err(dev->device, "		* DMA write.\n");

		dev_err(dev->device, "		* %s.\n",
		       sahara_err_dmasize[SAHARA_ERRSTATUS_GET_DMASZ(error)]);
		dev_err(dev->device, "		* %s.\n",
		       sahara_err_dmasrc[SAHARA_ERRSTATUS_GET_DMASRC(error)]);
	} else if (source == SAHARA_ERRSOURCE_CHA) {
		dev_err(dev->device, "		* %s.\n",
			sahara_cha_errsrc[chasrc]);
		dev_err(dev->device, "		* %s.\n",
		       sahara_cha_err[SAHARA_ERRSTATUS_GET_CHAERR(error)]);
	}
	dev_err(dev->device, "\n");
}

static char *sahara_state[4] = { "Idle", "Busy", "Error", "HW Fault" };

static void sahara_decode_status(struct sahara_dev *dev, unsigned int status)
{
	u8 state;

	if (!IS_ENABLED(DEBUG))
		return;

	state = SAHARA_STATUS_GET_STATE(status);

	dev_dbg(dev->device, "%s: Status Register = 0x%08x\n",
		__func__, status);

	dev_dbg(dev->device, "	- State = %d:\n", state);
	if (state & SAHARA_STATE_COMP_FLAG)
		dev_dbg(dev->device, "		* Descriptor completed. IRQ pending.\n");

	dev_dbg(dev->device, "		* %s.\n",
	       sahara_state[state & ~SAHARA_STATE_COMP_FLAG]);

	if (status & SAHARA_STATUS_DAR_FULL)
		dev_dbg(dev->device, "	- DAR Full.\n");
	if (status & SAHARA_STATUS_ERROR)
		dev_dbg(dev->device, "	- Error.\n");
	if (status & SAHARA_STATUS_SECURE)
		dev_dbg(dev->device, "	- Secure.\n");
	if (status & SAHARA_STATUS_FAIL)
		dev_dbg(dev->device, "	- Fail.\n");
	if (status & SAHARA_STATUS_RNG_RESEED)
		dev_dbg(dev->device, "	- RNG Reseed Request.\n");
	if (status & SAHARA_STATUS_ACTIVE_RNG)
		dev_dbg(dev->device, "	- RNG Active.\n");
	if (status & SAHARA_STATUS_ACTIVE_MDHA)
		dev_dbg(dev->device, "	- MDHA Active.\n");
	if (status & SAHARA_STATUS_ACTIVE_SKHA)
		dev_dbg(dev->device, "	- SKHA Active.\n");

	if (status & SAHARA_STATUS_MODE_BATCH)
		dev_dbg(dev->device, "	- Batch Mode.\n");
	else if (status & SAHARA_STATUS_MODE_DEDICATED)
		dev_dbg(dev->device, "	- Decidated Mode.\n");
	else if (status & SAHARA_STATUS_MODE_DEBUG)
		dev_dbg(dev->device, "	- Debug Mode.\n");

	dev_dbg(dev->device, "	- Internal state = 0x%02x\n",
	       SAHARA_STATUS_GET_ISTATE(status));

	dev_dbg(dev->device, "Current DAR: 0x%08x\n",
		sahara_read(dev, SAHARA_REG_CDAR));
	dev_dbg(dev->device, "Initial DAR: 0x%08x\n\n",
		sahara_read(dev, SAHARA_REG_IDAR));
}

static void sahara_dump_descriptors(struct sahara_dev *dev)
{
	int i;

	if (!IS_ENABLED(DEBUG))
		return;

	for (i = 0; i < SAHARA_MAX_HW_DESC; i++) {
		dev_dbg(dev->device, "Descriptor (%d) (0x%08x):\n",
			i, dev->hw_phys_desc[i]);
		dev_dbg(dev->device, "\thdr = 0x%08x\n", dev->hw_desc[i]->hdr);
		dev_dbg(dev->device, "\tlen1 = %u\n", dev->hw_desc[i]->len1);
		dev_dbg(dev->device, "\tp1 = 0x%08x\n", dev->hw_desc[i]->p1);
		dev_dbg(dev->device, "\tlen2 = %u\n", dev->hw_desc[i]->len2);
		dev_dbg(dev->device, "\tp2 = 0x%08x\n", dev->hw_desc[i]->p2);
		dev_dbg(dev->device, "\tnext = 0x%08x\n",
			dev->hw_desc[i]->next);
	}
	dev_dbg(dev->device, "\n");
}

static void sahara_dump_links(struct sahara_dev *dev)
{
	int i;

	if (!IS_ENABLED(DEBUG))
		return;

	for (i = 0; i < SAHARA_MAX_HW_LINK; i++) {
		dev_dbg(dev->device, "Link (%d) (0x%08x):\n",
			i, dev->hw_phys_link[i]);
		dev_dbg(dev->device, "\tlen = %u\n", dev->hw_link[i]->len);
		dev_dbg(dev->device, "\tp = 0x%08x\n", dev->hw_link[i]->p);
		dev_dbg(dev->device, "\tnext = 0x%08x\n",
			dev->hw_link[i]->next);
	}
	dev_dbg(dev->device, "\n");
}

static int sahara_hw_descriptor_create(struct sahara_dev *dev)
{
	struct sahara_ctx *ctx = dev->ctx;
	struct scatterlist *sg;
	int ret;
	int i, j;
	int idx = 0;

	/* Copy new key if necessary */
	if (ctx->flags & FLAGS_NEW_KEY) {
		memcpy(dev->key_base, ctx->key, ctx->keylen);
		ctx->flags &= ~FLAGS_NEW_KEY;

		if (dev->flags & FLAGS_CBC) {
			dev->hw_desc[idx]->len1 = AES_BLOCK_SIZE;
			dev->hw_desc[idx]->p1 = dev->iv_phys_base;
		} else {
			dev->hw_desc[idx]->len1 = 0;
			dev->hw_desc[idx]->p1 = 0;
		}
		dev->hw_desc[idx]->len2 = ctx->keylen;
		dev->hw_desc[idx]->p2 = dev->key_phys_base;
		dev->hw_desc[idx]->next = dev->hw_phys_desc[1];

		dev->hw_desc[idx]->hdr = sahara_aes_key_hdr(dev);

		idx++;
	}

	dev->nb_in_sg = sahara_sg_length(dev->in_sg, dev->total);
	dev->nb_out_sg = sahara_sg_length(dev->out_sg, dev->total);
	if ((dev->nb_in_sg + dev->nb_out_sg) > SAHARA_MAX_HW_LINK) {
		dev_err(dev->device, "not enough hw links (%d)\n",
			dev->nb_in_sg + dev->nb_out_sg);
		return -EINVAL;
	}

	ret = dma_map_sg(dev->device, dev->in_sg, dev->nb_in_sg,
			 DMA_TO_DEVICE);
	if (ret != dev->nb_in_sg) {
		dev_err(dev->device, "couldn't map in sg\n");
		goto unmap_in;
	}
	ret = dma_map_sg(dev->device, dev->out_sg, dev->nb_out_sg,
			 DMA_FROM_DEVICE);
	if (ret != dev->nb_out_sg) {
		dev_err(dev->device, "couldn't map out sg\n");
		goto unmap_out;
	}

	/* Create input links */
	dev->hw_desc[idx]->p1 = dev->hw_phys_link[0];
	sg = dev->in_sg;
	for (i = 0; i < dev->nb_in_sg; i++) {
		dev->hw_link[i]->len = sg->length;
		dev->hw_link[i]->p = sg->dma_address;
		if (i == (dev->nb_in_sg - 1)) {
			dev->hw_link[i]->next = 0;
		} else {
			dev->hw_link[i]->next = dev->hw_phys_link[i + 1];
			sg = sg_next(sg);
		}
	}

	/* Create output links */
	dev->hw_desc[idx]->p2 = dev->hw_phys_link[i];
	sg = dev->out_sg;
	for (j = i; j < dev->nb_out_sg + i; j++) {
		dev->hw_link[j]->len = sg->length;
		dev->hw_link[j]->p = sg->dma_address;
		if (j == (dev->nb_out_sg + i - 1)) {
			dev->hw_link[j]->next = 0;
		} else {
			dev->hw_link[j]->next = dev->hw_phys_link[j + 1];
			sg = sg_next(sg);
		}
	}

	/* Fill remaining fields of hw_desc[1] */
	dev->hw_desc[idx]->hdr = sahara_aes_data_link_hdr(dev);
	dev->hw_desc[idx]->len1 = dev->total;
	dev->hw_desc[idx]->len2 = dev->total;
	dev->hw_desc[idx]->next = 0;

	sahara_dump_descriptors(dev);
	sahara_dump_links(dev);

	sahara_write(dev, dev->hw_phys_desc[0], SAHARA_REG_DAR);

	return 0;

unmap_out:
	dma_unmap_sg(dev->device, dev->out_sg, dev->nb_out_sg,
		DMA_TO_DEVICE);
unmap_in:
	dma_unmap_sg(dev->device, dev->in_sg, dev->nb_in_sg,
		DMA_FROM_DEVICE);

	return -EINVAL;
}

static int sahara_aes_process(struct ablkcipher_request *req)
{
	struct sahara_dev *dev = dev_ptr;
	struct sahara_ctx *ctx;
	struct sahara_aes_reqctx *rctx;
	int ret;
	unsigned long timeout;

	/* Request is ready to be dispatched by the device */
	dev_dbg(dev->device,
		"dispatch request (nbytes=%d, src=%p, dst=%p)\n",
		req->nbytes, req->src, req->dst);

	/* assign new request to device */
	dev->total = req->nbytes;
	dev->in_sg = req->src;
	dev->out_sg = req->dst;

	rctx = ablkcipher_request_ctx(req);
	ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(req));
	rctx->mode &= FLAGS_MODE_MASK;
	dev->flags = (dev->flags & ~FLAGS_MODE_MASK) | rctx->mode;

	if ((dev->flags & FLAGS_CBC) && req->info)
		memcpy(dev->iv_base, req->info, AES_KEYSIZE_128);

	/* assign new context to device */
	dev->ctx = ctx;

	reinit_completion(&dev->dma_completion);

	ret = sahara_hw_descriptor_create(dev);
	if (ret)
		return -EINVAL;

	timeout = wait_for_completion_timeout(&dev->dma_completion,
				msecs_to_jiffies(SAHARA_TIMEOUT_MS));
	if (!timeout) {
		dev_err(dev->device, "AES timeout\n");
		return -ETIMEDOUT;
	}

	dma_unmap_sg(dev->device, dev->out_sg, dev->nb_out_sg,
		DMA_TO_DEVICE);
	dma_unmap_sg(dev->device, dev->in_sg, dev->nb_in_sg,
		DMA_FROM_DEVICE);

	return 0;
}

static int sahara_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
			     unsigned int keylen)
{
	struct sahara_ctx *ctx = crypto_ablkcipher_ctx(tfm);
	int ret;

	ctx->keylen = keylen;

	/* SAHARA only supports 128bit keys */
	if (keylen == AES_KEYSIZE_128) {
		memcpy(ctx->key, key, keylen);
		ctx->flags |= FLAGS_NEW_KEY;
		return 0;
	}

	if (keylen != AES_KEYSIZE_128 &&
	    keylen != AES_KEYSIZE_192 && keylen != AES_KEYSIZE_256)
		return -EINVAL;

	/*
	 * The requested key size is not supported by HW, do a fallback.
	 */
	ctx->fallback->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
	ctx->fallback->base.crt_flags |=
		(tfm->base.crt_flags & CRYPTO_TFM_REQ_MASK);

	ret = crypto_ablkcipher_setkey(ctx->fallback, key, keylen);
	if (ret) {
		struct crypto_tfm *tfm_aux = crypto_ablkcipher_tfm(tfm);

		tfm_aux->crt_flags &= ~CRYPTO_TFM_RES_MASK;
		tfm_aux->crt_flags |=
			(ctx->fallback->base.crt_flags & CRYPTO_TFM_RES_MASK);
	}
	return ret;
}

static int sahara_aes_crypt(struct ablkcipher_request *req, unsigned long mode)
{
	struct sahara_aes_reqctx *rctx = ablkcipher_request_ctx(req);
	struct sahara_dev *dev = dev_ptr;
	int err = 0;

	dev_dbg(dev->device, "nbytes: %d, enc: %d, cbc: %d\n",
		req->nbytes, !!(mode & FLAGS_ENCRYPT), !!(mode & FLAGS_CBC));

	if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE)) {
		dev_err(dev->device,
			"request size is not exact amount of AES blocks\n");
		return -EINVAL;
	}

	rctx->mode = mode;

	mutex_lock(&dev->queue_mutex);
	err = ablkcipher_enqueue_request(&dev->queue, req);
	mutex_unlock(&dev->queue_mutex);

	wake_up_process(dev->kthread);

	return err;
}

static int sahara_aes_ecb_encrypt(struct ablkcipher_request *req)
{
	struct crypto_tfm *tfm =
		crypto_ablkcipher_tfm(crypto_ablkcipher_reqtfm(req));
	struct sahara_ctx *ctx = crypto_ablkcipher_ctx(
		crypto_ablkcipher_reqtfm(req));
	int err;

	if (unlikely(ctx->keylen != AES_KEYSIZE_128)) {
		ablkcipher_request_set_tfm(req, ctx->fallback);
		err = crypto_ablkcipher_encrypt(req);
		ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(tfm));
		return err;
	}

	return sahara_aes_crypt(req, FLAGS_ENCRYPT);
}

static int sahara_aes_ecb_decrypt(struct ablkcipher_request *req)
{
	struct crypto_tfm *tfm =
		crypto_ablkcipher_tfm(crypto_ablkcipher_reqtfm(req));
	struct sahara_ctx *ctx = crypto_ablkcipher_ctx(
		crypto_ablkcipher_reqtfm(req));
	int err;

	if (unlikely(ctx->keylen != AES_KEYSIZE_128)) {
		ablkcipher_request_set_tfm(req, ctx->fallback);
		err = crypto_ablkcipher_decrypt(req);
		ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(tfm));
		return err;
	}

	return sahara_aes_crypt(req, 0);
}

static int sahara_aes_cbc_encrypt(struct ablkcipher_request *req)
{
	struct crypto_tfm *tfm =
		crypto_ablkcipher_tfm(crypto_ablkcipher_reqtfm(req));
	struct sahara_ctx *ctx = crypto_ablkcipher_ctx(
		crypto_ablkcipher_reqtfm(req));
	int err;

	if (unlikely(ctx->keylen != AES_KEYSIZE_128)) {
		ablkcipher_request_set_tfm(req, ctx->fallback);
		err = crypto_ablkcipher_encrypt(req);
		ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(tfm));
		return err;
	}

	return sahara_aes_crypt(req, FLAGS_ENCRYPT | FLAGS_CBC);
}

static int sahara_aes_cbc_decrypt(struct ablkcipher_request *req)
{
	struct crypto_tfm *tfm =
		crypto_ablkcipher_tfm(crypto_ablkcipher_reqtfm(req));
	struct sahara_ctx *ctx = crypto_ablkcipher_ctx(
		crypto_ablkcipher_reqtfm(req));
	int err;

	if (unlikely(ctx->keylen != AES_KEYSIZE_128)) {
		ablkcipher_request_set_tfm(req, ctx->fallback);
		err = crypto_ablkcipher_decrypt(req);
		ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(tfm));
		return err;
	}

	return sahara_aes_crypt(req, FLAGS_CBC);
}

static int sahara_aes_cra_init(struct crypto_tfm *tfm)
{
	const char *name = crypto_tfm_alg_name(tfm);
	struct sahara_ctx *ctx = crypto_tfm_ctx(tfm);

	ctx->fallback = crypto_alloc_ablkcipher(name, 0,
				CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK);
	if (IS_ERR(ctx->fallback)) {
		pr_err("Error allocating fallback algo %s\n", name);
		return PTR_ERR(ctx->fallback);
	}

	tfm->crt_ablkcipher.reqsize = sizeof(struct sahara_aes_reqctx);

	return 0;
}

static void sahara_aes_cra_exit(struct crypto_tfm *tfm)
{
	struct sahara_ctx *ctx = crypto_tfm_ctx(tfm);

	if (ctx->fallback)
		crypto_free_ablkcipher(ctx->fallback);
	ctx->fallback = NULL;
}

static u32 sahara_sha_init_hdr(struct sahara_dev *dev,
			      struct sahara_sha_reqctx *rctx)
{
	u32 hdr = 0;

	hdr = rctx->mode;

	if (rctx->first) {
		hdr |= SAHARA_HDR_MDHA_SET_MODE_HASH;
		hdr |= SAHARA_HDR_MDHA_INIT;
	} else {
		hdr |= SAHARA_HDR_MDHA_SET_MODE_MD_KEY;
	}

	if (rctx->last)
		hdr |= SAHARA_HDR_MDHA_PDATA;

	if (hweight_long(hdr) % 2 == 0)
		hdr |= SAHARA_HDR_PARITY_BIT;

	return hdr;
}

static int sahara_sha_hw_links_create(struct sahara_dev *dev,
				       struct sahara_sha_reqctx *rctx,
				       int start)
{
	struct scatterlist *sg;
	unsigned int i;
	int ret;

	dev->in_sg = rctx->in_sg;

	dev->nb_in_sg = sahara_sg_length(dev->in_sg, rctx->total);
	if ((dev->nb_in_sg) > SAHARA_MAX_HW_LINK) {
		dev_err(dev->device, "not enough hw links (%d)\n",
			dev->nb_in_sg + dev->nb_out_sg);
		return -EINVAL;
	}

	if (rctx->in_sg_chained) {
		i = start;
		sg = dev->in_sg;
		while (sg) {
			ret = dma_map_sg(dev->device, sg, 1,
					 DMA_TO_DEVICE);
			if (!ret)
				return -EFAULT;

			dev->hw_link[i]->len = sg->length;
			dev->hw_link[i]->p = sg->dma_address;
			dev->hw_link[i]->next = dev->hw_phys_link[i + 1];
			sg = sg_next(sg);
			i += 1;
		}
		dev->hw_link[i-1]->next = 0;
	} else {
		sg = dev->in_sg;
		ret = dma_map_sg(dev->device, dev->in_sg, dev->nb_in_sg,
				 DMA_TO_DEVICE);
		if (!ret)
			return -EFAULT;

		for (i = start; i < dev->nb_in_sg + start; i++) {
			dev->hw_link[i]->len = sg->length;
			dev->hw_link[i]->p = sg->dma_address;
			if (i == (dev->nb_in_sg + start - 1)) {
				dev->hw_link[i]->next = 0;
			} else {
				dev->hw_link[i]->next = dev->hw_phys_link[i + 1];
				sg = sg_next(sg);
			}
		}
	}

	return i;
}

static int sahara_sha_hw_data_descriptor_create(struct sahara_dev *dev,
						struct sahara_sha_reqctx *rctx,
						struct ahash_request *req,
						int index)
{
	unsigned result_len;
	int i = index;

	if (rctx->first)
		/* Create initial descriptor: #8*/
		dev->hw_desc[index]->hdr = sahara_sha_init_hdr(dev, rctx);
	else
		/* Create hash descriptor: #10. Must follow #6. */
		dev->hw_desc[index]->hdr = SAHARA_HDR_MDHA_HASH;

	dev->hw_desc[index]->len1 = rctx->total;
	if (dev->hw_desc[index]->len1 == 0) {
		/* if len1 is 0, p1 must be 0, too */
		dev->hw_desc[index]->p1 = 0;
		rctx->sg_in_idx = 0;
	} else {
		/* Create input links */
		dev->hw_desc[index]->p1 = dev->hw_phys_link[index];
		i = sahara_sha_hw_links_create(dev, rctx, index);

		rctx->sg_in_idx = index;
		if (i < 0)
			return i;
	}

	dev->hw_desc[index]->p2 = dev->hw_phys_link[i];

	/* Save the context for the next operation */
	result_len = rctx->context_size;
	dev->hw_link[i]->p = dev->context_phys_base;

	dev->hw_link[i]->len = result_len;
	dev->hw_desc[index]->len2 = result_len;

	dev->hw_link[i]->next = 0;

	return 0;
}

/*
 * Load descriptor aka #6
 *
 * To load a previously saved context back to the MDHA unit
 *
 * p1: Saved Context
 * p2: NULL
 *
 */
static int sahara_sha_hw_context_descriptor_create(struct sahara_dev *dev,
						struct sahara_sha_reqctx *rctx,
						struct ahash_request *req,
						int index)
{
	dev->hw_desc[index]->hdr = sahara_sha_init_hdr(dev, rctx);

	dev->hw_desc[index]->len1 = rctx->context_size;
	dev->hw_desc[index]->p1 = dev->hw_phys_link[index];
	dev->hw_desc[index]->len2 = 0;
	dev->hw_desc[index]->p2 = 0;

	dev->hw_link[index]->len = rctx->context_size;
	dev->hw_link[index]->p = dev->context_phys_base;
	dev->hw_link[index]->next = 0;

	return 0;
}

static int sahara_walk_and_recalc(struct scatterlist *sg, unsigned int nbytes)
{
	if (!sg || !sg->length)
		return nbytes;

	while (nbytes && sg) {
		if (nbytes <= sg->length) {
			sg->length = nbytes;
			sg_mark_end(sg);
			break;
		}
		nbytes -= sg->length;
		sg = sg_next(sg);
	}

	return nbytes;
}

static int sahara_sha_prepare_request(struct ahash_request *req)
{
	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
	struct sahara_sha_reqctx *rctx = ahash_request_ctx(req);
	unsigned int hash_later;
	unsigned int block_size;
	unsigned int len;

	block_size = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));

	/* append bytes from previous operation */
	len = rctx->buf_cnt + req->nbytes;

	/* only the last transfer can be padded in hardware */
	if (!rctx->last && (len < block_size)) {
		/* to few data, save for next operation */
		scatterwalk_map_and_copy(rctx->buf + rctx->buf_cnt, req->src,
					 0, req->nbytes, 0);
		rctx->buf_cnt += req->nbytes;

		return 0;
	}

	/* add data from previous operation first */
	if (rctx->buf_cnt)
		memcpy(rctx->rembuf, rctx->buf, rctx->buf_cnt);

	/* data must always be a multiple of block_size */
	hash_later = rctx->last ? 0 : len & (block_size - 1);
	if (hash_later) {
		unsigned int offset = req->nbytes - hash_later;
		/* Save remaining bytes for later use */
		scatterwalk_map_and_copy(rctx->buf, req->src, offset,
					hash_later, 0);
	}

	/* nbytes should now be multiple of blocksize */
	req->nbytes = req->nbytes - hash_later;

	sahara_walk_and_recalc(req->src, req->nbytes);

	/* have data from previous operation and current */
	if (rctx->buf_cnt && req->nbytes) {
		sg_init_table(rctx->in_sg_chain, 2);
		sg_set_buf(rctx->in_sg_chain, rctx->rembuf, rctx->buf_cnt);

		scatterwalk_sg_chain(rctx->in_sg_chain, 2, req->src);

		rctx->total = req->nbytes + rctx->buf_cnt;
		rctx->in_sg = rctx->in_sg_chain;

		rctx->in_sg_chained = true;
		req->src = rctx->in_sg_chain;
	/* only data from previous operation */
	} else if (rctx->buf_cnt) {
		if (req->src)
			rctx->in_sg = req->src;
		else
			rctx->in_sg = rctx->in_sg_chain;
		/* buf was copied into rembuf above */
		sg_init_one(rctx->in_sg, rctx->rembuf, rctx->buf_cnt);
		rctx->total = rctx->buf_cnt;
		rctx->in_sg_chained = false;
	/* no data from previous operation */
	} else {
		rctx->in_sg = req->src;
		rctx->total = req->nbytes;
		req->src = rctx->in_sg;
		rctx->in_sg_chained = false;
	}

	/* on next call, we only have the remaining data in the buffer */
	rctx->buf_cnt = hash_later;

	return -EINPROGRESS;
}

static void sahara_sha_unmap_sg(struct sahara_dev *dev,
				struct sahara_sha_reqctx *rctx)
{
	struct scatterlist *sg;

	if (rctx->in_sg_chained) {
		sg = dev->in_sg;
		while (sg) {
			dma_unmap_sg(dev->device, sg, 1, DMA_TO_DEVICE);
			sg = sg_next(sg);
		}
	} else {
		dma_unmap_sg(dev->device, dev->in_sg, dev->nb_in_sg,
			DMA_TO_DEVICE);
	}
}

static int sahara_sha_process(struct ahash_request *req)
{
	struct sahara_dev *dev = dev_ptr;
	struct sahara_sha_reqctx *rctx = ahash_request_ctx(req);
	int ret;
	unsigned long timeout;

	ret = sahara_sha_prepare_request(req);
	if (!ret)
		return ret;

	if (rctx->first) {
		sahara_sha_hw_data_descriptor_create(dev, rctx, req, 0);
		dev->hw_desc[0]->next = 0;
		rctx->first = 0;
	} else {
		memcpy(dev->context_base, rctx->context, rctx->context_size);

		sahara_sha_hw_context_descriptor_create(dev, rctx, req, 0);
		dev->hw_desc[0]->next = dev->hw_phys_desc[1];
		sahara_sha_hw_data_descriptor_create(dev, rctx, req, 1);
		dev->hw_desc[1]->next = 0;
	}

	sahara_dump_descriptors(dev);
	sahara_dump_links(dev);

	reinit_completion(&dev->dma_completion);

	sahara_write(dev, dev->hw_phys_desc[0], SAHARA_REG_DAR);

	timeout = wait_for_completion_timeout(&dev->dma_completion,
				msecs_to_jiffies(SAHARA_TIMEOUT_MS));
	if (!timeout) {
		dev_err(dev->device, "SHA timeout\n");
		return -ETIMEDOUT;
	}

	if (rctx->sg_in_idx)
		sahara_sha_unmap_sg(dev, rctx);

	memcpy(rctx->context, dev->context_base, rctx->context_size);

	if (req->result)
		memcpy(req->result, rctx->context, rctx->digest_size);

	return 0;
}

static int sahara_queue_manage(void *data)
{
	struct sahara_dev *dev = (struct sahara_dev *)data;
	struct crypto_async_request *async_req;
	struct crypto_async_request *backlog;
	int ret = 0;

	do {
		__set_current_state(TASK_INTERRUPTIBLE);

		mutex_lock(&dev->queue_mutex);
		backlog = crypto_get_backlog(&dev->queue);
		async_req = crypto_dequeue_request(&dev->queue);
		mutex_unlock(&dev->queue_mutex);

		if (backlog)
			backlog->complete(backlog, -EINPROGRESS);

		if (async_req) {
			if (crypto_tfm_alg_type(async_req->tfm) ==
			    CRYPTO_ALG_TYPE_AHASH) {
				struct ahash_request *req =
					ahash_request_cast(async_req);

				ret = sahara_sha_process(req);
			} else {
				struct ablkcipher_request *req =
					ablkcipher_request_cast(async_req);

				ret = sahara_aes_process(req);
			}

			async_req->complete(async_req, ret);

			continue;
		}

		schedule();
	} while (!kthread_should_stop());

	return 0;
}

static int sahara_sha_enqueue(struct ahash_request *req, int last)
{
	struct sahara_sha_reqctx *rctx = ahash_request_ctx(req);
	struct sahara_dev *dev = dev_ptr;
	int ret;

	if (!req->nbytes && !last)
		return 0;

	mutex_lock(&rctx->mutex);
	rctx->last = last;

	if (!rctx->active) {
		rctx->active = 1;
		rctx->first = 1;
	}

	mutex_lock(&dev->queue_mutex);
	ret = crypto_enqueue_request(&dev->queue, &req->base);
	mutex_unlock(&dev->queue_mutex);

	wake_up_process(dev->kthread);
	mutex_unlock(&rctx->mutex);

	return ret;
}

static int sahara_sha_init(struct ahash_request *req)
{
	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
	struct sahara_sha_reqctx *rctx = ahash_request_ctx(req);

	memset(rctx, 0, sizeof(*rctx));

	switch (crypto_ahash_digestsize(tfm)) {
	case SHA1_DIGEST_SIZE:
		rctx->mode |= SAHARA_HDR_MDHA_ALG_SHA1;
		rctx->digest_size = SHA1_DIGEST_SIZE;
		break;
	case SHA256_DIGEST_SIZE:
		rctx->mode |= SAHARA_HDR_MDHA_ALG_SHA256;
		rctx->digest_size = SHA256_DIGEST_SIZE;
		break;
	default:
		return -EINVAL;
	}

	rctx->context_size = rctx->digest_size + 4;
	rctx->active = 0;

	mutex_init(&rctx->mutex);

	return 0;
}

static int sahara_sha_update(struct ahash_request *req)
{
	return sahara_sha_enqueue(req, 0);
}

static int sahara_sha_final(struct ahash_request *req)
{
	req->nbytes = 0;
	return sahara_sha_enqueue(req, 1);
}

static int sahara_sha_finup(struct ahash_request *req)
{
	return sahara_sha_enqueue(req, 1);
}

static int sahara_sha_digest(struct ahash_request *req)
{
	sahara_sha_init(req);

	return sahara_sha_finup(req);
}

static int sahara_sha_export(struct ahash_request *req, void *out)
{
	struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
	struct sahara_ctx *ctx = crypto_ahash_ctx(ahash);
	struct sahara_sha_reqctx *rctx = ahash_request_ctx(req);

	memcpy(out, ctx, sizeof(struct sahara_ctx));
	memcpy(out + sizeof(struct sahara_sha_reqctx), rctx,
	       sizeof(struct sahara_sha_reqctx));

	return 0;
}

static int sahara_sha_import(struct ahash_request *req, const void *in)
{
	struct crypto_ahash *ahash = crypto_ahash_reqtfm(req);
	struct sahara_ctx *ctx = crypto_ahash_ctx(ahash);
	struct sahara_sha_reqctx *rctx = ahash_request_ctx(req);

	memcpy(ctx, in, sizeof(struct sahara_ctx));
	memcpy(rctx, in + sizeof(struct sahara_sha_reqctx),
	       sizeof(struct sahara_sha_reqctx));

	return 0;
}

static int sahara_sha_cra_init(struct crypto_tfm *tfm)
{
	const char *name = crypto_tfm_alg_name(tfm);
	struct sahara_ctx *ctx = crypto_tfm_ctx(tfm);

	ctx->shash_fallback = crypto_alloc_shash(name, 0,
					CRYPTO_ALG_NEED_FALLBACK);
	if (IS_ERR(ctx->shash_fallback)) {
		pr_err("Error allocating fallback algo %s\n", name);
		return PTR_ERR(ctx->shash_fallback);
	}
	crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
				 sizeof(struct sahara_sha_reqctx) +
				 SHA_BUFFER_LEN + SHA256_BLOCK_SIZE);

	return 0;
}

static void sahara_sha_cra_exit(struct crypto_tfm *tfm)
{
	struct sahara_ctx *ctx = crypto_tfm_ctx(tfm);

	crypto_free_shash(ctx->shash_fallback);
	ctx->shash_fallback = NULL;
}

static struct crypto_alg aes_algs[] = {
{
	.cra_name		= "ecb(aes)",
	.cra_driver_name	= "sahara-ecb-aes",
	.cra_priority		= 300,
	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER |
			CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
	.cra_blocksize		= AES_BLOCK_SIZE,
	.cra_ctxsize		= sizeof(struct sahara_ctx),
	.cra_alignmask		= 0x0,
	.cra_type		= &crypto_ablkcipher_type,
	.cra_module		= THIS_MODULE,
	.cra_init		= sahara_aes_cra_init,
	.cra_exit		= sahara_aes_cra_exit,
	.cra_u.ablkcipher = {
		.min_keysize	= AES_MIN_KEY_SIZE ,
		.max_keysize	= AES_MAX_KEY_SIZE,
		.setkey		= sahara_aes_setkey,
		.encrypt	= sahara_aes_ecb_encrypt,
		.decrypt	= sahara_aes_ecb_decrypt,
	}
}, {
	.cra_name		= "cbc(aes)",
	.cra_driver_name	= "sahara-cbc-aes",
	.cra_priority		= 300,
	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER |
			CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
	.cra_blocksize		= AES_BLOCK_SIZE,
	.cra_ctxsize		= sizeof(struct sahara_ctx),
	.cra_alignmask		= 0x0,
	.cra_type		= &crypto_ablkcipher_type,
	.cra_module		= THIS_MODULE,
	.cra_init		= sahara_aes_cra_init,
	.cra_exit		= sahara_aes_cra_exit,
	.cra_u.ablkcipher = {
		.min_keysize	= AES_MIN_KEY_SIZE ,
		.max_keysize	= AES_MAX_KEY_SIZE,
		.ivsize		= AES_BLOCK_SIZE,
		.setkey		= sahara_aes_setkey,
		.encrypt	= sahara_aes_cbc_encrypt,
		.decrypt	= sahara_aes_cbc_decrypt,
	}
}
};

static struct ahash_alg sha_v3_algs[] = {
{
	.init		= sahara_sha_init,
	.update		= sahara_sha_update,
	.final		= sahara_sha_final,
	.finup		= sahara_sha_finup,
	.digest		= sahara_sha_digest,
	.export		= sahara_sha_export,
	.import		= sahara_sha_import,
	.halg.digestsize	= SHA1_DIGEST_SIZE,
	.halg.base	= {
		.cra_name		= "sha1",
		.cra_driver_name	= "sahara-sha1",
		.cra_priority		= 300,
		.cra_flags		= CRYPTO_ALG_TYPE_AHASH |
						CRYPTO_ALG_ASYNC |
						CRYPTO_ALG_NEED_FALLBACK,
		.cra_blocksize		= SHA1_BLOCK_SIZE,
		.cra_ctxsize		= sizeof(struct sahara_ctx),
		.cra_alignmask		= 0,
		.cra_module		= THIS_MODULE,
		.cra_init		= sahara_sha_cra_init,
		.cra_exit		= sahara_sha_cra_exit,
	}
},
};

static struct ahash_alg sha_v4_algs[] = {
{
	.init		= sahara_sha_init,
	.update		= sahara_sha_update,
	.final		= sahara_sha_final,
	.finup		= sahara_sha_finup,
	.digest		= sahara_sha_digest,
	.export		= sahara_sha_export,
	.import		= sahara_sha_import,
	.halg.digestsize	= SHA256_DIGEST_SIZE,
	.halg.base	= {
		.cra_name		= "sha256",
		.cra_driver_name	= "sahara-sha256",
		.cra_priority		= 300,
		.cra_flags		= CRYPTO_ALG_TYPE_AHASH |
						CRYPTO_ALG_ASYNC |
						CRYPTO_ALG_NEED_FALLBACK,
		.cra_blocksize		= SHA256_BLOCK_SIZE,
		.cra_ctxsize		= sizeof(struct sahara_ctx),
		.cra_alignmask		= 0,
		.cra_module		= THIS_MODULE,
		.cra_init		= sahara_sha_cra_init,
		.cra_exit		= sahara_sha_cra_exit,
	}
},
};

static irqreturn_t sahara_irq_handler(int irq, void *data)
{
	struct sahara_dev *dev = (struct sahara_dev *)data;
	unsigned int stat = sahara_read(dev, SAHARA_REG_STATUS);
	unsigned int err = sahara_read(dev, SAHARA_REG_ERRSTATUS);

	sahara_write(dev, SAHARA_CMD_CLEAR_INT | SAHARA_CMD_CLEAR_ERR,
		     SAHARA_REG_CMD);

	sahara_decode_status(dev, stat);

	if (SAHARA_STATUS_GET_STATE(stat) == SAHARA_STATE_BUSY) {
		return IRQ_NONE;
	} else if (SAHARA_STATUS_GET_STATE(stat) == SAHARA_STATE_COMPLETE) {
		dev->error = 0;
	} else {
		sahara_decode_error(dev, err);
		dev->error = -EINVAL;
	}

	complete(&dev->dma_completion);

	return IRQ_HANDLED;
}


static int sahara_register_algs(struct sahara_dev *dev)
{
	int err;
	unsigned int i, j, k, l;

	for (i = 0; i < ARRAY_SIZE(aes_algs); i++) {
		INIT_LIST_HEAD(&aes_algs[i].cra_list);
		err = crypto_register_alg(&aes_algs[i]);
		if (err)
			goto err_aes_algs;
	}

	for (k = 0; k < ARRAY_SIZE(sha_v3_algs); k++) {
		err = crypto_register_ahash(&sha_v3_algs[k]);
		if (err)
			goto err_sha_v3_algs;
	}

	if (dev->version > SAHARA_VERSION_3)
		for (l = 0; l < ARRAY_SIZE(sha_v4_algs); l++) {
			err = crypto_register_ahash(&sha_v4_algs[l]);
			if (err)
				goto err_sha_v4_algs;
		}

	return 0;

err_sha_v4_algs:
	for (j = 0; j < l; j++)
		crypto_unregister_ahash(&sha_v4_algs[j]);

err_sha_v3_algs:
	for (j = 0; j < k; j++)
		crypto_unregister_ahash(&sha_v4_algs[j]);

err_aes_algs:
	for (j = 0; j < i; j++)
		crypto_unregister_alg(&aes_algs[j]);

	return err;
}

static void sahara_unregister_algs(struct sahara_dev *dev)
{
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(aes_algs); i++)
		crypto_unregister_alg(&aes_algs[i]);

	for (i = 0; i < ARRAY_SIZE(sha_v4_algs); i++)
		crypto_unregister_ahash(&sha_v3_algs[i]);

	if (dev->version > SAHARA_VERSION_3)
		for (i = 0; i < ARRAY_SIZE(sha_v4_algs); i++)
			crypto_unregister_ahash(&sha_v4_algs[i]);
}

static struct platform_device_id sahara_platform_ids[] = {
	{ .name = "sahara-imx27" },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, sahara_platform_ids);

static struct of_device_id sahara_dt_ids[] = {
	{ .compatible = "fsl,imx53-sahara" },
	{ .compatible = "fsl,imx27-sahara" },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, sahara_dt_ids);

static int sahara_probe(struct platform_device *pdev)
{
	struct sahara_dev *dev;
	struct resource *res;
	u32 version;
	int irq;
	int err;
	int i;

	dev = devm_kzalloc(&pdev->dev, sizeof(struct sahara_dev), GFP_KERNEL);
	if (dev == NULL) {
		dev_err(&pdev->dev, "unable to alloc data struct.\n");
		return -ENOMEM;
	}

	dev->device = &pdev->dev;
	platform_set_drvdata(pdev, dev);

	/* Get the base address */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	dev->regs_base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(dev->regs_base))
		return PTR_ERR(dev->regs_base);

	/* Get the IRQ */
	irq = platform_get_irq(pdev,  0);
	if (irq < 0) {
		dev_err(&pdev->dev, "failed to get irq resource\n");
		return irq;
	}

	err = devm_request_irq(&pdev->dev, irq, sahara_irq_handler,
			       0, dev_name(&pdev->dev), dev);
	if (err) {
		dev_err(&pdev->dev, "failed to request irq\n");
		return err;
	}

	/* clocks */
	dev->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
	if (IS_ERR(dev->clk_ipg)) {
		dev_err(&pdev->dev, "Could not get ipg clock\n");
		return PTR_ERR(dev->clk_ipg);
	}

	dev->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
	if (IS_ERR(dev->clk_ahb)) {
		dev_err(&pdev->dev, "Could not get ahb clock\n");
		return PTR_ERR(dev->clk_ahb);
	}

	/* Allocate HW descriptors */
	dev->hw_desc[0] = dma_alloc_coherent(&pdev->dev,
			SAHARA_MAX_HW_DESC * sizeof(struct sahara_hw_desc),
			&dev->hw_phys_desc[0], GFP_KERNEL);
	if (!dev->hw_desc[0]) {
		dev_err(&pdev->dev, "Could not allocate hw descriptors\n");
		return -ENOMEM;
	}
	dev->hw_desc[1] = dev->hw_desc[0] + 1;
	dev->hw_phys_desc[1] = dev->hw_phys_desc[0] +
				sizeof(struct sahara_hw_desc);

	/* Allocate space for iv and key */
	dev->key_base = dma_alloc_coherent(&pdev->dev, 2 * AES_KEYSIZE_128,
				&dev->key_phys_base, GFP_KERNEL);
	if (!dev->key_base) {
		dev_err(&pdev->dev, "Could not allocate memory for key\n");
		err = -ENOMEM;
		goto err_key;
	}
	dev->iv_base = dev->key_base + AES_KEYSIZE_128;
	dev->iv_phys_base = dev->key_phys_base + AES_KEYSIZE_128;

	/* Allocate space for context: largest digest + message length field */
	dev->context_base = dma_alloc_coherent(&pdev->dev,
					SHA256_DIGEST_SIZE + 4,
					&dev->context_phys_base, GFP_KERNEL);
	if (!dev->context_base) {
		dev_err(&pdev->dev, "Could not allocate memory for MDHA context\n");
		err = -ENOMEM;
		goto err_key;
	}

	/* Allocate space for HW links */
	dev->hw_link[0] = dma_alloc_coherent(&pdev->dev,
			SAHARA_MAX_HW_LINK * sizeof(struct sahara_hw_link),
			&dev->hw_phys_link[0], GFP_KERNEL);
	if (!dev->hw_link[0]) {
		dev_err(&pdev->dev, "Could not allocate hw links\n");
		err = -ENOMEM;
		goto err_link;
	}
	for (i = 1; i < SAHARA_MAX_HW_LINK; i++) {
		dev->hw_phys_link[i] = dev->hw_phys_link[i - 1] +
					sizeof(struct sahara_hw_link);
		dev->hw_link[i] = dev->hw_link[i - 1] + 1;
	}

	crypto_init_queue(&dev->queue, SAHARA_QUEUE_LENGTH);

	spin_lock_init(&dev->lock);
	mutex_init(&dev->queue_mutex);

	dev_ptr = dev;

	dev->kthread = kthread_run(sahara_queue_manage, dev, "sahara_crypto");
	if (IS_ERR(dev->kthread)) {
		err = PTR_ERR(dev->kthread);
		goto err_link;
	}

	init_completion(&dev->dma_completion);

	err = clk_prepare_enable(dev->clk_ipg);
	if (err)
		goto err_link;
	err = clk_prepare_enable(dev->clk_ahb);
	if (err)
		goto clk_ipg_disable;

	version = sahara_read(dev, SAHARA_REG_VERSION);
	if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx27-sahara")) {
		if (version != SAHARA_VERSION_3)
			err = -ENODEV;
	} else if (of_device_is_compatible(pdev->dev.of_node,
			"fsl,imx53-sahara")) {
		if (((version >> 8) & 0xff) != SAHARA_VERSION_4)
			err = -ENODEV;
		version = (version >> 8) & 0xff;
	}
	if (err == -ENODEV) {
		dev_err(&pdev->dev, "SAHARA version %d not supported\n",
				version);
		goto err_algs;
	}

	dev->version = version;

	sahara_write(dev, SAHARA_CMD_RESET | SAHARA_CMD_MODE_BATCH,
		     SAHARA_REG_CMD);
	sahara_write(dev, SAHARA_CONTROL_SET_THROTTLE(0) |
			SAHARA_CONTROL_SET_MAXBURST(8) |
			SAHARA_CONTROL_RNG_AUTORSD |
			SAHARA_CONTROL_ENABLE_INT,
			SAHARA_REG_CONTROL);

	err = sahara_register_algs(dev);
	if (err)
		goto err_algs;

	dev_info(&pdev->dev, "SAHARA version %d initialized\n", version);

	return 0;

err_algs:
	dma_free_coherent(&pdev->dev,
			  SAHARA_MAX_HW_LINK * sizeof(struct sahara_hw_link),
			  dev->hw_link[0], dev->hw_phys_link[0]);
	kthread_stop(dev->kthread);
	dev_ptr = NULL;
	clk_disable_unprepare(dev->clk_ahb);
clk_ipg_disable:
	clk_disable_unprepare(dev->clk_ipg);
err_link:
	dma_free_coherent(&pdev->dev,
			  2 * AES_KEYSIZE_128,
			  dev->key_base, dev->key_phys_base);
	dma_free_coherent(&pdev->dev,
			  SHA256_DIGEST_SIZE,
			  dev->context_base, dev->context_phys_base);
err_key:
	dma_free_coherent(&pdev->dev,
			  SAHARA_MAX_HW_DESC * sizeof(struct sahara_hw_desc),
			  dev->hw_desc[0], dev->hw_phys_desc[0]);

	return err;
}

static int sahara_remove(struct platform_device *pdev)
{
	struct sahara_dev *dev = platform_get_drvdata(pdev);

	dma_free_coherent(&pdev->dev,
			  SAHARA_MAX_HW_LINK * sizeof(struct sahara_hw_link),
			  dev->hw_link[0], dev->hw_phys_link[0]);
	dma_free_coherent(&pdev->dev,
			  2 * AES_KEYSIZE_128,
			  dev->key_base, dev->key_phys_base);
	dma_free_coherent(&pdev->dev,
			  SAHARA_MAX_HW_DESC * sizeof(struct sahara_hw_desc),
			  dev->hw_desc[0], dev->hw_phys_desc[0]);

	kthread_stop(dev->kthread);

	sahara_unregister_algs(dev);

	clk_disable_unprepare(dev->clk_ipg);
	clk_disable_unprepare(dev->clk_ahb);

	dev_ptr = NULL;

	return 0;
}

static struct platform_driver sahara_driver = {
	.probe		= sahara_probe,
	.remove		= sahara_remove,
	.driver		= {
		.name	= SAHARA_NAME,
		.of_match_table = sahara_dt_ids,
	},
	.id_table = sahara_platform_ids,
};

module_platform_driver(sahara_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
MODULE_AUTHOR("Steffen Trumtrar <s.trumtrar@pengutronix.de>");
MODULE_DESCRIPTION("SAHARA2 HW crypto accelerator");
