xref: /openbmc/linux/drivers/crypto/caam/caamalg.c (revision 35af6403)
18e8ec596SKim Phillips /*
28e8ec596SKim Phillips  * caam - Freescale FSL CAAM support for crypto API
38e8ec596SKim Phillips  *
48e8ec596SKim Phillips  * Copyright 2008-2011 Freescale Semiconductor, Inc.
58e8ec596SKim Phillips  *
68e8ec596SKim Phillips  * Based on talitos crypto API driver.
78e8ec596SKim Phillips  *
88e8ec596SKim Phillips  * relationship of job descriptors to shared descriptors (SteveC Dec 10 2008):
98e8ec596SKim Phillips  *
108e8ec596SKim Phillips  * ---------------                     ---------------
118e8ec596SKim Phillips  * | JobDesc #1  |-------------------->|  ShareDesc  |
128e8ec596SKim Phillips  * | *(packet 1) |                     |   (PDB)     |
138e8ec596SKim Phillips  * ---------------      |------------->|  (hashKey)  |
148e8ec596SKim Phillips  *       .              |              | (cipherKey) |
158e8ec596SKim Phillips  *       .              |    |-------->| (operation) |
168e8ec596SKim Phillips  * ---------------      |    |         ---------------
178e8ec596SKim Phillips  * | JobDesc #2  |------|    |
188e8ec596SKim Phillips  * | *(packet 2) |           |
198e8ec596SKim Phillips  * ---------------           |
208e8ec596SKim Phillips  *       .                   |
218e8ec596SKim Phillips  *       .                   |
228e8ec596SKim Phillips  * ---------------           |
238e8ec596SKim Phillips  * | JobDesc #3  |------------
248e8ec596SKim Phillips  * | *(packet 3) |
258e8ec596SKim Phillips  * ---------------
268e8ec596SKim Phillips  *
278e8ec596SKim Phillips  * The SharedDesc never changes for a connection unless rekeyed, but
288e8ec596SKim Phillips  * each packet will likely be in a different place. So all we need
298e8ec596SKim Phillips  * to know to process the packet is where the input is, where the
308e8ec596SKim Phillips  * output goes, and what context we want to process with. Context is
318e8ec596SKim Phillips  * in the SharedDesc, packet references in the JobDesc.
328e8ec596SKim Phillips  *
338e8ec596SKim Phillips  * So, a job desc looks like:
348e8ec596SKim Phillips  *
358e8ec596SKim Phillips  * ---------------------
368e8ec596SKim Phillips  * | Header            |
378e8ec596SKim Phillips  * | ShareDesc Pointer |
388e8ec596SKim Phillips  * | SEQ_OUT_PTR       |
398e8ec596SKim Phillips  * | (output buffer)   |
406ec47334SYuan Kang  * | (output length)   |
418e8ec596SKim Phillips  * | SEQ_IN_PTR        |
428e8ec596SKim Phillips  * | (input buffer)    |
436ec47334SYuan Kang  * | (input length)    |
448e8ec596SKim Phillips  * ---------------------
458e8ec596SKim Phillips  */
468e8ec596SKim Phillips 
478e8ec596SKim Phillips #include "compat.h"
488e8ec596SKim Phillips 
498e8ec596SKim Phillips #include "regs.h"
508e8ec596SKim Phillips #include "intern.h"
518e8ec596SKim Phillips #include "desc_constr.h"
528e8ec596SKim Phillips #include "jr.h"
538e8ec596SKim Phillips #include "error.h"
54a299c837SYuan Kang #include "sg_sw_sec4.h"
554c1ec1f9SYuan Kang #include "key_gen.h"
568e8ec596SKim Phillips 
578e8ec596SKim Phillips /*
588e8ec596SKim Phillips  * crypto alg
598e8ec596SKim Phillips  */
608e8ec596SKim Phillips #define CAAM_CRA_PRIORITY		3000
618e8ec596SKim Phillips /* max key is sum of AES_MAX_KEY_SIZE, max split key size */
628e8ec596SKim Phillips #define CAAM_MAX_KEY_SIZE		(AES_MAX_KEY_SIZE + \
638e8ec596SKim Phillips 					 SHA512_DIGEST_SIZE * 2)
648e8ec596SKim Phillips /* max IV is max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */
658e8ec596SKim Phillips #define CAAM_MAX_IV_LENGTH		16
668e8ec596SKim Phillips 
674427b1b4SKim Phillips /* length of descriptors text */
681acebad3SYuan Kang #define DESC_AEAD_BASE			(4 * CAAM_CMD_SZ)
694464a7d4SHoria Geanta #define DESC_AEAD_ENC_LEN		(DESC_AEAD_BASE + 15 * CAAM_CMD_SZ)
704464a7d4SHoria Geanta #define DESC_AEAD_DEC_LEN		(DESC_AEAD_BASE + 18 * CAAM_CMD_SZ)
711acebad3SYuan Kang #define DESC_AEAD_GIVENC_LEN		(DESC_AEAD_ENC_LEN + 7 * CAAM_CMD_SZ)
721acebad3SYuan Kang 
73ae4a825fSHoria Geanta #define DESC_AEAD_NULL_BASE		(3 * CAAM_CMD_SZ)
74ae4a825fSHoria Geanta #define DESC_AEAD_NULL_ENC_LEN		(DESC_AEAD_NULL_BASE + 14 * CAAM_CMD_SZ)
75ae4a825fSHoria Geanta #define DESC_AEAD_NULL_DEC_LEN		(DESC_AEAD_NULL_BASE + 17 * CAAM_CMD_SZ)
76ae4a825fSHoria Geanta 
77acdca31dSYuan Kang #define DESC_ABLKCIPHER_BASE		(3 * CAAM_CMD_SZ)
78acdca31dSYuan Kang #define DESC_ABLKCIPHER_ENC_LEN		(DESC_ABLKCIPHER_BASE + \
79acdca31dSYuan Kang 					 20 * CAAM_CMD_SZ)
80acdca31dSYuan Kang #define DESC_ABLKCIPHER_DEC_LEN		(DESC_ABLKCIPHER_BASE + \
81acdca31dSYuan Kang 					 15 * CAAM_CMD_SZ)
82acdca31dSYuan Kang 
831acebad3SYuan Kang #define DESC_MAX_USED_BYTES		(DESC_AEAD_GIVENC_LEN + \
841acebad3SYuan Kang 					 CAAM_MAX_KEY_SIZE)
851acebad3SYuan Kang #define DESC_MAX_USED_LEN		(DESC_MAX_USED_BYTES / CAAM_CMD_SZ)
864427b1b4SKim Phillips 
878e8ec596SKim Phillips #ifdef DEBUG
888e8ec596SKim Phillips /* for print_hex_dumps with line references */
898e8ec596SKim Phillips #define debug(format, arg...) printk(format, arg)
908e8ec596SKim Phillips #else
918e8ec596SKim Phillips #define debug(format, arg...)
928e8ec596SKim Phillips #endif
93cfc6f11bSRuchika Gupta static struct list_head alg_list;
948e8ec596SKim Phillips 
951acebad3SYuan Kang /* Set DK bit in class 1 operation if shared */
961acebad3SYuan Kang static inline void append_dec_op1(u32 *desc, u32 type)
971acebad3SYuan Kang {
981acebad3SYuan Kang 	u32 *jump_cmd, *uncond_jump_cmd;
991acebad3SYuan Kang 
1001acebad3SYuan Kang 	jump_cmd = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD);
1011acebad3SYuan Kang 	append_operation(desc, type | OP_ALG_AS_INITFINAL |
1021acebad3SYuan Kang 			 OP_ALG_DECRYPT);
1031acebad3SYuan Kang 	uncond_jump_cmd = append_jump(desc, JUMP_TEST_ALL);
1041acebad3SYuan Kang 	set_jump_tgt_here(desc, jump_cmd);
1051acebad3SYuan Kang 	append_operation(desc, type | OP_ALG_AS_INITFINAL |
1061acebad3SYuan Kang 			 OP_ALG_DECRYPT | OP_ALG_AAI_DK);
1071acebad3SYuan Kang 	set_jump_tgt_here(desc, uncond_jump_cmd);
1081acebad3SYuan Kang }
1091acebad3SYuan Kang 
1101acebad3SYuan Kang /*
1111acebad3SYuan Kang  * For aead functions, read payload and write payload,
1121acebad3SYuan Kang  * both of which are specified in req->src and req->dst
1131acebad3SYuan Kang  */
1141acebad3SYuan Kang static inline void aead_append_src_dst(u32 *desc, u32 msg_type)
1151acebad3SYuan Kang {
116ae4a825fSHoria Geanta 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
1171acebad3SYuan Kang 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH |
1181acebad3SYuan Kang 			     KEY_VLF | msg_type | FIFOLD_TYPE_LASTBOTH);
1191acebad3SYuan Kang }
1201acebad3SYuan Kang 
1211acebad3SYuan Kang /*
1221acebad3SYuan Kang  * For aead encrypt and decrypt, read iv for both classes
1231acebad3SYuan Kang  */
1241acebad3SYuan Kang static inline void aead_append_ld_iv(u32 *desc, int ivsize)
1251acebad3SYuan Kang {
1261acebad3SYuan Kang 	append_cmd(desc, CMD_SEQ_LOAD | LDST_SRCDST_BYTE_CONTEXT |
1271acebad3SYuan Kang 		   LDST_CLASS_1_CCB | ivsize);
1281acebad3SYuan Kang 	append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_CLASS2INFIFO | ivsize);
1291acebad3SYuan Kang }
1301acebad3SYuan Kang 
1311acebad3SYuan Kang /*
132acdca31dSYuan Kang  * For ablkcipher encrypt and decrypt, read from req->src and
133acdca31dSYuan Kang  * write to req->dst
134acdca31dSYuan Kang  */
135acdca31dSYuan Kang static inline void ablkcipher_append_src_dst(u32 *desc)
136acdca31dSYuan Kang {
13770d793ccSKim Phillips 	append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
13870d793ccSKim Phillips 	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
13970d793ccSKim Phillips 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 |
14070d793ccSKim Phillips 			     KEY_VLF | FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
14170d793ccSKim Phillips 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
142acdca31dSYuan Kang }
143acdca31dSYuan Kang 
144acdca31dSYuan Kang /*
1451acebad3SYuan Kang  * If all data, including src (with assoc and iv) or dst (with iv only) are
1461acebad3SYuan Kang  * contiguous
1471acebad3SYuan Kang  */
1481acebad3SYuan Kang #define GIV_SRC_CONTIG		1
1491acebad3SYuan Kang #define GIV_DST_CONTIG		(1 << 1)
1501acebad3SYuan Kang 
1518e8ec596SKim Phillips /*
1528e8ec596SKim Phillips  * per-session context
1538e8ec596SKim Phillips  */
1548e8ec596SKim Phillips struct caam_ctx {
1558e8ec596SKim Phillips 	struct device *jrdev;
1561acebad3SYuan Kang 	u32 sh_desc_enc[DESC_MAX_USED_LEN];
1571acebad3SYuan Kang 	u32 sh_desc_dec[DESC_MAX_USED_LEN];
1581acebad3SYuan Kang 	u32 sh_desc_givenc[DESC_MAX_USED_LEN];
1591acebad3SYuan Kang 	dma_addr_t sh_desc_enc_dma;
1601acebad3SYuan Kang 	dma_addr_t sh_desc_dec_dma;
1611acebad3SYuan Kang 	dma_addr_t sh_desc_givenc_dma;
1628e8ec596SKim Phillips 	u32 class1_alg_type;
1638e8ec596SKim Phillips 	u32 class2_alg_type;
1648e8ec596SKim Phillips 	u32 alg_op;
1651acebad3SYuan Kang 	u8 key[CAAM_MAX_KEY_SIZE];
166885e9e2fSYuan Kang 	dma_addr_t key_dma;
1678e8ec596SKim Phillips 	unsigned int enckeylen;
1688e8ec596SKim Phillips 	unsigned int split_key_len;
1698e8ec596SKim Phillips 	unsigned int split_key_pad_len;
1708e8ec596SKim Phillips 	unsigned int authsize;
1718e8ec596SKim Phillips };
1728e8ec596SKim Phillips 
1731acebad3SYuan Kang static void append_key_aead(u32 *desc, struct caam_ctx *ctx,
1741acebad3SYuan Kang 			    int keys_fit_inline)
1751acebad3SYuan Kang {
1761acebad3SYuan Kang 	if (keys_fit_inline) {
1771acebad3SYuan Kang 		append_key_as_imm(desc, ctx->key, ctx->split_key_pad_len,
1781acebad3SYuan Kang 				  ctx->split_key_len, CLASS_2 |
1791acebad3SYuan Kang 				  KEY_DEST_MDHA_SPLIT | KEY_ENC);
1801acebad3SYuan Kang 		append_key_as_imm(desc, (void *)ctx->key +
1811acebad3SYuan Kang 				  ctx->split_key_pad_len, ctx->enckeylen,
1821acebad3SYuan Kang 				  ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
1831acebad3SYuan Kang 	} else {
1841acebad3SYuan Kang 		append_key(desc, ctx->key_dma, ctx->split_key_len, CLASS_2 |
1851acebad3SYuan Kang 			   KEY_DEST_MDHA_SPLIT | KEY_ENC);
1861acebad3SYuan Kang 		append_key(desc, ctx->key_dma + ctx->split_key_pad_len,
1871acebad3SYuan Kang 			   ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
1881acebad3SYuan Kang 	}
1891acebad3SYuan Kang }
1901acebad3SYuan Kang 
1911acebad3SYuan Kang static void init_sh_desc_key_aead(u32 *desc, struct caam_ctx *ctx,
1921acebad3SYuan Kang 				  int keys_fit_inline)
1931acebad3SYuan Kang {
1941acebad3SYuan Kang 	u32 *key_jump_cmd;
1951acebad3SYuan Kang 
19661bb86bbSKim Phillips 	init_sh_desc(desc, HDR_SHARE_SERIAL);
1971acebad3SYuan Kang 
1981acebad3SYuan Kang 	/* Skip if already shared */
1991acebad3SYuan Kang 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
2001acebad3SYuan Kang 				   JUMP_COND_SHRD);
2011acebad3SYuan Kang 
2021acebad3SYuan Kang 	append_key_aead(desc, ctx, keys_fit_inline);
2031acebad3SYuan Kang 
2041acebad3SYuan Kang 	set_jump_tgt_here(desc, key_jump_cmd);
2051acebad3SYuan Kang }
2061acebad3SYuan Kang 
207ae4a825fSHoria Geanta static int aead_null_set_sh_desc(struct crypto_aead *aead)
208ae4a825fSHoria Geanta {
209ae4a825fSHoria Geanta 	struct aead_tfm *tfm = &aead->base.crt_aead;
210ae4a825fSHoria Geanta 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
211ae4a825fSHoria Geanta 	struct device *jrdev = ctx->jrdev;
212ae4a825fSHoria Geanta 	bool keys_fit_inline = false;
213ae4a825fSHoria Geanta 	u32 *key_jump_cmd, *jump_cmd, *read_move_cmd, *write_move_cmd;
214ae4a825fSHoria Geanta 	u32 *desc;
215ae4a825fSHoria Geanta 
216ae4a825fSHoria Geanta 	/*
217ae4a825fSHoria Geanta 	 * Job Descriptor and Shared Descriptors
218ae4a825fSHoria Geanta 	 * must all fit into the 64-word Descriptor h/w Buffer
219ae4a825fSHoria Geanta 	 */
220ae4a825fSHoria Geanta 	if (DESC_AEAD_NULL_ENC_LEN + DESC_JOB_IO_LEN +
221ae4a825fSHoria Geanta 	    ctx->split_key_pad_len <= CAAM_DESC_BYTES_MAX)
222ae4a825fSHoria Geanta 		keys_fit_inline = true;
223ae4a825fSHoria Geanta 
224ae4a825fSHoria Geanta 	/* aead_encrypt shared descriptor */
225ae4a825fSHoria Geanta 	desc = ctx->sh_desc_enc;
226ae4a825fSHoria Geanta 
227ae4a825fSHoria Geanta 	init_sh_desc(desc, HDR_SHARE_SERIAL);
228ae4a825fSHoria Geanta 
229ae4a825fSHoria Geanta 	/* Skip if already shared */
230ae4a825fSHoria Geanta 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
231ae4a825fSHoria Geanta 				   JUMP_COND_SHRD);
232ae4a825fSHoria Geanta 	if (keys_fit_inline)
233ae4a825fSHoria Geanta 		append_key_as_imm(desc, ctx->key, ctx->split_key_pad_len,
234ae4a825fSHoria Geanta 				  ctx->split_key_len, CLASS_2 |
235ae4a825fSHoria Geanta 				  KEY_DEST_MDHA_SPLIT | KEY_ENC);
236ae4a825fSHoria Geanta 	else
237ae4a825fSHoria Geanta 		append_key(desc, ctx->key_dma, ctx->split_key_len, CLASS_2 |
238ae4a825fSHoria Geanta 			   KEY_DEST_MDHA_SPLIT | KEY_ENC);
239ae4a825fSHoria Geanta 	set_jump_tgt_here(desc, key_jump_cmd);
240ae4a825fSHoria Geanta 
241ae4a825fSHoria Geanta 	/* cryptlen = seqoutlen - authsize */
242ae4a825fSHoria Geanta 	append_math_sub_imm_u32(desc, REG3, SEQOUTLEN, IMM, ctx->authsize);
243ae4a825fSHoria Geanta 
244ae4a825fSHoria Geanta 	/*
245ae4a825fSHoria Geanta 	 * NULL encryption; IV is zero
246ae4a825fSHoria Geanta 	 * assoclen = (assoclen + cryptlen) - cryptlen
247ae4a825fSHoria Geanta 	 */
248ae4a825fSHoria Geanta 	append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG3, CAAM_CMD_SZ);
249ae4a825fSHoria Geanta 
250ae4a825fSHoria Geanta 	/* read assoc before reading payload */
251ae4a825fSHoria Geanta 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
252ae4a825fSHoria Geanta 			     KEY_VLF);
253ae4a825fSHoria Geanta 
254ae4a825fSHoria Geanta 	/* Prepare to read and write cryptlen bytes */
255ae4a825fSHoria Geanta 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
256ae4a825fSHoria Geanta 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
257ae4a825fSHoria Geanta 
258ae4a825fSHoria Geanta 	/*
259ae4a825fSHoria Geanta 	 * MOVE_LEN opcode is not available in all SEC HW revisions,
260ae4a825fSHoria Geanta 	 * thus need to do some magic, i.e. self-patch the descriptor
261ae4a825fSHoria Geanta 	 * buffer.
262ae4a825fSHoria Geanta 	 */
263ae4a825fSHoria Geanta 	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
264ae4a825fSHoria Geanta 				    MOVE_DEST_MATH3 |
265ae4a825fSHoria Geanta 				    (0x6 << MOVE_LEN_SHIFT));
266ae4a825fSHoria Geanta 	write_move_cmd = append_move(desc, MOVE_SRC_MATH3 |
267ae4a825fSHoria Geanta 				     MOVE_DEST_DESCBUF |
268ae4a825fSHoria Geanta 				     MOVE_WAITCOMP |
269ae4a825fSHoria Geanta 				     (0x8 << MOVE_LEN_SHIFT));
270ae4a825fSHoria Geanta 
271ae4a825fSHoria Geanta 	/* Class 2 operation */
272ae4a825fSHoria Geanta 	append_operation(desc, ctx->class2_alg_type |
273ae4a825fSHoria Geanta 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
274ae4a825fSHoria Geanta 
275ae4a825fSHoria Geanta 	/* Read and write cryptlen bytes */
276ae4a825fSHoria Geanta 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
277ae4a825fSHoria Geanta 
278ae4a825fSHoria Geanta 	set_move_tgt_here(desc, read_move_cmd);
279ae4a825fSHoria Geanta 	set_move_tgt_here(desc, write_move_cmd);
280ae4a825fSHoria Geanta 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
281ae4a825fSHoria Geanta 	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO |
282ae4a825fSHoria Geanta 		    MOVE_AUX_LS);
283ae4a825fSHoria Geanta 
284ae4a825fSHoria Geanta 	/* Write ICV */
285ae4a825fSHoria Geanta 	append_seq_store(desc, ctx->authsize, LDST_CLASS_2_CCB |
286ae4a825fSHoria Geanta 			 LDST_SRCDST_BYTE_CONTEXT);
287ae4a825fSHoria Geanta 
288ae4a825fSHoria Geanta 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc,
289ae4a825fSHoria Geanta 					      desc_bytes(desc),
290ae4a825fSHoria Geanta 					      DMA_TO_DEVICE);
291ae4a825fSHoria Geanta 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
292ae4a825fSHoria Geanta 		dev_err(jrdev, "unable to map shared descriptor\n");
293ae4a825fSHoria Geanta 		return -ENOMEM;
294ae4a825fSHoria Geanta 	}
295ae4a825fSHoria Geanta #ifdef DEBUG
296ae4a825fSHoria Geanta 	print_hex_dump(KERN_ERR,
297ae4a825fSHoria Geanta 		       "aead null enc shdesc@"__stringify(__LINE__)": ",
298ae4a825fSHoria Geanta 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
299ae4a825fSHoria Geanta 		       desc_bytes(desc), 1);
300ae4a825fSHoria Geanta #endif
301ae4a825fSHoria Geanta 
302ae4a825fSHoria Geanta 	/*
303ae4a825fSHoria Geanta 	 * Job Descriptor and Shared Descriptors
304ae4a825fSHoria Geanta 	 * must all fit into the 64-word Descriptor h/w Buffer
305ae4a825fSHoria Geanta 	 */
30680cd88f2SVakul Garg 	keys_fit_inline = false;
307ae4a825fSHoria Geanta 	if (DESC_AEAD_NULL_DEC_LEN + DESC_JOB_IO_LEN +
308ae4a825fSHoria Geanta 	    ctx->split_key_pad_len <= CAAM_DESC_BYTES_MAX)
309ae4a825fSHoria Geanta 		keys_fit_inline = true;
310ae4a825fSHoria Geanta 
311ae4a825fSHoria Geanta 	desc = ctx->sh_desc_dec;
312ae4a825fSHoria Geanta 
313ae4a825fSHoria Geanta 	/* aead_decrypt shared descriptor */
314ae4a825fSHoria Geanta 	init_sh_desc(desc, HDR_SHARE_SERIAL);
315ae4a825fSHoria Geanta 
316ae4a825fSHoria Geanta 	/* Skip if already shared */
317ae4a825fSHoria Geanta 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
318ae4a825fSHoria Geanta 				   JUMP_COND_SHRD);
319ae4a825fSHoria Geanta 	if (keys_fit_inline)
320ae4a825fSHoria Geanta 		append_key_as_imm(desc, ctx->key, ctx->split_key_pad_len,
321ae4a825fSHoria Geanta 				  ctx->split_key_len, CLASS_2 |
322ae4a825fSHoria Geanta 				  KEY_DEST_MDHA_SPLIT | KEY_ENC);
323ae4a825fSHoria Geanta 	else
324ae4a825fSHoria Geanta 		append_key(desc, ctx->key_dma, ctx->split_key_len, CLASS_2 |
325ae4a825fSHoria Geanta 			   KEY_DEST_MDHA_SPLIT | KEY_ENC);
326ae4a825fSHoria Geanta 	set_jump_tgt_here(desc, key_jump_cmd);
327ae4a825fSHoria Geanta 
328ae4a825fSHoria Geanta 	/* Class 2 operation */
329ae4a825fSHoria Geanta 	append_operation(desc, ctx->class2_alg_type |
330ae4a825fSHoria Geanta 			 OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT | OP_ALG_ICV_ON);
331ae4a825fSHoria Geanta 
332ae4a825fSHoria Geanta 	/* assoclen + cryptlen = seqinlen - ivsize - authsize */
333ae4a825fSHoria Geanta 	append_math_sub_imm_u32(desc, REG3, SEQINLEN, IMM,
334ae4a825fSHoria Geanta 				ctx->authsize + tfm->ivsize);
335ae4a825fSHoria Geanta 	/* assoclen = (assoclen + cryptlen) - cryptlen */
336ae4a825fSHoria Geanta 	append_math_sub(desc, REG2, SEQOUTLEN, REG0, CAAM_CMD_SZ);
337ae4a825fSHoria Geanta 	append_math_sub(desc, VARSEQINLEN, REG3, REG2, CAAM_CMD_SZ);
338ae4a825fSHoria Geanta 
339ae4a825fSHoria Geanta 	/* read assoc before reading payload */
340ae4a825fSHoria Geanta 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
341ae4a825fSHoria Geanta 			     KEY_VLF);
342ae4a825fSHoria Geanta 
343ae4a825fSHoria Geanta 	/* Prepare to read and write cryptlen bytes */
344ae4a825fSHoria Geanta 	append_math_add(desc, VARSEQINLEN, ZERO, REG2, CAAM_CMD_SZ);
345ae4a825fSHoria Geanta 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG2, CAAM_CMD_SZ);
346ae4a825fSHoria Geanta 
347ae4a825fSHoria Geanta 	/*
348ae4a825fSHoria Geanta 	 * MOVE_LEN opcode is not available in all SEC HW revisions,
349ae4a825fSHoria Geanta 	 * thus need to do some magic, i.e. self-patch the descriptor
350ae4a825fSHoria Geanta 	 * buffer.
351ae4a825fSHoria Geanta 	 */
352ae4a825fSHoria Geanta 	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
353ae4a825fSHoria Geanta 				    MOVE_DEST_MATH2 |
354ae4a825fSHoria Geanta 				    (0x6 << MOVE_LEN_SHIFT));
355ae4a825fSHoria Geanta 	write_move_cmd = append_move(desc, MOVE_SRC_MATH2 |
356ae4a825fSHoria Geanta 				     MOVE_DEST_DESCBUF |
357ae4a825fSHoria Geanta 				     MOVE_WAITCOMP |
358ae4a825fSHoria Geanta 				     (0x8 << MOVE_LEN_SHIFT));
359ae4a825fSHoria Geanta 
360ae4a825fSHoria Geanta 	/* Read and write cryptlen bytes */
361ae4a825fSHoria Geanta 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
362ae4a825fSHoria Geanta 
363ae4a825fSHoria Geanta 	/*
364ae4a825fSHoria Geanta 	 * Insert a NOP here, since we need at least 4 instructions between
365ae4a825fSHoria Geanta 	 * code patching the descriptor buffer and the location being patched.
366ae4a825fSHoria Geanta 	 */
367ae4a825fSHoria Geanta 	jump_cmd = append_jump(desc, JUMP_TEST_ALL);
368ae4a825fSHoria Geanta 	set_jump_tgt_here(desc, jump_cmd);
369ae4a825fSHoria Geanta 
370ae4a825fSHoria Geanta 	set_move_tgt_here(desc, read_move_cmd);
371ae4a825fSHoria Geanta 	set_move_tgt_here(desc, write_move_cmd);
372ae4a825fSHoria Geanta 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
373ae4a825fSHoria Geanta 	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO |
374ae4a825fSHoria Geanta 		    MOVE_AUX_LS);
375ae4a825fSHoria Geanta 	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
376ae4a825fSHoria Geanta 
377ae4a825fSHoria Geanta 	/* Load ICV */
378ae4a825fSHoria Geanta 	append_seq_fifo_load(desc, ctx->authsize, FIFOLD_CLASS_CLASS2 |
379ae4a825fSHoria Geanta 			     FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
380ae4a825fSHoria Geanta 
381ae4a825fSHoria Geanta 	ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc,
382ae4a825fSHoria Geanta 					      desc_bytes(desc),
383ae4a825fSHoria Geanta 					      DMA_TO_DEVICE);
384ae4a825fSHoria Geanta 	if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) {
385ae4a825fSHoria Geanta 		dev_err(jrdev, "unable to map shared descriptor\n");
386ae4a825fSHoria Geanta 		return -ENOMEM;
387ae4a825fSHoria Geanta 	}
388ae4a825fSHoria Geanta #ifdef DEBUG
389ae4a825fSHoria Geanta 	print_hex_dump(KERN_ERR,
390ae4a825fSHoria Geanta 		       "aead null dec shdesc@"__stringify(__LINE__)": ",
391ae4a825fSHoria Geanta 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
392ae4a825fSHoria Geanta 		       desc_bytes(desc), 1);
393ae4a825fSHoria Geanta #endif
394ae4a825fSHoria Geanta 
395ae4a825fSHoria Geanta 	return 0;
396ae4a825fSHoria Geanta }
397ae4a825fSHoria Geanta 
3981acebad3SYuan Kang static int aead_set_sh_desc(struct crypto_aead *aead)
3991acebad3SYuan Kang {
4001acebad3SYuan Kang 	struct aead_tfm *tfm = &aead->base.crt_aead;
4011acebad3SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
4021acebad3SYuan Kang 	struct device *jrdev = ctx->jrdev;
4032af8f4a2SKim Phillips 	bool keys_fit_inline = false;
4041acebad3SYuan Kang 	u32 geniv, moveiv;
4051acebad3SYuan Kang 	u32 *desc;
4061acebad3SYuan Kang 
407ae4a825fSHoria Geanta 	if (!ctx->authsize)
4081acebad3SYuan Kang 		return 0;
4091acebad3SYuan Kang 
410ae4a825fSHoria Geanta 	/* NULL encryption / decryption */
411ae4a825fSHoria Geanta 	if (!ctx->enckeylen)
412ae4a825fSHoria Geanta 		return aead_null_set_sh_desc(aead);
413ae4a825fSHoria Geanta 
4141acebad3SYuan Kang 	/*
4151acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
4161acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
4171acebad3SYuan Kang 	 */
4181acebad3SYuan Kang 	if (DESC_AEAD_ENC_LEN + DESC_JOB_IO_LEN +
4191acebad3SYuan Kang 	    ctx->split_key_pad_len + ctx->enckeylen <=
4201acebad3SYuan Kang 	    CAAM_DESC_BYTES_MAX)
4212af8f4a2SKim Phillips 		keys_fit_inline = true;
4221acebad3SYuan Kang 
4231acebad3SYuan Kang 	/* aead_encrypt shared descriptor */
4241acebad3SYuan Kang 	desc = ctx->sh_desc_enc;
4251acebad3SYuan Kang 
4261acebad3SYuan Kang 	init_sh_desc_key_aead(desc, ctx, keys_fit_inline);
4271acebad3SYuan Kang 
4281acebad3SYuan Kang 	/* Class 2 operation */
4291acebad3SYuan Kang 	append_operation(desc, ctx->class2_alg_type |
4301acebad3SYuan Kang 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
4311acebad3SYuan Kang 
4321acebad3SYuan Kang 	/* cryptlen = seqoutlen - authsize */
4331acebad3SYuan Kang 	append_math_sub_imm_u32(desc, REG3, SEQOUTLEN, IMM, ctx->authsize);
4341acebad3SYuan Kang 
4351acebad3SYuan Kang 	/* assoclen + cryptlen = seqinlen - ivsize */
4361acebad3SYuan Kang 	append_math_sub_imm_u32(desc, REG2, SEQINLEN, IMM, tfm->ivsize);
4371acebad3SYuan Kang 
4384464a7d4SHoria Geanta 	/* assoclen = (assoclen + cryptlen) - cryptlen */
4391acebad3SYuan Kang 	append_math_sub(desc, VARSEQINLEN, REG2, REG3, CAAM_CMD_SZ);
4401acebad3SYuan Kang 
4411acebad3SYuan Kang 	/* read assoc before reading payload */
4421acebad3SYuan Kang 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
4431acebad3SYuan Kang 			     KEY_VLF);
4441acebad3SYuan Kang 	aead_append_ld_iv(desc, tfm->ivsize);
4451acebad3SYuan Kang 
4461acebad3SYuan Kang 	/* Class 1 operation */
4471acebad3SYuan Kang 	append_operation(desc, ctx->class1_alg_type |
4481acebad3SYuan Kang 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
4491acebad3SYuan Kang 
4501acebad3SYuan Kang 	/* Read and write cryptlen bytes */
4511acebad3SYuan Kang 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
4521acebad3SYuan Kang 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
4531acebad3SYuan Kang 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
4541acebad3SYuan Kang 
4551acebad3SYuan Kang 	/* Write ICV */
4561acebad3SYuan Kang 	append_seq_store(desc, ctx->authsize, LDST_CLASS_2_CCB |
4571acebad3SYuan Kang 			 LDST_SRCDST_BYTE_CONTEXT);
4581acebad3SYuan Kang 
4591acebad3SYuan Kang 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc,
4601acebad3SYuan Kang 					      desc_bytes(desc),
4611acebad3SYuan Kang 					      DMA_TO_DEVICE);
4621acebad3SYuan Kang 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
4631acebad3SYuan Kang 		dev_err(jrdev, "unable to map shared descriptor\n");
4641acebad3SYuan Kang 		return -ENOMEM;
4651acebad3SYuan Kang 	}
4661acebad3SYuan Kang #ifdef DEBUG
467514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead enc shdesc@"__stringify(__LINE__)": ",
4681acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
4691acebad3SYuan Kang 		       desc_bytes(desc), 1);
4701acebad3SYuan Kang #endif
4711acebad3SYuan Kang 
4721acebad3SYuan Kang 	/*
4731acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
4741acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
4751acebad3SYuan Kang 	 */
47680cd88f2SVakul Garg 	keys_fit_inline = false;
4771acebad3SYuan Kang 	if (DESC_AEAD_DEC_LEN + DESC_JOB_IO_LEN +
4781acebad3SYuan Kang 	    ctx->split_key_pad_len + ctx->enckeylen <=
4791acebad3SYuan Kang 	    CAAM_DESC_BYTES_MAX)
4802af8f4a2SKim Phillips 		keys_fit_inline = true;
4811acebad3SYuan Kang 
4824464a7d4SHoria Geanta 	/* aead_decrypt shared descriptor */
4831acebad3SYuan Kang 	desc = ctx->sh_desc_dec;
4841acebad3SYuan Kang 
4854464a7d4SHoria Geanta 	init_sh_desc_key_aead(desc, ctx, keys_fit_inline);
4861acebad3SYuan Kang 
4871acebad3SYuan Kang 	/* Class 2 operation */
4881acebad3SYuan Kang 	append_operation(desc, ctx->class2_alg_type |
4891acebad3SYuan Kang 			 OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT | OP_ALG_ICV_ON);
4901acebad3SYuan Kang 
4914464a7d4SHoria Geanta 	/* assoclen + cryptlen = seqinlen - ivsize - authsize */
4921acebad3SYuan Kang 	append_math_sub_imm_u32(desc, REG3, SEQINLEN, IMM,
493ae4a825fSHoria Geanta 				ctx->authsize + tfm->ivsize);
4941acebad3SYuan Kang 	/* assoclen = (assoclen + cryptlen) - cryptlen */
4951acebad3SYuan Kang 	append_math_sub(desc, REG2, SEQOUTLEN, REG0, CAAM_CMD_SZ);
4961acebad3SYuan Kang 	append_math_sub(desc, VARSEQINLEN, REG3, REG2, CAAM_CMD_SZ);
4971acebad3SYuan Kang 
4981acebad3SYuan Kang 	/* read assoc before reading payload */
4991acebad3SYuan Kang 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
5001acebad3SYuan Kang 			     KEY_VLF);
5011acebad3SYuan Kang 
5021acebad3SYuan Kang 	aead_append_ld_iv(desc, tfm->ivsize);
5031acebad3SYuan Kang 
5041acebad3SYuan Kang 	append_dec_op1(desc, ctx->class1_alg_type);
5051acebad3SYuan Kang 
5061acebad3SYuan Kang 	/* Read and write cryptlen bytes */
5071acebad3SYuan Kang 	append_math_add(desc, VARSEQINLEN, ZERO, REG2, CAAM_CMD_SZ);
5081acebad3SYuan Kang 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG2, CAAM_CMD_SZ);
5091acebad3SYuan Kang 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG);
5101acebad3SYuan Kang 
5111acebad3SYuan Kang 	/* Load ICV */
5121acebad3SYuan Kang 	append_seq_fifo_load(desc, ctx->authsize, FIFOLD_CLASS_CLASS2 |
5131acebad3SYuan Kang 			     FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
5141acebad3SYuan Kang 
5151acebad3SYuan Kang 	ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc,
5161acebad3SYuan Kang 					      desc_bytes(desc),
5171acebad3SYuan Kang 					      DMA_TO_DEVICE);
5181acebad3SYuan Kang 	if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) {
5191acebad3SYuan Kang 		dev_err(jrdev, "unable to map shared descriptor\n");
5201acebad3SYuan Kang 		return -ENOMEM;
5211acebad3SYuan Kang 	}
5221acebad3SYuan Kang #ifdef DEBUG
523514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead dec shdesc@"__stringify(__LINE__)": ",
5241acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
5251acebad3SYuan Kang 		       desc_bytes(desc), 1);
5261acebad3SYuan Kang #endif
5271acebad3SYuan Kang 
5281acebad3SYuan Kang 	/*
5291acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
5301acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
5311acebad3SYuan Kang 	 */
53280cd88f2SVakul Garg 	keys_fit_inline = false;
5331acebad3SYuan Kang 	if (DESC_AEAD_GIVENC_LEN + DESC_JOB_IO_LEN +
5341acebad3SYuan Kang 	    ctx->split_key_pad_len + ctx->enckeylen <=
5351acebad3SYuan Kang 	    CAAM_DESC_BYTES_MAX)
5362af8f4a2SKim Phillips 		keys_fit_inline = true;
5371acebad3SYuan Kang 
5381acebad3SYuan Kang 	/* aead_givencrypt shared descriptor */
5391acebad3SYuan Kang 	desc = ctx->sh_desc_givenc;
5401acebad3SYuan Kang 
5411acebad3SYuan Kang 	init_sh_desc_key_aead(desc, ctx, keys_fit_inline);
5421acebad3SYuan Kang 
5431acebad3SYuan Kang 	/* Generate IV */
5441acebad3SYuan Kang 	geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO |
5451acebad3SYuan Kang 		NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_LC1 |
5461acebad3SYuan Kang 		NFIFOENTRY_PTYPE_RND | (tfm->ivsize << NFIFOENTRY_DLEN_SHIFT);
5471acebad3SYuan Kang 	append_load_imm_u32(desc, geniv, LDST_CLASS_IND_CCB |
5481acebad3SYuan Kang 			    LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
5491acebad3SYuan Kang 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
5501acebad3SYuan Kang 	append_move(desc, MOVE_SRC_INFIFO |
5511acebad3SYuan Kang 		    MOVE_DEST_CLASS1CTX | (tfm->ivsize << MOVE_LEN_SHIFT));
5521acebad3SYuan Kang 	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
5531acebad3SYuan Kang 
5541acebad3SYuan Kang 	/* Copy IV to class 1 context */
5551acebad3SYuan Kang 	append_move(desc, MOVE_SRC_CLASS1CTX |
5561acebad3SYuan Kang 		    MOVE_DEST_OUTFIFO | (tfm->ivsize << MOVE_LEN_SHIFT));
5571acebad3SYuan Kang 
5581acebad3SYuan Kang 	/* Return to encryption */
5591acebad3SYuan Kang 	append_operation(desc, ctx->class2_alg_type |
5601acebad3SYuan Kang 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
5611acebad3SYuan Kang 
5621acebad3SYuan Kang 	/* ivsize + cryptlen = seqoutlen - authsize */
5631acebad3SYuan Kang 	append_math_sub_imm_u32(desc, REG3, SEQOUTLEN, IMM, ctx->authsize);
5641acebad3SYuan Kang 
5651acebad3SYuan Kang 	/* assoclen = seqinlen - (ivsize + cryptlen) */
5661acebad3SYuan Kang 	append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG3, CAAM_CMD_SZ);
5671acebad3SYuan Kang 
5681acebad3SYuan Kang 	/* read assoc before reading payload */
5691acebad3SYuan Kang 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
5701acebad3SYuan Kang 			     KEY_VLF);
5711acebad3SYuan Kang 
5721acebad3SYuan Kang 	/* Copy iv from class 1 ctx to class 2 fifo*/
5731acebad3SYuan Kang 	moveiv = NFIFOENTRY_STYPE_OFIFO | NFIFOENTRY_DEST_CLASS2 |
5741acebad3SYuan Kang 		 NFIFOENTRY_DTYPE_MSG | (tfm->ivsize << NFIFOENTRY_DLEN_SHIFT);
5751acebad3SYuan Kang 	append_load_imm_u32(desc, moveiv, LDST_CLASS_IND_CCB |
5761acebad3SYuan Kang 			    LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
5771acebad3SYuan Kang 	append_load_imm_u32(desc, tfm->ivsize, LDST_CLASS_2_CCB |
5781acebad3SYuan Kang 			    LDST_SRCDST_WORD_DATASZ_REG | LDST_IMM);
5791acebad3SYuan Kang 
5801acebad3SYuan Kang 	/* Class 1 operation */
5811acebad3SYuan Kang 	append_operation(desc, ctx->class1_alg_type |
5821acebad3SYuan Kang 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
5831acebad3SYuan Kang 
5841acebad3SYuan Kang 	/* Will write ivsize + cryptlen */
5851acebad3SYuan Kang 	append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
5861acebad3SYuan Kang 
5871acebad3SYuan Kang 	/* Not need to reload iv */
5881acebad3SYuan Kang 	append_seq_fifo_load(desc, tfm->ivsize,
5891acebad3SYuan Kang 			     FIFOLD_CLASS_SKIP);
5901acebad3SYuan Kang 
5911acebad3SYuan Kang 	/* Will read cryptlen */
5921acebad3SYuan Kang 	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
5931acebad3SYuan Kang 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
5941acebad3SYuan Kang 
5951acebad3SYuan Kang 	/* Write ICV */
5961acebad3SYuan Kang 	append_seq_store(desc, ctx->authsize, LDST_CLASS_2_CCB |
5971acebad3SYuan Kang 			 LDST_SRCDST_BYTE_CONTEXT);
5981acebad3SYuan Kang 
5991acebad3SYuan Kang 	ctx->sh_desc_givenc_dma = dma_map_single(jrdev, desc,
6001acebad3SYuan Kang 						 desc_bytes(desc),
6011acebad3SYuan Kang 						 DMA_TO_DEVICE);
6021acebad3SYuan Kang 	if (dma_mapping_error(jrdev, ctx->sh_desc_givenc_dma)) {
6031acebad3SYuan Kang 		dev_err(jrdev, "unable to map shared descriptor\n");
6041acebad3SYuan Kang 		return -ENOMEM;
6051acebad3SYuan Kang 	}
6061acebad3SYuan Kang #ifdef DEBUG
607514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead givenc shdesc@"__stringify(__LINE__)": ",
6081acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
6091acebad3SYuan Kang 		       desc_bytes(desc), 1);
6101acebad3SYuan Kang #endif
6111acebad3SYuan Kang 
6121acebad3SYuan Kang 	return 0;
6131acebad3SYuan Kang }
6141acebad3SYuan Kang 
6150e479300SYuan Kang static int aead_setauthsize(struct crypto_aead *authenc,
6168e8ec596SKim Phillips 				    unsigned int authsize)
6178e8ec596SKim Phillips {
6188e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
6198e8ec596SKim Phillips 
6208e8ec596SKim Phillips 	ctx->authsize = authsize;
6211acebad3SYuan Kang 	aead_set_sh_desc(authenc);
6228e8ec596SKim Phillips 
6238e8ec596SKim Phillips 	return 0;
6248e8ec596SKim Phillips }
6258e8ec596SKim Phillips 
6264c1ec1f9SYuan Kang static u32 gen_split_aead_key(struct caam_ctx *ctx, const u8 *key_in,
6274c1ec1f9SYuan Kang 			      u32 authkeylen)
6288e8ec596SKim Phillips {
6294c1ec1f9SYuan Kang 	return gen_split_key(ctx->jrdev, ctx->key, ctx->split_key_len,
6304c1ec1f9SYuan Kang 			       ctx->split_key_pad_len, key_in, authkeylen,
6314c1ec1f9SYuan Kang 			       ctx->alg_op);
6328e8ec596SKim Phillips }
6338e8ec596SKim Phillips 
6340e479300SYuan Kang static int aead_setkey(struct crypto_aead *aead,
6358e8ec596SKim Phillips 			       const u8 *key, unsigned int keylen)
6368e8ec596SKim Phillips {
6378e8ec596SKim Phillips 	/* Sizes for MDHA pads (*not* keys): MD5, SHA1, 224, 256, 384, 512 */
6388e8ec596SKim Phillips 	static const u8 mdpadlen[] = { 16, 20, 32, 32, 64, 64 };
6398e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
6408e8ec596SKim Phillips 	struct device *jrdev = ctx->jrdev;
6414e6e0b27SHoria Geanta 	struct crypto_authenc_keys keys;
6428e8ec596SKim Phillips 	int ret = 0;
6438e8ec596SKim Phillips 
6444e6e0b27SHoria Geanta 	if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
6458e8ec596SKim Phillips 		goto badkey;
6468e8ec596SKim Phillips 
6478e8ec596SKim Phillips 	/* Pick class 2 key length from algorithm submask */
6488e8ec596SKim Phillips 	ctx->split_key_len = mdpadlen[(ctx->alg_op & OP_ALG_ALGSEL_SUBMASK) >>
6498e8ec596SKim Phillips 				      OP_ALG_ALGSEL_SHIFT] * 2;
6508e8ec596SKim Phillips 	ctx->split_key_pad_len = ALIGN(ctx->split_key_len, 16);
6518e8ec596SKim Phillips 
6524e6e0b27SHoria Geanta 	if (ctx->split_key_pad_len + keys.enckeylen > CAAM_MAX_KEY_SIZE)
6534e6e0b27SHoria Geanta 		goto badkey;
6544e6e0b27SHoria Geanta 
6558e8ec596SKim Phillips #ifdef DEBUG
6568e8ec596SKim Phillips 	printk(KERN_ERR "keylen %d enckeylen %d authkeylen %d\n",
6574e6e0b27SHoria Geanta 	       keys.authkeylen + keys.enckeylen, keys.enckeylen,
6584e6e0b27SHoria Geanta 	       keys.authkeylen);
6598e8ec596SKim Phillips 	printk(KERN_ERR "split_key_len %d split_key_pad_len %d\n",
6608e8ec596SKim Phillips 	       ctx->split_key_len, ctx->split_key_pad_len);
661514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
6628e8ec596SKim Phillips 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
6638e8ec596SKim Phillips #endif
6648e8ec596SKim Phillips 
6654e6e0b27SHoria Geanta 	ret = gen_split_aead_key(ctx, keys.authkey, keys.authkeylen);
6668e8ec596SKim Phillips 	if (ret) {
6678e8ec596SKim Phillips 		goto badkey;
6688e8ec596SKim Phillips 	}
6698e8ec596SKim Phillips 
6708e8ec596SKim Phillips 	/* postpend encryption key to auth split key */
6714e6e0b27SHoria Geanta 	memcpy(ctx->key + ctx->split_key_pad_len, keys.enckey, keys.enckeylen);
6728e8ec596SKim Phillips 
673885e9e2fSYuan Kang 	ctx->key_dma = dma_map_single(jrdev, ctx->key, ctx->split_key_pad_len +
6744e6e0b27SHoria Geanta 				      keys.enckeylen, DMA_TO_DEVICE);
675885e9e2fSYuan Kang 	if (dma_mapping_error(jrdev, ctx->key_dma)) {
6768e8ec596SKim Phillips 		dev_err(jrdev, "unable to map key i/o memory\n");
6778e8ec596SKim Phillips 		return -ENOMEM;
6788e8ec596SKim Phillips 	}
6798e8ec596SKim Phillips #ifdef DEBUG
680514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "ctx.key@"__stringify(__LINE__)": ",
6818e8ec596SKim Phillips 		       DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
6824e6e0b27SHoria Geanta 		       ctx->split_key_pad_len + keys.enckeylen, 1);
6838e8ec596SKim Phillips #endif
6848e8ec596SKim Phillips 
6854e6e0b27SHoria Geanta 	ctx->enckeylen = keys.enckeylen;
6868e8ec596SKim Phillips 
6871acebad3SYuan Kang 	ret = aead_set_sh_desc(aead);
6888e8ec596SKim Phillips 	if (ret) {
689885e9e2fSYuan Kang 		dma_unmap_single(jrdev, ctx->key_dma, ctx->split_key_pad_len +
6904e6e0b27SHoria Geanta 				 keys.enckeylen, DMA_TO_DEVICE);
6918e8ec596SKim Phillips 	}
6928e8ec596SKim Phillips 
6938e8ec596SKim Phillips 	return ret;
6948e8ec596SKim Phillips badkey:
6958e8ec596SKim Phillips 	crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
6968e8ec596SKim Phillips 	return -EINVAL;
6978e8ec596SKim Phillips }
6988e8ec596SKim Phillips 
699acdca31dSYuan Kang static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
700acdca31dSYuan Kang 			     const u8 *key, unsigned int keylen)
701acdca31dSYuan Kang {
702acdca31dSYuan Kang 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
703acdca31dSYuan Kang 	struct ablkcipher_tfm *tfm = &ablkcipher->base.crt_ablkcipher;
704acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
705acdca31dSYuan Kang 	int ret = 0;
7064464a7d4SHoria Geanta 	u32 *key_jump_cmd;
707acdca31dSYuan Kang 	u32 *desc;
708acdca31dSYuan Kang 
709acdca31dSYuan Kang #ifdef DEBUG
710514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
711acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
712acdca31dSYuan Kang #endif
713acdca31dSYuan Kang 
714acdca31dSYuan Kang 	memcpy(ctx->key, key, keylen);
715acdca31dSYuan Kang 	ctx->key_dma = dma_map_single(jrdev, ctx->key, keylen,
716acdca31dSYuan Kang 				      DMA_TO_DEVICE);
717acdca31dSYuan Kang 	if (dma_mapping_error(jrdev, ctx->key_dma)) {
718acdca31dSYuan Kang 		dev_err(jrdev, "unable to map key i/o memory\n");
719acdca31dSYuan Kang 		return -ENOMEM;
720acdca31dSYuan Kang 	}
721acdca31dSYuan Kang 	ctx->enckeylen = keylen;
722acdca31dSYuan Kang 
723acdca31dSYuan Kang 	/* ablkcipher_encrypt shared descriptor */
724acdca31dSYuan Kang 	desc = ctx->sh_desc_enc;
72561bb86bbSKim Phillips 	init_sh_desc(desc, HDR_SHARE_SERIAL);
726acdca31dSYuan Kang 	/* Skip if already shared */
727acdca31dSYuan Kang 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
728acdca31dSYuan Kang 				   JUMP_COND_SHRD);
729acdca31dSYuan Kang 
730acdca31dSYuan Kang 	/* Load class1 key only */
731acdca31dSYuan Kang 	append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
732acdca31dSYuan Kang 			  ctx->enckeylen, CLASS_1 |
733acdca31dSYuan Kang 			  KEY_DEST_CLASS_REG);
734acdca31dSYuan Kang 
735acdca31dSYuan Kang 	set_jump_tgt_here(desc, key_jump_cmd);
736acdca31dSYuan Kang 
737acdca31dSYuan Kang 	/* Load iv */
738acdca31dSYuan Kang 	append_cmd(desc, CMD_SEQ_LOAD | LDST_SRCDST_BYTE_CONTEXT |
739acdca31dSYuan Kang 		   LDST_CLASS_1_CCB | tfm->ivsize);
740acdca31dSYuan Kang 
741acdca31dSYuan Kang 	/* Load operation */
742acdca31dSYuan Kang 	append_operation(desc, ctx->class1_alg_type |
743acdca31dSYuan Kang 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
744acdca31dSYuan Kang 
745acdca31dSYuan Kang 	/* Perform operation */
746acdca31dSYuan Kang 	ablkcipher_append_src_dst(desc);
747acdca31dSYuan Kang 
748acdca31dSYuan Kang 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc,
749acdca31dSYuan Kang 					      desc_bytes(desc),
750acdca31dSYuan Kang 					      DMA_TO_DEVICE);
751acdca31dSYuan Kang 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
752acdca31dSYuan Kang 		dev_err(jrdev, "unable to map shared descriptor\n");
753acdca31dSYuan Kang 		return -ENOMEM;
754acdca31dSYuan Kang 	}
755acdca31dSYuan Kang #ifdef DEBUG
756514df281SAlex Porosanu 	print_hex_dump(KERN_ERR,
757514df281SAlex Porosanu 		       "ablkcipher enc shdesc@"__stringify(__LINE__)": ",
758acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
759acdca31dSYuan Kang 		       desc_bytes(desc), 1);
760acdca31dSYuan Kang #endif
761acdca31dSYuan Kang 	/* ablkcipher_decrypt shared descriptor */
762acdca31dSYuan Kang 	desc = ctx->sh_desc_dec;
763acdca31dSYuan Kang 
76461bb86bbSKim Phillips 	init_sh_desc(desc, HDR_SHARE_SERIAL);
765acdca31dSYuan Kang 	/* Skip if already shared */
766acdca31dSYuan Kang 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
767acdca31dSYuan Kang 				   JUMP_COND_SHRD);
768acdca31dSYuan Kang 
769acdca31dSYuan Kang 	/* Load class1 key only */
770acdca31dSYuan Kang 	append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
771acdca31dSYuan Kang 			  ctx->enckeylen, CLASS_1 |
772acdca31dSYuan Kang 			  KEY_DEST_CLASS_REG);
773acdca31dSYuan Kang 
774acdca31dSYuan Kang 	set_jump_tgt_here(desc, key_jump_cmd);
775acdca31dSYuan Kang 
776acdca31dSYuan Kang 	/* load IV */
777acdca31dSYuan Kang 	append_cmd(desc, CMD_SEQ_LOAD | LDST_SRCDST_BYTE_CONTEXT |
778acdca31dSYuan Kang 		   LDST_CLASS_1_CCB | tfm->ivsize);
779acdca31dSYuan Kang 
780acdca31dSYuan Kang 	/* Choose operation */
781acdca31dSYuan Kang 	append_dec_op1(desc, ctx->class1_alg_type);
782acdca31dSYuan Kang 
783acdca31dSYuan Kang 	/* Perform operation */
784acdca31dSYuan Kang 	ablkcipher_append_src_dst(desc);
785acdca31dSYuan Kang 
786acdca31dSYuan Kang 	ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc,
787acdca31dSYuan Kang 					      desc_bytes(desc),
788acdca31dSYuan Kang 					      DMA_TO_DEVICE);
789acdca31dSYuan Kang 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
790acdca31dSYuan Kang 		dev_err(jrdev, "unable to map shared descriptor\n");
791acdca31dSYuan Kang 		return -ENOMEM;
792acdca31dSYuan Kang 	}
793acdca31dSYuan Kang 
794acdca31dSYuan Kang #ifdef DEBUG
795514df281SAlex Porosanu 	print_hex_dump(KERN_ERR,
796514df281SAlex Porosanu 		       "ablkcipher dec shdesc@"__stringify(__LINE__)": ",
797acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
798acdca31dSYuan Kang 		       desc_bytes(desc), 1);
799acdca31dSYuan Kang #endif
800acdca31dSYuan Kang 
801acdca31dSYuan Kang 	return ret;
802acdca31dSYuan Kang }
803acdca31dSYuan Kang 
8048e8ec596SKim Phillips /*
8051acebad3SYuan Kang  * aead_edesc - s/w-extended aead descriptor
8061acebad3SYuan Kang  * @assoc_nents: number of segments in associated data (SPI+Seq) scatterlist
807643b39b0SYuan Kang  * @assoc_chained: if source is chained
8088e8ec596SKim Phillips  * @src_nents: number of segments in input scatterlist
809643b39b0SYuan Kang  * @src_chained: if source is chained
8108e8ec596SKim Phillips  * @dst_nents: number of segments in output scatterlist
811643b39b0SYuan Kang  * @dst_chained: if destination is chained
8121acebad3SYuan Kang  * @iv_dma: dma address of iv for checking continuity and link table
8138e8ec596SKim Phillips  * @desc: h/w descriptor (variable length; must not exceed MAX_CAAM_DESCSIZE)
814a299c837SYuan Kang  * @sec4_sg_bytes: length of dma mapped sec4_sg space
815a299c837SYuan Kang  * @sec4_sg_dma: bus physical mapped address of h/w link table
8168e8ec596SKim Phillips  * @hw_desc: the h/w job descriptor followed by any referenced link tables
8178e8ec596SKim Phillips  */
8180e479300SYuan Kang struct aead_edesc {
8198e8ec596SKim Phillips 	int assoc_nents;
820643b39b0SYuan Kang 	bool assoc_chained;
8218e8ec596SKim Phillips 	int src_nents;
822643b39b0SYuan Kang 	bool src_chained;
8238e8ec596SKim Phillips 	int dst_nents;
824643b39b0SYuan Kang 	bool dst_chained;
8251acebad3SYuan Kang 	dma_addr_t iv_dma;
826a299c837SYuan Kang 	int sec4_sg_bytes;
827a299c837SYuan Kang 	dma_addr_t sec4_sg_dma;
828a299c837SYuan Kang 	struct sec4_sg_entry *sec4_sg;
8298e8ec596SKim Phillips 	u32 hw_desc[0];
8308e8ec596SKim Phillips };
8318e8ec596SKim Phillips 
832acdca31dSYuan Kang /*
833acdca31dSYuan Kang  * ablkcipher_edesc - s/w-extended ablkcipher descriptor
834acdca31dSYuan Kang  * @src_nents: number of segments in input scatterlist
835643b39b0SYuan Kang  * @src_chained: if source is chained
836acdca31dSYuan Kang  * @dst_nents: number of segments in output scatterlist
837643b39b0SYuan Kang  * @dst_chained: if destination is chained
838acdca31dSYuan Kang  * @iv_dma: dma address of iv for checking continuity and link table
839acdca31dSYuan Kang  * @desc: h/w descriptor (variable length; must not exceed MAX_CAAM_DESCSIZE)
840a299c837SYuan Kang  * @sec4_sg_bytes: length of dma mapped sec4_sg space
841a299c837SYuan Kang  * @sec4_sg_dma: bus physical mapped address of h/w link table
842acdca31dSYuan Kang  * @hw_desc: the h/w job descriptor followed by any referenced link tables
843acdca31dSYuan Kang  */
844acdca31dSYuan Kang struct ablkcipher_edesc {
845acdca31dSYuan Kang 	int src_nents;
846643b39b0SYuan Kang 	bool src_chained;
847acdca31dSYuan Kang 	int dst_nents;
848643b39b0SYuan Kang 	bool dst_chained;
849acdca31dSYuan Kang 	dma_addr_t iv_dma;
850a299c837SYuan Kang 	int sec4_sg_bytes;
851a299c837SYuan Kang 	dma_addr_t sec4_sg_dma;
852a299c837SYuan Kang 	struct sec4_sg_entry *sec4_sg;
853acdca31dSYuan Kang 	u32 hw_desc[0];
854acdca31dSYuan Kang };
855acdca31dSYuan Kang 
8561acebad3SYuan Kang static void caam_unmap(struct device *dev, struct scatterlist *src,
857643b39b0SYuan Kang 		       struct scatterlist *dst, int src_nents,
858643b39b0SYuan Kang 		       bool src_chained, int dst_nents, bool dst_chained,
859a299c837SYuan Kang 		       dma_addr_t iv_dma, int ivsize, dma_addr_t sec4_sg_dma,
860a299c837SYuan Kang 		       int sec4_sg_bytes)
8611acebad3SYuan Kang {
862643b39b0SYuan Kang 	if (dst != src) {
863643b39b0SYuan Kang 		dma_unmap_sg_chained(dev, src, src_nents ? : 1, DMA_TO_DEVICE,
864643b39b0SYuan Kang 				     src_chained);
865643b39b0SYuan Kang 		dma_unmap_sg_chained(dev, dst, dst_nents ? : 1, DMA_FROM_DEVICE,
866643b39b0SYuan Kang 				     dst_chained);
8671acebad3SYuan Kang 	} else {
868643b39b0SYuan Kang 		dma_unmap_sg_chained(dev, src, src_nents ? : 1,
869643b39b0SYuan Kang 				     DMA_BIDIRECTIONAL, src_chained);
8701acebad3SYuan Kang 	}
8711acebad3SYuan Kang 
8721acebad3SYuan Kang 	if (iv_dma)
8731acebad3SYuan Kang 		dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE);
874a299c837SYuan Kang 	if (sec4_sg_bytes)
875a299c837SYuan Kang 		dma_unmap_single(dev, sec4_sg_dma, sec4_sg_bytes,
8761acebad3SYuan Kang 				 DMA_TO_DEVICE);
8771acebad3SYuan Kang }
8781acebad3SYuan Kang 
8790e479300SYuan Kang static void aead_unmap(struct device *dev,
8800e479300SYuan Kang 		       struct aead_edesc *edesc,
8810e479300SYuan Kang 		       struct aead_request *req)
8828e8ec596SKim Phillips {
8831acebad3SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
8841acebad3SYuan Kang 	int ivsize = crypto_aead_ivsize(aead);
8851acebad3SYuan Kang 
886643b39b0SYuan Kang 	dma_unmap_sg_chained(dev, req->assoc, edesc->assoc_nents,
887643b39b0SYuan Kang 			     DMA_TO_DEVICE, edesc->assoc_chained);
8888e8ec596SKim Phillips 
8891acebad3SYuan Kang 	caam_unmap(dev, req->src, req->dst,
890643b39b0SYuan Kang 		   edesc->src_nents, edesc->src_chained, edesc->dst_nents,
891643b39b0SYuan Kang 		   edesc->dst_chained, edesc->iv_dma, ivsize,
892643b39b0SYuan Kang 		   edesc->sec4_sg_dma, edesc->sec4_sg_bytes);
8938e8ec596SKim Phillips }
8948e8ec596SKim Phillips 
895acdca31dSYuan Kang static void ablkcipher_unmap(struct device *dev,
896acdca31dSYuan Kang 			     struct ablkcipher_edesc *edesc,
897acdca31dSYuan Kang 			     struct ablkcipher_request *req)
898acdca31dSYuan Kang {
899acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
900acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
901acdca31dSYuan Kang 
902acdca31dSYuan Kang 	caam_unmap(dev, req->src, req->dst,
903643b39b0SYuan Kang 		   edesc->src_nents, edesc->src_chained, edesc->dst_nents,
904643b39b0SYuan Kang 		   edesc->dst_chained, edesc->iv_dma, ivsize,
905643b39b0SYuan Kang 		   edesc->sec4_sg_dma, edesc->sec4_sg_bytes);
906acdca31dSYuan Kang }
907acdca31dSYuan Kang 
9080e479300SYuan Kang static void aead_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
9098e8ec596SKim Phillips 				   void *context)
9108e8ec596SKim Phillips {
9110e479300SYuan Kang 	struct aead_request *req = context;
9120e479300SYuan Kang 	struct aead_edesc *edesc;
9138e8ec596SKim Phillips #ifdef DEBUG
9140e479300SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
9158e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
9161acebad3SYuan Kang 	int ivsize = crypto_aead_ivsize(aead);
9178e8ec596SKim Phillips 
9188e8ec596SKim Phillips 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
9198e8ec596SKim Phillips #endif
9201acebad3SYuan Kang 
9210e479300SYuan Kang 	edesc = (struct aead_edesc *)((char *)desc -
9220e479300SYuan Kang 		 offsetof(struct aead_edesc, hw_desc));
9238e8ec596SKim Phillips 
924fa9659cdSMarek Vasut 	if (err)
925fa9659cdSMarek Vasut 		caam_jr_strstatus(jrdev, err);
9268e8ec596SKim Phillips 
9270e479300SYuan Kang 	aead_unmap(jrdev, edesc, req);
9288e8ec596SKim Phillips 
9298e8ec596SKim Phillips #ifdef DEBUG
930514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "assoc  @"__stringify(__LINE__)": ",
9310e479300SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->assoc),
9320e479300SYuan Kang 		       req->assoclen , 1);
933514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "dstiv  @"__stringify(__LINE__)": ",
9340e479300SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src) - ivsize,
9358e8ec596SKim Phillips 		       edesc->src_nents ? 100 : ivsize, 1);
936514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "dst    @"__stringify(__LINE__)": ",
9370e479300SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src),
9380e479300SYuan Kang 		       edesc->src_nents ? 100 : req->cryptlen +
9398e8ec596SKim Phillips 		       ctx->authsize + 4, 1);
9408e8ec596SKim Phillips #endif
9418e8ec596SKim Phillips 
9428e8ec596SKim Phillips 	kfree(edesc);
9438e8ec596SKim Phillips 
9440e479300SYuan Kang 	aead_request_complete(req, err);
9458e8ec596SKim Phillips }
9468e8ec596SKim Phillips 
9470e479300SYuan Kang static void aead_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
9488e8ec596SKim Phillips 				   void *context)
9498e8ec596SKim Phillips {
9500e479300SYuan Kang 	struct aead_request *req = context;
9510e479300SYuan Kang 	struct aead_edesc *edesc;
9528e8ec596SKim Phillips #ifdef DEBUG
9530e479300SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
9548e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
9551acebad3SYuan Kang 	int ivsize = crypto_aead_ivsize(aead);
9568e8ec596SKim Phillips 
9578e8ec596SKim Phillips 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
9588e8ec596SKim Phillips #endif
9591acebad3SYuan Kang 
9600e479300SYuan Kang 	edesc = (struct aead_edesc *)((char *)desc -
9610e479300SYuan Kang 		 offsetof(struct aead_edesc, hw_desc));
9628e8ec596SKim Phillips 
9631acebad3SYuan Kang #ifdef DEBUG
964514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "dstiv  @"__stringify(__LINE__)": ",
9651acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, req->iv,
9661acebad3SYuan Kang 		       ivsize, 1);
967514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "dst    @"__stringify(__LINE__)": ",
9681acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->dst),
969bbf9c893SHoria Geanta 		       req->cryptlen - ctx->authsize, 1);
9701acebad3SYuan Kang #endif
9711acebad3SYuan Kang 
972fa9659cdSMarek Vasut 	if (err)
973fa9659cdSMarek Vasut 		caam_jr_strstatus(jrdev, err);
9748e8ec596SKim Phillips 
9750e479300SYuan Kang 	aead_unmap(jrdev, edesc, req);
9768e8ec596SKim Phillips 
9778e8ec596SKim Phillips 	/*
9788e8ec596SKim Phillips 	 * verify hw auth check passed else return -EBADMSG
9798e8ec596SKim Phillips 	 */
9808e8ec596SKim Phillips 	if ((err & JRSTA_CCBERR_ERRID_MASK) == JRSTA_CCBERR_ERRID_ICVCHK)
9818e8ec596SKim Phillips 		err = -EBADMSG;
9828e8ec596SKim Phillips 
9838e8ec596SKim Phillips #ifdef DEBUG
984514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "iphdrout@"__stringify(__LINE__)": ",
9858e8ec596SKim Phillips 		       DUMP_PREFIX_ADDRESS, 16, 4,
9860e479300SYuan Kang 		       ((char *)sg_virt(req->assoc) - sizeof(struct iphdr)),
9870e479300SYuan Kang 		       sizeof(struct iphdr) + req->assoclen +
9880e479300SYuan Kang 		       ((req->cryptlen > 1500) ? 1500 : req->cryptlen) +
9898e8ec596SKim Phillips 		       ctx->authsize + 36, 1);
990a299c837SYuan Kang 	if (!err && edesc->sec4_sg_bytes) {
9910e479300SYuan Kang 		struct scatterlist *sg = sg_last(req->src, edesc->src_nents);
992514df281SAlex Porosanu 		print_hex_dump(KERN_ERR, "sglastout@"__stringify(__LINE__)": ",
9938e8ec596SKim Phillips 			       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(sg),
9948e8ec596SKim Phillips 			sg->length + ctx->authsize + 16, 1);
9958e8ec596SKim Phillips 	}
9968e8ec596SKim Phillips #endif
9971acebad3SYuan Kang 
9988e8ec596SKim Phillips 	kfree(edesc);
9998e8ec596SKim Phillips 
10000e479300SYuan Kang 	aead_request_complete(req, err);
10018e8ec596SKim Phillips }
10028e8ec596SKim Phillips 
1003acdca31dSYuan Kang static void ablkcipher_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
1004acdca31dSYuan Kang 				   void *context)
1005acdca31dSYuan Kang {
1006acdca31dSYuan Kang 	struct ablkcipher_request *req = context;
1007acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
1008acdca31dSYuan Kang #ifdef DEBUG
1009acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
1010acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
1011acdca31dSYuan Kang 
1012acdca31dSYuan Kang 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
1013acdca31dSYuan Kang #endif
1014acdca31dSYuan Kang 
1015acdca31dSYuan Kang 	edesc = (struct ablkcipher_edesc *)((char *)desc -
1016acdca31dSYuan Kang 		 offsetof(struct ablkcipher_edesc, hw_desc));
1017acdca31dSYuan Kang 
1018fa9659cdSMarek Vasut 	if (err)
1019fa9659cdSMarek Vasut 		caam_jr_strstatus(jrdev, err);
1020acdca31dSYuan Kang 
1021acdca31dSYuan Kang #ifdef DEBUG
1022514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "dstiv  @"__stringify(__LINE__)": ",
1023acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, req->info,
1024acdca31dSYuan Kang 		       edesc->src_nents > 1 ? 100 : ivsize, 1);
1025514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "dst    @"__stringify(__LINE__)": ",
1026acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src),
1027acdca31dSYuan Kang 		       edesc->dst_nents > 1 ? 100 : req->nbytes, 1);
1028acdca31dSYuan Kang #endif
1029acdca31dSYuan Kang 
1030acdca31dSYuan Kang 	ablkcipher_unmap(jrdev, edesc, req);
1031acdca31dSYuan Kang 	kfree(edesc);
1032acdca31dSYuan Kang 
1033acdca31dSYuan Kang 	ablkcipher_request_complete(req, err);
1034acdca31dSYuan Kang }
1035acdca31dSYuan Kang 
1036acdca31dSYuan Kang static void ablkcipher_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
1037acdca31dSYuan Kang 				    void *context)
1038acdca31dSYuan Kang {
1039acdca31dSYuan Kang 	struct ablkcipher_request *req = context;
1040acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
1041acdca31dSYuan Kang #ifdef DEBUG
1042acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
1043acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
1044acdca31dSYuan Kang 
1045acdca31dSYuan Kang 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
1046acdca31dSYuan Kang #endif
1047acdca31dSYuan Kang 
1048acdca31dSYuan Kang 	edesc = (struct ablkcipher_edesc *)((char *)desc -
1049acdca31dSYuan Kang 		 offsetof(struct ablkcipher_edesc, hw_desc));
1050fa9659cdSMarek Vasut 	if (err)
1051fa9659cdSMarek Vasut 		caam_jr_strstatus(jrdev, err);
1052acdca31dSYuan Kang 
1053acdca31dSYuan Kang #ifdef DEBUG
1054514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "dstiv  @"__stringify(__LINE__)": ",
1055acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, req->info,
1056acdca31dSYuan Kang 		       ivsize, 1);
1057514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "dst    @"__stringify(__LINE__)": ",
1058acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src),
1059acdca31dSYuan Kang 		       edesc->dst_nents > 1 ? 100 : req->nbytes, 1);
1060acdca31dSYuan Kang #endif
1061acdca31dSYuan Kang 
1062acdca31dSYuan Kang 	ablkcipher_unmap(jrdev, edesc, req);
1063acdca31dSYuan Kang 	kfree(edesc);
1064acdca31dSYuan Kang 
1065acdca31dSYuan Kang 	ablkcipher_request_complete(req, err);
1066acdca31dSYuan Kang }
1067acdca31dSYuan Kang 
10688e8ec596SKim Phillips /*
10691acebad3SYuan Kang  * Fill in aead job descriptor
10708e8ec596SKim Phillips  */
10711acebad3SYuan Kang static void init_aead_job(u32 *sh_desc, dma_addr_t ptr,
10721acebad3SYuan Kang 			  struct aead_edesc *edesc,
10731acebad3SYuan Kang 			  struct aead_request *req,
10741acebad3SYuan Kang 			  bool all_contig, bool encrypt)
10758e8ec596SKim Phillips {
10760e479300SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
10778e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
10788e8ec596SKim Phillips 	int ivsize = crypto_aead_ivsize(aead);
10798e8ec596SKim Phillips 	int authsize = ctx->authsize;
10801acebad3SYuan Kang 	u32 *desc = edesc->hw_desc;
10811acebad3SYuan Kang 	u32 out_options = 0, in_options;
10821acebad3SYuan Kang 	dma_addr_t dst_dma, src_dma;
1083a299c837SYuan Kang 	int len, sec4_sg_index = 0;
10848e8ec596SKim Phillips 
10851acebad3SYuan Kang #ifdef DEBUG
10868e8ec596SKim Phillips 	debug("assoclen %d cryptlen %d authsize %d\n",
10870e479300SYuan Kang 	      req->assoclen, req->cryptlen, authsize);
1088514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "assoc  @"__stringify(__LINE__)": ",
10890e479300SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->assoc),
10900e479300SYuan Kang 		       req->assoclen , 1);
1091514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "presciv@"__stringify(__LINE__)": ",
10921acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, req->iv,
10938e8ec596SKim Phillips 		       edesc->src_nents ? 100 : ivsize, 1);
1094514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "src    @"__stringify(__LINE__)": ",
10950e479300SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src),
10961acebad3SYuan Kang 			edesc->src_nents ? 100 : req->cryptlen, 1);
1097514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "shrdesc@"__stringify(__LINE__)": ",
10988e8ec596SKim Phillips 		       DUMP_PREFIX_ADDRESS, 16, 4, sh_desc,
10998e8ec596SKim Phillips 		       desc_bytes(sh_desc), 1);
11008e8ec596SKim Phillips #endif
11011acebad3SYuan Kang 
11021acebad3SYuan Kang 	len = desc_len(sh_desc);
11031acebad3SYuan Kang 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
11041acebad3SYuan Kang 
11051acebad3SYuan Kang 	if (all_contig) {
11061acebad3SYuan Kang 		src_dma = sg_dma_address(req->assoc);
11071acebad3SYuan Kang 		in_options = 0;
11081acebad3SYuan Kang 	} else {
1109a299c837SYuan Kang 		src_dma = edesc->sec4_sg_dma;
1110a299c837SYuan Kang 		sec4_sg_index += (edesc->assoc_nents ? : 1) + 1 +
11111acebad3SYuan Kang 				 (edesc->src_nents ? : 1);
11121acebad3SYuan Kang 		in_options = LDST_SGF;
11131acebad3SYuan Kang 	}
1114bbf9c893SHoria Geanta 
1115bbf9c893SHoria Geanta 	append_seq_in_ptr(desc, src_dma, req->assoclen + ivsize + req->cryptlen,
1116bbf9c893SHoria Geanta 			  in_options);
11178e8ec596SKim Phillips 
11181acebad3SYuan Kang 	if (likely(req->src == req->dst)) {
11191acebad3SYuan Kang 		if (all_contig) {
11201acebad3SYuan Kang 			dst_dma = sg_dma_address(req->src);
11218e8ec596SKim Phillips 		} else {
1122a299c837SYuan Kang 			dst_dma = src_dma + sizeof(struct sec4_sg_entry) *
11231acebad3SYuan Kang 				  ((edesc->assoc_nents ? : 1) + 1);
11241acebad3SYuan Kang 			out_options = LDST_SGF;
11258e8ec596SKim Phillips 		}
11268e8ec596SKim Phillips 	} else {
11278e8ec596SKim Phillips 		if (!edesc->dst_nents) {
11280e479300SYuan Kang 			dst_dma = sg_dma_address(req->dst);
11298e8ec596SKim Phillips 		} else {
1130a299c837SYuan Kang 			dst_dma = edesc->sec4_sg_dma +
1131a299c837SYuan Kang 				  sec4_sg_index *
1132a299c837SYuan Kang 				  sizeof(struct sec4_sg_entry);
11331acebad3SYuan Kang 			out_options = LDST_SGF;
11348e8ec596SKim Phillips 		}
11358e8ec596SKim Phillips 	}
11368e8ec596SKim Phillips 	if (encrypt)
1137bbf9c893SHoria Geanta 		append_seq_out_ptr(desc, dst_dma, req->cryptlen + authsize,
1138bbf9c893SHoria Geanta 				   out_options);
11398e8ec596SKim Phillips 	else
11401acebad3SYuan Kang 		append_seq_out_ptr(desc, dst_dma, req->cryptlen - authsize,
11411acebad3SYuan Kang 				   out_options);
11421acebad3SYuan Kang }
11431acebad3SYuan Kang 
11441acebad3SYuan Kang /*
11451acebad3SYuan Kang  * Fill in aead givencrypt job descriptor
11461acebad3SYuan Kang  */
11471acebad3SYuan Kang static void init_aead_giv_job(u32 *sh_desc, dma_addr_t ptr,
11481acebad3SYuan Kang 			      struct aead_edesc *edesc,
11491acebad3SYuan Kang 			      struct aead_request *req,
11501acebad3SYuan Kang 			      int contig)
11511acebad3SYuan Kang {
11521acebad3SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
11531acebad3SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
11541acebad3SYuan Kang 	int ivsize = crypto_aead_ivsize(aead);
11551acebad3SYuan Kang 	int authsize = ctx->authsize;
11561acebad3SYuan Kang 	u32 *desc = edesc->hw_desc;
11571acebad3SYuan Kang 	u32 out_options = 0, in_options;
11581acebad3SYuan Kang 	dma_addr_t dst_dma, src_dma;
1159a299c837SYuan Kang 	int len, sec4_sg_index = 0;
11608e8ec596SKim Phillips 
11618e8ec596SKim Phillips #ifdef DEBUG
11621acebad3SYuan Kang 	debug("assoclen %d cryptlen %d authsize %d\n",
11631acebad3SYuan Kang 	      req->assoclen, req->cryptlen, authsize);
1164514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "assoc  @"__stringify(__LINE__)": ",
11651acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->assoc),
11661acebad3SYuan Kang 		       req->assoclen , 1);
1167514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "presciv@"__stringify(__LINE__)": ",
11681acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, req->iv, ivsize, 1);
1169514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "src    @"__stringify(__LINE__)": ",
11701acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src),
11711acebad3SYuan Kang 			edesc->src_nents > 1 ? 100 : req->cryptlen, 1);
1172514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "shrdesc@"__stringify(__LINE__)": ",
11731acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, sh_desc,
11741acebad3SYuan Kang 		       desc_bytes(sh_desc), 1);
11758e8ec596SKim Phillips #endif
11768e8ec596SKim Phillips 
11771acebad3SYuan Kang 	len = desc_len(sh_desc);
11781acebad3SYuan Kang 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
11791acebad3SYuan Kang 
11801acebad3SYuan Kang 	if (contig & GIV_SRC_CONTIG) {
11811acebad3SYuan Kang 		src_dma = sg_dma_address(req->assoc);
11821acebad3SYuan Kang 		in_options = 0;
11831acebad3SYuan Kang 	} else {
1184a299c837SYuan Kang 		src_dma = edesc->sec4_sg_dma;
1185a299c837SYuan Kang 		sec4_sg_index += edesc->assoc_nents + 1 + edesc->src_nents;
11861acebad3SYuan Kang 		in_options = LDST_SGF;
11871acebad3SYuan Kang 	}
1188bbf9c893SHoria Geanta 	append_seq_in_ptr(desc, src_dma, req->assoclen + ivsize + req->cryptlen,
1189bbf9c893SHoria Geanta 			  in_options);
11901acebad3SYuan Kang 
11911acebad3SYuan Kang 	if (contig & GIV_DST_CONTIG) {
11921acebad3SYuan Kang 		dst_dma = edesc->iv_dma;
11931acebad3SYuan Kang 	} else {
11941acebad3SYuan Kang 		if (likely(req->src == req->dst)) {
1195a299c837SYuan Kang 			dst_dma = src_dma + sizeof(struct sec4_sg_entry) *
11961acebad3SYuan Kang 				  edesc->assoc_nents;
11971acebad3SYuan Kang 			out_options = LDST_SGF;
11981acebad3SYuan Kang 		} else {
1199a299c837SYuan Kang 			dst_dma = edesc->sec4_sg_dma +
1200a299c837SYuan Kang 				  sec4_sg_index *
1201a299c837SYuan Kang 				  sizeof(struct sec4_sg_entry);
12021acebad3SYuan Kang 			out_options = LDST_SGF;
12031acebad3SYuan Kang 		}
12048e8ec596SKim Phillips 	}
12058e8ec596SKim Phillips 
1206bbf9c893SHoria Geanta 	append_seq_out_ptr(desc, dst_dma, ivsize + req->cryptlen + authsize,
1207bbf9c893SHoria Geanta 			   out_options);
12088e8ec596SKim Phillips }
12098e8ec596SKim Phillips 
12108e8ec596SKim Phillips /*
1211acdca31dSYuan Kang  * Fill in ablkcipher job descriptor
1212acdca31dSYuan Kang  */
1213acdca31dSYuan Kang static void init_ablkcipher_job(u32 *sh_desc, dma_addr_t ptr,
1214acdca31dSYuan Kang 				struct ablkcipher_edesc *edesc,
1215acdca31dSYuan Kang 				struct ablkcipher_request *req,
1216acdca31dSYuan Kang 				bool iv_contig)
1217acdca31dSYuan Kang {
1218acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
1219acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
1220acdca31dSYuan Kang 	u32 *desc = edesc->hw_desc;
1221acdca31dSYuan Kang 	u32 out_options = 0, in_options;
1222acdca31dSYuan Kang 	dma_addr_t dst_dma, src_dma;
1223a299c837SYuan Kang 	int len, sec4_sg_index = 0;
1224acdca31dSYuan Kang 
1225acdca31dSYuan Kang #ifdef DEBUG
1226514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "presciv@"__stringify(__LINE__)": ",
1227acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, req->info,
1228acdca31dSYuan Kang 		       ivsize, 1);
1229514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "src    @"__stringify(__LINE__)": ",
1230acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src),
1231acdca31dSYuan Kang 		       edesc->src_nents ? 100 : req->nbytes, 1);
1232acdca31dSYuan Kang #endif
1233acdca31dSYuan Kang 
1234acdca31dSYuan Kang 	len = desc_len(sh_desc);
1235acdca31dSYuan Kang 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
1236acdca31dSYuan Kang 
1237acdca31dSYuan Kang 	if (iv_contig) {
1238acdca31dSYuan Kang 		src_dma = edesc->iv_dma;
1239acdca31dSYuan Kang 		in_options = 0;
1240acdca31dSYuan Kang 	} else {
1241a299c837SYuan Kang 		src_dma = edesc->sec4_sg_dma;
1242a299c837SYuan Kang 		sec4_sg_index += (iv_contig ? 0 : 1) + edesc->src_nents;
1243acdca31dSYuan Kang 		in_options = LDST_SGF;
1244acdca31dSYuan Kang 	}
1245acdca31dSYuan Kang 	append_seq_in_ptr(desc, src_dma, req->nbytes + ivsize, in_options);
1246acdca31dSYuan Kang 
1247acdca31dSYuan Kang 	if (likely(req->src == req->dst)) {
1248acdca31dSYuan Kang 		if (!edesc->src_nents && iv_contig) {
1249acdca31dSYuan Kang 			dst_dma = sg_dma_address(req->src);
1250acdca31dSYuan Kang 		} else {
1251a299c837SYuan Kang 			dst_dma = edesc->sec4_sg_dma +
1252a299c837SYuan Kang 				sizeof(struct sec4_sg_entry);
1253acdca31dSYuan Kang 			out_options = LDST_SGF;
1254acdca31dSYuan Kang 		}
1255acdca31dSYuan Kang 	} else {
1256acdca31dSYuan Kang 		if (!edesc->dst_nents) {
1257acdca31dSYuan Kang 			dst_dma = sg_dma_address(req->dst);
1258acdca31dSYuan Kang 		} else {
1259a299c837SYuan Kang 			dst_dma = edesc->sec4_sg_dma +
1260a299c837SYuan Kang 				sec4_sg_index * sizeof(struct sec4_sg_entry);
1261acdca31dSYuan Kang 			out_options = LDST_SGF;
1262acdca31dSYuan Kang 		}
1263acdca31dSYuan Kang 	}
1264acdca31dSYuan Kang 	append_seq_out_ptr(desc, dst_dma, req->nbytes, out_options);
1265acdca31dSYuan Kang }
1266acdca31dSYuan Kang 
1267acdca31dSYuan Kang /*
12681acebad3SYuan Kang  * allocate and map the aead extended descriptor
12698e8ec596SKim Phillips  */
12700e479300SYuan Kang static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
1271bbf9c893SHoria Geanta 					   int desc_bytes, bool *all_contig_ptr,
1272bbf9c893SHoria Geanta 					   bool encrypt)
12738e8ec596SKim Phillips {
12740e479300SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
12758e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
12768e8ec596SKim Phillips 	struct device *jrdev = ctx->jrdev;
12771acebad3SYuan Kang 	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
12781acebad3SYuan Kang 		       CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC;
12791acebad3SYuan Kang 	int assoc_nents, src_nents, dst_nents = 0;
12800e479300SYuan Kang 	struct aead_edesc *edesc;
12811acebad3SYuan Kang 	dma_addr_t iv_dma = 0;
12821acebad3SYuan Kang 	int sgc;
12831acebad3SYuan Kang 	bool all_contig = true;
1284643b39b0SYuan Kang 	bool assoc_chained = false, src_chained = false, dst_chained = false;
12851acebad3SYuan Kang 	int ivsize = crypto_aead_ivsize(aead);
1286a299c837SYuan Kang 	int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes;
1287bbf9c893SHoria Geanta 	unsigned int authsize = ctx->authsize;
12888e8ec596SKim Phillips 
1289643b39b0SYuan Kang 	assoc_nents = sg_count(req->assoc, req->assoclen, &assoc_chained);
12908e8ec596SKim Phillips 
1291bbf9c893SHoria Geanta 	if (unlikely(req->dst != req->src)) {
1292bbf9c893SHoria Geanta 		src_nents = sg_count(req->src, req->cryptlen, &src_chained);
1293bbf9c893SHoria Geanta 		dst_nents = sg_count(req->dst,
1294bbf9c893SHoria Geanta 				     req->cryptlen +
1295bbf9c893SHoria Geanta 					(encrypt ? authsize : (-authsize)),
1296bbf9c893SHoria Geanta 				     &dst_chained);
1297bbf9c893SHoria Geanta 	} else {
1298bbf9c893SHoria Geanta 		src_nents = sg_count(req->src,
1299bbf9c893SHoria Geanta 				     req->cryptlen +
1300bbf9c893SHoria Geanta 					(encrypt ? authsize : 0),
1301bbf9c893SHoria Geanta 				     &src_chained);
1302bbf9c893SHoria Geanta 	}
13038e8ec596SKim Phillips 
1304643b39b0SYuan Kang 	sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1,
1305286233e6SHoria Geanta 				 DMA_TO_DEVICE, assoc_chained);
13061acebad3SYuan Kang 	if (likely(req->src == req->dst)) {
1307643b39b0SYuan Kang 		sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1,
1308643b39b0SYuan Kang 					 DMA_BIDIRECTIONAL, src_chained);
13091acebad3SYuan Kang 	} else {
1310643b39b0SYuan Kang 		sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1,
1311643b39b0SYuan Kang 					 DMA_TO_DEVICE, src_chained);
1312643b39b0SYuan Kang 		sgc = dma_map_sg_chained(jrdev, req->dst, dst_nents ? : 1,
1313643b39b0SYuan Kang 					 DMA_FROM_DEVICE, dst_chained);
13148e8ec596SKim Phillips 	}
13158e8ec596SKim Phillips 
13161acebad3SYuan Kang 	/* Check if data are contiguous */
13171acebad3SYuan Kang 	iv_dma = dma_map_single(jrdev, req->iv, ivsize, DMA_TO_DEVICE);
13181acebad3SYuan Kang 	if (assoc_nents || sg_dma_address(req->assoc) + req->assoclen !=
13191acebad3SYuan Kang 	    iv_dma || src_nents || iv_dma + ivsize !=
13201acebad3SYuan Kang 	    sg_dma_address(req->src)) {
13211acebad3SYuan Kang 		all_contig = false;
13221acebad3SYuan Kang 		assoc_nents = assoc_nents ? : 1;
13231acebad3SYuan Kang 		src_nents = src_nents ? : 1;
1324a299c837SYuan Kang 		sec4_sg_len = assoc_nents + 1 + src_nents;
13251acebad3SYuan Kang 	}
1326a299c837SYuan Kang 	sec4_sg_len += dst_nents;
13271acebad3SYuan Kang 
1328a299c837SYuan Kang 	sec4_sg_bytes = sec4_sg_len * sizeof(struct sec4_sg_entry);
13298e8ec596SKim Phillips 
13308e8ec596SKim Phillips 	/* allocate space for base edesc and hw desc commands, link tables */
13310e479300SYuan Kang 	edesc = kmalloc(sizeof(struct aead_edesc) + desc_bytes +
1332a299c837SYuan Kang 			sec4_sg_bytes, GFP_DMA | flags);
13338e8ec596SKim Phillips 	if (!edesc) {
13348e8ec596SKim Phillips 		dev_err(jrdev, "could not allocate extended descriptor\n");
13358e8ec596SKim Phillips 		return ERR_PTR(-ENOMEM);
13368e8ec596SKim Phillips 	}
13378e8ec596SKim Phillips 
13388e8ec596SKim Phillips 	edesc->assoc_nents = assoc_nents;
1339643b39b0SYuan Kang 	edesc->assoc_chained = assoc_chained;
13408e8ec596SKim Phillips 	edesc->src_nents = src_nents;
1341643b39b0SYuan Kang 	edesc->src_chained = src_chained;
13428e8ec596SKim Phillips 	edesc->dst_nents = dst_nents;
1343643b39b0SYuan Kang 	edesc->dst_chained = dst_chained;
13441acebad3SYuan Kang 	edesc->iv_dma = iv_dma;
1345a299c837SYuan Kang 	edesc->sec4_sg_bytes = sec4_sg_bytes;
1346a299c837SYuan Kang 	edesc->sec4_sg = (void *)edesc + sizeof(struct aead_edesc) +
13478e8ec596SKim Phillips 			 desc_bytes;
13481acebad3SYuan Kang 	*all_contig_ptr = all_contig;
13491acebad3SYuan Kang 
1350a299c837SYuan Kang 	sec4_sg_index = 0;
13511acebad3SYuan Kang 	if (!all_contig) {
1352a299c837SYuan Kang 		sg_to_sec4_sg(req->assoc,
13531acebad3SYuan Kang 			      (assoc_nents ? : 1),
1354a299c837SYuan Kang 			      edesc->sec4_sg +
1355a299c837SYuan Kang 			      sec4_sg_index, 0);
1356a299c837SYuan Kang 		sec4_sg_index += assoc_nents ? : 1;
1357a299c837SYuan Kang 		dma_to_sec4_sg_one(edesc->sec4_sg + sec4_sg_index,
13581acebad3SYuan Kang 				   iv_dma, ivsize, 0);
1359a299c837SYuan Kang 		sec4_sg_index += 1;
1360a299c837SYuan Kang 		sg_to_sec4_sg_last(req->src,
13611acebad3SYuan Kang 				   (src_nents ? : 1),
1362a299c837SYuan Kang 				   edesc->sec4_sg +
1363a299c837SYuan Kang 				   sec4_sg_index, 0);
1364a299c837SYuan Kang 		sec4_sg_index += src_nents ? : 1;
13651acebad3SYuan Kang 	}
13661acebad3SYuan Kang 	if (dst_nents) {
1367a299c837SYuan Kang 		sg_to_sec4_sg_last(req->dst, dst_nents,
1368a299c837SYuan Kang 				   edesc->sec4_sg + sec4_sg_index, 0);
13691acebad3SYuan Kang 	}
13701da2be33SRuchika Gupta 	edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
13711da2be33SRuchika Gupta 					    sec4_sg_bytes, DMA_TO_DEVICE);
13728e8ec596SKim Phillips 
13738e8ec596SKim Phillips 	return edesc;
13748e8ec596SKim Phillips }
13758e8ec596SKim Phillips 
13760e479300SYuan Kang static int aead_encrypt(struct aead_request *req)
13778e8ec596SKim Phillips {
13780e479300SYuan Kang 	struct aead_edesc *edesc;
13798e8ec596SKim Phillips 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
13808e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
13818e8ec596SKim Phillips 	struct device *jrdev = ctx->jrdev;
13821acebad3SYuan Kang 	bool all_contig;
13838e8ec596SKim Phillips 	u32 *desc;
13841acebad3SYuan Kang 	int ret = 0;
13851acebad3SYuan Kang 
13868e8ec596SKim Phillips 	/* allocate extended descriptor */
13871acebad3SYuan Kang 	edesc = aead_edesc_alloc(req, DESC_JOB_IO_LEN *
1388bbf9c893SHoria Geanta 				 CAAM_CMD_SZ, &all_contig, true);
13898e8ec596SKim Phillips 	if (IS_ERR(edesc))
13908e8ec596SKim Phillips 		return PTR_ERR(edesc);
13918e8ec596SKim Phillips 
13921acebad3SYuan Kang 	/* Create and submit job descriptor */
13931acebad3SYuan Kang 	init_aead_job(ctx->sh_desc_enc, ctx->sh_desc_enc_dma, edesc, req,
13941acebad3SYuan Kang 		      all_contig, true);
13951acebad3SYuan Kang #ifdef DEBUG
1396514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
13971acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
13981acebad3SYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
13991acebad3SYuan Kang #endif
14001acebad3SYuan Kang 
14018e8ec596SKim Phillips 	desc = edesc->hw_desc;
14021acebad3SYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req);
14031acebad3SYuan Kang 	if (!ret) {
14041acebad3SYuan Kang 		ret = -EINPROGRESS;
14051acebad3SYuan Kang 	} else {
14061acebad3SYuan Kang 		aead_unmap(jrdev, edesc, req);
14071acebad3SYuan Kang 		kfree(edesc);
14081acebad3SYuan Kang 	}
14098e8ec596SKim Phillips 
14101acebad3SYuan Kang 	return ret;
14118e8ec596SKim Phillips }
14128e8ec596SKim Phillips 
14130e479300SYuan Kang static int aead_decrypt(struct aead_request *req)
14148e8ec596SKim Phillips {
14151acebad3SYuan Kang 	struct aead_edesc *edesc;
14160e479300SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
14170e479300SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
14180e479300SYuan Kang 	struct device *jrdev = ctx->jrdev;
14191acebad3SYuan Kang 	bool all_contig;
14200e479300SYuan Kang 	u32 *desc;
14211acebad3SYuan Kang 	int ret = 0;
14220e479300SYuan Kang 
14230e479300SYuan Kang 	/* allocate extended descriptor */
14241acebad3SYuan Kang 	edesc = aead_edesc_alloc(req, DESC_JOB_IO_LEN *
1425bbf9c893SHoria Geanta 				 CAAM_CMD_SZ, &all_contig, false);
14260e479300SYuan Kang 	if (IS_ERR(edesc))
14270e479300SYuan Kang 		return PTR_ERR(edesc);
14280e479300SYuan Kang 
14291acebad3SYuan Kang #ifdef DEBUG
1430514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "dec src@"__stringify(__LINE__)": ",
14311acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src),
14321acebad3SYuan Kang 		       req->cryptlen, 1);
14331acebad3SYuan Kang #endif
14341acebad3SYuan Kang 
14351acebad3SYuan Kang 	/* Create and submit job descriptor*/
14361acebad3SYuan Kang 	init_aead_job(ctx->sh_desc_dec,
14371acebad3SYuan Kang 		      ctx->sh_desc_dec_dma, edesc, req, all_contig, false);
14381acebad3SYuan Kang #ifdef DEBUG
1439514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
14401acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
14411acebad3SYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
14421acebad3SYuan Kang #endif
14431acebad3SYuan Kang 
14440e479300SYuan Kang 	desc = edesc->hw_desc;
14451acebad3SYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, aead_decrypt_done, req);
14461acebad3SYuan Kang 	if (!ret) {
14471acebad3SYuan Kang 		ret = -EINPROGRESS;
14481acebad3SYuan Kang 	} else {
14491acebad3SYuan Kang 		aead_unmap(jrdev, edesc, req);
14501acebad3SYuan Kang 		kfree(edesc);
14511acebad3SYuan Kang 	}
14520e479300SYuan Kang 
14531acebad3SYuan Kang 	return ret;
14541acebad3SYuan Kang }
14550e479300SYuan Kang 
14561acebad3SYuan Kang /*
14571acebad3SYuan Kang  * allocate and map the aead extended descriptor for aead givencrypt
14581acebad3SYuan Kang  */
14591acebad3SYuan Kang static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request
14601acebad3SYuan Kang 					       *greq, int desc_bytes,
14611acebad3SYuan Kang 					       u32 *contig_ptr)
14621acebad3SYuan Kang {
14631acebad3SYuan Kang 	struct aead_request *req = &greq->areq;
14641acebad3SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
14651acebad3SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
14661acebad3SYuan Kang 	struct device *jrdev = ctx->jrdev;
14671acebad3SYuan Kang 	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
14681acebad3SYuan Kang 		       CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC;
14691acebad3SYuan Kang 	int assoc_nents, src_nents, dst_nents = 0;
14701acebad3SYuan Kang 	struct aead_edesc *edesc;
14711acebad3SYuan Kang 	dma_addr_t iv_dma = 0;
14721acebad3SYuan Kang 	int sgc;
14731acebad3SYuan Kang 	u32 contig = GIV_SRC_CONTIG | GIV_DST_CONTIG;
14741acebad3SYuan Kang 	int ivsize = crypto_aead_ivsize(aead);
1475643b39b0SYuan Kang 	bool assoc_chained = false, src_chained = false, dst_chained = false;
1476a299c837SYuan Kang 	int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes;
14770e479300SYuan Kang 
1478643b39b0SYuan Kang 	assoc_nents = sg_count(req->assoc, req->assoclen, &assoc_chained);
1479643b39b0SYuan Kang 	src_nents = sg_count(req->src, req->cryptlen, &src_chained);
14800e479300SYuan Kang 
14811acebad3SYuan Kang 	if (unlikely(req->dst != req->src))
1482bbf9c893SHoria Geanta 		dst_nents = sg_count(req->dst, req->cryptlen + ctx->authsize,
1483bbf9c893SHoria Geanta 				     &dst_chained);
14841acebad3SYuan Kang 
1485643b39b0SYuan Kang 	sgc = dma_map_sg_chained(jrdev, req->assoc, assoc_nents ? : 1,
1486286233e6SHoria Geanta 				 DMA_TO_DEVICE, assoc_chained);
14871acebad3SYuan Kang 	if (likely(req->src == req->dst)) {
1488643b39b0SYuan Kang 		sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1,
1489643b39b0SYuan Kang 					 DMA_BIDIRECTIONAL, src_chained);
14901acebad3SYuan Kang 	} else {
1491643b39b0SYuan Kang 		sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1,
1492643b39b0SYuan Kang 					 DMA_TO_DEVICE, src_chained);
1493643b39b0SYuan Kang 		sgc = dma_map_sg_chained(jrdev, req->dst, dst_nents ? : 1,
1494643b39b0SYuan Kang 					 DMA_FROM_DEVICE, dst_chained);
14951acebad3SYuan Kang 	}
14961acebad3SYuan Kang 
14971acebad3SYuan Kang 	/* Check if data are contiguous */
14981acebad3SYuan Kang 	iv_dma = dma_map_single(jrdev, greq->giv, ivsize, DMA_TO_DEVICE);
14991acebad3SYuan Kang 	if (assoc_nents || sg_dma_address(req->assoc) + req->assoclen !=
15001acebad3SYuan Kang 	    iv_dma || src_nents || iv_dma + ivsize != sg_dma_address(req->src))
15011acebad3SYuan Kang 		contig &= ~GIV_SRC_CONTIG;
15021acebad3SYuan Kang 	if (dst_nents || iv_dma + ivsize != sg_dma_address(req->dst))
15031acebad3SYuan Kang 		contig &= ~GIV_DST_CONTIG;
15041acebad3SYuan Kang 	if (unlikely(req->src != req->dst)) {
15051acebad3SYuan Kang 		dst_nents = dst_nents ? : 1;
1506a299c837SYuan Kang 		sec4_sg_len += 1;
15071acebad3SYuan Kang 	}
15081acebad3SYuan Kang 	if (!(contig & GIV_SRC_CONTIG)) {
15091acebad3SYuan Kang 		assoc_nents = assoc_nents ? : 1;
15101acebad3SYuan Kang 		src_nents = src_nents ? : 1;
1511a299c837SYuan Kang 		sec4_sg_len += assoc_nents + 1 + src_nents;
15121acebad3SYuan Kang 		if (likely(req->src == req->dst))
15131acebad3SYuan Kang 			contig &= ~GIV_DST_CONTIG;
15141acebad3SYuan Kang 	}
1515a299c837SYuan Kang 	sec4_sg_len += dst_nents;
15161acebad3SYuan Kang 
1517a299c837SYuan Kang 	sec4_sg_bytes = sec4_sg_len * sizeof(struct sec4_sg_entry);
15181acebad3SYuan Kang 
15191acebad3SYuan Kang 	/* allocate space for base edesc and hw desc commands, link tables */
15201acebad3SYuan Kang 	edesc = kmalloc(sizeof(struct aead_edesc) + desc_bytes +
1521a299c837SYuan Kang 			sec4_sg_bytes, GFP_DMA | flags);
15221acebad3SYuan Kang 	if (!edesc) {
15231acebad3SYuan Kang 		dev_err(jrdev, "could not allocate extended descriptor\n");
15241acebad3SYuan Kang 		return ERR_PTR(-ENOMEM);
15251acebad3SYuan Kang 	}
15261acebad3SYuan Kang 
15271acebad3SYuan Kang 	edesc->assoc_nents = assoc_nents;
1528643b39b0SYuan Kang 	edesc->assoc_chained = assoc_chained;
15291acebad3SYuan Kang 	edesc->src_nents = src_nents;
1530643b39b0SYuan Kang 	edesc->src_chained = src_chained;
15311acebad3SYuan Kang 	edesc->dst_nents = dst_nents;
1532643b39b0SYuan Kang 	edesc->dst_chained = dst_chained;
15331acebad3SYuan Kang 	edesc->iv_dma = iv_dma;
1534a299c837SYuan Kang 	edesc->sec4_sg_bytes = sec4_sg_bytes;
1535a299c837SYuan Kang 	edesc->sec4_sg = (void *)edesc + sizeof(struct aead_edesc) +
15361acebad3SYuan Kang 			 desc_bytes;
15371acebad3SYuan Kang 	*contig_ptr = contig;
15381acebad3SYuan Kang 
1539a299c837SYuan Kang 	sec4_sg_index = 0;
15401acebad3SYuan Kang 	if (!(contig & GIV_SRC_CONTIG)) {
1541a299c837SYuan Kang 		sg_to_sec4_sg(req->assoc, assoc_nents,
1542a299c837SYuan Kang 			      edesc->sec4_sg +
1543a299c837SYuan Kang 			      sec4_sg_index, 0);
1544a299c837SYuan Kang 		sec4_sg_index += assoc_nents;
1545a299c837SYuan Kang 		dma_to_sec4_sg_one(edesc->sec4_sg + sec4_sg_index,
15461acebad3SYuan Kang 				   iv_dma, ivsize, 0);
1547a299c837SYuan Kang 		sec4_sg_index += 1;
1548a299c837SYuan Kang 		sg_to_sec4_sg_last(req->src, src_nents,
1549a299c837SYuan Kang 				   edesc->sec4_sg +
1550a299c837SYuan Kang 				   sec4_sg_index, 0);
1551a299c837SYuan Kang 		sec4_sg_index += src_nents;
15521acebad3SYuan Kang 	}
15531acebad3SYuan Kang 	if (unlikely(req->src != req->dst && !(contig & GIV_DST_CONTIG))) {
1554a299c837SYuan Kang 		dma_to_sec4_sg_one(edesc->sec4_sg + sec4_sg_index,
15551acebad3SYuan Kang 				   iv_dma, ivsize, 0);
1556a299c837SYuan Kang 		sec4_sg_index += 1;
1557a299c837SYuan Kang 		sg_to_sec4_sg_last(req->dst, dst_nents,
1558a299c837SYuan Kang 				   edesc->sec4_sg + sec4_sg_index, 0);
15591acebad3SYuan Kang 	}
15601da2be33SRuchika Gupta 	edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
15611da2be33SRuchika Gupta 					    sec4_sg_bytes, DMA_TO_DEVICE);
15621acebad3SYuan Kang 
15631acebad3SYuan Kang 	return edesc;
15640e479300SYuan Kang }
15650e479300SYuan Kang 
15660e479300SYuan Kang static int aead_givencrypt(struct aead_givcrypt_request *areq)
15670e479300SYuan Kang {
15680e479300SYuan Kang 	struct aead_request *req = &areq->areq;
15690e479300SYuan Kang 	struct aead_edesc *edesc;
15700e479300SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
15718e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
15728e8ec596SKim Phillips 	struct device *jrdev = ctx->jrdev;
15731acebad3SYuan Kang 	u32 contig;
15748e8ec596SKim Phillips 	u32 *desc;
15751acebad3SYuan Kang 	int ret = 0;
15768e8ec596SKim Phillips 
15778e8ec596SKim Phillips 	/* allocate extended descriptor */
15781acebad3SYuan Kang 	edesc = aead_giv_edesc_alloc(areq, DESC_JOB_IO_LEN *
15791acebad3SYuan Kang 				     CAAM_CMD_SZ, &contig);
15801acebad3SYuan Kang 
15818e8ec596SKim Phillips 	if (IS_ERR(edesc))
15828e8ec596SKim Phillips 		return PTR_ERR(edesc);
15838e8ec596SKim Phillips 
15841acebad3SYuan Kang #ifdef DEBUG
1585514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "giv src@"__stringify(__LINE__)": ",
15861acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src),
15871acebad3SYuan Kang 		       req->cryptlen, 1);
15881acebad3SYuan Kang #endif
15891acebad3SYuan Kang 
15901acebad3SYuan Kang 	/* Create and submit job descriptor*/
15911acebad3SYuan Kang 	init_aead_giv_job(ctx->sh_desc_givenc,
15921acebad3SYuan Kang 			  ctx->sh_desc_givenc_dma, edesc, req, contig);
15931acebad3SYuan Kang #ifdef DEBUG
1594514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
15951acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
15961acebad3SYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
15971acebad3SYuan Kang #endif
15981acebad3SYuan Kang 
15998e8ec596SKim Phillips 	desc = edesc->hw_desc;
16001acebad3SYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req);
16011acebad3SYuan Kang 	if (!ret) {
16021acebad3SYuan Kang 		ret = -EINPROGRESS;
16031acebad3SYuan Kang 	} else {
16041acebad3SYuan Kang 		aead_unmap(jrdev, edesc, req);
16051acebad3SYuan Kang 		kfree(edesc);
16061acebad3SYuan Kang 	}
16078e8ec596SKim Phillips 
16081acebad3SYuan Kang 	return ret;
16098e8ec596SKim Phillips }
16108e8ec596SKim Phillips 
1611ae4a825fSHoria Geanta static int aead_null_givencrypt(struct aead_givcrypt_request *areq)
1612ae4a825fSHoria Geanta {
1613ae4a825fSHoria Geanta 	return aead_encrypt(&areq->areq);
1614ae4a825fSHoria Geanta }
1615ae4a825fSHoria Geanta 
1616acdca31dSYuan Kang /*
1617acdca31dSYuan Kang  * allocate and map the ablkcipher extended descriptor for ablkcipher
1618acdca31dSYuan Kang  */
1619acdca31dSYuan Kang static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request
1620acdca31dSYuan Kang 						       *req, int desc_bytes,
1621acdca31dSYuan Kang 						       bool *iv_contig_out)
1622acdca31dSYuan Kang {
1623acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
1624acdca31dSYuan Kang 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
1625acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
1626acdca31dSYuan Kang 	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
1627acdca31dSYuan Kang 					  CRYPTO_TFM_REQ_MAY_SLEEP)) ?
1628acdca31dSYuan Kang 		       GFP_KERNEL : GFP_ATOMIC;
1629a299c837SYuan Kang 	int src_nents, dst_nents = 0, sec4_sg_bytes;
1630acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
1631acdca31dSYuan Kang 	dma_addr_t iv_dma = 0;
1632acdca31dSYuan Kang 	bool iv_contig = false;
1633acdca31dSYuan Kang 	int sgc;
1634acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
1635643b39b0SYuan Kang 	bool src_chained = false, dst_chained = false;
1636a299c837SYuan Kang 	int sec4_sg_index;
1637acdca31dSYuan Kang 
1638643b39b0SYuan Kang 	src_nents = sg_count(req->src, req->nbytes, &src_chained);
1639acdca31dSYuan Kang 
1640643b39b0SYuan Kang 	if (req->dst != req->src)
1641643b39b0SYuan Kang 		dst_nents = sg_count(req->dst, req->nbytes, &dst_chained);
1642acdca31dSYuan Kang 
1643acdca31dSYuan Kang 	if (likely(req->src == req->dst)) {
1644643b39b0SYuan Kang 		sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1,
1645643b39b0SYuan Kang 					 DMA_BIDIRECTIONAL, src_chained);
1646acdca31dSYuan Kang 	} else {
1647643b39b0SYuan Kang 		sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1,
1648643b39b0SYuan Kang 					 DMA_TO_DEVICE, src_chained);
1649643b39b0SYuan Kang 		sgc = dma_map_sg_chained(jrdev, req->dst, dst_nents ? : 1,
1650643b39b0SYuan Kang 					 DMA_FROM_DEVICE, dst_chained);
1651acdca31dSYuan Kang 	}
1652acdca31dSYuan Kang 
1653acdca31dSYuan Kang 	/*
1654acdca31dSYuan Kang 	 * Check if iv can be contiguous with source and destination.
1655acdca31dSYuan Kang 	 * If so, include it. If not, create scatterlist.
1656acdca31dSYuan Kang 	 */
1657acdca31dSYuan Kang 	iv_dma = dma_map_single(jrdev, req->info, ivsize, DMA_TO_DEVICE);
1658acdca31dSYuan Kang 	if (!src_nents && iv_dma + ivsize == sg_dma_address(req->src))
1659acdca31dSYuan Kang 		iv_contig = true;
1660acdca31dSYuan Kang 	else
1661acdca31dSYuan Kang 		src_nents = src_nents ? : 1;
1662a299c837SYuan Kang 	sec4_sg_bytes = ((iv_contig ? 0 : 1) + src_nents + dst_nents) *
1663a299c837SYuan Kang 			sizeof(struct sec4_sg_entry);
1664acdca31dSYuan Kang 
1665acdca31dSYuan Kang 	/* allocate space for base edesc and hw desc commands, link tables */
1666acdca31dSYuan Kang 	edesc = kmalloc(sizeof(struct ablkcipher_edesc) + desc_bytes +
1667a299c837SYuan Kang 			sec4_sg_bytes, GFP_DMA | flags);
1668acdca31dSYuan Kang 	if (!edesc) {
1669acdca31dSYuan Kang 		dev_err(jrdev, "could not allocate extended descriptor\n");
1670acdca31dSYuan Kang 		return ERR_PTR(-ENOMEM);
1671acdca31dSYuan Kang 	}
1672acdca31dSYuan Kang 
1673acdca31dSYuan Kang 	edesc->src_nents = src_nents;
1674643b39b0SYuan Kang 	edesc->src_chained = src_chained;
1675acdca31dSYuan Kang 	edesc->dst_nents = dst_nents;
1676643b39b0SYuan Kang 	edesc->dst_chained = dst_chained;
1677a299c837SYuan Kang 	edesc->sec4_sg_bytes = sec4_sg_bytes;
1678a299c837SYuan Kang 	edesc->sec4_sg = (void *)edesc + sizeof(struct ablkcipher_edesc) +
1679acdca31dSYuan Kang 			 desc_bytes;
1680acdca31dSYuan Kang 
1681a299c837SYuan Kang 	sec4_sg_index = 0;
1682acdca31dSYuan Kang 	if (!iv_contig) {
1683a299c837SYuan Kang 		dma_to_sec4_sg_one(edesc->sec4_sg, iv_dma, ivsize, 0);
1684a299c837SYuan Kang 		sg_to_sec4_sg_last(req->src, src_nents,
1685a299c837SYuan Kang 				   edesc->sec4_sg + 1, 0);
1686a299c837SYuan Kang 		sec4_sg_index += 1 + src_nents;
1687acdca31dSYuan Kang 	}
1688acdca31dSYuan Kang 
1689643b39b0SYuan Kang 	if (dst_nents) {
1690a299c837SYuan Kang 		sg_to_sec4_sg_last(req->dst, dst_nents,
1691a299c837SYuan Kang 			edesc->sec4_sg + sec4_sg_index, 0);
1692acdca31dSYuan Kang 	}
1693acdca31dSYuan Kang 
1694a299c837SYuan Kang 	edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
1695a299c837SYuan Kang 					    sec4_sg_bytes, DMA_TO_DEVICE);
1696acdca31dSYuan Kang 	edesc->iv_dma = iv_dma;
1697acdca31dSYuan Kang 
1698acdca31dSYuan Kang #ifdef DEBUG
1699514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "ablkcipher sec4_sg@"__stringify(__LINE__)": ",
1700a299c837SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->sec4_sg,
1701a299c837SYuan Kang 		       sec4_sg_bytes, 1);
1702acdca31dSYuan Kang #endif
1703acdca31dSYuan Kang 
1704acdca31dSYuan Kang 	*iv_contig_out = iv_contig;
1705acdca31dSYuan Kang 	return edesc;
1706acdca31dSYuan Kang }
1707acdca31dSYuan Kang 
1708acdca31dSYuan Kang static int ablkcipher_encrypt(struct ablkcipher_request *req)
1709acdca31dSYuan Kang {
1710acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
1711acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
1712acdca31dSYuan Kang 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
1713acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
1714acdca31dSYuan Kang 	bool iv_contig;
1715acdca31dSYuan Kang 	u32 *desc;
1716acdca31dSYuan Kang 	int ret = 0;
1717acdca31dSYuan Kang 
1718acdca31dSYuan Kang 	/* allocate extended descriptor */
1719acdca31dSYuan Kang 	edesc = ablkcipher_edesc_alloc(req, DESC_JOB_IO_LEN *
1720acdca31dSYuan Kang 				       CAAM_CMD_SZ, &iv_contig);
1721acdca31dSYuan Kang 	if (IS_ERR(edesc))
1722acdca31dSYuan Kang 		return PTR_ERR(edesc);
1723acdca31dSYuan Kang 
1724acdca31dSYuan Kang 	/* Create and submit job descriptor*/
1725acdca31dSYuan Kang 	init_ablkcipher_job(ctx->sh_desc_enc,
1726acdca31dSYuan Kang 		ctx->sh_desc_enc_dma, edesc, req, iv_contig);
1727acdca31dSYuan Kang #ifdef DEBUG
1728514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "ablkcipher jobdesc@"__stringify(__LINE__)": ",
1729acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1730acdca31dSYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
1731acdca31dSYuan Kang #endif
1732acdca31dSYuan Kang 	desc = edesc->hw_desc;
1733acdca31dSYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, ablkcipher_encrypt_done, req);
1734acdca31dSYuan Kang 
1735acdca31dSYuan Kang 	if (!ret) {
1736acdca31dSYuan Kang 		ret = -EINPROGRESS;
1737acdca31dSYuan Kang 	} else {
1738acdca31dSYuan Kang 		ablkcipher_unmap(jrdev, edesc, req);
1739acdca31dSYuan Kang 		kfree(edesc);
1740acdca31dSYuan Kang 	}
1741acdca31dSYuan Kang 
1742acdca31dSYuan Kang 	return ret;
1743acdca31dSYuan Kang }
1744acdca31dSYuan Kang 
1745acdca31dSYuan Kang static int ablkcipher_decrypt(struct ablkcipher_request *req)
1746acdca31dSYuan Kang {
1747acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
1748acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
1749acdca31dSYuan Kang 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
1750acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
1751acdca31dSYuan Kang 	bool iv_contig;
1752acdca31dSYuan Kang 	u32 *desc;
1753acdca31dSYuan Kang 	int ret = 0;
1754acdca31dSYuan Kang 
1755acdca31dSYuan Kang 	/* allocate extended descriptor */
1756acdca31dSYuan Kang 	edesc = ablkcipher_edesc_alloc(req, DESC_JOB_IO_LEN *
1757acdca31dSYuan Kang 				       CAAM_CMD_SZ, &iv_contig);
1758acdca31dSYuan Kang 	if (IS_ERR(edesc))
1759acdca31dSYuan Kang 		return PTR_ERR(edesc);
1760acdca31dSYuan Kang 
1761acdca31dSYuan Kang 	/* Create and submit job descriptor*/
1762acdca31dSYuan Kang 	init_ablkcipher_job(ctx->sh_desc_dec,
1763acdca31dSYuan Kang 		ctx->sh_desc_dec_dma, edesc, req, iv_contig);
1764acdca31dSYuan Kang 	desc = edesc->hw_desc;
1765acdca31dSYuan Kang #ifdef DEBUG
1766514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "ablkcipher jobdesc@"__stringify(__LINE__)": ",
1767acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1768acdca31dSYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
1769acdca31dSYuan Kang #endif
1770acdca31dSYuan Kang 
1771acdca31dSYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, ablkcipher_decrypt_done, req);
1772acdca31dSYuan Kang 	if (!ret) {
1773acdca31dSYuan Kang 		ret = -EINPROGRESS;
1774acdca31dSYuan Kang 	} else {
1775acdca31dSYuan Kang 		ablkcipher_unmap(jrdev, edesc, req);
1776acdca31dSYuan Kang 		kfree(edesc);
1777acdca31dSYuan Kang 	}
1778acdca31dSYuan Kang 
1779acdca31dSYuan Kang 	return ret;
1780acdca31dSYuan Kang }
1781acdca31dSYuan Kang 
1782885e9e2fSYuan Kang #define template_aead		template_u.aead
1783acdca31dSYuan Kang #define template_ablkcipher	template_u.ablkcipher
17848e8ec596SKim Phillips struct caam_alg_template {
17858e8ec596SKim Phillips 	char name[CRYPTO_MAX_ALG_NAME];
17868e8ec596SKim Phillips 	char driver_name[CRYPTO_MAX_ALG_NAME];
17878e8ec596SKim Phillips 	unsigned int blocksize;
1788885e9e2fSYuan Kang 	u32 type;
1789885e9e2fSYuan Kang 	union {
1790885e9e2fSYuan Kang 		struct ablkcipher_alg ablkcipher;
17918e8ec596SKim Phillips 		struct aead_alg aead;
1792885e9e2fSYuan Kang 		struct blkcipher_alg blkcipher;
1793885e9e2fSYuan Kang 		struct cipher_alg cipher;
1794885e9e2fSYuan Kang 		struct compress_alg compress;
1795885e9e2fSYuan Kang 		struct rng_alg rng;
1796885e9e2fSYuan Kang 	} template_u;
17978e8ec596SKim Phillips 	u32 class1_alg_type;
17988e8ec596SKim Phillips 	u32 class2_alg_type;
17998e8ec596SKim Phillips 	u32 alg_op;
18008e8ec596SKim Phillips };
18018e8ec596SKim Phillips 
18028e8ec596SKim Phillips static struct caam_alg_template driver_algs[] = {
1803246bbedbSHoria Geanta 	/* single-pass ipsec_esp descriptor */
18048e8ec596SKim Phillips 	{
1805ae4a825fSHoria Geanta 		.name = "authenc(hmac(md5),ecb(cipher_null))",
1806ae4a825fSHoria Geanta 		.driver_name = "authenc-hmac-md5-ecb-cipher_null-caam",
1807ae4a825fSHoria Geanta 		.blocksize = NULL_BLOCK_SIZE,
1808ae4a825fSHoria Geanta 		.type = CRYPTO_ALG_TYPE_AEAD,
1809ae4a825fSHoria Geanta 		.template_aead = {
1810ae4a825fSHoria Geanta 			.setkey = aead_setkey,
1811ae4a825fSHoria Geanta 			.setauthsize = aead_setauthsize,
1812ae4a825fSHoria Geanta 			.encrypt = aead_encrypt,
1813ae4a825fSHoria Geanta 			.decrypt = aead_decrypt,
1814ae4a825fSHoria Geanta 			.givencrypt = aead_null_givencrypt,
1815ae4a825fSHoria Geanta 			.geniv = "<built-in>",
1816ae4a825fSHoria Geanta 			.ivsize = NULL_IV_SIZE,
1817ae4a825fSHoria Geanta 			.maxauthsize = MD5_DIGEST_SIZE,
1818ae4a825fSHoria Geanta 			},
1819ae4a825fSHoria Geanta 		.class1_alg_type = 0,
1820ae4a825fSHoria Geanta 		.class2_alg_type = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC_PRECOMP,
1821ae4a825fSHoria Geanta 		.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
1822ae4a825fSHoria Geanta 	},
1823ae4a825fSHoria Geanta 	{
1824ae4a825fSHoria Geanta 		.name = "authenc(hmac(sha1),ecb(cipher_null))",
1825ae4a825fSHoria Geanta 		.driver_name = "authenc-hmac-sha1-ecb-cipher_null-caam",
1826ae4a825fSHoria Geanta 		.blocksize = NULL_BLOCK_SIZE,
1827ae4a825fSHoria Geanta 		.type = CRYPTO_ALG_TYPE_AEAD,
1828ae4a825fSHoria Geanta 		.template_aead = {
1829ae4a825fSHoria Geanta 			.setkey = aead_setkey,
1830ae4a825fSHoria Geanta 			.setauthsize = aead_setauthsize,
1831ae4a825fSHoria Geanta 			.encrypt = aead_encrypt,
1832ae4a825fSHoria Geanta 			.decrypt = aead_decrypt,
1833ae4a825fSHoria Geanta 			.givencrypt = aead_null_givencrypt,
1834ae4a825fSHoria Geanta 			.geniv = "<built-in>",
1835ae4a825fSHoria Geanta 			.ivsize = NULL_IV_SIZE,
1836ae4a825fSHoria Geanta 			.maxauthsize = SHA1_DIGEST_SIZE,
1837ae4a825fSHoria Geanta 			},
1838ae4a825fSHoria Geanta 		.class1_alg_type = 0,
1839ae4a825fSHoria Geanta 		.class2_alg_type = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC_PRECOMP,
1840ae4a825fSHoria Geanta 		.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
1841ae4a825fSHoria Geanta 	},
1842ae4a825fSHoria Geanta 	{
1843ae4a825fSHoria Geanta 		.name = "authenc(hmac(sha224),ecb(cipher_null))",
1844ae4a825fSHoria Geanta 		.driver_name = "authenc-hmac-sha224-ecb-cipher_null-caam",
1845ae4a825fSHoria Geanta 		.blocksize = NULL_BLOCK_SIZE,
1846ae4a825fSHoria Geanta 		.type = CRYPTO_ALG_TYPE_AEAD,
1847ae4a825fSHoria Geanta 		.template_aead = {
1848ae4a825fSHoria Geanta 			.setkey = aead_setkey,
1849ae4a825fSHoria Geanta 			.setauthsize = aead_setauthsize,
1850ae4a825fSHoria Geanta 			.encrypt = aead_encrypt,
1851ae4a825fSHoria Geanta 			.decrypt = aead_decrypt,
1852ae4a825fSHoria Geanta 			.givencrypt = aead_null_givencrypt,
1853ae4a825fSHoria Geanta 			.geniv = "<built-in>",
1854ae4a825fSHoria Geanta 			.ivsize = NULL_IV_SIZE,
1855ae4a825fSHoria Geanta 			.maxauthsize = SHA224_DIGEST_SIZE,
1856ae4a825fSHoria Geanta 			},
1857ae4a825fSHoria Geanta 		.class1_alg_type = 0,
1858ae4a825fSHoria Geanta 		.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
1859ae4a825fSHoria Geanta 				   OP_ALG_AAI_HMAC_PRECOMP,
1860ae4a825fSHoria Geanta 		.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
1861ae4a825fSHoria Geanta 	},
1862ae4a825fSHoria Geanta 	{
1863ae4a825fSHoria Geanta 		.name = "authenc(hmac(sha256),ecb(cipher_null))",
1864ae4a825fSHoria Geanta 		.driver_name = "authenc-hmac-sha256-ecb-cipher_null-caam",
1865ae4a825fSHoria Geanta 		.blocksize = NULL_BLOCK_SIZE,
1866ae4a825fSHoria Geanta 		.type = CRYPTO_ALG_TYPE_AEAD,
1867ae4a825fSHoria Geanta 		.template_aead = {
1868ae4a825fSHoria Geanta 			.setkey = aead_setkey,
1869ae4a825fSHoria Geanta 			.setauthsize = aead_setauthsize,
1870ae4a825fSHoria Geanta 			.encrypt = aead_encrypt,
1871ae4a825fSHoria Geanta 			.decrypt = aead_decrypt,
1872ae4a825fSHoria Geanta 			.givencrypt = aead_null_givencrypt,
1873ae4a825fSHoria Geanta 			.geniv = "<built-in>",
1874ae4a825fSHoria Geanta 			.ivsize = NULL_IV_SIZE,
1875ae4a825fSHoria Geanta 			.maxauthsize = SHA256_DIGEST_SIZE,
1876ae4a825fSHoria Geanta 			},
1877ae4a825fSHoria Geanta 		.class1_alg_type = 0,
1878ae4a825fSHoria Geanta 		.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
1879ae4a825fSHoria Geanta 				   OP_ALG_AAI_HMAC_PRECOMP,
1880ae4a825fSHoria Geanta 		.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
1881ae4a825fSHoria Geanta 	},
1882ae4a825fSHoria Geanta 	{
1883ae4a825fSHoria Geanta 		.name = "authenc(hmac(sha384),ecb(cipher_null))",
1884ae4a825fSHoria Geanta 		.driver_name = "authenc-hmac-sha384-ecb-cipher_null-caam",
1885ae4a825fSHoria Geanta 		.blocksize = NULL_BLOCK_SIZE,
1886ae4a825fSHoria Geanta 		.type = CRYPTO_ALG_TYPE_AEAD,
1887ae4a825fSHoria Geanta 		.template_aead = {
1888ae4a825fSHoria Geanta 			.setkey = aead_setkey,
1889ae4a825fSHoria Geanta 			.setauthsize = aead_setauthsize,
1890ae4a825fSHoria Geanta 			.encrypt = aead_encrypt,
1891ae4a825fSHoria Geanta 			.decrypt = aead_decrypt,
1892ae4a825fSHoria Geanta 			.givencrypt = aead_null_givencrypt,
1893ae4a825fSHoria Geanta 			.geniv = "<built-in>",
1894ae4a825fSHoria Geanta 			.ivsize = NULL_IV_SIZE,
1895ae4a825fSHoria Geanta 			.maxauthsize = SHA384_DIGEST_SIZE,
1896ae4a825fSHoria Geanta 			},
1897ae4a825fSHoria Geanta 		.class1_alg_type = 0,
1898ae4a825fSHoria Geanta 		.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
1899ae4a825fSHoria Geanta 				   OP_ALG_AAI_HMAC_PRECOMP,
1900ae4a825fSHoria Geanta 		.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
1901ae4a825fSHoria Geanta 	},
1902ae4a825fSHoria Geanta 	{
1903ae4a825fSHoria Geanta 		.name = "authenc(hmac(sha512),ecb(cipher_null))",
1904ae4a825fSHoria Geanta 		.driver_name = "authenc-hmac-sha512-ecb-cipher_null-caam",
1905ae4a825fSHoria Geanta 		.blocksize = NULL_BLOCK_SIZE,
1906ae4a825fSHoria Geanta 		.type = CRYPTO_ALG_TYPE_AEAD,
1907ae4a825fSHoria Geanta 		.template_aead = {
1908ae4a825fSHoria Geanta 			.setkey = aead_setkey,
1909ae4a825fSHoria Geanta 			.setauthsize = aead_setauthsize,
1910ae4a825fSHoria Geanta 			.encrypt = aead_encrypt,
1911ae4a825fSHoria Geanta 			.decrypt = aead_decrypt,
1912ae4a825fSHoria Geanta 			.givencrypt = aead_null_givencrypt,
1913ae4a825fSHoria Geanta 			.geniv = "<built-in>",
1914ae4a825fSHoria Geanta 			.ivsize = NULL_IV_SIZE,
1915ae4a825fSHoria Geanta 			.maxauthsize = SHA512_DIGEST_SIZE,
1916ae4a825fSHoria Geanta 			},
1917ae4a825fSHoria Geanta 		.class1_alg_type = 0,
1918ae4a825fSHoria Geanta 		.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
1919ae4a825fSHoria Geanta 				   OP_ALG_AAI_HMAC_PRECOMP,
1920ae4a825fSHoria Geanta 		.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
1921ae4a825fSHoria Geanta 	},
1922ae4a825fSHoria Geanta 	{
19238b4d43a4SKim Phillips 		.name = "authenc(hmac(md5),cbc(aes))",
19248b4d43a4SKim Phillips 		.driver_name = "authenc-hmac-md5-cbc-aes-caam",
19258b4d43a4SKim Phillips 		.blocksize = AES_BLOCK_SIZE,
19268b4d43a4SKim Phillips 		.type = CRYPTO_ALG_TYPE_AEAD,
19278b4d43a4SKim Phillips 		.template_aead = {
19288b4d43a4SKim Phillips 			.setkey = aead_setkey,
19298b4d43a4SKim Phillips 			.setauthsize = aead_setauthsize,
19308b4d43a4SKim Phillips 			.encrypt = aead_encrypt,
19318b4d43a4SKim Phillips 			.decrypt = aead_decrypt,
19328b4d43a4SKim Phillips 			.givencrypt = aead_givencrypt,
19338b4d43a4SKim Phillips 			.geniv = "<built-in>",
19348b4d43a4SKim Phillips 			.ivsize = AES_BLOCK_SIZE,
19358b4d43a4SKim Phillips 			.maxauthsize = MD5_DIGEST_SIZE,
19368b4d43a4SKim Phillips 			},
19378b4d43a4SKim Phillips 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
19388b4d43a4SKim Phillips 		.class2_alg_type = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC_PRECOMP,
19398b4d43a4SKim Phillips 		.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
19408b4d43a4SKim Phillips 	},
19418b4d43a4SKim Phillips 	{
19428e8ec596SKim Phillips 		.name = "authenc(hmac(sha1),cbc(aes))",
19438e8ec596SKim Phillips 		.driver_name = "authenc-hmac-sha1-cbc-aes-caam",
19448e8ec596SKim Phillips 		.blocksize = AES_BLOCK_SIZE,
1945885e9e2fSYuan Kang 		.type = CRYPTO_ALG_TYPE_AEAD,
1946885e9e2fSYuan Kang 		.template_aead = {
19470e479300SYuan Kang 			.setkey = aead_setkey,
19480e479300SYuan Kang 			.setauthsize = aead_setauthsize,
19490e479300SYuan Kang 			.encrypt = aead_encrypt,
19500e479300SYuan Kang 			.decrypt = aead_decrypt,
19510e479300SYuan Kang 			.givencrypt = aead_givencrypt,
19528e8ec596SKim Phillips 			.geniv = "<built-in>",
19538e8ec596SKim Phillips 			.ivsize = AES_BLOCK_SIZE,
19548e8ec596SKim Phillips 			.maxauthsize = SHA1_DIGEST_SIZE,
19558e8ec596SKim Phillips 			},
19568e8ec596SKim Phillips 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
19578e8ec596SKim Phillips 		.class2_alg_type = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC_PRECOMP,
19588e8ec596SKim Phillips 		.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
19598e8ec596SKim Phillips 	},
19608e8ec596SKim Phillips 	{
1961e863f9ccSHemant Agrawal 		.name = "authenc(hmac(sha224),cbc(aes))",
1962e863f9ccSHemant Agrawal 		.driver_name = "authenc-hmac-sha224-cbc-aes-caam",
1963e863f9ccSHemant Agrawal 		.blocksize = AES_BLOCK_SIZE,
1964cb7d5662SVakul Garg 		.type = CRYPTO_ALG_TYPE_AEAD,
1965e863f9ccSHemant Agrawal 		.template_aead = {
1966e863f9ccSHemant Agrawal 			.setkey = aead_setkey,
1967e863f9ccSHemant Agrawal 			.setauthsize = aead_setauthsize,
1968e863f9ccSHemant Agrawal 			.encrypt = aead_encrypt,
1969e863f9ccSHemant Agrawal 			.decrypt = aead_decrypt,
1970e863f9ccSHemant Agrawal 			.givencrypt = aead_givencrypt,
1971e863f9ccSHemant Agrawal 			.geniv = "<built-in>",
1972e863f9ccSHemant Agrawal 			.ivsize = AES_BLOCK_SIZE,
1973e863f9ccSHemant Agrawal 			.maxauthsize = SHA224_DIGEST_SIZE,
1974e863f9ccSHemant Agrawal 			},
1975e863f9ccSHemant Agrawal 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
1976e863f9ccSHemant Agrawal 		.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
1977e863f9ccSHemant Agrawal 				   OP_ALG_AAI_HMAC_PRECOMP,
1978e863f9ccSHemant Agrawal 		.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
1979e863f9ccSHemant Agrawal 	},
1980e863f9ccSHemant Agrawal 	{
19818e8ec596SKim Phillips 		.name = "authenc(hmac(sha256),cbc(aes))",
19828e8ec596SKim Phillips 		.driver_name = "authenc-hmac-sha256-cbc-aes-caam",
19838e8ec596SKim Phillips 		.blocksize = AES_BLOCK_SIZE,
1984885e9e2fSYuan Kang 		.type = CRYPTO_ALG_TYPE_AEAD,
1985885e9e2fSYuan Kang 		.template_aead = {
19860e479300SYuan Kang 			.setkey = aead_setkey,
19870e479300SYuan Kang 			.setauthsize = aead_setauthsize,
19880e479300SYuan Kang 			.encrypt = aead_encrypt,
19890e479300SYuan Kang 			.decrypt = aead_decrypt,
19900e479300SYuan Kang 			.givencrypt = aead_givencrypt,
19918e8ec596SKim Phillips 			.geniv = "<built-in>",
19928e8ec596SKim Phillips 			.ivsize = AES_BLOCK_SIZE,
19938e8ec596SKim Phillips 			.maxauthsize = SHA256_DIGEST_SIZE,
19948e8ec596SKim Phillips 			},
19958e8ec596SKim Phillips 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
19968e8ec596SKim Phillips 		.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
19978e8ec596SKim Phillips 				   OP_ALG_AAI_HMAC_PRECOMP,
19988e8ec596SKim Phillips 		.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
19998e8ec596SKim Phillips 	},
20008e8ec596SKim Phillips 	{
2001e863f9ccSHemant Agrawal 		.name = "authenc(hmac(sha384),cbc(aes))",
2002e863f9ccSHemant Agrawal 		.driver_name = "authenc-hmac-sha384-cbc-aes-caam",
2003e863f9ccSHemant Agrawal 		.blocksize = AES_BLOCK_SIZE,
2004cb7d5662SVakul Garg 		.type = CRYPTO_ALG_TYPE_AEAD,
2005e863f9ccSHemant Agrawal 		.template_aead = {
2006e863f9ccSHemant Agrawal 			.setkey = aead_setkey,
2007e863f9ccSHemant Agrawal 			.setauthsize = aead_setauthsize,
2008e863f9ccSHemant Agrawal 			.encrypt = aead_encrypt,
2009e863f9ccSHemant Agrawal 			.decrypt = aead_decrypt,
2010e863f9ccSHemant Agrawal 			.givencrypt = aead_givencrypt,
2011e863f9ccSHemant Agrawal 			.geniv = "<built-in>",
2012e863f9ccSHemant Agrawal 			.ivsize = AES_BLOCK_SIZE,
2013e863f9ccSHemant Agrawal 			.maxauthsize = SHA384_DIGEST_SIZE,
2014e863f9ccSHemant Agrawal 			},
2015e863f9ccSHemant Agrawal 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2016e863f9ccSHemant Agrawal 		.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2017e863f9ccSHemant Agrawal 				   OP_ALG_AAI_HMAC_PRECOMP,
2018e863f9ccSHemant Agrawal 		.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
2019e863f9ccSHemant Agrawal 	},
2020e863f9ccSHemant Agrawal 
2021e863f9ccSHemant Agrawal 	{
20224427b1b4SKim Phillips 		.name = "authenc(hmac(sha512),cbc(aes))",
20234427b1b4SKim Phillips 		.driver_name = "authenc-hmac-sha512-cbc-aes-caam",
20244427b1b4SKim Phillips 		.blocksize = AES_BLOCK_SIZE,
2025885e9e2fSYuan Kang 		.type = CRYPTO_ALG_TYPE_AEAD,
2026885e9e2fSYuan Kang 		.template_aead = {
20270e479300SYuan Kang 			.setkey = aead_setkey,
20280e479300SYuan Kang 			.setauthsize = aead_setauthsize,
20290e479300SYuan Kang 			.encrypt = aead_encrypt,
20300e479300SYuan Kang 			.decrypt = aead_decrypt,
20310e479300SYuan Kang 			.givencrypt = aead_givencrypt,
20324427b1b4SKim Phillips 			.geniv = "<built-in>",
20334427b1b4SKim Phillips 			.ivsize = AES_BLOCK_SIZE,
20344427b1b4SKim Phillips 			.maxauthsize = SHA512_DIGEST_SIZE,
20354427b1b4SKim Phillips 			},
20364427b1b4SKim Phillips 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
20374427b1b4SKim Phillips 		.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
20384427b1b4SKim Phillips 				   OP_ALG_AAI_HMAC_PRECOMP,
20394427b1b4SKim Phillips 		.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
20404427b1b4SKim Phillips 	},
20414427b1b4SKim Phillips 	{
20428b4d43a4SKim Phillips 		.name = "authenc(hmac(md5),cbc(des3_ede))",
20438b4d43a4SKim Phillips 		.driver_name = "authenc-hmac-md5-cbc-des3_ede-caam",
20448b4d43a4SKim Phillips 		.blocksize = DES3_EDE_BLOCK_SIZE,
20458b4d43a4SKim Phillips 		.type = CRYPTO_ALG_TYPE_AEAD,
20468b4d43a4SKim Phillips 		.template_aead = {
20478b4d43a4SKim Phillips 			.setkey = aead_setkey,
20488b4d43a4SKim Phillips 			.setauthsize = aead_setauthsize,
20498b4d43a4SKim Phillips 			.encrypt = aead_encrypt,
20508b4d43a4SKim Phillips 			.decrypt = aead_decrypt,
20518b4d43a4SKim Phillips 			.givencrypt = aead_givencrypt,
20528b4d43a4SKim Phillips 			.geniv = "<built-in>",
20538b4d43a4SKim Phillips 			.ivsize = DES3_EDE_BLOCK_SIZE,
20548b4d43a4SKim Phillips 			.maxauthsize = MD5_DIGEST_SIZE,
20558b4d43a4SKim Phillips 			},
20568b4d43a4SKim Phillips 		.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
20578b4d43a4SKim Phillips 		.class2_alg_type = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC_PRECOMP,
20588b4d43a4SKim Phillips 		.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
20598b4d43a4SKim Phillips 	},
20608b4d43a4SKim Phillips 	{
20618e8ec596SKim Phillips 		.name = "authenc(hmac(sha1),cbc(des3_ede))",
20628e8ec596SKim Phillips 		.driver_name = "authenc-hmac-sha1-cbc-des3_ede-caam",
20638e8ec596SKim Phillips 		.blocksize = DES3_EDE_BLOCK_SIZE,
2064885e9e2fSYuan Kang 		.type = CRYPTO_ALG_TYPE_AEAD,
2065885e9e2fSYuan Kang 		.template_aead = {
20660e479300SYuan Kang 			.setkey = aead_setkey,
20670e479300SYuan Kang 			.setauthsize = aead_setauthsize,
20680e479300SYuan Kang 			.encrypt = aead_encrypt,
20690e479300SYuan Kang 			.decrypt = aead_decrypt,
20700e479300SYuan Kang 			.givencrypt = aead_givencrypt,
20718e8ec596SKim Phillips 			.geniv = "<built-in>",
20728e8ec596SKim Phillips 			.ivsize = DES3_EDE_BLOCK_SIZE,
20738e8ec596SKim Phillips 			.maxauthsize = SHA1_DIGEST_SIZE,
20748e8ec596SKim Phillips 			},
20758e8ec596SKim Phillips 		.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
20768e8ec596SKim Phillips 		.class2_alg_type = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC_PRECOMP,
20778e8ec596SKim Phillips 		.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
20788e8ec596SKim Phillips 	},
20798e8ec596SKim Phillips 	{
2080e863f9ccSHemant Agrawal 		.name = "authenc(hmac(sha224),cbc(des3_ede))",
2081e863f9ccSHemant Agrawal 		.driver_name = "authenc-hmac-sha224-cbc-des3_ede-caam",
2082e863f9ccSHemant Agrawal 		.blocksize = DES3_EDE_BLOCK_SIZE,
2083cb7d5662SVakul Garg 		.type = CRYPTO_ALG_TYPE_AEAD,
2084e863f9ccSHemant Agrawal 		.template_aead = {
2085e863f9ccSHemant Agrawal 			.setkey = aead_setkey,
2086e863f9ccSHemant Agrawal 			.setauthsize = aead_setauthsize,
2087e863f9ccSHemant Agrawal 			.encrypt = aead_encrypt,
2088e863f9ccSHemant Agrawal 			.decrypt = aead_decrypt,
2089e863f9ccSHemant Agrawal 			.givencrypt = aead_givencrypt,
2090e863f9ccSHemant Agrawal 			.geniv = "<built-in>",
2091e863f9ccSHemant Agrawal 			.ivsize = DES3_EDE_BLOCK_SIZE,
2092e863f9ccSHemant Agrawal 			.maxauthsize = SHA224_DIGEST_SIZE,
2093e863f9ccSHemant Agrawal 			},
2094e863f9ccSHemant Agrawal 		.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2095e863f9ccSHemant Agrawal 		.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2096e863f9ccSHemant Agrawal 				   OP_ALG_AAI_HMAC_PRECOMP,
2097e863f9ccSHemant Agrawal 		.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
2098e863f9ccSHemant Agrawal 	},
2099e863f9ccSHemant Agrawal 	{
21008e8ec596SKim Phillips 		.name = "authenc(hmac(sha256),cbc(des3_ede))",
21018e8ec596SKim Phillips 		.driver_name = "authenc-hmac-sha256-cbc-des3_ede-caam",
21028e8ec596SKim Phillips 		.blocksize = DES3_EDE_BLOCK_SIZE,
2103885e9e2fSYuan Kang 		.type = CRYPTO_ALG_TYPE_AEAD,
2104885e9e2fSYuan Kang 		.template_aead = {
21050e479300SYuan Kang 			.setkey = aead_setkey,
21060e479300SYuan Kang 			.setauthsize = aead_setauthsize,
21070e479300SYuan Kang 			.encrypt = aead_encrypt,
21080e479300SYuan Kang 			.decrypt = aead_decrypt,
21090e479300SYuan Kang 			.givencrypt = aead_givencrypt,
21108e8ec596SKim Phillips 			.geniv = "<built-in>",
21118e8ec596SKim Phillips 			.ivsize = DES3_EDE_BLOCK_SIZE,
21128e8ec596SKim Phillips 			.maxauthsize = SHA256_DIGEST_SIZE,
21138e8ec596SKim Phillips 			},
21148e8ec596SKim Phillips 		.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
21158e8ec596SKim Phillips 		.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
21168e8ec596SKim Phillips 				   OP_ALG_AAI_HMAC_PRECOMP,
21178e8ec596SKim Phillips 		.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
21188e8ec596SKim Phillips 	},
21198e8ec596SKim Phillips 	{
2120e863f9ccSHemant Agrawal 		.name = "authenc(hmac(sha384),cbc(des3_ede))",
2121e863f9ccSHemant Agrawal 		.driver_name = "authenc-hmac-sha384-cbc-des3_ede-caam",
2122e863f9ccSHemant Agrawal 		.blocksize = DES3_EDE_BLOCK_SIZE,
2123cb7d5662SVakul Garg 		.type = CRYPTO_ALG_TYPE_AEAD,
2124e863f9ccSHemant Agrawal 		.template_aead = {
2125e863f9ccSHemant Agrawal 			.setkey = aead_setkey,
2126e863f9ccSHemant Agrawal 			.setauthsize = aead_setauthsize,
2127e863f9ccSHemant Agrawal 			.encrypt = aead_encrypt,
2128e863f9ccSHemant Agrawal 			.decrypt = aead_decrypt,
2129e863f9ccSHemant Agrawal 			.givencrypt = aead_givencrypt,
2130e863f9ccSHemant Agrawal 			.geniv = "<built-in>",
2131e863f9ccSHemant Agrawal 			.ivsize = DES3_EDE_BLOCK_SIZE,
2132e863f9ccSHemant Agrawal 			.maxauthsize = SHA384_DIGEST_SIZE,
2133e863f9ccSHemant Agrawal 			},
2134e863f9ccSHemant Agrawal 		.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2135e863f9ccSHemant Agrawal 		.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2136e863f9ccSHemant Agrawal 				   OP_ALG_AAI_HMAC_PRECOMP,
2137e863f9ccSHemant Agrawal 		.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
2138e863f9ccSHemant Agrawal 	},
2139e863f9ccSHemant Agrawal 	{
21404427b1b4SKim Phillips 		.name = "authenc(hmac(sha512),cbc(des3_ede))",
21414427b1b4SKim Phillips 		.driver_name = "authenc-hmac-sha512-cbc-des3_ede-caam",
21424427b1b4SKim Phillips 		.blocksize = DES3_EDE_BLOCK_SIZE,
2143885e9e2fSYuan Kang 		.type = CRYPTO_ALG_TYPE_AEAD,
2144885e9e2fSYuan Kang 		.template_aead = {
21450e479300SYuan Kang 			.setkey = aead_setkey,
21460e479300SYuan Kang 			.setauthsize = aead_setauthsize,
21470e479300SYuan Kang 			.encrypt = aead_encrypt,
21480e479300SYuan Kang 			.decrypt = aead_decrypt,
21490e479300SYuan Kang 			.givencrypt = aead_givencrypt,
21504427b1b4SKim Phillips 			.geniv = "<built-in>",
21514427b1b4SKim Phillips 			.ivsize = DES3_EDE_BLOCK_SIZE,
21524427b1b4SKim Phillips 			.maxauthsize = SHA512_DIGEST_SIZE,
21534427b1b4SKim Phillips 			},
21544427b1b4SKim Phillips 		.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
21554427b1b4SKim Phillips 		.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
21564427b1b4SKim Phillips 				   OP_ALG_AAI_HMAC_PRECOMP,
21574427b1b4SKim Phillips 		.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
21584427b1b4SKim Phillips 	},
21594427b1b4SKim Phillips 	{
21608b4d43a4SKim Phillips 		.name = "authenc(hmac(md5),cbc(des))",
21618b4d43a4SKim Phillips 		.driver_name = "authenc-hmac-md5-cbc-des-caam",
21628b4d43a4SKim Phillips 		.blocksize = DES_BLOCK_SIZE,
21638b4d43a4SKim Phillips 		.type = CRYPTO_ALG_TYPE_AEAD,
21648b4d43a4SKim Phillips 		.template_aead = {
21658b4d43a4SKim Phillips 			.setkey = aead_setkey,
21668b4d43a4SKim Phillips 			.setauthsize = aead_setauthsize,
21678b4d43a4SKim Phillips 			.encrypt = aead_encrypt,
21688b4d43a4SKim Phillips 			.decrypt = aead_decrypt,
21698b4d43a4SKim Phillips 			.givencrypt = aead_givencrypt,
21708b4d43a4SKim Phillips 			.geniv = "<built-in>",
21718b4d43a4SKim Phillips 			.ivsize = DES_BLOCK_SIZE,
21728b4d43a4SKim Phillips 			.maxauthsize = MD5_DIGEST_SIZE,
21738b4d43a4SKim Phillips 			},
21748b4d43a4SKim Phillips 		.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
21758b4d43a4SKim Phillips 		.class2_alg_type = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC_PRECOMP,
21768b4d43a4SKim Phillips 		.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
21778b4d43a4SKim Phillips 	},
21788b4d43a4SKim Phillips 	{
21798e8ec596SKim Phillips 		.name = "authenc(hmac(sha1),cbc(des))",
21808e8ec596SKim Phillips 		.driver_name = "authenc-hmac-sha1-cbc-des-caam",
21818e8ec596SKim Phillips 		.blocksize = DES_BLOCK_SIZE,
2182885e9e2fSYuan Kang 		.type = CRYPTO_ALG_TYPE_AEAD,
2183885e9e2fSYuan Kang 		.template_aead = {
21840e479300SYuan Kang 			.setkey = aead_setkey,
21850e479300SYuan Kang 			.setauthsize = aead_setauthsize,
21860e479300SYuan Kang 			.encrypt = aead_encrypt,
21870e479300SYuan Kang 			.decrypt = aead_decrypt,
21880e479300SYuan Kang 			.givencrypt = aead_givencrypt,
21898e8ec596SKim Phillips 			.geniv = "<built-in>",
21908e8ec596SKim Phillips 			.ivsize = DES_BLOCK_SIZE,
21918e8ec596SKim Phillips 			.maxauthsize = SHA1_DIGEST_SIZE,
21928e8ec596SKim Phillips 			},
21938e8ec596SKim Phillips 		.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
21948e8ec596SKim Phillips 		.class2_alg_type = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC_PRECOMP,
21958e8ec596SKim Phillips 		.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
21968e8ec596SKim Phillips 	},
21978e8ec596SKim Phillips 	{
2198e863f9ccSHemant Agrawal 		.name = "authenc(hmac(sha224),cbc(des))",
2199e863f9ccSHemant Agrawal 		.driver_name = "authenc-hmac-sha224-cbc-des-caam",
2200e863f9ccSHemant Agrawal 		.blocksize = DES_BLOCK_SIZE,
2201cb7d5662SVakul Garg 		.type = CRYPTO_ALG_TYPE_AEAD,
2202e863f9ccSHemant Agrawal 		.template_aead = {
2203e863f9ccSHemant Agrawal 			.setkey = aead_setkey,
2204e863f9ccSHemant Agrawal 			.setauthsize = aead_setauthsize,
2205e863f9ccSHemant Agrawal 			.encrypt = aead_encrypt,
2206e863f9ccSHemant Agrawal 			.decrypt = aead_decrypt,
2207e863f9ccSHemant Agrawal 			.givencrypt = aead_givencrypt,
2208e863f9ccSHemant Agrawal 			.geniv = "<built-in>",
2209e863f9ccSHemant Agrawal 			.ivsize = DES_BLOCK_SIZE,
2210e863f9ccSHemant Agrawal 			.maxauthsize = SHA224_DIGEST_SIZE,
2211e863f9ccSHemant Agrawal 			},
2212e863f9ccSHemant Agrawal 		.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2213e863f9ccSHemant Agrawal 		.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2214e863f9ccSHemant Agrawal 				   OP_ALG_AAI_HMAC_PRECOMP,
2215e863f9ccSHemant Agrawal 		.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
2216e863f9ccSHemant Agrawal 	},
2217e863f9ccSHemant Agrawal 	{
22188e8ec596SKim Phillips 		.name = "authenc(hmac(sha256),cbc(des))",
22198e8ec596SKim Phillips 		.driver_name = "authenc-hmac-sha256-cbc-des-caam",
22208e8ec596SKim Phillips 		.blocksize = DES_BLOCK_SIZE,
2221885e9e2fSYuan Kang 		.type = CRYPTO_ALG_TYPE_AEAD,
2222885e9e2fSYuan Kang 		.template_aead = {
22230e479300SYuan Kang 			.setkey = aead_setkey,
22240e479300SYuan Kang 			.setauthsize = aead_setauthsize,
22250e479300SYuan Kang 			.encrypt = aead_encrypt,
22260e479300SYuan Kang 			.decrypt = aead_decrypt,
22270e479300SYuan Kang 			.givencrypt = aead_givencrypt,
22288e8ec596SKim Phillips 			.geniv = "<built-in>",
22298e8ec596SKim Phillips 			.ivsize = DES_BLOCK_SIZE,
22308e8ec596SKim Phillips 			.maxauthsize = SHA256_DIGEST_SIZE,
22318e8ec596SKim Phillips 			},
22328e8ec596SKim Phillips 		.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
22338e8ec596SKim Phillips 		.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
22348e8ec596SKim Phillips 				   OP_ALG_AAI_HMAC_PRECOMP,
22358e8ec596SKim Phillips 		.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
22368e8ec596SKim Phillips 	},
22374427b1b4SKim Phillips 	{
2238e863f9ccSHemant Agrawal 		.name = "authenc(hmac(sha384),cbc(des))",
2239e863f9ccSHemant Agrawal 		.driver_name = "authenc-hmac-sha384-cbc-des-caam",
2240e863f9ccSHemant Agrawal 		.blocksize = DES_BLOCK_SIZE,
2241cb7d5662SVakul Garg 		.type = CRYPTO_ALG_TYPE_AEAD,
2242e863f9ccSHemant Agrawal 		.template_aead = {
2243e863f9ccSHemant Agrawal 			.setkey = aead_setkey,
2244e863f9ccSHemant Agrawal 			.setauthsize = aead_setauthsize,
2245e863f9ccSHemant Agrawal 			.encrypt = aead_encrypt,
2246e863f9ccSHemant Agrawal 			.decrypt = aead_decrypt,
2247e863f9ccSHemant Agrawal 			.givencrypt = aead_givencrypt,
2248e863f9ccSHemant Agrawal 			.geniv = "<built-in>",
2249e863f9ccSHemant Agrawal 			.ivsize = DES_BLOCK_SIZE,
2250e863f9ccSHemant Agrawal 			.maxauthsize = SHA384_DIGEST_SIZE,
2251e863f9ccSHemant Agrawal 			},
2252e863f9ccSHemant Agrawal 		.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2253e863f9ccSHemant Agrawal 		.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2254e863f9ccSHemant Agrawal 				   OP_ALG_AAI_HMAC_PRECOMP,
2255e863f9ccSHemant Agrawal 		.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
2256e863f9ccSHemant Agrawal 	},
2257e863f9ccSHemant Agrawal 	{
22584427b1b4SKim Phillips 		.name = "authenc(hmac(sha512),cbc(des))",
22594427b1b4SKim Phillips 		.driver_name = "authenc-hmac-sha512-cbc-des-caam",
22604427b1b4SKim Phillips 		.blocksize = DES_BLOCK_SIZE,
2261885e9e2fSYuan Kang 		.type = CRYPTO_ALG_TYPE_AEAD,
2262885e9e2fSYuan Kang 		.template_aead = {
22630e479300SYuan Kang 			.setkey = aead_setkey,
22640e479300SYuan Kang 			.setauthsize = aead_setauthsize,
22650e479300SYuan Kang 			.encrypt = aead_encrypt,
22660e479300SYuan Kang 			.decrypt = aead_decrypt,
22670e479300SYuan Kang 			.givencrypt = aead_givencrypt,
22684427b1b4SKim Phillips 			.geniv = "<built-in>",
22694427b1b4SKim Phillips 			.ivsize = DES_BLOCK_SIZE,
22704427b1b4SKim Phillips 			.maxauthsize = SHA512_DIGEST_SIZE,
22714427b1b4SKim Phillips 			},
22724427b1b4SKim Phillips 		.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
22734427b1b4SKim Phillips 		.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
22744427b1b4SKim Phillips 				   OP_ALG_AAI_HMAC_PRECOMP,
22754427b1b4SKim Phillips 		.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
22764427b1b4SKim Phillips 	},
2277acdca31dSYuan Kang 	/* ablkcipher descriptor */
2278acdca31dSYuan Kang 	{
2279acdca31dSYuan Kang 		.name = "cbc(aes)",
2280acdca31dSYuan Kang 		.driver_name = "cbc-aes-caam",
2281acdca31dSYuan Kang 		.blocksize = AES_BLOCK_SIZE,
2282acdca31dSYuan Kang 		.type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2283acdca31dSYuan Kang 		.template_ablkcipher = {
2284acdca31dSYuan Kang 			.setkey = ablkcipher_setkey,
2285acdca31dSYuan Kang 			.encrypt = ablkcipher_encrypt,
2286acdca31dSYuan Kang 			.decrypt = ablkcipher_decrypt,
2287acdca31dSYuan Kang 			.geniv = "eseqiv",
2288acdca31dSYuan Kang 			.min_keysize = AES_MIN_KEY_SIZE,
2289acdca31dSYuan Kang 			.max_keysize = AES_MAX_KEY_SIZE,
2290acdca31dSYuan Kang 			.ivsize = AES_BLOCK_SIZE,
2291acdca31dSYuan Kang 			},
2292acdca31dSYuan Kang 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2293acdca31dSYuan Kang 	},
2294acdca31dSYuan Kang 	{
2295acdca31dSYuan Kang 		.name = "cbc(des3_ede)",
2296acdca31dSYuan Kang 		.driver_name = "cbc-3des-caam",
2297acdca31dSYuan Kang 		.blocksize = DES3_EDE_BLOCK_SIZE,
2298acdca31dSYuan Kang 		.type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2299acdca31dSYuan Kang 		.template_ablkcipher = {
2300acdca31dSYuan Kang 			.setkey = ablkcipher_setkey,
2301acdca31dSYuan Kang 			.encrypt = ablkcipher_encrypt,
2302acdca31dSYuan Kang 			.decrypt = ablkcipher_decrypt,
2303acdca31dSYuan Kang 			.geniv = "eseqiv",
2304acdca31dSYuan Kang 			.min_keysize = DES3_EDE_KEY_SIZE,
2305acdca31dSYuan Kang 			.max_keysize = DES3_EDE_KEY_SIZE,
2306acdca31dSYuan Kang 			.ivsize = DES3_EDE_BLOCK_SIZE,
2307acdca31dSYuan Kang 			},
2308acdca31dSYuan Kang 		.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2309acdca31dSYuan Kang 	},
2310acdca31dSYuan Kang 	{
2311acdca31dSYuan Kang 		.name = "cbc(des)",
2312acdca31dSYuan Kang 		.driver_name = "cbc-des-caam",
2313acdca31dSYuan Kang 		.blocksize = DES_BLOCK_SIZE,
2314acdca31dSYuan Kang 		.type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2315acdca31dSYuan Kang 		.template_ablkcipher = {
2316acdca31dSYuan Kang 			.setkey = ablkcipher_setkey,
2317acdca31dSYuan Kang 			.encrypt = ablkcipher_encrypt,
2318acdca31dSYuan Kang 			.decrypt = ablkcipher_decrypt,
2319acdca31dSYuan Kang 			.geniv = "eseqiv",
2320acdca31dSYuan Kang 			.min_keysize = DES_KEY_SIZE,
2321acdca31dSYuan Kang 			.max_keysize = DES_KEY_SIZE,
2322acdca31dSYuan Kang 			.ivsize = DES_BLOCK_SIZE,
2323acdca31dSYuan Kang 			},
2324acdca31dSYuan Kang 		.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2325acdca31dSYuan Kang 	}
23268e8ec596SKim Phillips };
23278e8ec596SKim Phillips 
23288e8ec596SKim Phillips struct caam_crypto_alg {
23298e8ec596SKim Phillips 	struct list_head entry;
23308e8ec596SKim Phillips 	int class1_alg_type;
23318e8ec596SKim Phillips 	int class2_alg_type;
23328e8ec596SKim Phillips 	int alg_op;
23338e8ec596SKim Phillips 	struct crypto_alg crypto_alg;
23348e8ec596SKim Phillips };
23358e8ec596SKim Phillips 
23368e8ec596SKim Phillips static int caam_cra_init(struct crypto_tfm *tfm)
23378e8ec596SKim Phillips {
23388e8ec596SKim Phillips 	struct crypto_alg *alg = tfm->__crt_alg;
23398e8ec596SKim Phillips 	struct caam_crypto_alg *caam_alg =
23408e8ec596SKim Phillips 		 container_of(alg, struct caam_crypto_alg, crypto_alg);
23418e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_tfm_ctx(tfm);
23428e8ec596SKim Phillips 
2343cfc6f11bSRuchika Gupta 	ctx->jrdev = caam_jr_alloc();
2344cfc6f11bSRuchika Gupta 	if (IS_ERR(ctx->jrdev)) {
2345cfc6f11bSRuchika Gupta 		pr_err("Job Ring Device allocation for transform failed\n");
2346cfc6f11bSRuchika Gupta 		return PTR_ERR(ctx->jrdev);
2347cfc6f11bSRuchika Gupta 	}
23488e8ec596SKim Phillips 
23498e8ec596SKim Phillips 	/* copy descriptor header template value */
23508e8ec596SKim Phillips 	ctx->class1_alg_type = OP_TYPE_CLASS1_ALG | caam_alg->class1_alg_type;
23518e8ec596SKim Phillips 	ctx->class2_alg_type = OP_TYPE_CLASS2_ALG | caam_alg->class2_alg_type;
23528e8ec596SKim Phillips 	ctx->alg_op = OP_TYPE_CLASS2_ALG | caam_alg->alg_op;
23538e8ec596SKim Phillips 
23548e8ec596SKim Phillips 	return 0;
23558e8ec596SKim Phillips }
23568e8ec596SKim Phillips 
23578e8ec596SKim Phillips static void caam_cra_exit(struct crypto_tfm *tfm)
23588e8ec596SKim Phillips {
23598e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_tfm_ctx(tfm);
23608e8ec596SKim Phillips 
23611acebad3SYuan Kang 	if (ctx->sh_desc_enc_dma &&
23621acebad3SYuan Kang 	    !dma_mapping_error(ctx->jrdev, ctx->sh_desc_enc_dma))
23631acebad3SYuan Kang 		dma_unmap_single(ctx->jrdev, ctx->sh_desc_enc_dma,
23641acebad3SYuan Kang 				 desc_bytes(ctx->sh_desc_enc), DMA_TO_DEVICE);
23651acebad3SYuan Kang 	if (ctx->sh_desc_dec_dma &&
23661acebad3SYuan Kang 	    !dma_mapping_error(ctx->jrdev, ctx->sh_desc_dec_dma))
23671acebad3SYuan Kang 		dma_unmap_single(ctx->jrdev, ctx->sh_desc_dec_dma,
23681acebad3SYuan Kang 				 desc_bytes(ctx->sh_desc_dec), DMA_TO_DEVICE);
23691acebad3SYuan Kang 	if (ctx->sh_desc_givenc_dma &&
23701acebad3SYuan Kang 	    !dma_mapping_error(ctx->jrdev, ctx->sh_desc_givenc_dma))
23711acebad3SYuan Kang 		dma_unmap_single(ctx->jrdev, ctx->sh_desc_givenc_dma,
23721acebad3SYuan Kang 				 desc_bytes(ctx->sh_desc_givenc),
23734427b1b4SKim Phillips 				 DMA_TO_DEVICE);
2374ec31eed7SHoria Geanta 	if (ctx->key_dma &&
2375ec31eed7SHoria Geanta 	    !dma_mapping_error(ctx->jrdev, ctx->key_dma))
2376ec31eed7SHoria Geanta 		dma_unmap_single(ctx->jrdev, ctx->key_dma,
2377ec31eed7SHoria Geanta 				 ctx->enckeylen + ctx->split_key_pad_len,
2378ec31eed7SHoria Geanta 				 DMA_TO_DEVICE);
2379cfc6f11bSRuchika Gupta 
2380cfc6f11bSRuchika Gupta 	caam_jr_free(ctx->jrdev);
23818e8ec596SKim Phillips }
23828e8ec596SKim Phillips 
23838e8ec596SKim Phillips static void __exit caam_algapi_exit(void)
23848e8ec596SKim Phillips {
23858e8ec596SKim Phillips 
23868e8ec596SKim Phillips 	struct caam_crypto_alg *t_alg, *n;
23878e8ec596SKim Phillips 
2388cfc6f11bSRuchika Gupta 	if (!alg_list.next)
23898e8ec596SKim Phillips 		return;
23908e8ec596SKim Phillips 
2391cfc6f11bSRuchika Gupta 	list_for_each_entry_safe(t_alg, n, &alg_list, entry) {
23928e8ec596SKim Phillips 		crypto_unregister_alg(&t_alg->crypto_alg);
23938e8ec596SKim Phillips 		list_del(&t_alg->entry);
23948e8ec596SKim Phillips 		kfree(t_alg);
23958e8ec596SKim Phillips 	}
23968e8ec596SKim Phillips }
23978e8ec596SKim Phillips 
2398cfc6f11bSRuchika Gupta static struct caam_crypto_alg *caam_alg_alloc(struct caam_alg_template
23998e8ec596SKim Phillips 					      *template)
24008e8ec596SKim Phillips {
24018e8ec596SKim Phillips 	struct caam_crypto_alg *t_alg;
24028e8ec596SKim Phillips 	struct crypto_alg *alg;
24038e8ec596SKim Phillips 
24048e8ec596SKim Phillips 	t_alg = kzalloc(sizeof(struct caam_crypto_alg), GFP_KERNEL);
24058e8ec596SKim Phillips 	if (!t_alg) {
2406cfc6f11bSRuchika Gupta 		pr_err("failed to allocate t_alg\n");
24078e8ec596SKim Phillips 		return ERR_PTR(-ENOMEM);
24088e8ec596SKim Phillips 	}
24098e8ec596SKim Phillips 
24108e8ec596SKim Phillips 	alg = &t_alg->crypto_alg;
24118e8ec596SKim Phillips 
24128e8ec596SKim Phillips 	snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", template->name);
24138e8ec596SKim Phillips 	snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s",
24148e8ec596SKim Phillips 		 template->driver_name);
24158e8ec596SKim Phillips 	alg->cra_module = THIS_MODULE;
24168e8ec596SKim Phillips 	alg->cra_init = caam_cra_init;
24178e8ec596SKim Phillips 	alg->cra_exit = caam_cra_exit;
24188e8ec596SKim Phillips 	alg->cra_priority = CAAM_CRA_PRIORITY;
24198e8ec596SKim Phillips 	alg->cra_blocksize = template->blocksize;
24208e8ec596SKim Phillips 	alg->cra_alignmask = 0;
24218e8ec596SKim Phillips 	alg->cra_ctxsize = sizeof(struct caam_ctx);
2422d912bb76SNikos Mavrogiannopoulos 	alg->cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY |
2423d912bb76SNikos Mavrogiannopoulos 			 template->type;
2424885e9e2fSYuan Kang 	switch (template->type) {
2425acdca31dSYuan Kang 	case CRYPTO_ALG_TYPE_ABLKCIPHER:
2426acdca31dSYuan Kang 		alg->cra_type = &crypto_ablkcipher_type;
2427acdca31dSYuan Kang 		alg->cra_ablkcipher = template->template_ablkcipher;
2428acdca31dSYuan Kang 		break;
2429885e9e2fSYuan Kang 	case CRYPTO_ALG_TYPE_AEAD:
2430885e9e2fSYuan Kang 		alg->cra_type = &crypto_aead_type;
2431885e9e2fSYuan Kang 		alg->cra_aead = template->template_aead;
2432885e9e2fSYuan Kang 		break;
2433885e9e2fSYuan Kang 	}
24348e8ec596SKim Phillips 
24358e8ec596SKim Phillips 	t_alg->class1_alg_type = template->class1_alg_type;
24368e8ec596SKim Phillips 	t_alg->class2_alg_type = template->class2_alg_type;
24378e8ec596SKim Phillips 	t_alg->alg_op = template->alg_op;
24388e8ec596SKim Phillips 
24398e8ec596SKim Phillips 	return t_alg;
24408e8ec596SKim Phillips }
24418e8ec596SKim Phillips 
24428e8ec596SKim Phillips static int __init caam_algapi_init(void)
24438e8ec596SKim Phillips {
244435af6403SRuchika Gupta 	struct device_node *dev_node;
244535af6403SRuchika Gupta 	struct platform_device *pdev;
244635af6403SRuchika Gupta 	struct device *ctrldev;
244735af6403SRuchika Gupta 	void *priv;
24488e8ec596SKim Phillips 	int i = 0, err = 0;
24498e8ec596SKim Phillips 
245035af6403SRuchika Gupta 	dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
245135af6403SRuchika Gupta 	if (!dev_node) {
245235af6403SRuchika Gupta 		dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
245335af6403SRuchika Gupta 		if (!dev_node)
245435af6403SRuchika Gupta 			return -ENODEV;
245535af6403SRuchika Gupta 	}
245635af6403SRuchika Gupta 
245735af6403SRuchika Gupta 	pdev = of_find_device_by_node(dev_node);
245835af6403SRuchika Gupta 	if (!pdev) {
245935af6403SRuchika Gupta 		of_node_put(dev_node);
246035af6403SRuchika Gupta 		return -ENODEV;
246135af6403SRuchika Gupta 	}
246235af6403SRuchika Gupta 
246335af6403SRuchika Gupta 	ctrldev = &pdev->dev;
246435af6403SRuchika Gupta 	priv = dev_get_drvdata(ctrldev);
246535af6403SRuchika Gupta 	of_node_put(dev_node);
246635af6403SRuchika Gupta 
246735af6403SRuchika Gupta 	/*
246835af6403SRuchika Gupta 	 * If priv is NULL, it's probably because the caam driver wasn't
246935af6403SRuchika Gupta 	 * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
247035af6403SRuchika Gupta 	 */
247135af6403SRuchika Gupta 	if (!priv)
247235af6403SRuchika Gupta 		return -ENODEV;
247335af6403SRuchika Gupta 
247435af6403SRuchika Gupta 
2475cfc6f11bSRuchika Gupta 	INIT_LIST_HEAD(&alg_list);
24768e8ec596SKim Phillips 
24778e8ec596SKim Phillips 	/* register crypto algorithms the device supports */
24788e8ec596SKim Phillips 	for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
24798e8ec596SKim Phillips 		/* TODO: check if h/w supports alg */
24808e8ec596SKim Phillips 		struct caam_crypto_alg *t_alg;
24818e8ec596SKim Phillips 
2482cfc6f11bSRuchika Gupta 		t_alg = caam_alg_alloc(&driver_algs[i]);
24838e8ec596SKim Phillips 		if (IS_ERR(t_alg)) {
24848e8ec596SKim Phillips 			err = PTR_ERR(t_alg);
2485cfc6f11bSRuchika Gupta 			pr_warn("%s alg allocation failed\n",
2486cdc712d8SDan Carpenter 				driver_algs[i].driver_name);
24878e8ec596SKim Phillips 			continue;
24888e8ec596SKim Phillips 		}
24898e8ec596SKim Phillips 
24908e8ec596SKim Phillips 		err = crypto_register_alg(&t_alg->crypto_alg);
24918e8ec596SKim Phillips 		if (err) {
2492cfc6f11bSRuchika Gupta 			pr_warn("%s alg registration failed\n",
24938e8ec596SKim Phillips 				t_alg->crypto_alg.cra_driver_name);
24948e8ec596SKim Phillips 			kfree(t_alg);
2495246bbedbSHoria Geanta 		} else
2496cfc6f11bSRuchika Gupta 			list_add_tail(&t_alg->entry, &alg_list);
24978e8ec596SKim Phillips 	}
2498cfc6f11bSRuchika Gupta 	if (!list_empty(&alg_list))
2499cfc6f11bSRuchika Gupta 		pr_info("caam algorithms registered in /proc/crypto\n");
25008e8ec596SKim Phillips 
25018e8ec596SKim Phillips 	return err;
25028e8ec596SKim Phillips }
25038e8ec596SKim Phillips 
25048e8ec596SKim Phillips module_init(caam_algapi_init);
25058e8ec596SKim Phillips module_exit(caam_algapi_exit);
25068e8ec596SKim Phillips 
25078e8ec596SKim Phillips MODULE_LICENSE("GPL");
25088e8ec596SKim Phillips MODULE_DESCRIPTION("FSL CAAM support for crypto API");
25098e8ec596SKim Phillips MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");
2510