/*
* Cryptographic API.
*
* Support for OMAP AES HW ACCELERATOR defines
*
* Copyright (c) 2015 Texas Instruments Incorporated
*
* 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.
*
*/
#ifndef __OMAP_AES_H__
#define __OMAP_AES_H__
#include
#define DST_MAXBURST4
#define DMA_MIN(DST_MAXBURST * sizeof(u32))
#define _calc_walked(inout) (dd->inout##_walk.offset - dd->inout##_sg->offset)
/*
* OMAP TRM gives bitfields as start:end, where start is the higher bit
* number. For example 7:0
*/
#define FLD_MASK(start, end)(((1 << ((start) - (end) + 1)) - 1) << (end))
#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end))
#define AES_REG_KEY(dd, x)((dd)->pdata->key_ofs - \
(((x) ^ 0x01) * 0x04))
#define AES_REG_IV(dd, x)((dd)->pdata->iv_ofs + ((x) * 0x04))
#define AES_REG_CTRL(dd)((dd)->pdata->ctrl_ofs)
#define AES_REG_CTRL_CONTEXT_READYBIT(31)
#define AES_REG_CTRL_CTR_WIDTH_MASKGENMASK(8, 7)
#define AES_REG_CTRL_CTR_WIDTH_320
#define AES_REG_CTRL_CTR_WIDTH_64BIT(7)
#define AES_REG_CTRL_CTR_WIDTH_96BIT(8)
#define AES_REG_CTRL_CTR_WIDTH_128GENMASK(8, 7)
#define AES_REG_CTRL_GCMGENMASK(17, 16)
#define AES_REG_CTRL_CTRBIT(6)
#define AES_REG_CTRL_CBCBIT(5)
#define AES_REG_CTRL_KEY_SIZEGENMASK(4, 3)
#define AES_REG_CTRL_DIRECTIONBIT(2)
#define AES_REG_CTRL_INPUT_READYBIT(1)
#define AES_REG_CTRL_OUTPUT_READYBIT(0)
#define AES_REG_CTRL_MASKGENMASK(24, 2)
#define AES_REG_C_LEN_00x54
#define AES_REG_C_LEN_10x58
#define AES_REG_A_LEN0x5C
#define AES_REG_DATA_N(dd, x)((dd)->pdata->data_ofs + ((x) * 0x04))
#define AES_REG_TAG_N(dd, x)(0x70 + ((x) * 0x04))
#define AES_REG_REV(dd)((dd)->pdata->rev_ofs)
#define AES_REG_MASK(dd)((dd)->pdata->mask_ofs)
#define AES_REG_MASK_SIDLEBIT(6)
#define AES_REG_MASK_STARTBIT(5)
#define AES_REG_MASK_DMA_OUT_ENBIT(3)
#define AES_REG_MASK_DMA_IN_ENBIT(2)
#define AES_REG_MASK_SOFTRESETBIT(1)
#define AES_REG_AUTOIDLEBIT(0)
#define AES_REG_LENGTH_N(x)(0x54 + ((x) * 0x04))
#define AES_REG_IRQ_STATUS(dd) ((dd)->pdata->irq_status_ofs)
#define AES_REG_IRQ_ENABLE(dd) ((dd)->pdata->irq_enable_ofs)
#define AES_REG_IRQ_DATA_IN BIT(1)
#define AES_REG_IRQ_DATA_OUT BIT(2)
#define DEFAULT_TIMEOUT(5 * HZ)
#define DEFAULT_AUTOSUSPEND_DELAY1000
#define FLAGS_MODE_MASK0x001f
#define FLAGS_ENCRYPTBIT(0)
#define FLAGS_CBCBIT(1)
#define FLAGS_CTRBIT(2)
#define FLAGS_GCMBIT(3)
#define FLAGS_RFC4106_GCMBIT(4)
#define FLAGS_INITBIT(5)
#define FLAGS_FASTBIT(6)
#define FLAGS_BUSYBIT(7)
#define FLAGS_IN_DATA_ST_SHIFT8
#define FLAGS_OUT_DATA_ST_SHIFT10
#define FLAGS_ASSOC_DATA_ST_SHIFT12
#define AES_BLOCK_WORDS(AES_BLOCK_SIZE >> 2)
struct omap_aes_gcm_result {
struct completion completion;
int err;
};
struct omap_aes_ctx {
struct crypto_engine_ctx enginectx;
intkeylen;
u32key[AES_KEYSIZE_256 / sizeof(u32)];
u8nonce[4];
struct crypto_sync_skcipher*fallback;
struct crypto_skcipher*ctr;
};
struct omap_aes_reqctx {
struct omap_aes_dev *dd;
unsigned long mode;
u8 iv[AES_BLOCK_SIZE];
u32 auth_tag[AES_BLOCK_SIZE / sizeof(u32)];
};
#define OMAP_AES_QUEUE_LENGTH1
#define OMAP_AES_CACHE_SIZE0
struct omap_aes_algs_info {
struct crypto_alg*algs_list;
unsigned intsize;
unsigned intregistered;
};
struct omap_aes_aead_algs {
struct aead_alg*algs_list;
unsigned intsize;
unsigned intregistered;
};
struct omap_aes_pdata {
struct omap_aes_algs_info*algs_info;
unsigned intalgs_info_size;
struct omap_aes_aead_algs*aead_algs_info;
void(*trigger)(struct omap_aes_dev *dd, int length);
u32key_ofs;
u32iv_ofs;
u32ctrl_ofs;
u32data_ofs;
u32rev_ofs;
u32mask_ofs;
u32 irq_enable_ofs;
u32 irq_status_ofs;
u32dma_enable_in;
u32dma_enable_out;
u32dma_start;
u32major_mask;
u32major_shift;
u32minor_mask;
u32minor_shift;
};
struct omap_aes_dev {
struct list_headlist;
unsigned longphys_base;
void __iomem*io_base;
struct omap_aes_ctx*ctx;
struct device*dev;
unsigned longflags;
interr;
struct tasklet_structdone_task;
struct aead_queueaead_queue;
spinlock_tlock;
struct ablkcipher_request*req;
struct aead_request*aead_req;
struct crypto_engine*engine;
/*
* total is used by PIO mode for book keeping so introduce
* variable total_save as need it to calc page_order
*/
size_ttotal;
size_ttotal_save;
size_tassoc_len;
size_tauthsize;
struct scatterlist*in_sg;
struct scatterlist*out_sg;
/* Buffers for copying for unaligned cases */
struct scatterlistin_sgl[2];
struct scatterlistout_sgl;
struct scatterlist*orig_out;
struct scatter_walkin_walk;
struct scatter_walkout_walk;
struct dma_chan*dma_lch_in;
struct dma_chan*dma_lch_out;
intin_sg_len;
intout_sg_len;
intpio_only;
const struct omap_aes_pdata*pdata;
};
u32 omap_aes_read(struct omap_aes_dev *dd, u32 offset);
void omap_aes_write(struct omap_aes_dev *dd, u32 offset, u32 value);
struct omap_aes_dev *omap_aes_find_dev(struct omap_aes_reqctx *rctx);
int omap_aes_gcm_setkey(struct crypto_aead *tfm, const u8 *key,
unsigned int keylen);
int omap_aes_4106gcm_setkey(struct crypto_aead *tfm, const u8 *key,
unsigned int keylen);
int omap_aes_gcm_encrypt(struct aead_request *req);
int omap_aes_gcm_decrypt(struct aead_request *req);
int omap_aes_4106gcm_encrypt(struct aead_request *req);
int omap_aes_4106gcm_decrypt(struct aead_request *req);
int omap_aes_write_ctrl(struct omap_aes_dev *dd);
int omap_aes_crypt_dma_start(struct omap_aes_dev *dd);
int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd);
void omap_aes_gcm_dma_out_callback(void *data);
void omap_aes_clear_copy_flags(struct omap_aes_dev *dd);
#