blob: c7058f481d8991f3668dd566520078a9f899a5b1 [file] [log] [blame]
#ifndef _ASR_BCM_SHA_H_
#define _ASR_BCM_SHA_H_
#include <linux/scatterlist.h>
#include <linux/crypto.h>
#include <crypto/sha.h>
#include <crypto/hash.h>
#include <crypto/internal/hash.h>
#define ROUND_UP_TO_WORD_CNT(x) ((x + 0x3) >> 2)
#define HASH_ALIGN_BUF_SIZE 4096
#define BLOCK_ALGIN_SIZE 64
#define ASR_SHA_BUFFER_ORDER 2
#define ASR_SHA_BUFFER_SIZE (PAGE_SIZE << ASR_SHA_BUFFER_ORDER)
/* SHA flags */
#define SHA_FLAGS_BUSY BIT(0)
#define SHA_FLAGS_INIT BIT(1)
#define SHA_FLAGS_FINAL BIT(2)
#define SHA_FLAGS_FINUP BIT(3)
#define SHA_FLAGS_OUTPUT_READY BIT(4)
#define SHA_FLAGS_ALGO_MASK GENMASK(10, 5)
#define SHA_FLAGS_MD5 BIT(5)
#define SHA_FLAGS_SHA1 BIT(6)
#define SHA_FLAGS_SHA224 BIT(7)
#define SHA_FLAGS_SHA256 BIT(8)
#define SHA_FLAGS_SHA384 BIT(9)
#define SHA_FLAGS_SHA512 BIT(10)
#define SHA_FLAGS_HMAC BIT(11)
#define SHA_FLAGS_PAD BIT(12)
#define SHA_FLAGS_ERROR BIT(13)
#define SHA_OP_INIT 1
#define SHA_OP_UPDATE 2
#define SHA_OP_FINAL 3
typedef enum {
HASH_INIT = 0x1,
HASH_UPDATE = 0x2,
HASH_FINAL = 0x3,
} HASH_OP_MODE_T;
typedef enum {
HASH_LEN_SHA1 = 20,
HASH_LEN_SHA256 = 32,
HASH_LEN_SHA224 = 28,
HASH_LEN_MD5 = 16,
HASH_LEN_SHA512 = 64,
HASH_LEN_SHA384 = 48,
} HASH_LEN_T;
typedef enum {
HASH_SIMPLE = 0,
HASH_HMAC,
} HASH_MODE_T;
typedef enum {
HASH_SHA1 = 0x0,
HASH_SHA256 = 0x1,
HASH_SHA224 = 0X2,
HASH_MD5 = 0x3,
HASH_SHA512 = 0x4,
HASH_SHA384 = 0X5,
} HASH_ALGO_T;
struct sha512_digst {
unsigned int state[16];
};
struct sha256_digst {
unsigned int state[8];
};
struct sha1_digst {
unsigned int state[5];
};
struct md5_digst {
unsigned int state[4];
};
struct hash_state {
uint64_t length;
unsigned int curlen;
unsigned char buf[BLOCK_ALGIN_SIZE];
uint32_t block_size;
int alg;
struct sha512_digst sha512;
struct sha256_digst sha256;
struct sha1_digst sha1;
struct md5_digst md5;
};
struct asr_bcm_sha;
typedef int (*asr_sha_fn_t)(struct asr_bcm_sha *);
typedef irqreturn_t (*asr_sha_irq_t)(void *);
struct asr_bcm_sha {
unsigned long phys_base;
struct device *dev;
struct clk *iclk;
int irq;
void __iomem *io_base;
spinlock_t lock;
struct mutex sha_lock;
struct mutex queue_lock;
int err;
struct tasklet_struct done_task;
struct tasklet_struct queue_task;
int int_mode;
asr_sha_irq_t sha_irq;
unsigned long flags;
struct crypto_queue queue;
struct ahash_request *req;
bool is_async;
bool force_complete;
asr_sha_fn_t resume;
struct hash_state md;
};
/*
* .statesize = sizeof(struct asr_sha_reqctx) must be <= PAGE_SIZE / 8 as
* tested by the ahash_prepare_alg() function.
*/
struct asr_sha_reqctx {
struct asr_bcm_sha *dd;
unsigned long op;
u8 digest[SHA512_DIGEST_SIZE] __aligned(sizeof(u32));
void *buffer;
size_t bufcnt;
size_t buflen;
/* walk state */
struct scatterlist *sg;
unsigned int offset; /* offset in current sg */
unsigned int total; /* total request */
unsigned long flags;
struct hash_state md;
};
struct asr_sha_ctx {
struct asr_bcm_sha *dd;
asr_sha_fn_t start;
unsigned long flags;
};
#define ASR_SHA_QUEUE_LENGTH 50
#define ASR_SHA_PRIORITY 300
#endif