xref: /dpdk/drivers/common/cpt/cpt_ucode.h (revision cb7842f23eadf33e7227ab0fcab2bb7f4dfb2eea)
143d01767SNithin Dabilpuram /* SPDX-License-Identifier: BSD-3-Clause
243d01767SNithin Dabilpuram  * Copyright(c) 2018 Cavium, Inc
343d01767SNithin Dabilpuram  */
443d01767SNithin Dabilpuram 
543d01767SNithin Dabilpuram #ifndef _CPT_UCODE_H_
643d01767SNithin Dabilpuram #define _CPT_UCODE_H_
7b74652f3SRagothaman Jayaraman #include <stdbool.h>
8b74652f3SRagothaman Jayaraman 
9b74652f3SRagothaman Jayaraman #include "cpt_common.h"
10b74652f3SRagothaman Jayaraman #include "cpt_hw_types.h"
1143d01767SNithin Dabilpuram #include "cpt_mcode_defines.h"
1243d01767SNithin Dabilpuram 
1343d01767SNithin Dabilpuram /*
1443d01767SNithin Dabilpuram  * This file defines functions that are interfaces to microcode spec.
1543d01767SNithin Dabilpuram  *
1643d01767SNithin Dabilpuram  */
1743d01767SNithin Dabilpuram 
186cc54096SNithin Dabilpuram static uint8_t zuc_d[32] = {
196cc54096SNithin Dabilpuram 	0x44, 0xD7, 0x26, 0xBC, 0x62, 0x6B, 0x13, 0x5E,
206cc54096SNithin Dabilpuram 	0x57, 0x89, 0x35, 0xE2, 0x71, 0x35, 0x09, 0xAF,
216cc54096SNithin Dabilpuram 	0x4D, 0x78, 0x2F, 0x13, 0x6B, 0xC4, 0x1A, 0xF1,
226cc54096SNithin Dabilpuram 	0x5E, 0x26, 0x3C, 0x4D, 0x78, 0x9A, 0x47, 0xAC
236cc54096SNithin Dabilpuram };
246cc54096SNithin Dabilpuram 
256cc54096SNithin Dabilpuram static __rte_always_inline void
26186b14d6SFan Zhang gen_key_snow3g(const uint8_t *ck, uint32_t *keyx)
276cc54096SNithin Dabilpuram {
286cc54096SNithin Dabilpuram 	int i, base;
296cc54096SNithin Dabilpuram 
306cc54096SNithin Dabilpuram 	for (i = 0; i < 4; i++) {
316cc54096SNithin Dabilpuram 		base = 4 * i;
326cc54096SNithin Dabilpuram 		keyx[3 - i] = (ck[base] << 24) | (ck[base + 1] << 16) |
336cc54096SNithin Dabilpuram 			(ck[base + 2] << 8) | (ck[base + 3]);
346cc54096SNithin Dabilpuram 		keyx[3 - i] = rte_cpu_to_be_32(keyx[3 - i]);
356cc54096SNithin Dabilpuram 	}
366cc54096SNithin Dabilpuram }
376cc54096SNithin Dabilpuram 
38b74652f3SRagothaman Jayaraman static __rte_always_inline void
39b74652f3SRagothaman Jayaraman cpt_fc_salt_update(void *ctx,
40b74652f3SRagothaman Jayaraman 		   uint8_t *salt)
41b74652f3SRagothaman Jayaraman {
42b74652f3SRagothaman Jayaraman 	struct cpt_ctx *cpt_ctx = ctx;
43b74652f3SRagothaman Jayaraman 	memcpy(&cpt_ctx->fctx.enc.encr_iv, salt, 4);
44b74652f3SRagothaman Jayaraman }
45b74652f3SRagothaman Jayaraman 
466cc54096SNithin Dabilpuram static __rte_always_inline int
476cc54096SNithin Dabilpuram cpt_fc_ciph_validate_key_aes(uint16_t key_len)
486cc54096SNithin Dabilpuram {
496cc54096SNithin Dabilpuram 	switch (key_len) {
506cc54096SNithin Dabilpuram 	case CPT_BYTE_16:
516cc54096SNithin Dabilpuram 	case CPT_BYTE_24:
526cc54096SNithin Dabilpuram 	case CPT_BYTE_32:
536cc54096SNithin Dabilpuram 		return 0;
546cc54096SNithin Dabilpuram 	default:
556cc54096SNithin Dabilpuram 		return -1;
566cc54096SNithin Dabilpuram 	}
576cc54096SNithin Dabilpuram }
586cc54096SNithin Dabilpuram 
596cc54096SNithin Dabilpuram static __rte_always_inline int
608de5ede7SAnoob Joseph cpt_fc_ciph_set_type(cipher_type_t type, struct cpt_ctx *ctx, uint16_t key_len)
616cc54096SNithin Dabilpuram {
626cc54096SNithin Dabilpuram 	int fc_type = 0;
636cc54096SNithin Dabilpuram 	switch (type) {
646cc54096SNithin Dabilpuram 	case PASSTHROUGH:
656cc54096SNithin Dabilpuram 		fc_type = FC_GEN;
666cc54096SNithin Dabilpuram 		break;
676cc54096SNithin Dabilpuram 	case DES3_CBC:
686cc54096SNithin Dabilpuram 	case DES3_ECB:
696cc54096SNithin Dabilpuram 		fc_type = FC_GEN;
706cc54096SNithin Dabilpuram 		break;
716cc54096SNithin Dabilpuram 	case AES_CBC:
726cc54096SNithin Dabilpuram 	case AES_ECB:
736cc54096SNithin Dabilpuram 	case AES_CFB:
746cc54096SNithin Dabilpuram 	case AES_CTR:
756cc54096SNithin Dabilpuram 	case AES_GCM:
766cc54096SNithin Dabilpuram 		if (unlikely(cpt_fc_ciph_validate_key_aes(key_len) != 0))
776cc54096SNithin Dabilpuram 			return -1;
786cc54096SNithin Dabilpuram 		fc_type = FC_GEN;
796cc54096SNithin Dabilpuram 		break;
80*cb7842f2STejasree Kondoj 	case CHACHA20:
81*cb7842f2STejasree Kondoj 		fc_type = FC_GEN;
82*cb7842f2STejasree Kondoj 		break;
836cc54096SNithin Dabilpuram 	case AES_XTS:
846cc54096SNithin Dabilpuram 		key_len = key_len / 2;
856cc54096SNithin Dabilpuram 		if (unlikely(key_len == CPT_BYTE_24)) {
866cc54096SNithin Dabilpuram 			CPT_LOG_DP_ERR("Invalid AES key len for XTS");
876cc54096SNithin Dabilpuram 			return -1;
886cc54096SNithin Dabilpuram 		}
896cc54096SNithin Dabilpuram 		if (unlikely(cpt_fc_ciph_validate_key_aes(key_len) != 0))
906cc54096SNithin Dabilpuram 			return -1;
916cc54096SNithin Dabilpuram 		fc_type = FC_GEN;
926cc54096SNithin Dabilpuram 		break;
936cc54096SNithin Dabilpuram 	case ZUC_EEA3:
946cc54096SNithin Dabilpuram 	case SNOW3G_UEA2:
956cc54096SNithin Dabilpuram 		if (unlikely(key_len != 16))
966cc54096SNithin Dabilpuram 			return -1;
976cc54096SNithin Dabilpuram 		/* No support for AEAD yet */
988de5ede7SAnoob Joseph 		if (unlikely(ctx->hash_type))
996cc54096SNithin Dabilpuram 			return -1;
1006cc54096SNithin Dabilpuram 		fc_type = ZUC_SNOW3G;
1016cc54096SNithin Dabilpuram 		break;
1026cc54096SNithin Dabilpuram 	case KASUMI_F8_CBC:
1036cc54096SNithin Dabilpuram 	case KASUMI_F8_ECB:
1046cc54096SNithin Dabilpuram 		if (unlikely(key_len != 16))
1056cc54096SNithin Dabilpuram 			return -1;
1066cc54096SNithin Dabilpuram 		/* No support for AEAD yet */
1078de5ede7SAnoob Joseph 		if (unlikely(ctx->hash_type))
1086cc54096SNithin Dabilpuram 			return -1;
1096cc54096SNithin Dabilpuram 		fc_type = KASUMI;
1106cc54096SNithin Dabilpuram 		break;
1116cc54096SNithin Dabilpuram 	default:
1126cc54096SNithin Dabilpuram 		return -1;
1136cc54096SNithin Dabilpuram 	}
1148de5ede7SAnoob Joseph 
1158de5ede7SAnoob Joseph 	ctx->fc_type = fc_type;
1168de5ede7SAnoob Joseph 	return 0;
1176cc54096SNithin Dabilpuram }
1186cc54096SNithin Dabilpuram 
1196cc54096SNithin Dabilpuram static __rte_always_inline void
1206cc54096SNithin Dabilpuram cpt_fc_ciph_set_key_passthrough(struct cpt_ctx *cpt_ctx, mc_fc_context_t *fctx)
1216cc54096SNithin Dabilpuram {
1226cc54096SNithin Dabilpuram 	cpt_ctx->enc_cipher = 0;
123c3d0bc45SAnoob Joseph 	fctx->enc.enc_cipher = 0;
1246cc54096SNithin Dabilpuram }
1256cc54096SNithin Dabilpuram 
1266cc54096SNithin Dabilpuram static __rte_always_inline void
1276cc54096SNithin Dabilpuram cpt_fc_ciph_set_key_set_aes_key_type(mc_fc_context_t *fctx, uint16_t key_len)
1286cc54096SNithin Dabilpuram {
1296cc54096SNithin Dabilpuram 	mc_aes_type_t aes_key_type = 0;
1306cc54096SNithin Dabilpuram 	switch (key_len) {
1316cc54096SNithin Dabilpuram 	case CPT_BYTE_16:
1326cc54096SNithin Dabilpuram 		aes_key_type = AES_128_BIT;
1336cc54096SNithin Dabilpuram 		break;
1346cc54096SNithin Dabilpuram 	case CPT_BYTE_24:
1356cc54096SNithin Dabilpuram 		aes_key_type = AES_192_BIT;
1366cc54096SNithin Dabilpuram 		break;
1376cc54096SNithin Dabilpuram 	case CPT_BYTE_32:
1386cc54096SNithin Dabilpuram 		aes_key_type = AES_256_BIT;
1396cc54096SNithin Dabilpuram 		break;
1406cc54096SNithin Dabilpuram 	default:
1416cc54096SNithin Dabilpuram 		/* This should not happen */
1426cc54096SNithin Dabilpuram 		CPT_LOG_DP_ERR("Invalid AES key len");
1436cc54096SNithin Dabilpuram 		return;
1446cc54096SNithin Dabilpuram 	}
145c3d0bc45SAnoob Joseph 	fctx->enc.aes_key = aes_key_type;
1466cc54096SNithin Dabilpuram }
1476cc54096SNithin Dabilpuram 
1486cc54096SNithin Dabilpuram static __rte_always_inline void
149186b14d6SFan Zhang cpt_fc_ciph_set_key_snow3g_uea2(struct cpt_ctx *cpt_ctx, const uint8_t *key,
1506cc54096SNithin Dabilpuram 		uint16_t key_len)
1516cc54096SNithin Dabilpuram {
1526cc54096SNithin Dabilpuram 	uint32_t keyx[4];
1536cc54096SNithin Dabilpuram 	cpt_ctx->snow3g = 1;
1546cc54096SNithin Dabilpuram 	gen_key_snow3g(key, keyx);
1556cc54096SNithin Dabilpuram 	memcpy(cpt_ctx->zs_ctx.ci_key, keyx, key_len);
1566cc54096SNithin Dabilpuram 	cpt_ctx->zsk_flags = 0;
1576cc54096SNithin Dabilpuram }
1586cc54096SNithin Dabilpuram 
1596cc54096SNithin Dabilpuram static __rte_always_inline void
160186b14d6SFan Zhang cpt_fc_ciph_set_key_zuc_eea3(struct cpt_ctx *cpt_ctx, const uint8_t *key,
1616cc54096SNithin Dabilpuram 		uint16_t key_len)
1626cc54096SNithin Dabilpuram {
1636cc54096SNithin Dabilpuram 	cpt_ctx->snow3g = 0;
1646cc54096SNithin Dabilpuram 	memcpy(cpt_ctx->zs_ctx.ci_key, key, key_len);
1656cc54096SNithin Dabilpuram 	memcpy(cpt_ctx->zs_ctx.zuc_const, zuc_d, 32);
1666cc54096SNithin Dabilpuram 	cpt_ctx->zsk_flags = 0;
1676cc54096SNithin Dabilpuram }
1686cc54096SNithin Dabilpuram 
1696cc54096SNithin Dabilpuram static __rte_always_inline void
170186b14d6SFan Zhang cpt_fc_ciph_set_key_kasumi_f8_ecb(struct cpt_ctx *cpt_ctx, const uint8_t *key,
1716cc54096SNithin Dabilpuram 		uint16_t key_len)
1726cc54096SNithin Dabilpuram {
1736cc54096SNithin Dabilpuram 	cpt_ctx->k_ecb = 1;
1746cc54096SNithin Dabilpuram 	memcpy(cpt_ctx->k_ctx.ci_key, key, key_len);
1756cc54096SNithin Dabilpuram 	cpt_ctx->zsk_flags = 0;
1766cc54096SNithin Dabilpuram }
1776cc54096SNithin Dabilpuram 
1786cc54096SNithin Dabilpuram static __rte_always_inline void
179186b14d6SFan Zhang cpt_fc_ciph_set_key_kasumi_f8_cbc(struct cpt_ctx *cpt_ctx, const uint8_t *key,
1806cc54096SNithin Dabilpuram 		uint16_t key_len)
1816cc54096SNithin Dabilpuram {
1826cc54096SNithin Dabilpuram 	memcpy(cpt_ctx->k_ctx.ci_key, key, key_len);
1836cc54096SNithin Dabilpuram 	cpt_ctx->zsk_flags = 0;
1846cc54096SNithin Dabilpuram }
1856cc54096SNithin Dabilpuram 
1866cc54096SNithin Dabilpuram static __rte_always_inline int
187186b14d6SFan Zhang cpt_fc_ciph_set_key(void *ctx, cipher_type_t type, const uint8_t *key,
1886cc54096SNithin Dabilpuram 		    uint16_t key_len, uint8_t *salt)
1896cc54096SNithin Dabilpuram {
1906cc54096SNithin Dabilpuram 	struct cpt_ctx *cpt_ctx = ctx;
1916cc54096SNithin Dabilpuram 	mc_fc_context_t *fctx = &cpt_ctx->fctx;
1928de5ede7SAnoob Joseph 	int ret;
1936cc54096SNithin Dabilpuram 
1948de5ede7SAnoob Joseph 	ret = cpt_fc_ciph_set_type(type, cpt_ctx, key_len);
1958de5ede7SAnoob Joseph 	if (unlikely(ret))
1966cc54096SNithin Dabilpuram 		return -1;
1976cc54096SNithin Dabilpuram 
1988de5ede7SAnoob Joseph 	if (cpt_ctx->fc_type == FC_GEN) {
1996cc54096SNithin Dabilpuram 		/*
2006cc54096SNithin Dabilpuram 		 * We need to always say IV is from DPTR as user can
2016cc54096SNithin Dabilpuram 		 * sometimes iverride IV per operation.
2026cc54096SNithin Dabilpuram 		 */
203c3d0bc45SAnoob Joseph 		fctx->enc.iv_source = CPT_FROM_DPTR;
2042839a8abSSucharitha Sarananaga 
2052839a8abSSucharitha Sarananaga 		if (cpt_ctx->auth_key_len > 64)
2062839a8abSSucharitha Sarananaga 			return -1;
2076cc54096SNithin Dabilpuram 	}
2086cc54096SNithin Dabilpuram 
2096cc54096SNithin Dabilpuram 	switch (type) {
2106cc54096SNithin Dabilpuram 	case PASSTHROUGH:
2116cc54096SNithin Dabilpuram 		cpt_fc_ciph_set_key_passthrough(cpt_ctx, fctx);
212c3d0bc45SAnoob Joseph 		goto success;
2136cc54096SNithin Dabilpuram 	case DES3_CBC:
2146cc54096SNithin Dabilpuram 		/* CPT performs DES using 3DES with the 8B DES-key
2156cc54096SNithin Dabilpuram 		 * replicated 2 more times to match the 24B 3DES-key.
2166cc54096SNithin Dabilpuram 		 * Eg. If org. key is "0x0a 0x0b", then new key is
2176cc54096SNithin Dabilpuram 		 * "0x0a 0x0b 0x0a 0x0b 0x0a 0x0b"
2186cc54096SNithin Dabilpuram 		 */
2196cc54096SNithin Dabilpuram 		if (key_len == 8) {
2206cc54096SNithin Dabilpuram 			/* Skipping the first 8B as it will be copied
2216cc54096SNithin Dabilpuram 			 * in the regular code flow
2226cc54096SNithin Dabilpuram 			 */
2236cc54096SNithin Dabilpuram 			memcpy(fctx->enc.encr_key+key_len, key, key_len);
2246cc54096SNithin Dabilpuram 			memcpy(fctx->enc.encr_key+2*key_len, key, key_len);
2256cc54096SNithin Dabilpuram 		}
2266cc54096SNithin Dabilpuram 		break;
2276cc54096SNithin Dabilpuram 	case DES3_ECB:
2286cc54096SNithin Dabilpuram 		/* For DES3_ECB IV need to be from CTX. */
229c3d0bc45SAnoob Joseph 		fctx->enc.iv_source = CPT_FROM_CTX;
2306cc54096SNithin Dabilpuram 		break;
2316cc54096SNithin Dabilpuram 	case AES_CBC:
2326cc54096SNithin Dabilpuram 	case AES_ECB:
2336cc54096SNithin Dabilpuram 	case AES_CFB:
2346cc54096SNithin Dabilpuram 	case AES_CTR:
235*cb7842f2STejasree Kondoj 	case CHACHA20:
2366cc54096SNithin Dabilpuram 		cpt_fc_ciph_set_key_set_aes_key_type(fctx, key_len);
2376cc54096SNithin Dabilpuram 		break;
2386cc54096SNithin Dabilpuram 	case AES_GCM:
2396cc54096SNithin Dabilpuram 		/* Even though iv source is from dptr,
2406cc54096SNithin Dabilpuram 		 * aes_gcm salt is taken from ctx
2416cc54096SNithin Dabilpuram 		 */
2426cc54096SNithin Dabilpuram 		if (salt) {
2436cc54096SNithin Dabilpuram 			memcpy(fctx->enc.encr_iv, salt, 4);
2446cc54096SNithin Dabilpuram 			/* Assuming it was just salt update
2456cc54096SNithin Dabilpuram 			 * and nothing else
2466cc54096SNithin Dabilpuram 			 */
2476cc54096SNithin Dabilpuram 			if (!key)
248c3d0bc45SAnoob Joseph 				goto success;
2496cc54096SNithin Dabilpuram 		}
2506cc54096SNithin Dabilpuram 		cpt_fc_ciph_set_key_set_aes_key_type(fctx, key_len);
2516cc54096SNithin Dabilpuram 		break;
2526cc54096SNithin Dabilpuram 	case AES_XTS:
2536cc54096SNithin Dabilpuram 		key_len = key_len / 2;
2546cc54096SNithin Dabilpuram 		cpt_fc_ciph_set_key_set_aes_key_type(fctx, key_len);
2556cc54096SNithin Dabilpuram 
2566cc54096SNithin Dabilpuram 		/* Copy key2 for XTS into ipad */
2576cc54096SNithin Dabilpuram 		memset(fctx->hmac.ipad, 0, sizeof(fctx->hmac.ipad));
2586cc54096SNithin Dabilpuram 		memcpy(fctx->hmac.ipad, &key[key_len], key_len);
2596cc54096SNithin Dabilpuram 		break;
2606cc54096SNithin Dabilpuram 	case SNOW3G_UEA2:
2616cc54096SNithin Dabilpuram 		cpt_fc_ciph_set_key_snow3g_uea2(cpt_ctx, key, key_len);
2626cc54096SNithin Dabilpuram 		goto success;
2636cc54096SNithin Dabilpuram 	case ZUC_EEA3:
2646cc54096SNithin Dabilpuram 		cpt_fc_ciph_set_key_zuc_eea3(cpt_ctx, key, key_len);
2656cc54096SNithin Dabilpuram 		goto success;
2666cc54096SNithin Dabilpuram 	case KASUMI_F8_ECB:
2676cc54096SNithin Dabilpuram 		cpt_fc_ciph_set_key_kasumi_f8_ecb(cpt_ctx, key, key_len);
2686cc54096SNithin Dabilpuram 		goto success;
2696cc54096SNithin Dabilpuram 	case KASUMI_F8_CBC:
2706cc54096SNithin Dabilpuram 		cpt_fc_ciph_set_key_kasumi_f8_cbc(cpt_ctx, key, key_len);
2716cc54096SNithin Dabilpuram 		goto success;
2726cc54096SNithin Dabilpuram 	default:
273e40175c5SArchana Muniganti 		return -1;
2746cc54096SNithin Dabilpuram 	}
2756cc54096SNithin Dabilpuram 
2766cc54096SNithin Dabilpuram 	/* Only for FC_GEN case */
2776cc54096SNithin Dabilpuram 
2786cc54096SNithin Dabilpuram 	/* For GMAC auth, cipher must be NULL */
2796cc54096SNithin Dabilpuram 	if (cpt_ctx->hash_type != GMAC_TYPE)
280c3d0bc45SAnoob Joseph 		fctx->enc.enc_cipher = type;
2816cc54096SNithin Dabilpuram 
2826cc54096SNithin Dabilpuram 	memcpy(fctx->enc.encr_key, key, key_len);
2836cc54096SNithin Dabilpuram 
2846cc54096SNithin Dabilpuram success:
2856cc54096SNithin Dabilpuram 	cpt_ctx->enc_cipher = type;
2866cc54096SNithin Dabilpuram 
2876cc54096SNithin Dabilpuram 	return 0;
2886cc54096SNithin Dabilpuram }
2896cc54096SNithin Dabilpuram 
290b74652f3SRagothaman Jayaraman static __rte_always_inline uint32_t
291b74652f3SRagothaman Jayaraman fill_sg_comp(sg_comp_t *list,
292b74652f3SRagothaman Jayaraman 	     uint32_t i,
293b74652f3SRagothaman Jayaraman 	     phys_addr_t dma_addr,
294b74652f3SRagothaman Jayaraman 	     uint32_t size)
295b74652f3SRagothaman Jayaraman {
296b74652f3SRagothaman Jayaraman 	sg_comp_t *to = &list[i>>2];
297b74652f3SRagothaman Jayaraman 
298b74652f3SRagothaman Jayaraman 	to->u.s.len[i%4] = rte_cpu_to_be_16(size);
299b74652f3SRagothaman Jayaraman 	to->ptr[i%4] = rte_cpu_to_be_64(dma_addr);
300b74652f3SRagothaman Jayaraman 	i++;
301b74652f3SRagothaman Jayaraman 	return i;
302b74652f3SRagothaman Jayaraman }
303b74652f3SRagothaman Jayaraman 
304b74652f3SRagothaman Jayaraman static __rte_always_inline uint32_t
305b74652f3SRagothaman Jayaraman fill_sg_comp_from_buf(sg_comp_t *list,
306b74652f3SRagothaman Jayaraman 		      uint32_t i,
307b74652f3SRagothaman Jayaraman 		      buf_ptr_t *from)
308b74652f3SRagothaman Jayaraman {
309b74652f3SRagothaman Jayaraman 	sg_comp_t *to = &list[i>>2];
310b74652f3SRagothaman Jayaraman 
311b74652f3SRagothaman Jayaraman 	to->u.s.len[i%4] = rte_cpu_to_be_16(from->size);
312b74652f3SRagothaman Jayaraman 	to->ptr[i%4] = rte_cpu_to_be_64(from->dma_addr);
313b74652f3SRagothaman Jayaraman 	i++;
314b74652f3SRagothaman Jayaraman 	return i;
315b74652f3SRagothaman Jayaraman }
316b74652f3SRagothaman Jayaraman 
317b74652f3SRagothaman Jayaraman static __rte_always_inline uint32_t
318b74652f3SRagothaman Jayaraman fill_sg_comp_from_buf_min(sg_comp_t *list,
319b74652f3SRagothaman Jayaraman 			  uint32_t i,
320b74652f3SRagothaman Jayaraman 			  buf_ptr_t *from,
321b74652f3SRagothaman Jayaraman 			  uint32_t *psize)
322b74652f3SRagothaman Jayaraman {
323b74652f3SRagothaman Jayaraman 	sg_comp_t *to = &list[i >> 2];
324b74652f3SRagothaman Jayaraman 	uint32_t size = *psize;
325b74652f3SRagothaman Jayaraman 	uint32_t e_len;
326b74652f3SRagothaman Jayaraman 
327b74652f3SRagothaman Jayaraman 	e_len = (size > from->size) ? from->size : size;
328b74652f3SRagothaman Jayaraman 	to->u.s.len[i % 4] = rte_cpu_to_be_16(e_len);
329b74652f3SRagothaman Jayaraman 	to->ptr[i % 4] = rte_cpu_to_be_64(from->dma_addr);
330b74652f3SRagothaman Jayaraman 	*psize -= e_len;
331b74652f3SRagothaman Jayaraman 	i++;
332b74652f3SRagothaman Jayaraman 	return i;
333b74652f3SRagothaman Jayaraman }
334b74652f3SRagothaman Jayaraman 
335b74652f3SRagothaman Jayaraman /*
336b74652f3SRagothaman Jayaraman  * This fills the MC expected SGIO list
337b74652f3SRagothaman Jayaraman  * from IOV given by user.
338b74652f3SRagothaman Jayaraman  */
339b74652f3SRagothaman Jayaraman static __rte_always_inline uint32_t
340b74652f3SRagothaman Jayaraman fill_sg_comp_from_iov(sg_comp_t *list,
341b74652f3SRagothaman Jayaraman 		      uint32_t i,
342b74652f3SRagothaman Jayaraman 		      iov_ptr_t *from, uint32_t from_offset,
343b74652f3SRagothaman Jayaraman 		      uint32_t *psize, buf_ptr_t *extra_buf,
344b74652f3SRagothaman Jayaraman 		      uint32_t extra_offset)
345b74652f3SRagothaman Jayaraman {
346b74652f3SRagothaman Jayaraman 	int32_t j;
347b74652f3SRagothaman Jayaraman 	uint32_t extra_len = extra_buf ? extra_buf->size : 0;
3480022ae1eSArchana Muniganti 	uint32_t size = *psize;
349b74652f3SRagothaman Jayaraman 	buf_ptr_t *bufs;
350b74652f3SRagothaman Jayaraman 
351b74652f3SRagothaman Jayaraman 	bufs = from->bufs;
352b74652f3SRagothaman Jayaraman 	for (j = 0; (j < from->buf_cnt) && size; j++) {
353b74652f3SRagothaman Jayaraman 		phys_addr_t e_dma_addr;
354b74652f3SRagothaman Jayaraman 		uint32_t e_len;
355b74652f3SRagothaman Jayaraman 		sg_comp_t *to = &list[i >> 2];
356b74652f3SRagothaman Jayaraman 
357b74652f3SRagothaman Jayaraman 		if (unlikely(from_offset)) {
358b74652f3SRagothaman Jayaraman 			if (from_offset >= bufs[j].size) {
359b74652f3SRagothaman Jayaraman 				from_offset -= bufs[j].size;
360b74652f3SRagothaman Jayaraman 				continue;
361b74652f3SRagothaman Jayaraman 			}
362b74652f3SRagothaman Jayaraman 			e_dma_addr = bufs[j].dma_addr + from_offset;
363b74652f3SRagothaman Jayaraman 			e_len = (size > (bufs[j].size - from_offset)) ?
364b74652f3SRagothaman Jayaraman 				(bufs[j].size - from_offset) : size;
365b74652f3SRagothaman Jayaraman 			from_offset = 0;
366b74652f3SRagothaman Jayaraman 		} else {
367b74652f3SRagothaman Jayaraman 			e_dma_addr = bufs[j].dma_addr;
368b74652f3SRagothaman Jayaraman 			e_len = (size > bufs[j].size) ?
369b74652f3SRagothaman Jayaraman 				bufs[j].size : size;
370b74652f3SRagothaman Jayaraman 		}
371b74652f3SRagothaman Jayaraman 
372b74652f3SRagothaman Jayaraman 		to->u.s.len[i % 4] = rte_cpu_to_be_16(e_len);
373b74652f3SRagothaman Jayaraman 		to->ptr[i % 4] = rte_cpu_to_be_64(e_dma_addr);
374b74652f3SRagothaman Jayaraman 
375b74652f3SRagothaman Jayaraman 		if (extra_len && (e_len >= extra_offset)) {
376b74652f3SRagothaman Jayaraman 			/* Break the data at given offset */
377b74652f3SRagothaman Jayaraman 			uint32_t next_len = e_len - extra_offset;
378b74652f3SRagothaman Jayaraman 			phys_addr_t next_dma = e_dma_addr + extra_offset;
379b74652f3SRagothaman Jayaraman 
380b74652f3SRagothaman Jayaraman 			if (!extra_offset) {
381b74652f3SRagothaman Jayaraman 				i--;
382b74652f3SRagothaman Jayaraman 			} else {
383b74652f3SRagothaman Jayaraman 				e_len = extra_offset;
384b74652f3SRagothaman Jayaraman 				size -= e_len;
385b74652f3SRagothaman Jayaraman 				to->u.s.len[i % 4] = rte_cpu_to_be_16(e_len);
386b74652f3SRagothaman Jayaraman 			}
387b74652f3SRagothaman Jayaraman 
3880022ae1eSArchana Muniganti 			extra_len = RTE_MIN(extra_len, size);
389b74652f3SRagothaman Jayaraman 			/* Insert extra data ptr */
390b74652f3SRagothaman Jayaraman 			if (extra_len) {
391b74652f3SRagothaman Jayaraman 				i++;
392b74652f3SRagothaman Jayaraman 				to = &list[i >> 2];
393b74652f3SRagothaman Jayaraman 				to->u.s.len[i % 4] =
3940022ae1eSArchana Muniganti 					rte_cpu_to_be_16(extra_len);
395b74652f3SRagothaman Jayaraman 				to->ptr[i % 4] =
396b74652f3SRagothaman Jayaraman 					rte_cpu_to_be_64(extra_buf->dma_addr);
3970022ae1eSArchana Muniganti 				size -= extra_len;
398b74652f3SRagothaman Jayaraman 			}
399b74652f3SRagothaman Jayaraman 
4000022ae1eSArchana Muniganti 			next_len = RTE_MIN(next_len, size);
401b74652f3SRagothaman Jayaraman 			/* insert the rest of the data */
402b74652f3SRagothaman Jayaraman 			if (next_len) {
403b74652f3SRagothaman Jayaraman 				i++;
404b74652f3SRagothaman Jayaraman 				to = &list[i >> 2];
405b74652f3SRagothaman Jayaraman 				to->u.s.len[i % 4] = rte_cpu_to_be_16(next_len);
406b74652f3SRagothaman Jayaraman 				to->ptr[i % 4] = rte_cpu_to_be_64(next_dma);
407b74652f3SRagothaman Jayaraman 				size -= next_len;
408b74652f3SRagothaman Jayaraman 			}
409b74652f3SRagothaman Jayaraman 			extra_len = 0;
410b74652f3SRagothaman Jayaraman 
411b74652f3SRagothaman Jayaraman 		} else {
412b74652f3SRagothaman Jayaraman 			size -= e_len;
413b74652f3SRagothaman Jayaraman 		}
414b74652f3SRagothaman Jayaraman 		if (extra_offset)
415b74652f3SRagothaman Jayaraman 			extra_offset -= size;
416b74652f3SRagothaman Jayaraman 		i++;
417b74652f3SRagothaman Jayaraman 	}
418b74652f3SRagothaman Jayaraman 
419b74652f3SRagothaman Jayaraman 	*psize = size;
420b74652f3SRagothaman Jayaraman 	return (uint32_t)i;
421b74652f3SRagothaman Jayaraman }
422b74652f3SRagothaman Jayaraman 
423f39928e6SAnoob Joseph static __rte_always_inline void
424351fbee2SSrisivasubramanian S cpt_digest_gen_prep(uint32_t flags,
425351fbee2SSrisivasubramanian S 		    uint64_t d_lens,
426351fbee2SSrisivasubramanian S 		    digest_params_t *params,
427351fbee2SSrisivasubramanian S 		    void *op,
428351fbee2SSrisivasubramanian S 		    void **prep_req)
429351fbee2SSrisivasubramanian S {
430351fbee2SSrisivasubramanian S 	struct cpt_request_info *req;
431351fbee2SSrisivasubramanian S 	uint32_t size, i;
432351fbee2SSrisivasubramanian S 	uint16_t data_len, mac_len, key_len;
433351fbee2SSrisivasubramanian S 	auth_type_t hash_type;
434351fbee2SSrisivasubramanian S 	buf_ptr_t *meta_p;
435351fbee2SSrisivasubramanian S 	struct cpt_ctx *ctx;
436351fbee2SSrisivasubramanian S 	sg_comp_t *gather_comp;
437351fbee2SSrisivasubramanian S 	sg_comp_t *scatter_comp;
438351fbee2SSrisivasubramanian S 	uint8_t *in_buffer;
439351fbee2SSrisivasubramanian S 	uint32_t g_size_bytes, s_size_bytes;
440351fbee2SSrisivasubramanian S 	uint64_t dptr_dma, rptr_dma;
441351fbee2SSrisivasubramanian S 	vq_cmd_word0_t vq_cmd_w0;
442351fbee2SSrisivasubramanian S 	vq_cmd_word3_t vq_cmd_w3;
443351fbee2SSrisivasubramanian S 	void *c_vaddr, *m_vaddr;
444351fbee2SSrisivasubramanian S 	uint64_t c_dma, m_dma;
445351fbee2SSrisivasubramanian S 	opcode_info_t opcode;
446351fbee2SSrisivasubramanian S 
447351fbee2SSrisivasubramanian S 	ctx = params->ctx_buf.vaddr;
448351fbee2SSrisivasubramanian S 	meta_p = &params->meta_buf;
449351fbee2SSrisivasubramanian S 
450351fbee2SSrisivasubramanian S 	m_vaddr = meta_p->vaddr;
451351fbee2SSrisivasubramanian S 	m_dma = meta_p->dma_addr;
452351fbee2SSrisivasubramanian S 
453351fbee2SSrisivasubramanian S 	/*
454351fbee2SSrisivasubramanian S 	 * Save initial space that followed app data for completion code &
455351fbee2SSrisivasubramanian S 	 * alternate completion code to fall in same cache line as app data
456351fbee2SSrisivasubramanian S 	 */
457351fbee2SSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE;
458351fbee2SSrisivasubramanian S 	m_dma += COMPLETION_CODE_SIZE;
459351fbee2SSrisivasubramanian S 	size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) -
460351fbee2SSrisivasubramanian S 		(uint8_t *)m_vaddr;
461351fbee2SSrisivasubramanian S 	c_vaddr = (uint8_t *)m_vaddr + size;
462351fbee2SSrisivasubramanian S 	c_dma = m_dma + size;
463351fbee2SSrisivasubramanian S 	size += sizeof(cpt_res_s_t);
464351fbee2SSrisivasubramanian S 
465351fbee2SSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
466351fbee2SSrisivasubramanian S 	m_dma += size;
467351fbee2SSrisivasubramanian S 
468351fbee2SSrisivasubramanian S 	req = m_vaddr;
469351fbee2SSrisivasubramanian S 
470351fbee2SSrisivasubramanian S 	size = sizeof(struct cpt_request_info);
471351fbee2SSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
472351fbee2SSrisivasubramanian S 	m_dma += size;
473351fbee2SSrisivasubramanian S 
474351fbee2SSrisivasubramanian S 	hash_type = ctx->hash_type;
475351fbee2SSrisivasubramanian S 	mac_len = ctx->mac_len;
476351fbee2SSrisivasubramanian S 	key_len = ctx->auth_key_len;
477351fbee2SSrisivasubramanian S 	data_len = AUTH_DLEN(d_lens);
478351fbee2SSrisivasubramanian S 
479351fbee2SSrisivasubramanian S 	/*GP op header */
480351fbee2SSrisivasubramanian S 	vq_cmd_w0.u64 = 0;
481426af86bSAnoob Joseph 	vq_cmd_w0.s.param2 = ((uint16_t)hash_type << 8);
482351fbee2SSrisivasubramanian S 	if (ctx->hmac) {
483351fbee2SSrisivasubramanian S 		opcode.s.major = CPT_MAJOR_OP_HMAC | CPT_DMA_MODE;
484426af86bSAnoob Joseph 		vq_cmd_w0.s.param1 = key_len;
485426af86bSAnoob Joseph 		vq_cmd_w0.s.dlen = data_len + ROUNDUP8(key_len);
486351fbee2SSrisivasubramanian S 	} else {
487351fbee2SSrisivasubramanian S 		opcode.s.major = CPT_MAJOR_OP_HASH | CPT_DMA_MODE;
488351fbee2SSrisivasubramanian S 		vq_cmd_w0.s.param1 = 0;
489426af86bSAnoob Joseph 		vq_cmd_w0.s.dlen = data_len;
490351fbee2SSrisivasubramanian S 	}
491351fbee2SSrisivasubramanian S 
492351fbee2SSrisivasubramanian S 	opcode.s.minor = 0;
493351fbee2SSrisivasubramanian S 
494351fbee2SSrisivasubramanian S 	/* Null auth only case enters the if */
495351fbee2SSrisivasubramanian S 	if (unlikely(!hash_type && !ctx->enc_cipher)) {
496351fbee2SSrisivasubramanian S 		opcode.s.major = CPT_MAJOR_OP_MISC;
497351fbee2SSrisivasubramanian S 		/* Minor op is passthrough */
498351fbee2SSrisivasubramanian S 		opcode.s.minor = 0x03;
499351fbee2SSrisivasubramanian S 		/* Send out completion code only */
500426af86bSAnoob Joseph 		vq_cmd_w0.s.param2 = 0x1;
501351fbee2SSrisivasubramanian S 	}
502351fbee2SSrisivasubramanian S 
503426af86bSAnoob Joseph 	vq_cmd_w0.s.opcode = opcode.flags;
504351fbee2SSrisivasubramanian S 
505351fbee2SSrisivasubramanian S 	/* DPTR has SG list */
506351fbee2SSrisivasubramanian S 	in_buffer = m_vaddr;
507351fbee2SSrisivasubramanian S 	dptr_dma = m_dma;
508351fbee2SSrisivasubramanian S 
509351fbee2SSrisivasubramanian S 	((uint16_t *)in_buffer)[0] = 0;
510351fbee2SSrisivasubramanian S 	((uint16_t *)in_buffer)[1] = 0;
511351fbee2SSrisivasubramanian S 
512351fbee2SSrisivasubramanian S 	/* TODO Add error check if space will be sufficient */
513351fbee2SSrisivasubramanian S 	gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8);
514351fbee2SSrisivasubramanian S 
515351fbee2SSrisivasubramanian S 	/*
516351fbee2SSrisivasubramanian S 	 * Input gather list
517351fbee2SSrisivasubramanian S 	 */
518351fbee2SSrisivasubramanian S 
519351fbee2SSrisivasubramanian S 	i = 0;
520351fbee2SSrisivasubramanian S 
521351fbee2SSrisivasubramanian S 	if (ctx->hmac) {
522351fbee2SSrisivasubramanian S 		uint64_t k_dma = params->ctx_buf.dma_addr +
523351fbee2SSrisivasubramanian S 			offsetof(struct cpt_ctx, auth_key);
524351fbee2SSrisivasubramanian S 		/* Key */
525351fbee2SSrisivasubramanian S 		i = fill_sg_comp(gather_comp, i, k_dma, ROUNDUP8(key_len));
526351fbee2SSrisivasubramanian S 	}
527351fbee2SSrisivasubramanian S 
528351fbee2SSrisivasubramanian S 	/* input data */
529351fbee2SSrisivasubramanian S 	size = data_len;
530351fbee2SSrisivasubramanian S 	if (size) {
531351fbee2SSrisivasubramanian S 		i = fill_sg_comp_from_iov(gather_comp, i, params->src_iov,
532351fbee2SSrisivasubramanian S 					  0, &size, NULL, 0);
533f39928e6SAnoob Joseph 		if (unlikely(size)) {
534351fbee2SSrisivasubramanian S 			CPT_LOG_DP_DEBUG("Insufficient dst IOV size, short"
535351fbee2SSrisivasubramanian S 					 " by %dB", size);
536f39928e6SAnoob Joseph 			return;
537351fbee2SSrisivasubramanian S 		}
538351fbee2SSrisivasubramanian S 	} else {
539351fbee2SSrisivasubramanian S 		/*
540351fbee2SSrisivasubramanian S 		 * Looks like we need to support zero data
541351fbee2SSrisivasubramanian S 		 * gather ptr in case of hash & hmac
542351fbee2SSrisivasubramanian S 		 */
543351fbee2SSrisivasubramanian S 		i++;
544351fbee2SSrisivasubramanian S 	}
545351fbee2SSrisivasubramanian S 	((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i);
546351fbee2SSrisivasubramanian S 	g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
547351fbee2SSrisivasubramanian S 
548351fbee2SSrisivasubramanian S 	/*
549351fbee2SSrisivasubramanian S 	 * Output Gather list
550351fbee2SSrisivasubramanian S 	 */
551351fbee2SSrisivasubramanian S 
552351fbee2SSrisivasubramanian S 	i = 0;
553351fbee2SSrisivasubramanian S 	scatter_comp = (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes);
554351fbee2SSrisivasubramanian S 
555351fbee2SSrisivasubramanian S 	if (flags & VALID_MAC_BUF) {
556f39928e6SAnoob Joseph 		if (unlikely(params->mac_buf.size < mac_len)) {
557f39928e6SAnoob Joseph 			CPT_LOG_DP_ERR("Insufficient MAC size");
558f39928e6SAnoob Joseph 			return;
559f39928e6SAnoob Joseph 		}
560351fbee2SSrisivasubramanian S 
561351fbee2SSrisivasubramanian S 		size = mac_len;
562351fbee2SSrisivasubramanian S 		i = fill_sg_comp_from_buf_min(scatter_comp, i,
563351fbee2SSrisivasubramanian S 					      &params->mac_buf, &size);
564351fbee2SSrisivasubramanian S 	} else {
565351fbee2SSrisivasubramanian S 		size = mac_len;
566351fbee2SSrisivasubramanian S 		i = fill_sg_comp_from_iov(scatter_comp, i,
567351fbee2SSrisivasubramanian S 					  params->src_iov, data_len,
568351fbee2SSrisivasubramanian S 					  &size, NULL, 0);
569f39928e6SAnoob Joseph 		if (unlikely(size)) {
570f39928e6SAnoob Joseph 			CPT_LOG_DP_ERR("Insufficient dst IOV size, short by"
571351fbee2SSrisivasubramanian S 				       " %dB", size);
572f39928e6SAnoob Joseph 			return;
573351fbee2SSrisivasubramanian S 		}
574351fbee2SSrisivasubramanian S 	}
575351fbee2SSrisivasubramanian S 
576351fbee2SSrisivasubramanian S 	((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i);
577351fbee2SSrisivasubramanian S 	s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
578351fbee2SSrisivasubramanian S 
579351fbee2SSrisivasubramanian S 	size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE;
580351fbee2SSrisivasubramanian S 
581351fbee2SSrisivasubramanian S 	/* This is DPTR len incase of SG mode */
582426af86bSAnoob Joseph 	vq_cmd_w0.s.dlen = size;
583351fbee2SSrisivasubramanian S 
584351fbee2SSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
585351fbee2SSrisivasubramanian S 	m_dma += size;
586351fbee2SSrisivasubramanian S 
587351fbee2SSrisivasubramanian S 	/* cpt alternate completion address saved earlier */
588351fbee2SSrisivasubramanian S 	req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8);
589351fbee2SSrisivasubramanian S 	*req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT);
590351fbee2SSrisivasubramanian S 	rptr_dma = c_dma - 8;
591351fbee2SSrisivasubramanian S 
592351fbee2SSrisivasubramanian S 	req->ist.ei1 = dptr_dma;
593351fbee2SSrisivasubramanian S 	req->ist.ei2 = rptr_dma;
594351fbee2SSrisivasubramanian S 
595351fbee2SSrisivasubramanian S 	/* vq command w3 */
596351fbee2SSrisivasubramanian S 	vq_cmd_w3.u64 = 0;
597351fbee2SSrisivasubramanian S 
598351fbee2SSrisivasubramanian S 	/* 16 byte aligned cpt res address */
599351fbee2SSrisivasubramanian S 	req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr);
600351fbee2SSrisivasubramanian S 	*req->completion_addr = COMPLETION_CODE_INIT;
601351fbee2SSrisivasubramanian S 	req->comp_baddr  = c_dma;
602351fbee2SSrisivasubramanian S 
603351fbee2SSrisivasubramanian S 	/* Fill microcode part of instruction */
604351fbee2SSrisivasubramanian S 	req->ist.ei0 = vq_cmd_w0.u64;
605351fbee2SSrisivasubramanian S 	req->ist.ei3 = vq_cmd_w3.u64;
606351fbee2SSrisivasubramanian S 
607351fbee2SSrisivasubramanian S 	req->op = op;
608351fbee2SSrisivasubramanian S 
609351fbee2SSrisivasubramanian S 	*prep_req = req;
610f39928e6SAnoob Joseph 	return;
611351fbee2SSrisivasubramanian S }
612351fbee2SSrisivasubramanian S 
613f39928e6SAnoob Joseph static __rte_always_inline void
614b74652f3SRagothaman Jayaraman cpt_enc_hmac_prep(uint32_t flags,
615b74652f3SRagothaman Jayaraman 		  uint64_t d_offs,
616b74652f3SRagothaman Jayaraman 		  uint64_t d_lens,
617b74652f3SRagothaman Jayaraman 		  fc_params_t *fc_params,
618b74652f3SRagothaman Jayaraman 		  void *op,
619b74652f3SRagothaman Jayaraman 		  void **prep_req)
620b74652f3SRagothaman Jayaraman {
621b74652f3SRagothaman Jayaraman 	uint32_t iv_offset = 0;
622b74652f3SRagothaman Jayaraman 	int32_t inputlen, outputlen, enc_dlen, auth_dlen;
623b74652f3SRagothaman Jayaraman 	struct cpt_ctx *cpt_ctx;
624b74652f3SRagothaman Jayaraman 	uint32_t cipher_type, hash_type;
625b74652f3SRagothaman Jayaraman 	uint32_t mac_len, size;
626b74652f3SRagothaman Jayaraman 	uint8_t iv_len = 16;
627b74652f3SRagothaman Jayaraman 	struct cpt_request_info *req;
628b74652f3SRagothaman Jayaraman 	buf_ptr_t *meta_p, *aad_buf = NULL;
629b74652f3SRagothaman Jayaraman 	uint32_t encr_offset, auth_offset;
630b74652f3SRagothaman Jayaraman 	uint32_t encr_data_len, auth_data_len, aad_len = 0;
631b74652f3SRagothaman Jayaraman 	uint32_t passthrough_len = 0;
632b74652f3SRagothaman Jayaraman 	void *m_vaddr, *offset_vaddr;
633b74652f3SRagothaman Jayaraman 	uint64_t m_dma, offset_dma, ctx_dma;
634b74652f3SRagothaman Jayaraman 	vq_cmd_word0_t vq_cmd_w0;
635b74652f3SRagothaman Jayaraman 	vq_cmd_word3_t vq_cmd_w3;
636b74652f3SRagothaman Jayaraman 	void *c_vaddr;
637b74652f3SRagothaman Jayaraman 	uint64_t c_dma;
638b74652f3SRagothaman Jayaraman 	opcode_info_t opcode;
639b74652f3SRagothaman Jayaraman 
640b74652f3SRagothaman Jayaraman 	meta_p = &fc_params->meta_buf;
641b74652f3SRagothaman Jayaraman 	m_vaddr = meta_p->vaddr;
642b74652f3SRagothaman Jayaraman 	m_dma = meta_p->dma_addr;
643b74652f3SRagothaman Jayaraman 
644b74652f3SRagothaman Jayaraman 	encr_offset = ENCR_OFFSET(d_offs);
645b74652f3SRagothaman Jayaraman 	auth_offset = AUTH_OFFSET(d_offs);
646b74652f3SRagothaman Jayaraman 	encr_data_len = ENCR_DLEN(d_lens);
647b74652f3SRagothaman Jayaraman 	auth_data_len = AUTH_DLEN(d_lens);
648b74652f3SRagothaman Jayaraman 	if (unlikely(flags & VALID_AAD_BUF)) {
649b74652f3SRagothaman Jayaraman 		/*
650b74652f3SRagothaman Jayaraman 		 * We dont support both aad
651b74652f3SRagothaman Jayaraman 		 * and auth data separately
652b74652f3SRagothaman Jayaraman 		 */
653b74652f3SRagothaman Jayaraman 		auth_data_len = 0;
654b74652f3SRagothaman Jayaraman 		auth_offset = 0;
655b74652f3SRagothaman Jayaraman 		aad_len = fc_params->aad_buf.size;
656b74652f3SRagothaman Jayaraman 		aad_buf = &fc_params->aad_buf;
657b74652f3SRagothaman Jayaraman 	}
658b74652f3SRagothaman Jayaraman 	cpt_ctx = fc_params->ctx_buf.vaddr;
659b74652f3SRagothaman Jayaraman 	cipher_type = cpt_ctx->enc_cipher;
660b74652f3SRagothaman Jayaraman 	hash_type = cpt_ctx->hash_type;
661b74652f3SRagothaman Jayaraman 	mac_len = cpt_ctx->mac_len;
662b74652f3SRagothaman Jayaraman 
663b74652f3SRagothaman Jayaraman 	/*
664b74652f3SRagothaman Jayaraman 	 * Save initial space that followed app data for completion code &
665b74652f3SRagothaman Jayaraman 	 * alternate completion code to fall in same cache line as app data
666b74652f3SRagothaman Jayaraman 	 */
667b74652f3SRagothaman Jayaraman 	m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE;
668b74652f3SRagothaman Jayaraman 	m_dma += COMPLETION_CODE_SIZE;
669b74652f3SRagothaman Jayaraman 	size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) -
670b74652f3SRagothaman Jayaraman 		(uint8_t *)m_vaddr;
671b74652f3SRagothaman Jayaraman 
672b74652f3SRagothaman Jayaraman 	c_vaddr = (uint8_t *)m_vaddr + size;
673b74652f3SRagothaman Jayaraman 	c_dma = m_dma + size;
674b74652f3SRagothaman Jayaraman 	size += sizeof(cpt_res_s_t);
675b74652f3SRagothaman Jayaraman 
676b74652f3SRagothaman Jayaraman 	m_vaddr = (uint8_t *)m_vaddr + size;
677b74652f3SRagothaman Jayaraman 	m_dma += size;
678b74652f3SRagothaman Jayaraman 
679b74652f3SRagothaman Jayaraman 	/* start cpt request info struct at 8 byte boundary */
680b74652f3SRagothaman Jayaraman 	size = (uint8_t *)RTE_PTR_ALIGN(m_vaddr, 8) -
681b74652f3SRagothaman Jayaraman 		(uint8_t *)m_vaddr;
682b74652f3SRagothaman Jayaraman 
683b74652f3SRagothaman Jayaraman 	req = (struct cpt_request_info *)((uint8_t *)m_vaddr + size);
684b74652f3SRagothaman Jayaraman 
685b74652f3SRagothaman Jayaraman 	size += sizeof(struct cpt_request_info);
686b74652f3SRagothaman Jayaraman 	m_vaddr = (uint8_t *)m_vaddr + size;
687b74652f3SRagothaman Jayaraman 	m_dma += size;
688b74652f3SRagothaman Jayaraman 
689b74652f3SRagothaman Jayaraman 	if (unlikely(!(flags & VALID_IV_BUF))) {
690b74652f3SRagothaman Jayaraman 		iv_len = 0;
691b74652f3SRagothaman Jayaraman 		iv_offset = ENCR_IV_OFFSET(d_offs);
692b74652f3SRagothaman Jayaraman 	}
693b74652f3SRagothaman Jayaraman 
694b74652f3SRagothaman Jayaraman 	if (unlikely(flags & VALID_AAD_BUF)) {
695b74652f3SRagothaman Jayaraman 		/*
696b74652f3SRagothaman Jayaraman 		 * When AAD is given, data above encr_offset is pass through
697b74652f3SRagothaman Jayaraman 		 * Since AAD is given as separate pointer and not as offset,
698b74652f3SRagothaman Jayaraman 		 * this is a special case as we need to fragment input data
699b74652f3SRagothaman Jayaraman 		 * into passthrough + encr_data and then insert AAD in between.
700b74652f3SRagothaman Jayaraman 		 */
701b74652f3SRagothaman Jayaraman 		if (hash_type != GMAC_TYPE) {
702b74652f3SRagothaman Jayaraman 			passthrough_len = encr_offset;
703b74652f3SRagothaman Jayaraman 			auth_offset = passthrough_len + iv_len;
704b74652f3SRagothaman Jayaraman 			encr_offset = passthrough_len + aad_len + iv_len;
705b74652f3SRagothaman Jayaraman 			auth_data_len = aad_len + encr_data_len;
706b74652f3SRagothaman Jayaraman 		} else {
707b74652f3SRagothaman Jayaraman 			passthrough_len = 16 + aad_len;
708b74652f3SRagothaman Jayaraman 			auth_offset = passthrough_len + iv_len;
709b74652f3SRagothaman Jayaraman 			auth_data_len = aad_len;
710b74652f3SRagothaman Jayaraman 		}
711b74652f3SRagothaman Jayaraman 	} else {
712b74652f3SRagothaman Jayaraman 		encr_offset += iv_len;
713b74652f3SRagothaman Jayaraman 		auth_offset += iv_len;
714b74652f3SRagothaman Jayaraman 	}
715b74652f3SRagothaman Jayaraman 
716b74652f3SRagothaman Jayaraman 	/* Encryption */
717b74652f3SRagothaman Jayaraman 	opcode.s.major = CPT_MAJOR_OP_FC;
718b74652f3SRagothaman Jayaraman 	opcode.s.minor = 0;
719b74652f3SRagothaman Jayaraman 
7200058f305SAnkur Dwivedi 	if (hash_type == GMAC_TYPE) {
7210058f305SAnkur Dwivedi 		encr_offset = 0;
7220058f305SAnkur Dwivedi 		encr_data_len = 0;
7230058f305SAnkur Dwivedi 	}
7240058f305SAnkur Dwivedi 
725b74652f3SRagothaman Jayaraman 	auth_dlen = auth_offset + auth_data_len;
726b74652f3SRagothaman Jayaraman 	enc_dlen = encr_data_len + encr_offset;
727b74652f3SRagothaman Jayaraman 	if (unlikely(encr_data_len & 0xf)) {
728b74652f3SRagothaman Jayaraman 		if ((cipher_type == DES3_CBC) || (cipher_type == DES3_ECB))
729b74652f3SRagothaman Jayaraman 			enc_dlen = ROUNDUP8(encr_data_len) + encr_offset;
730b74652f3SRagothaman Jayaraman 		else if (likely((cipher_type == AES_CBC) ||
731b74652f3SRagothaman Jayaraman 				(cipher_type == AES_ECB)))
732b74652f3SRagothaman Jayaraman 			enc_dlen = ROUNDUP16(encr_data_len) + encr_offset;
733b74652f3SRagothaman Jayaraman 	}
734b74652f3SRagothaman Jayaraman 
735b74652f3SRagothaman Jayaraman 	if (unlikely(auth_dlen > enc_dlen)) {
736b74652f3SRagothaman Jayaraman 		inputlen = auth_dlen;
737b74652f3SRagothaman Jayaraman 		outputlen = auth_dlen + mac_len;
738b74652f3SRagothaman Jayaraman 	} else {
739b74652f3SRagothaman Jayaraman 		inputlen = enc_dlen;
740b74652f3SRagothaman Jayaraman 		outputlen = enc_dlen + mac_len;
741b74652f3SRagothaman Jayaraman 	}
742b74652f3SRagothaman Jayaraman 
743b74652f3SRagothaman Jayaraman 	/* GP op header */
744b74652f3SRagothaman Jayaraman 	vq_cmd_w0.u64 = 0;
745426af86bSAnoob Joseph 	vq_cmd_w0.s.param1 = encr_data_len;
746426af86bSAnoob Joseph 	vq_cmd_w0.s.param2 = auth_data_len;
747b74652f3SRagothaman Jayaraman 	/*
748b74652f3SRagothaman Jayaraman 	 * In 83XX since we have a limitation of
749b74652f3SRagothaman Jayaraman 	 * IV & Offset control word not part of instruction
750b74652f3SRagothaman Jayaraman 	 * and need to be part of Data Buffer, we check if
751b74652f3SRagothaman Jayaraman 	 * head room is there and then only do the Direct mode processing
752b74652f3SRagothaman Jayaraman 	 */
753b74652f3SRagothaman Jayaraman 	if (likely((flags & SINGLE_BUF_INPLACE) &&
754b74652f3SRagothaman Jayaraman 		   (flags & SINGLE_BUF_HEADTAILROOM))) {
755b74652f3SRagothaman Jayaraman 		void *dm_vaddr = fc_params->bufs[0].vaddr;
756b74652f3SRagothaman Jayaraman 		uint64_t dm_dma_addr = fc_params->bufs[0].dma_addr;
757b74652f3SRagothaman Jayaraman 		/*
758b74652f3SRagothaman Jayaraman 		 * This flag indicates that there is 24 bytes head room and
759b74652f3SRagothaman Jayaraman 		 * 8 bytes tail room available, so that we get to do
760b74652f3SRagothaman Jayaraman 		 * DIRECT MODE with limitation
761b74652f3SRagothaman Jayaraman 		 */
762b74652f3SRagothaman Jayaraman 
763b74652f3SRagothaman Jayaraman 		offset_vaddr = (uint8_t *)dm_vaddr - OFF_CTRL_LEN - iv_len;
764b74652f3SRagothaman Jayaraman 		offset_dma = dm_dma_addr - OFF_CTRL_LEN - iv_len;
765b74652f3SRagothaman Jayaraman 
766b74652f3SRagothaman Jayaraman 		/* DPTR */
767b74652f3SRagothaman Jayaraman 		req->ist.ei1 = offset_dma;
768b74652f3SRagothaman Jayaraman 		/* RPTR should just exclude offset control word */
769b74652f3SRagothaman Jayaraman 		req->ist.ei2 = dm_dma_addr - iv_len;
770b74652f3SRagothaman Jayaraman 		req->alternate_caddr = (uint64_t *)((uint8_t *)dm_vaddr
771b74652f3SRagothaman Jayaraman 						    + outputlen - iv_len);
772b74652f3SRagothaman Jayaraman 
773426af86bSAnoob Joseph 		vq_cmd_w0.s.dlen = inputlen + OFF_CTRL_LEN;
774b74652f3SRagothaman Jayaraman 
775426af86bSAnoob Joseph 		vq_cmd_w0.s.opcode = opcode.flags;
776b74652f3SRagothaman Jayaraman 
777b74652f3SRagothaman Jayaraman 		if (likely(iv_len)) {
778b74652f3SRagothaman Jayaraman 			uint64_t *dest = (uint64_t *)((uint8_t *)offset_vaddr
779b74652f3SRagothaman Jayaraman 						      + OFF_CTRL_LEN);
780b74652f3SRagothaman Jayaraman 			uint64_t *src = fc_params->iv_buf;
781b74652f3SRagothaman Jayaraman 			dest[0] = src[0];
782b74652f3SRagothaman Jayaraman 			dest[1] = src[1];
783b74652f3SRagothaman Jayaraman 		}
784b74652f3SRagothaman Jayaraman 
785b74652f3SRagothaman Jayaraman 		*(uint64_t *)offset_vaddr =
786b74652f3SRagothaman Jayaraman 			rte_cpu_to_be_64(((uint64_t)encr_offset << 16) |
787b74652f3SRagothaman Jayaraman 				((uint64_t)iv_offset << 8) |
788b74652f3SRagothaman Jayaraman 				((uint64_t)auth_offset));
789b74652f3SRagothaman Jayaraman 
790b74652f3SRagothaman Jayaraman 	} else {
791b74652f3SRagothaman Jayaraman 		uint32_t i, g_size_bytes, s_size_bytes;
792b74652f3SRagothaman Jayaraman 		uint64_t dptr_dma, rptr_dma;
793b74652f3SRagothaman Jayaraman 		sg_comp_t *gather_comp;
794b74652f3SRagothaman Jayaraman 		sg_comp_t *scatter_comp;
795b74652f3SRagothaman Jayaraman 		uint8_t *in_buffer;
796b74652f3SRagothaman Jayaraman 
797b74652f3SRagothaman Jayaraman 		/* This falls under strict SG mode */
798b74652f3SRagothaman Jayaraman 		offset_vaddr = m_vaddr;
799b74652f3SRagothaman Jayaraman 		offset_dma = m_dma;
800b74652f3SRagothaman Jayaraman 		size = OFF_CTRL_LEN + iv_len;
801b74652f3SRagothaman Jayaraman 
802b74652f3SRagothaman Jayaraman 		m_vaddr = (uint8_t *)m_vaddr + size;
803b74652f3SRagothaman Jayaraman 		m_dma += size;
804b74652f3SRagothaman Jayaraman 
805b74652f3SRagothaman Jayaraman 		opcode.s.major |= CPT_DMA_MODE;
806b74652f3SRagothaman Jayaraman 
807426af86bSAnoob Joseph 		vq_cmd_w0.s.opcode = opcode.flags;
808b74652f3SRagothaman Jayaraman 
809b74652f3SRagothaman Jayaraman 		if (likely(iv_len)) {
810b74652f3SRagothaman Jayaraman 			uint64_t *dest = (uint64_t *)((uint8_t *)offset_vaddr
811b74652f3SRagothaman Jayaraman 						      + OFF_CTRL_LEN);
812b74652f3SRagothaman Jayaraman 			uint64_t *src = fc_params->iv_buf;
813b74652f3SRagothaman Jayaraman 			dest[0] = src[0];
814b74652f3SRagothaman Jayaraman 			dest[1] = src[1];
815b74652f3SRagothaman Jayaraman 		}
816b74652f3SRagothaman Jayaraman 
817b74652f3SRagothaman Jayaraman 		*(uint64_t *)offset_vaddr =
818b74652f3SRagothaman Jayaraman 			rte_cpu_to_be_64(((uint64_t)encr_offset << 16) |
819b74652f3SRagothaman Jayaraman 				((uint64_t)iv_offset << 8) |
820b74652f3SRagothaman Jayaraman 				((uint64_t)auth_offset));
821b74652f3SRagothaman Jayaraman 
822b74652f3SRagothaman Jayaraman 		/* DPTR has SG list */
823b74652f3SRagothaman Jayaraman 		in_buffer = m_vaddr;
824b74652f3SRagothaman Jayaraman 		dptr_dma = m_dma;
825b74652f3SRagothaman Jayaraman 
826b74652f3SRagothaman Jayaraman 		((uint16_t *)in_buffer)[0] = 0;
827b74652f3SRagothaman Jayaraman 		((uint16_t *)in_buffer)[1] = 0;
828b74652f3SRagothaman Jayaraman 
829b74652f3SRagothaman Jayaraman 		/* TODO Add error check if space will be sufficient */
830b74652f3SRagothaman Jayaraman 		gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8);
831b74652f3SRagothaman Jayaraman 
832b74652f3SRagothaman Jayaraman 		/*
833b74652f3SRagothaman Jayaraman 		 * Input Gather List
834b74652f3SRagothaman Jayaraman 		 */
835b74652f3SRagothaman Jayaraman 
836b74652f3SRagothaman Jayaraman 		i = 0;
837b74652f3SRagothaman Jayaraman 
838b74652f3SRagothaman Jayaraman 		/* Offset control word that includes iv */
839b74652f3SRagothaman Jayaraman 		i = fill_sg_comp(gather_comp, i, offset_dma,
840b74652f3SRagothaman Jayaraman 				 OFF_CTRL_LEN + iv_len);
841b74652f3SRagothaman Jayaraman 
842b74652f3SRagothaman Jayaraman 		/* Add input data */
843b74652f3SRagothaman Jayaraman 		size = inputlen - iv_len;
844b74652f3SRagothaman Jayaraman 		if (likely(size)) {
845b74652f3SRagothaman Jayaraman 			uint32_t aad_offset = aad_len ? passthrough_len : 0;
846b74652f3SRagothaman Jayaraman 
847b74652f3SRagothaman Jayaraman 			if (unlikely(flags & SINGLE_BUF_INPLACE)) {
848b74652f3SRagothaman Jayaraman 				i = fill_sg_comp_from_buf_min(gather_comp, i,
849b74652f3SRagothaman Jayaraman 							      fc_params->bufs,
850b74652f3SRagothaman Jayaraman 							      &size);
851b74652f3SRagothaman Jayaraman 			} else {
852b74652f3SRagothaman Jayaraman 				i = fill_sg_comp_from_iov(gather_comp, i,
853b74652f3SRagothaman Jayaraman 							  fc_params->src_iov,
854b74652f3SRagothaman Jayaraman 							  0, &size,
855b74652f3SRagothaman Jayaraman 							  aad_buf, aad_offset);
856b74652f3SRagothaman Jayaraman 			}
857b74652f3SRagothaman Jayaraman 
858b74652f3SRagothaman Jayaraman 			if (unlikely(size)) {
859b74652f3SRagothaman Jayaraman 				CPT_LOG_DP_ERR("Insufficient buffer space,"
860b74652f3SRagothaman Jayaraman 					       " size %d needed", size);
861f39928e6SAnoob Joseph 				return;
862b74652f3SRagothaman Jayaraman 			}
863b74652f3SRagothaman Jayaraman 		}
864b74652f3SRagothaman Jayaraman 		((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i);
865b74652f3SRagothaman Jayaraman 		g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
866b74652f3SRagothaman Jayaraman 
867b74652f3SRagothaman Jayaraman 		/*
868b74652f3SRagothaman Jayaraman 		 * Output Scatter list
869b74652f3SRagothaman Jayaraman 		 */
870b74652f3SRagothaman Jayaraman 		i = 0;
871b74652f3SRagothaman Jayaraman 		scatter_comp =
872b74652f3SRagothaman Jayaraman 			(sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes);
873b74652f3SRagothaman Jayaraman 
874b74652f3SRagothaman Jayaraman 		/* Add IV */
875b74652f3SRagothaman Jayaraman 		if (likely(iv_len)) {
876b74652f3SRagothaman Jayaraman 			i = fill_sg_comp(scatter_comp, i,
877b74652f3SRagothaman Jayaraman 					 offset_dma + OFF_CTRL_LEN,
878b74652f3SRagothaman Jayaraman 					 iv_len);
879b74652f3SRagothaman Jayaraman 		}
880b74652f3SRagothaman Jayaraman 
881b74652f3SRagothaman Jayaraman 		/* output data or output data + digest*/
882b74652f3SRagothaman Jayaraman 		if (unlikely(flags & VALID_MAC_BUF)) {
883b74652f3SRagothaman Jayaraman 			size = outputlen - iv_len - mac_len;
884b74652f3SRagothaman Jayaraman 			if (size) {
885b74652f3SRagothaman Jayaraman 				uint32_t aad_offset =
886b74652f3SRagothaman Jayaraman 					aad_len ? passthrough_len : 0;
887b74652f3SRagothaman Jayaraman 
888b74652f3SRagothaman Jayaraman 				if (unlikely(flags & SINGLE_BUF_INPLACE)) {
889b74652f3SRagothaman Jayaraman 					i = fill_sg_comp_from_buf_min(
890b74652f3SRagothaman Jayaraman 							scatter_comp,
891b74652f3SRagothaman Jayaraman 							i,
892b74652f3SRagothaman Jayaraman 							fc_params->bufs,
893b74652f3SRagothaman Jayaraman 							&size);
894b74652f3SRagothaman Jayaraman 				} else {
895b74652f3SRagothaman Jayaraman 					i = fill_sg_comp_from_iov(scatter_comp,
896b74652f3SRagothaman Jayaraman 							i,
897b74652f3SRagothaman Jayaraman 							fc_params->dst_iov,
898b74652f3SRagothaman Jayaraman 							0,
899b74652f3SRagothaman Jayaraman 							&size,
900b74652f3SRagothaman Jayaraman 							aad_buf,
901b74652f3SRagothaman Jayaraman 							aad_offset);
902b74652f3SRagothaman Jayaraman 				}
903f39928e6SAnoob Joseph 				if (unlikely(size)) {
904f39928e6SAnoob Joseph 					CPT_LOG_DP_ERR("Insufficient buffer"
905f39928e6SAnoob Joseph 						       " space, size %d needed",
906f39928e6SAnoob Joseph 						       size);
907f39928e6SAnoob Joseph 					return;
908f39928e6SAnoob Joseph 				}
909b74652f3SRagothaman Jayaraman 			}
910b74652f3SRagothaman Jayaraman 			/* mac_data */
911b74652f3SRagothaman Jayaraman 			if (mac_len) {
912b74652f3SRagothaman Jayaraman 				i = fill_sg_comp_from_buf(scatter_comp, i,
913b74652f3SRagothaman Jayaraman 							  &fc_params->mac_buf);
914b74652f3SRagothaman Jayaraman 			}
915b74652f3SRagothaman Jayaraman 		} else {
916b74652f3SRagothaman Jayaraman 			/* Output including mac */
917b74652f3SRagothaman Jayaraman 			size = outputlen - iv_len;
918b74652f3SRagothaman Jayaraman 			if (likely(size)) {
919b74652f3SRagothaman Jayaraman 				uint32_t aad_offset =
920b74652f3SRagothaman Jayaraman 					aad_len ? passthrough_len : 0;
921b74652f3SRagothaman Jayaraman 
922b74652f3SRagothaman Jayaraman 				if (unlikely(flags & SINGLE_BUF_INPLACE)) {
923b74652f3SRagothaman Jayaraman 					i = fill_sg_comp_from_buf_min(
924b74652f3SRagothaman Jayaraman 							scatter_comp,
925b74652f3SRagothaman Jayaraman 							i,
926b74652f3SRagothaman Jayaraman 							fc_params->bufs,
927b74652f3SRagothaman Jayaraman 							&size);
928b74652f3SRagothaman Jayaraman 				} else {
929b74652f3SRagothaman Jayaraman 					i = fill_sg_comp_from_iov(scatter_comp,
930b74652f3SRagothaman Jayaraman 							i,
931b74652f3SRagothaman Jayaraman 							fc_params->dst_iov,
932b74652f3SRagothaman Jayaraman 							0,
933b74652f3SRagothaman Jayaraman 							&size,
934b74652f3SRagothaman Jayaraman 							aad_buf,
935b74652f3SRagothaman Jayaraman 							aad_offset);
936b74652f3SRagothaman Jayaraman 				}
937b74652f3SRagothaman Jayaraman 				if (unlikely(size)) {
938b74652f3SRagothaman Jayaraman 					CPT_LOG_DP_ERR("Insufficient buffer"
939b74652f3SRagothaman Jayaraman 						       " space, size %d needed",
940b74652f3SRagothaman Jayaraman 						       size);
941f39928e6SAnoob Joseph 					return;
942b74652f3SRagothaman Jayaraman 				}
943b74652f3SRagothaman Jayaraman 			}
944b74652f3SRagothaman Jayaraman 		}
945b74652f3SRagothaman Jayaraman 		((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i);
946b74652f3SRagothaman Jayaraman 		s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
947b74652f3SRagothaman Jayaraman 
948b74652f3SRagothaman Jayaraman 		size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE;
949b74652f3SRagothaman Jayaraman 
950b74652f3SRagothaman Jayaraman 		/* This is DPTR len incase of SG mode */
951426af86bSAnoob Joseph 		vq_cmd_w0.s.dlen = size;
952b74652f3SRagothaman Jayaraman 
953b74652f3SRagothaman Jayaraman 		m_vaddr = (uint8_t *)m_vaddr + size;
954b74652f3SRagothaman Jayaraman 		m_dma += size;
955b74652f3SRagothaman Jayaraman 
956b74652f3SRagothaman Jayaraman 		/* cpt alternate completion address saved earlier */
957b74652f3SRagothaman Jayaraman 		req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8);
958b74652f3SRagothaman Jayaraman 		*req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT);
959b74652f3SRagothaman Jayaraman 		rptr_dma = c_dma - 8;
960b74652f3SRagothaman Jayaraman 
961b74652f3SRagothaman Jayaraman 		req->ist.ei1 = dptr_dma;
962b74652f3SRagothaman Jayaraman 		req->ist.ei2 = rptr_dma;
963b74652f3SRagothaman Jayaraman 	}
964b74652f3SRagothaman Jayaraman 
965b74652f3SRagothaman Jayaraman 	ctx_dma = fc_params->ctx_buf.dma_addr +
966b74652f3SRagothaman Jayaraman 		offsetof(struct cpt_ctx, fctx);
967b74652f3SRagothaman Jayaraman 	/* vq command w3 */
968b74652f3SRagothaman Jayaraman 	vq_cmd_w3.u64 = 0;
969b74652f3SRagothaman Jayaraman 	vq_cmd_w3.s.grp = 0;
970b74652f3SRagothaman Jayaraman 	vq_cmd_w3.s.cptr = ctx_dma;
971b74652f3SRagothaman Jayaraman 
972b74652f3SRagothaman Jayaraman 	/* 16 byte aligned cpt res address */
973b74652f3SRagothaman Jayaraman 	req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr);
974b74652f3SRagothaman Jayaraman 	*req->completion_addr = COMPLETION_CODE_INIT;
975b74652f3SRagothaman Jayaraman 	req->comp_baddr  = c_dma;
976b74652f3SRagothaman Jayaraman 
977b74652f3SRagothaman Jayaraman 	/* Fill microcode part of instruction */
978b74652f3SRagothaman Jayaraman 	req->ist.ei0 = vq_cmd_w0.u64;
979b74652f3SRagothaman Jayaraman 	req->ist.ei3 = vq_cmd_w3.u64;
980b74652f3SRagothaman Jayaraman 
981b74652f3SRagothaman Jayaraman 	req->op  = op;
982b74652f3SRagothaman Jayaraman 
983b74652f3SRagothaman Jayaraman 	*prep_req = req;
984f39928e6SAnoob Joseph 	return;
985b74652f3SRagothaman Jayaraman }
986b74652f3SRagothaman Jayaraman 
987f39928e6SAnoob Joseph static __rte_always_inline void
988177b41ceSRagothaman Jayaraman cpt_dec_hmac_prep(uint32_t flags,
989177b41ceSRagothaman Jayaraman 		  uint64_t d_offs,
990177b41ceSRagothaman Jayaraman 		  uint64_t d_lens,
991177b41ceSRagothaman Jayaraman 		  fc_params_t *fc_params,
992177b41ceSRagothaman Jayaraman 		  void *op,
993177b41ceSRagothaman Jayaraman 		  void **prep_req)
994177b41ceSRagothaman Jayaraman {
995177b41ceSRagothaman Jayaraman 	uint32_t iv_offset = 0, size;
996177b41ceSRagothaman Jayaraman 	int32_t inputlen, outputlen, enc_dlen, auth_dlen;
997177b41ceSRagothaman Jayaraman 	struct cpt_ctx *cpt_ctx;
9988de5ede7SAnoob Joseph 	int32_t hash_type, mac_len;
999177b41ceSRagothaman Jayaraman 	uint8_t iv_len = 16;
1000177b41ceSRagothaman Jayaraman 	struct cpt_request_info *req;
1001177b41ceSRagothaman Jayaraman 	buf_ptr_t *meta_p, *aad_buf = NULL;
1002177b41ceSRagothaman Jayaraman 	uint32_t encr_offset, auth_offset;
1003177b41ceSRagothaman Jayaraman 	uint32_t encr_data_len, auth_data_len, aad_len = 0;
1004177b41ceSRagothaman Jayaraman 	uint32_t passthrough_len = 0;
1005177b41ceSRagothaman Jayaraman 	void *m_vaddr, *offset_vaddr;
1006177b41ceSRagothaman Jayaraman 	uint64_t m_dma, offset_dma, ctx_dma;
1007177b41ceSRagothaman Jayaraman 	opcode_info_t opcode;
1008177b41ceSRagothaman Jayaraman 	vq_cmd_word0_t vq_cmd_w0;
1009177b41ceSRagothaman Jayaraman 	vq_cmd_word3_t vq_cmd_w3;
1010177b41ceSRagothaman Jayaraman 	void *c_vaddr;
1011177b41ceSRagothaman Jayaraman 	uint64_t c_dma;
1012177b41ceSRagothaman Jayaraman 
1013177b41ceSRagothaman Jayaraman 	meta_p = &fc_params->meta_buf;
1014177b41ceSRagothaman Jayaraman 	m_vaddr = meta_p->vaddr;
1015177b41ceSRagothaman Jayaraman 	m_dma = meta_p->dma_addr;
1016177b41ceSRagothaman Jayaraman 
1017177b41ceSRagothaman Jayaraman 	encr_offset = ENCR_OFFSET(d_offs);
1018177b41ceSRagothaman Jayaraman 	auth_offset = AUTH_OFFSET(d_offs);
1019177b41ceSRagothaman Jayaraman 	encr_data_len = ENCR_DLEN(d_lens);
1020177b41ceSRagothaman Jayaraman 	auth_data_len = AUTH_DLEN(d_lens);
1021177b41ceSRagothaman Jayaraman 
1022177b41ceSRagothaman Jayaraman 	if (unlikely(flags & VALID_AAD_BUF)) {
1023177b41ceSRagothaman Jayaraman 		/*
1024177b41ceSRagothaman Jayaraman 		 * We dont support both aad
1025177b41ceSRagothaman Jayaraman 		 * and auth data separately
1026177b41ceSRagothaman Jayaraman 		 */
1027177b41ceSRagothaman Jayaraman 		auth_data_len = 0;
1028177b41ceSRagothaman Jayaraman 		auth_offset = 0;
1029177b41ceSRagothaman Jayaraman 		aad_len = fc_params->aad_buf.size;
1030177b41ceSRagothaman Jayaraman 		aad_buf = &fc_params->aad_buf;
1031177b41ceSRagothaman Jayaraman 	}
1032177b41ceSRagothaman Jayaraman 
1033177b41ceSRagothaman Jayaraman 	cpt_ctx = fc_params->ctx_buf.vaddr;
1034177b41ceSRagothaman Jayaraman 	hash_type = cpt_ctx->hash_type;
1035177b41ceSRagothaman Jayaraman 	mac_len = cpt_ctx->mac_len;
1036177b41ceSRagothaman Jayaraman 
1037177b41ceSRagothaman Jayaraman 	if (unlikely(!(flags & VALID_IV_BUF))) {
1038177b41ceSRagothaman Jayaraman 		iv_len = 0;
1039177b41ceSRagothaman Jayaraman 		iv_offset = ENCR_IV_OFFSET(d_offs);
1040177b41ceSRagothaman Jayaraman 	}
1041177b41ceSRagothaman Jayaraman 
1042177b41ceSRagothaman Jayaraman 	if (unlikely(flags & VALID_AAD_BUF)) {
1043177b41ceSRagothaman Jayaraman 		/*
1044177b41ceSRagothaman Jayaraman 		 * When AAD is given, data above encr_offset is pass through
1045177b41ceSRagothaman Jayaraman 		 * Since AAD is given as separate pointer and not as offset,
1046177b41ceSRagothaman Jayaraman 		 * this is a special case as we need to fragment input data
1047177b41ceSRagothaman Jayaraman 		 * into passthrough + encr_data and then insert AAD in between.
1048177b41ceSRagothaman Jayaraman 		 */
1049177b41ceSRagothaman Jayaraman 		if (hash_type != GMAC_TYPE) {
1050177b41ceSRagothaman Jayaraman 			passthrough_len = encr_offset;
1051177b41ceSRagothaman Jayaraman 			auth_offset = passthrough_len + iv_len;
1052177b41ceSRagothaman Jayaraman 			encr_offset = passthrough_len + aad_len + iv_len;
1053177b41ceSRagothaman Jayaraman 			auth_data_len = aad_len + encr_data_len;
1054177b41ceSRagothaman Jayaraman 		} else {
1055177b41ceSRagothaman Jayaraman 			passthrough_len = 16 + aad_len;
1056177b41ceSRagothaman Jayaraman 			auth_offset = passthrough_len + iv_len;
1057177b41ceSRagothaman Jayaraman 			auth_data_len = aad_len;
1058177b41ceSRagothaman Jayaraman 		}
1059177b41ceSRagothaman Jayaraman 	} else {
1060177b41ceSRagothaman Jayaraman 		encr_offset += iv_len;
1061177b41ceSRagothaman Jayaraman 		auth_offset += iv_len;
1062177b41ceSRagothaman Jayaraman 	}
1063177b41ceSRagothaman Jayaraman 
1064177b41ceSRagothaman Jayaraman 	/*
1065177b41ceSRagothaman Jayaraman 	 * Save initial space that followed app data for completion code &
1066177b41ceSRagothaman Jayaraman 	 * alternate completion code to fall in same cache line as app data
1067177b41ceSRagothaman Jayaraman 	 */
1068177b41ceSRagothaman Jayaraman 	m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE;
1069177b41ceSRagothaman Jayaraman 	m_dma += COMPLETION_CODE_SIZE;
1070177b41ceSRagothaman Jayaraman 	size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) -
1071177b41ceSRagothaman Jayaraman 	       (uint8_t *)m_vaddr;
1072177b41ceSRagothaman Jayaraman 	c_vaddr = (uint8_t *)m_vaddr + size;
1073177b41ceSRagothaman Jayaraman 	c_dma = m_dma + size;
1074177b41ceSRagothaman Jayaraman 	size += sizeof(cpt_res_s_t);
1075177b41ceSRagothaman Jayaraman 
1076177b41ceSRagothaman Jayaraman 	m_vaddr = (uint8_t *)m_vaddr + size;
1077177b41ceSRagothaman Jayaraman 	m_dma += size;
1078177b41ceSRagothaman Jayaraman 
1079177b41ceSRagothaman Jayaraman 	/* start cpt request info structure at 8 byte alignment */
1080177b41ceSRagothaman Jayaraman 	size = (uint8_t *)RTE_PTR_ALIGN(m_vaddr, 8) -
1081177b41ceSRagothaman Jayaraman 		(uint8_t *)m_vaddr;
1082177b41ceSRagothaman Jayaraman 
1083177b41ceSRagothaman Jayaraman 	req = (struct cpt_request_info *)((uint8_t *)m_vaddr + size);
1084177b41ceSRagothaman Jayaraman 
1085177b41ceSRagothaman Jayaraman 	size += sizeof(struct cpt_request_info);
1086177b41ceSRagothaman Jayaraman 	m_vaddr = (uint8_t *)m_vaddr + size;
1087177b41ceSRagothaman Jayaraman 	m_dma += size;
1088177b41ceSRagothaman Jayaraman 
1089177b41ceSRagothaman Jayaraman 	/* Decryption */
1090177b41ceSRagothaman Jayaraman 	opcode.s.major = CPT_MAJOR_OP_FC;
1091177b41ceSRagothaman Jayaraman 	opcode.s.minor = 1;
1092177b41ceSRagothaman Jayaraman 
10930058f305SAnkur Dwivedi 	if (hash_type == GMAC_TYPE) {
10940058f305SAnkur Dwivedi 		encr_offset = 0;
10950058f305SAnkur Dwivedi 		encr_data_len = 0;
10960058f305SAnkur Dwivedi 	}
10970058f305SAnkur Dwivedi 
1098177b41ceSRagothaman Jayaraman 	enc_dlen = encr_offset + encr_data_len;
1099177b41ceSRagothaman Jayaraman 	auth_dlen = auth_offset + auth_data_len;
1100177b41ceSRagothaman Jayaraman 
1101177b41ceSRagothaman Jayaraman 	if (auth_dlen > enc_dlen) {
1102177b41ceSRagothaman Jayaraman 		inputlen = auth_dlen + mac_len;
1103177b41ceSRagothaman Jayaraman 		outputlen = auth_dlen;
1104177b41ceSRagothaman Jayaraman 	} else {
1105177b41ceSRagothaman Jayaraman 		inputlen = enc_dlen + mac_len;
1106177b41ceSRagothaman Jayaraman 		outputlen = enc_dlen;
1107177b41ceSRagothaman Jayaraman 	}
1108177b41ceSRagothaman Jayaraman 
1109177b41ceSRagothaman Jayaraman 	vq_cmd_w0.u64 = 0;
1110426af86bSAnoob Joseph 	vq_cmd_w0.s.param1 = encr_data_len;
1111426af86bSAnoob Joseph 	vq_cmd_w0.s.param2 = auth_data_len;
1112177b41ceSRagothaman Jayaraman 
1113177b41ceSRagothaman Jayaraman 	/*
1114177b41ceSRagothaman Jayaraman 	 * In 83XX since we have a limitation of
1115177b41ceSRagothaman Jayaraman 	 * IV & Offset control word not part of instruction
1116177b41ceSRagothaman Jayaraman 	 * and need to be part of Data Buffer, we check if
1117177b41ceSRagothaman Jayaraman 	 * head room is there and then only do the Direct mode processing
1118177b41ceSRagothaman Jayaraman 	 */
1119177b41ceSRagothaman Jayaraman 	if (likely((flags & SINGLE_BUF_INPLACE) &&
1120177b41ceSRagothaman Jayaraman 		   (flags & SINGLE_BUF_HEADTAILROOM))) {
1121177b41ceSRagothaman Jayaraman 		void *dm_vaddr = fc_params->bufs[0].vaddr;
1122177b41ceSRagothaman Jayaraman 		uint64_t dm_dma_addr = fc_params->bufs[0].dma_addr;
1123177b41ceSRagothaman Jayaraman 		/*
1124177b41ceSRagothaman Jayaraman 		 * This flag indicates that there is 24 bytes head room and
1125177b41ceSRagothaman Jayaraman 		 * 8 bytes tail room available, so that we get to do
1126177b41ceSRagothaman Jayaraman 		 * DIRECT MODE with limitation
1127177b41ceSRagothaman Jayaraman 		 */
1128177b41ceSRagothaman Jayaraman 
1129177b41ceSRagothaman Jayaraman 		offset_vaddr = (uint8_t *)dm_vaddr - OFF_CTRL_LEN - iv_len;
1130177b41ceSRagothaman Jayaraman 		offset_dma = dm_dma_addr - OFF_CTRL_LEN - iv_len;
1131177b41ceSRagothaman Jayaraman 		req->ist.ei1 = offset_dma;
1132177b41ceSRagothaman Jayaraman 
1133177b41ceSRagothaman Jayaraman 		/* RPTR should just exclude offset control word */
1134177b41ceSRagothaman Jayaraman 		req->ist.ei2 = dm_dma_addr - iv_len;
1135177b41ceSRagothaman Jayaraman 
1136177b41ceSRagothaman Jayaraman 		req->alternate_caddr = (uint64_t *)((uint8_t *)dm_vaddr +
1137177b41ceSRagothaman Jayaraman 					outputlen - iv_len);
1138177b41ceSRagothaman Jayaraman 		/* since this is decryption,
1139177b41ceSRagothaman Jayaraman 		 * don't touch the content of
1140177b41ceSRagothaman Jayaraman 		 * alternate ccode space as it contains
1141177b41ceSRagothaman Jayaraman 		 * hmac.
1142177b41ceSRagothaman Jayaraman 		 */
1143177b41ceSRagothaman Jayaraman 
1144426af86bSAnoob Joseph 		vq_cmd_w0.s.dlen = inputlen + OFF_CTRL_LEN;
1145177b41ceSRagothaman Jayaraman 
1146426af86bSAnoob Joseph 		vq_cmd_w0.s.opcode = opcode.flags;
1147177b41ceSRagothaman Jayaraman 
1148177b41ceSRagothaman Jayaraman 		if (likely(iv_len)) {
1149177b41ceSRagothaman Jayaraman 			uint64_t *dest = (uint64_t *)((uint8_t *)offset_vaddr +
1150177b41ceSRagothaman Jayaraman 						      OFF_CTRL_LEN);
1151177b41ceSRagothaman Jayaraman 			uint64_t *src = fc_params->iv_buf;
1152177b41ceSRagothaman Jayaraman 			dest[0] = src[0];
1153177b41ceSRagothaman Jayaraman 			dest[1] = src[1];
1154177b41ceSRagothaman Jayaraman 		}
1155177b41ceSRagothaman Jayaraman 
1156177b41ceSRagothaman Jayaraman 		*(uint64_t *)offset_vaddr =
1157177b41ceSRagothaman Jayaraman 			rte_cpu_to_be_64(((uint64_t)encr_offset << 16) |
1158177b41ceSRagothaman Jayaraman 				((uint64_t)iv_offset << 8) |
1159177b41ceSRagothaman Jayaraman 				((uint64_t)auth_offset));
1160177b41ceSRagothaman Jayaraman 
1161177b41ceSRagothaman Jayaraman 	} else {
1162177b41ceSRagothaman Jayaraman 		uint64_t dptr_dma, rptr_dma;
1163177b41ceSRagothaman Jayaraman 		uint32_t g_size_bytes, s_size_bytes;
1164177b41ceSRagothaman Jayaraman 		sg_comp_t *gather_comp;
1165177b41ceSRagothaman Jayaraman 		sg_comp_t *scatter_comp;
1166177b41ceSRagothaman Jayaraman 		uint8_t *in_buffer;
1167177b41ceSRagothaman Jayaraman 		uint8_t i = 0;
1168177b41ceSRagothaman Jayaraman 
1169177b41ceSRagothaman Jayaraman 		/* This falls under strict SG mode */
1170177b41ceSRagothaman Jayaraman 		offset_vaddr = m_vaddr;
1171177b41ceSRagothaman Jayaraman 		offset_dma = m_dma;
1172177b41ceSRagothaman Jayaraman 		size = OFF_CTRL_LEN + iv_len;
1173177b41ceSRagothaman Jayaraman 
1174177b41ceSRagothaman Jayaraman 		m_vaddr = (uint8_t *)m_vaddr + size;
1175177b41ceSRagothaman Jayaraman 		m_dma += size;
1176177b41ceSRagothaman Jayaraman 
1177177b41ceSRagothaman Jayaraman 		opcode.s.major |= CPT_DMA_MODE;
1178177b41ceSRagothaman Jayaraman 
1179426af86bSAnoob Joseph 		vq_cmd_w0.s.opcode = opcode.flags;
1180177b41ceSRagothaman Jayaraman 
1181177b41ceSRagothaman Jayaraman 		if (likely(iv_len)) {
1182177b41ceSRagothaman Jayaraman 			uint64_t *dest = (uint64_t *)((uint8_t *)offset_vaddr +
1183177b41ceSRagothaman Jayaraman 						      OFF_CTRL_LEN);
1184177b41ceSRagothaman Jayaraman 			uint64_t *src = fc_params->iv_buf;
1185177b41ceSRagothaman Jayaraman 			dest[0] = src[0];
1186177b41ceSRagothaman Jayaraman 			dest[1] = src[1];
1187177b41ceSRagothaman Jayaraman 		}
1188177b41ceSRagothaman Jayaraman 
1189177b41ceSRagothaman Jayaraman 		*(uint64_t *)offset_vaddr =
1190177b41ceSRagothaman Jayaraman 			rte_cpu_to_be_64(((uint64_t)encr_offset << 16) |
1191177b41ceSRagothaman Jayaraman 				((uint64_t)iv_offset << 8) |
1192177b41ceSRagothaman Jayaraman 				((uint64_t)auth_offset));
1193177b41ceSRagothaman Jayaraman 
1194177b41ceSRagothaman Jayaraman 		/* DPTR has SG list */
1195177b41ceSRagothaman Jayaraman 		in_buffer = m_vaddr;
1196177b41ceSRagothaman Jayaraman 		dptr_dma = m_dma;
1197177b41ceSRagothaman Jayaraman 
1198177b41ceSRagothaman Jayaraman 		((uint16_t *)in_buffer)[0] = 0;
1199177b41ceSRagothaman Jayaraman 		((uint16_t *)in_buffer)[1] = 0;
1200177b41ceSRagothaman Jayaraman 
1201177b41ceSRagothaman Jayaraman 		/* TODO Add error check if space will be sufficient */
1202177b41ceSRagothaman Jayaraman 		gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8);
1203177b41ceSRagothaman Jayaraman 
1204177b41ceSRagothaman Jayaraman 		/*
1205177b41ceSRagothaman Jayaraman 		 * Input Gather List
1206177b41ceSRagothaman Jayaraman 		 */
1207177b41ceSRagothaman Jayaraman 		i = 0;
1208177b41ceSRagothaman Jayaraman 
1209177b41ceSRagothaman Jayaraman 		/* Offset control word that includes iv */
1210177b41ceSRagothaman Jayaraman 		i = fill_sg_comp(gather_comp, i, offset_dma,
1211177b41ceSRagothaman Jayaraman 				 OFF_CTRL_LEN + iv_len);
1212177b41ceSRagothaman Jayaraman 
1213177b41ceSRagothaman Jayaraman 		/* Add input data */
1214177b41ceSRagothaman Jayaraman 		if (flags & VALID_MAC_BUF) {
1215177b41ceSRagothaman Jayaraman 			size = inputlen - iv_len - mac_len;
1216177b41ceSRagothaman Jayaraman 			if (size) {
1217177b41ceSRagothaman Jayaraman 				/* input data only */
1218177b41ceSRagothaman Jayaraman 				if (unlikely(flags & SINGLE_BUF_INPLACE)) {
1219177b41ceSRagothaman Jayaraman 					i = fill_sg_comp_from_buf_min(
1220177b41ceSRagothaman Jayaraman 							gather_comp, i,
1221177b41ceSRagothaman Jayaraman 							fc_params->bufs,
1222177b41ceSRagothaman Jayaraman 							&size);
1223177b41ceSRagothaman Jayaraman 				} else {
1224177b41ceSRagothaman Jayaraman 					uint32_t aad_offset = aad_len ?
1225177b41ceSRagothaman Jayaraman 						passthrough_len : 0;
1226177b41ceSRagothaman Jayaraman 
1227177b41ceSRagothaman Jayaraman 					i = fill_sg_comp_from_iov(gather_comp,
1228177b41ceSRagothaman Jayaraman 							i,
1229177b41ceSRagothaman Jayaraman 							fc_params->src_iov,
1230177b41ceSRagothaman Jayaraman 							0, &size,
1231177b41ceSRagothaman Jayaraman 							aad_buf,
1232177b41ceSRagothaman Jayaraman 							aad_offset);
1233177b41ceSRagothaman Jayaraman 				}
1234f39928e6SAnoob Joseph 				if (unlikely(size)) {
1235f39928e6SAnoob Joseph 					CPT_LOG_DP_ERR("Insufficient buffer"
1236f39928e6SAnoob Joseph 						       " space, size %d needed",
1237f39928e6SAnoob Joseph 						       size);
1238f39928e6SAnoob Joseph 					return;
1239f39928e6SAnoob Joseph 				}
1240177b41ceSRagothaman Jayaraman 			}
1241177b41ceSRagothaman Jayaraman 
1242177b41ceSRagothaman Jayaraman 			/* mac data */
1243177b41ceSRagothaman Jayaraman 			if (mac_len) {
1244177b41ceSRagothaman Jayaraman 				i = fill_sg_comp_from_buf(gather_comp, i,
1245177b41ceSRagothaman Jayaraman 							  &fc_params->mac_buf);
1246177b41ceSRagothaman Jayaraman 			}
1247177b41ceSRagothaman Jayaraman 		} else {
1248177b41ceSRagothaman Jayaraman 			/* input data + mac */
1249177b41ceSRagothaman Jayaraman 			size = inputlen - iv_len;
1250177b41ceSRagothaman Jayaraman 			if (size) {
1251177b41ceSRagothaman Jayaraman 				if (unlikely(flags & SINGLE_BUF_INPLACE)) {
1252177b41ceSRagothaman Jayaraman 					i = fill_sg_comp_from_buf_min(
1253177b41ceSRagothaman Jayaraman 							gather_comp, i,
1254177b41ceSRagothaman Jayaraman 							fc_params->bufs,
1255177b41ceSRagothaman Jayaraman 							&size);
1256177b41ceSRagothaman Jayaraman 				} else {
1257177b41ceSRagothaman Jayaraman 					uint32_t aad_offset = aad_len ?
1258177b41ceSRagothaman Jayaraman 						passthrough_len : 0;
1259177b41ceSRagothaman Jayaraman 
1260f39928e6SAnoob Joseph 					if (unlikely(!fc_params->src_iov)) {
1261f39928e6SAnoob Joseph 						CPT_LOG_DP_ERR("Bad input args");
1262f39928e6SAnoob Joseph 						return;
1263f39928e6SAnoob Joseph 					}
1264177b41ceSRagothaman Jayaraman 
1265177b41ceSRagothaman Jayaraman 					i = fill_sg_comp_from_iov(
1266177b41ceSRagothaman Jayaraman 							gather_comp, i,
1267177b41ceSRagothaman Jayaraman 							fc_params->src_iov,
1268177b41ceSRagothaman Jayaraman 							0, &size,
1269177b41ceSRagothaman Jayaraman 							aad_buf,
1270177b41ceSRagothaman Jayaraman 							aad_offset);
1271177b41ceSRagothaman Jayaraman 				}
1272177b41ceSRagothaman Jayaraman 
1273f39928e6SAnoob Joseph 				if (unlikely(size)) {
1274f39928e6SAnoob Joseph 					CPT_LOG_DP_ERR("Insufficient buffer"
1275f39928e6SAnoob Joseph 						       " space, size %d needed",
1276f39928e6SAnoob Joseph 						       size);
1277f39928e6SAnoob Joseph 					return;
1278f39928e6SAnoob Joseph 				}
1279177b41ceSRagothaman Jayaraman 			}
1280177b41ceSRagothaman Jayaraman 		}
1281177b41ceSRagothaman Jayaraman 		((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i);
1282177b41ceSRagothaman Jayaraman 		g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
1283177b41ceSRagothaman Jayaraman 
1284177b41ceSRagothaman Jayaraman 		/*
1285177b41ceSRagothaman Jayaraman 		 * Output Scatter List
1286177b41ceSRagothaman Jayaraman 		 */
1287177b41ceSRagothaman Jayaraman 
1288177b41ceSRagothaman Jayaraman 		i = 0;
1289177b41ceSRagothaman Jayaraman 		scatter_comp =
1290177b41ceSRagothaman Jayaraman 			(sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes);
1291177b41ceSRagothaman Jayaraman 
1292177b41ceSRagothaman Jayaraman 		/* Add iv */
1293177b41ceSRagothaman Jayaraman 		if (iv_len) {
1294177b41ceSRagothaman Jayaraman 			i = fill_sg_comp(scatter_comp, i,
1295177b41ceSRagothaman Jayaraman 					 offset_dma + OFF_CTRL_LEN,
1296177b41ceSRagothaman Jayaraman 					 iv_len);
1297177b41ceSRagothaman Jayaraman 		}
1298177b41ceSRagothaman Jayaraman 
1299177b41ceSRagothaman Jayaraman 		/* Add output data */
1300177b41ceSRagothaman Jayaraman 		size = outputlen - iv_len;
1301177b41ceSRagothaman Jayaraman 		if (size) {
1302177b41ceSRagothaman Jayaraman 			if (unlikely(flags & SINGLE_BUF_INPLACE)) {
1303177b41ceSRagothaman Jayaraman 				/* handle single buffer here */
1304177b41ceSRagothaman Jayaraman 				i = fill_sg_comp_from_buf_min(scatter_comp, i,
1305177b41ceSRagothaman Jayaraman 							      fc_params->bufs,
1306177b41ceSRagothaman Jayaraman 							      &size);
1307177b41ceSRagothaman Jayaraman 			} else {
1308177b41ceSRagothaman Jayaraman 				uint32_t aad_offset = aad_len ?
1309177b41ceSRagothaman Jayaraman 					passthrough_len : 0;
1310177b41ceSRagothaman Jayaraman 
1311f39928e6SAnoob Joseph 				if (unlikely(!fc_params->dst_iov)) {
1312f39928e6SAnoob Joseph 					CPT_LOG_DP_ERR("Bad input args");
1313f39928e6SAnoob Joseph 					return;
1314f39928e6SAnoob Joseph 				}
1315177b41ceSRagothaman Jayaraman 
1316177b41ceSRagothaman Jayaraman 				i = fill_sg_comp_from_iov(scatter_comp, i,
1317177b41ceSRagothaman Jayaraman 							  fc_params->dst_iov, 0,
1318177b41ceSRagothaman Jayaraman 							  &size, aad_buf,
1319177b41ceSRagothaman Jayaraman 							  aad_offset);
1320177b41ceSRagothaman Jayaraman 			}
1321177b41ceSRagothaman Jayaraman 
1322f39928e6SAnoob Joseph 			if (unlikely(size)) {
1323f39928e6SAnoob Joseph 				CPT_LOG_DP_ERR("Insufficient buffer space,"
1324f39928e6SAnoob Joseph 					       " size %d needed", size);
1325f39928e6SAnoob Joseph 				return;
1326f39928e6SAnoob Joseph 			}
1327177b41ceSRagothaman Jayaraman 		}
1328177b41ceSRagothaman Jayaraman 
1329177b41ceSRagothaman Jayaraman 		((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i);
1330177b41ceSRagothaman Jayaraman 		s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
1331177b41ceSRagothaman Jayaraman 
1332177b41ceSRagothaman Jayaraman 		size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE;
1333177b41ceSRagothaman Jayaraman 
1334177b41ceSRagothaman Jayaraman 		/* This is DPTR len incase of SG mode */
1335426af86bSAnoob Joseph 		vq_cmd_w0.s.dlen = size;
1336177b41ceSRagothaman Jayaraman 
1337177b41ceSRagothaman Jayaraman 		m_vaddr = (uint8_t *)m_vaddr + size;
1338177b41ceSRagothaman Jayaraman 		m_dma += size;
1339177b41ceSRagothaman Jayaraman 
1340177b41ceSRagothaman Jayaraman 		/* cpt alternate completion address saved earlier */
1341177b41ceSRagothaman Jayaraman 		req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8);
1342177b41ceSRagothaman Jayaraman 		*req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT);
1343177b41ceSRagothaman Jayaraman 		rptr_dma = c_dma - 8;
1344177b41ceSRagothaman Jayaraman 		size += COMPLETION_CODE_SIZE;
1345177b41ceSRagothaman Jayaraman 
1346177b41ceSRagothaman Jayaraman 		req->ist.ei1 = dptr_dma;
1347177b41ceSRagothaman Jayaraman 		req->ist.ei2 = rptr_dma;
1348177b41ceSRagothaman Jayaraman 	}
1349177b41ceSRagothaman Jayaraman 
1350177b41ceSRagothaman Jayaraman 	ctx_dma = fc_params->ctx_buf.dma_addr +
1351177b41ceSRagothaman Jayaraman 		offsetof(struct cpt_ctx, fctx);
1352177b41ceSRagothaman Jayaraman 	/* vq command w3 */
1353177b41ceSRagothaman Jayaraman 	vq_cmd_w3.u64 = 0;
1354177b41ceSRagothaman Jayaraman 	vq_cmd_w3.s.grp = 0;
1355177b41ceSRagothaman Jayaraman 	vq_cmd_w3.s.cptr = ctx_dma;
1356177b41ceSRagothaman Jayaraman 
1357177b41ceSRagothaman Jayaraman 	/* 16 byte aligned cpt res address */
1358177b41ceSRagothaman Jayaraman 	req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr);
1359177b41ceSRagothaman Jayaraman 	*req->completion_addr = COMPLETION_CODE_INIT;
1360177b41ceSRagothaman Jayaraman 	req->comp_baddr  = c_dma;
1361177b41ceSRagothaman Jayaraman 
1362177b41ceSRagothaman Jayaraman 	/* Fill microcode part of instruction */
1363177b41ceSRagothaman Jayaraman 	req->ist.ei0 = vq_cmd_w0.u64;
1364177b41ceSRagothaman Jayaraman 	req->ist.ei3 = vq_cmd_w3.u64;
1365177b41ceSRagothaman Jayaraman 
1366177b41ceSRagothaman Jayaraman 	req->op = op;
1367177b41ceSRagothaman Jayaraman 
1368177b41ceSRagothaman Jayaraman 	*prep_req = req;
1369f39928e6SAnoob Joseph 	return;
1370177b41ceSRagothaman Jayaraman }
1371177b41ceSRagothaman Jayaraman 
1372f39928e6SAnoob Joseph static __rte_always_inline void
137300d92c66SSrisivasubramanian S cpt_zuc_snow3g_enc_prep(uint32_t req_flags,
137400d92c66SSrisivasubramanian S 			uint64_t d_offs,
137500d92c66SSrisivasubramanian S 			uint64_t d_lens,
137600d92c66SSrisivasubramanian S 			fc_params_t *params,
137700d92c66SSrisivasubramanian S 			void *op,
137800d92c66SSrisivasubramanian S 			void **prep_req)
137900d92c66SSrisivasubramanian S {
138000d92c66SSrisivasubramanian S 	uint32_t size;
138100d92c66SSrisivasubramanian S 	int32_t inputlen, outputlen;
138200d92c66SSrisivasubramanian S 	struct cpt_ctx *cpt_ctx;
138300d92c66SSrisivasubramanian S 	uint32_t mac_len = 0;
138400d92c66SSrisivasubramanian S 	uint8_t snow3g, j;
138500d92c66SSrisivasubramanian S 	struct cpt_request_info *req;
138600d92c66SSrisivasubramanian S 	buf_ptr_t *buf_p;
138700d92c66SSrisivasubramanian S 	uint32_t encr_offset = 0, auth_offset = 0;
138800d92c66SSrisivasubramanian S 	uint32_t encr_data_len = 0, auth_data_len = 0;
13898de5ede7SAnoob Joseph 	int flags, iv_len = 16;
139000d92c66SSrisivasubramanian S 	void *m_vaddr, *c_vaddr;
139100d92c66SSrisivasubramanian S 	uint64_t m_dma, c_dma, offset_ctrl;
139200d92c66SSrisivasubramanian S 	uint64_t *offset_vaddr, offset_dma;
139300d92c66SSrisivasubramanian S 	uint32_t *iv_s, iv[4];
139400d92c66SSrisivasubramanian S 	vq_cmd_word0_t vq_cmd_w0;
139500d92c66SSrisivasubramanian S 	vq_cmd_word3_t vq_cmd_w3;
139600d92c66SSrisivasubramanian S 	opcode_info_t opcode;
139700d92c66SSrisivasubramanian S 
139800d92c66SSrisivasubramanian S 	buf_p = &params->meta_buf;
139900d92c66SSrisivasubramanian S 	m_vaddr = buf_p->vaddr;
140000d92c66SSrisivasubramanian S 	m_dma = buf_p->dma_addr;
140100d92c66SSrisivasubramanian S 
140200d92c66SSrisivasubramanian S 	cpt_ctx = params->ctx_buf.vaddr;
140300d92c66SSrisivasubramanian S 	flags = cpt_ctx->zsk_flags;
140400d92c66SSrisivasubramanian S 	mac_len = cpt_ctx->mac_len;
140500d92c66SSrisivasubramanian S 	snow3g = cpt_ctx->snow3g;
140600d92c66SSrisivasubramanian S 
140700d92c66SSrisivasubramanian S 	/*
140800d92c66SSrisivasubramanian S 	 * Save initial space that followed app data for completion code &
140900d92c66SSrisivasubramanian S 	 * alternate completion code to fall in same cache line as app data
141000d92c66SSrisivasubramanian S 	 */
141100d92c66SSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE;
141200d92c66SSrisivasubramanian S 	m_dma += COMPLETION_CODE_SIZE;
141300d92c66SSrisivasubramanian S 	size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) -
141400d92c66SSrisivasubramanian S 		(uint8_t *)m_vaddr;
141500d92c66SSrisivasubramanian S 
141600d92c66SSrisivasubramanian S 	c_vaddr = (uint8_t *)m_vaddr + size;
141700d92c66SSrisivasubramanian S 	c_dma = m_dma + size;
141800d92c66SSrisivasubramanian S 	size += sizeof(cpt_res_s_t);
141900d92c66SSrisivasubramanian S 
142000d92c66SSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
142100d92c66SSrisivasubramanian S 	m_dma += size;
142200d92c66SSrisivasubramanian S 
142300d92c66SSrisivasubramanian S 	/* Reserve memory for cpt request info */
142400d92c66SSrisivasubramanian S 	req = m_vaddr;
142500d92c66SSrisivasubramanian S 
142600d92c66SSrisivasubramanian S 	size = sizeof(struct cpt_request_info);
142700d92c66SSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
142800d92c66SSrisivasubramanian S 	m_dma += size;
142900d92c66SSrisivasubramanian S 
143000d92c66SSrisivasubramanian S 	opcode.s.major = CPT_MAJOR_OP_ZUC_SNOW3G;
143100d92c66SSrisivasubramanian S 
143200d92c66SSrisivasubramanian S 	/* indicates CPTR ctx, operation type, KEY & IV mode from DPTR */
1433131966f8SAnkur Dwivedi 
1434131966f8SAnkur Dwivedi 	opcode.s.minor = ((1 << 7) | (snow3g << 5) | (0 << 4) |
143500d92c66SSrisivasubramanian S 			  (0 << 3) | (flags & 0x7));
143600d92c66SSrisivasubramanian S 
143700d92c66SSrisivasubramanian S 	if (flags == 0x1) {
143800d92c66SSrisivasubramanian S 		/*
143900d92c66SSrisivasubramanian S 		 * Microcode expects offsets in bytes
144000d92c66SSrisivasubramanian S 		 * TODO: Rounding off
144100d92c66SSrisivasubramanian S 		 */
144200d92c66SSrisivasubramanian S 		auth_data_len = AUTH_DLEN(d_lens);
144300d92c66SSrisivasubramanian S 
144400d92c66SSrisivasubramanian S 		/* EIA3 or UIA2 */
144500d92c66SSrisivasubramanian S 		auth_offset = AUTH_OFFSET(d_offs);
144600d92c66SSrisivasubramanian S 		auth_offset = auth_offset / 8;
144700d92c66SSrisivasubramanian S 
144800d92c66SSrisivasubramanian S 		/* consider iv len */
144900d92c66SSrisivasubramanian S 		auth_offset += iv_len;
145000d92c66SSrisivasubramanian S 
145100d92c66SSrisivasubramanian S 		inputlen = auth_offset + (RTE_ALIGN(auth_data_len, 8) / 8);
145200d92c66SSrisivasubramanian S 		outputlen = mac_len;
145300d92c66SSrisivasubramanian S 
145400d92c66SSrisivasubramanian S 		offset_ctrl = rte_cpu_to_be_64((uint64_t)auth_offset);
145500d92c66SSrisivasubramanian S 
145600d92c66SSrisivasubramanian S 	} else {
145700d92c66SSrisivasubramanian S 		/* EEA3 or UEA2 */
145800d92c66SSrisivasubramanian S 		/*
145900d92c66SSrisivasubramanian S 		 * Microcode expects offsets in bytes
146000d92c66SSrisivasubramanian S 		 * TODO: Rounding off
146100d92c66SSrisivasubramanian S 		 */
146200d92c66SSrisivasubramanian S 		encr_data_len = ENCR_DLEN(d_lens);
146300d92c66SSrisivasubramanian S 
146400d92c66SSrisivasubramanian S 		encr_offset = ENCR_OFFSET(d_offs);
146500d92c66SSrisivasubramanian S 		encr_offset = encr_offset / 8;
146600d92c66SSrisivasubramanian S 		/* consider iv len */
146700d92c66SSrisivasubramanian S 		encr_offset += iv_len;
146800d92c66SSrisivasubramanian S 
146900d92c66SSrisivasubramanian S 		inputlen = encr_offset + (RTE_ALIGN(encr_data_len, 8) / 8);
147000d92c66SSrisivasubramanian S 		outputlen = inputlen;
147100d92c66SSrisivasubramanian S 
147200d92c66SSrisivasubramanian S 		/* iv offset is 0 */
147300d92c66SSrisivasubramanian S 		offset_ctrl = rte_cpu_to_be_64((uint64_t)encr_offset << 16);
147400d92c66SSrisivasubramanian S 	}
147500d92c66SSrisivasubramanian S 
147600d92c66SSrisivasubramanian S 	/* IV */
147700d92c66SSrisivasubramanian S 	iv_s = (flags == 0x1) ? params->auth_iv_buf :
147800d92c66SSrisivasubramanian S 		params->iv_buf;
147900d92c66SSrisivasubramanian S 
148000d92c66SSrisivasubramanian S 	if (snow3g) {
148100d92c66SSrisivasubramanian S 		/*
148200d92c66SSrisivasubramanian S 		 * DPDK seems to provide it in form of IV3 IV2 IV1 IV0
148300d92c66SSrisivasubramanian S 		 * and BigEndian, MC needs it as IV0 IV1 IV2 IV3
148400d92c66SSrisivasubramanian S 		 */
148500d92c66SSrisivasubramanian S 
148600d92c66SSrisivasubramanian S 		for (j = 0; j < 4; j++)
148700d92c66SSrisivasubramanian S 			iv[j] = iv_s[3 - j];
148800d92c66SSrisivasubramanian S 	} else {
148900d92c66SSrisivasubramanian S 		/* ZUC doesn't need a swap */
149000d92c66SSrisivasubramanian S 		for (j = 0; j < 4; j++)
149100d92c66SSrisivasubramanian S 			iv[j] = iv_s[j];
149200d92c66SSrisivasubramanian S 	}
149300d92c66SSrisivasubramanian S 
149400d92c66SSrisivasubramanian S 	/*
149500d92c66SSrisivasubramanian S 	 * GP op header, lengths are expected in bits.
149600d92c66SSrisivasubramanian S 	 */
149700d92c66SSrisivasubramanian S 	vq_cmd_w0.u64 = 0;
1498426af86bSAnoob Joseph 	vq_cmd_w0.s.param1 = encr_data_len;
1499426af86bSAnoob Joseph 	vq_cmd_w0.s.param2 = auth_data_len;
150000d92c66SSrisivasubramanian S 
150100d92c66SSrisivasubramanian S 	/*
150200d92c66SSrisivasubramanian S 	 * In 83XX since we have a limitation of
150300d92c66SSrisivasubramanian S 	 * IV & Offset control word not part of instruction
150400d92c66SSrisivasubramanian S 	 * and need to be part of Data Buffer, we check if
150500d92c66SSrisivasubramanian S 	 * head room is there and then only do the Direct mode processing
150600d92c66SSrisivasubramanian S 	 */
150700d92c66SSrisivasubramanian S 	if (likely((req_flags & SINGLE_BUF_INPLACE) &&
150800d92c66SSrisivasubramanian S 		   (req_flags & SINGLE_BUF_HEADTAILROOM))) {
150900d92c66SSrisivasubramanian S 		void *dm_vaddr = params->bufs[0].vaddr;
151000d92c66SSrisivasubramanian S 		uint64_t dm_dma_addr = params->bufs[0].dma_addr;
151100d92c66SSrisivasubramanian S 		/*
151200d92c66SSrisivasubramanian S 		 * This flag indicates that there is 24 bytes head room and
151300d92c66SSrisivasubramanian S 		 * 8 bytes tail room available, so that we get to do
151400d92c66SSrisivasubramanian S 		 * DIRECT MODE with limitation
151500d92c66SSrisivasubramanian S 		 */
151600d92c66SSrisivasubramanian S 
151700d92c66SSrisivasubramanian S 		offset_vaddr = (uint64_t *)((uint8_t *)dm_vaddr -
151800d92c66SSrisivasubramanian S 					    OFF_CTRL_LEN - iv_len);
151900d92c66SSrisivasubramanian S 		offset_dma = dm_dma_addr - OFF_CTRL_LEN - iv_len;
152000d92c66SSrisivasubramanian S 
152100d92c66SSrisivasubramanian S 		/* DPTR */
152200d92c66SSrisivasubramanian S 		req->ist.ei1 = offset_dma;
152300d92c66SSrisivasubramanian S 		/* RPTR should just exclude offset control word */
152400d92c66SSrisivasubramanian S 		req->ist.ei2 = dm_dma_addr - iv_len;
152500d92c66SSrisivasubramanian S 		req->alternate_caddr = (uint64_t *)((uint8_t *)dm_vaddr
152600d92c66SSrisivasubramanian S 						    + outputlen - iv_len);
152700d92c66SSrisivasubramanian S 
1528426af86bSAnoob Joseph 		vq_cmd_w0.s.dlen = inputlen + OFF_CTRL_LEN;
152900d92c66SSrisivasubramanian S 
1530426af86bSAnoob Joseph 		vq_cmd_w0.s.opcode = opcode.flags;
153100d92c66SSrisivasubramanian S 
153200d92c66SSrisivasubramanian S 		if (likely(iv_len)) {
153300d92c66SSrisivasubramanian S 			uint32_t *iv_d = (uint32_t *)((uint8_t *)offset_vaddr
153400d92c66SSrisivasubramanian S 						      + OFF_CTRL_LEN);
153500d92c66SSrisivasubramanian S 			memcpy(iv_d, iv, 16);
153600d92c66SSrisivasubramanian S 		}
153700d92c66SSrisivasubramanian S 
153800d92c66SSrisivasubramanian S 		*offset_vaddr = offset_ctrl;
153900d92c66SSrisivasubramanian S 	} else {
154000d92c66SSrisivasubramanian S 		uint32_t i, g_size_bytes, s_size_bytes;
154100d92c66SSrisivasubramanian S 		uint64_t dptr_dma, rptr_dma;
154200d92c66SSrisivasubramanian S 		sg_comp_t *gather_comp;
154300d92c66SSrisivasubramanian S 		sg_comp_t *scatter_comp;
154400d92c66SSrisivasubramanian S 		uint8_t *in_buffer;
154500d92c66SSrisivasubramanian S 		uint32_t *iv_d;
154600d92c66SSrisivasubramanian S 
154700d92c66SSrisivasubramanian S 		/* save space for iv */
154800d92c66SSrisivasubramanian S 		offset_vaddr = m_vaddr;
154900d92c66SSrisivasubramanian S 		offset_dma = m_dma;
155000d92c66SSrisivasubramanian S 
155100d92c66SSrisivasubramanian S 		m_vaddr = (uint8_t *)m_vaddr + OFF_CTRL_LEN + iv_len;
155200d92c66SSrisivasubramanian S 		m_dma += OFF_CTRL_LEN + iv_len;
155300d92c66SSrisivasubramanian S 
155400d92c66SSrisivasubramanian S 		opcode.s.major |= CPT_DMA_MODE;
155500d92c66SSrisivasubramanian S 
1556426af86bSAnoob Joseph 		vq_cmd_w0.s.opcode = opcode.flags;
155700d92c66SSrisivasubramanian S 
155800d92c66SSrisivasubramanian S 		/* DPTR has SG list */
155900d92c66SSrisivasubramanian S 		in_buffer = m_vaddr;
156000d92c66SSrisivasubramanian S 		dptr_dma = m_dma;
156100d92c66SSrisivasubramanian S 
156200d92c66SSrisivasubramanian S 		((uint16_t *)in_buffer)[0] = 0;
156300d92c66SSrisivasubramanian S 		((uint16_t *)in_buffer)[1] = 0;
156400d92c66SSrisivasubramanian S 
156500d92c66SSrisivasubramanian S 		/* TODO Add error check if space will be sufficient */
156600d92c66SSrisivasubramanian S 		gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8);
156700d92c66SSrisivasubramanian S 
156800d92c66SSrisivasubramanian S 		/*
156900d92c66SSrisivasubramanian S 		 * Input Gather List
157000d92c66SSrisivasubramanian S 		 */
157100d92c66SSrisivasubramanian S 		i = 0;
157200d92c66SSrisivasubramanian S 
157300d92c66SSrisivasubramanian S 		/* Offset control word followed by iv */
157400d92c66SSrisivasubramanian S 
157500d92c66SSrisivasubramanian S 		i = fill_sg_comp(gather_comp, i, offset_dma,
157600d92c66SSrisivasubramanian S 				 OFF_CTRL_LEN + iv_len);
157700d92c66SSrisivasubramanian S 
157800d92c66SSrisivasubramanian S 		/* iv offset is 0 */
157900d92c66SSrisivasubramanian S 		*offset_vaddr = offset_ctrl;
158000d92c66SSrisivasubramanian S 
158100d92c66SSrisivasubramanian S 		iv_d = (uint32_t *)((uint8_t *)offset_vaddr + OFF_CTRL_LEN);
158200d92c66SSrisivasubramanian S 		memcpy(iv_d, iv, 16);
158300d92c66SSrisivasubramanian S 
158400d92c66SSrisivasubramanian S 		/* input data */
158500d92c66SSrisivasubramanian S 		size = inputlen - iv_len;
158600d92c66SSrisivasubramanian S 		if (size) {
158700d92c66SSrisivasubramanian S 			i = fill_sg_comp_from_iov(gather_comp, i,
158800d92c66SSrisivasubramanian S 						  params->src_iov,
158900d92c66SSrisivasubramanian S 						  0, &size, NULL, 0);
1590f39928e6SAnoob Joseph 			if (unlikely(size)) {
1591f39928e6SAnoob Joseph 				CPT_LOG_DP_ERR("Insufficient buffer space,"
1592f39928e6SAnoob Joseph 					       " size %d needed", size);
1593f39928e6SAnoob Joseph 				return;
1594f39928e6SAnoob Joseph 			}
159500d92c66SSrisivasubramanian S 		}
159600d92c66SSrisivasubramanian S 		((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i);
159700d92c66SSrisivasubramanian S 		g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
159800d92c66SSrisivasubramanian S 
159900d92c66SSrisivasubramanian S 		/*
160000d92c66SSrisivasubramanian S 		 * Output Scatter List
160100d92c66SSrisivasubramanian S 		 */
160200d92c66SSrisivasubramanian S 
160300d92c66SSrisivasubramanian S 		i = 0;
160400d92c66SSrisivasubramanian S 		scatter_comp =
160500d92c66SSrisivasubramanian S 			(sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes);
160600d92c66SSrisivasubramanian S 
160700d92c66SSrisivasubramanian S 		if (flags == 0x1) {
160800d92c66SSrisivasubramanian S 			/* IV in SLIST only for EEA3 & UEA2 */
160900d92c66SSrisivasubramanian S 			iv_len = 0;
161000d92c66SSrisivasubramanian S 		}
161100d92c66SSrisivasubramanian S 
161200d92c66SSrisivasubramanian S 		if (iv_len) {
161300d92c66SSrisivasubramanian S 			i = fill_sg_comp(scatter_comp, i,
161400d92c66SSrisivasubramanian S 					 offset_dma + OFF_CTRL_LEN, iv_len);
161500d92c66SSrisivasubramanian S 		}
161600d92c66SSrisivasubramanian S 
161700d92c66SSrisivasubramanian S 		/* Add output data */
161800d92c66SSrisivasubramanian S 		if (req_flags & VALID_MAC_BUF) {
161900d92c66SSrisivasubramanian S 			size = outputlen - iv_len - mac_len;
162000d92c66SSrisivasubramanian S 			if (size) {
162100d92c66SSrisivasubramanian S 				i = fill_sg_comp_from_iov(scatter_comp, i,
162200d92c66SSrisivasubramanian S 							  params->dst_iov, 0,
162300d92c66SSrisivasubramanian S 							  &size, NULL, 0);
162400d92c66SSrisivasubramanian S 
1625f39928e6SAnoob Joseph 				if (unlikely(size)) {
1626f39928e6SAnoob Joseph 					CPT_LOG_DP_ERR("Insufficient buffer space,"
1627f39928e6SAnoob Joseph 						       " size %d needed", size);
1628f39928e6SAnoob Joseph 					return;
1629f39928e6SAnoob Joseph 				}
163000d92c66SSrisivasubramanian S 			}
163100d92c66SSrisivasubramanian S 
163200d92c66SSrisivasubramanian S 			/* mac data */
163300d92c66SSrisivasubramanian S 			if (mac_len) {
163400d92c66SSrisivasubramanian S 				i = fill_sg_comp_from_buf(scatter_comp, i,
163500d92c66SSrisivasubramanian S 							  &params->mac_buf);
163600d92c66SSrisivasubramanian S 			}
163700d92c66SSrisivasubramanian S 		} else {
163800d92c66SSrisivasubramanian S 			/* Output including mac */
163900d92c66SSrisivasubramanian S 			size = outputlen - iv_len;
164000d92c66SSrisivasubramanian S 			if (size) {
164100d92c66SSrisivasubramanian S 				i = fill_sg_comp_from_iov(scatter_comp, i,
164200d92c66SSrisivasubramanian S 							  params->dst_iov, 0,
164300d92c66SSrisivasubramanian S 							  &size, NULL, 0);
164400d92c66SSrisivasubramanian S 
1645f39928e6SAnoob Joseph 				if (unlikely(size)) {
1646f39928e6SAnoob Joseph 					CPT_LOG_DP_ERR("Insufficient buffer space,"
1647f39928e6SAnoob Joseph 						       " size %d needed", size);
1648f39928e6SAnoob Joseph 					return;
1649f39928e6SAnoob Joseph 				}
165000d92c66SSrisivasubramanian S 			}
165100d92c66SSrisivasubramanian S 		}
165200d92c66SSrisivasubramanian S 		((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i);
165300d92c66SSrisivasubramanian S 		s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
165400d92c66SSrisivasubramanian S 
165500d92c66SSrisivasubramanian S 		size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE;
165600d92c66SSrisivasubramanian S 
165700d92c66SSrisivasubramanian S 		/* This is DPTR len incase of SG mode */
1658426af86bSAnoob Joseph 		vq_cmd_w0.s.dlen = size;
165900d92c66SSrisivasubramanian S 
166000d92c66SSrisivasubramanian S 		m_vaddr = (uint8_t *)m_vaddr + size;
166100d92c66SSrisivasubramanian S 		m_dma += size;
166200d92c66SSrisivasubramanian S 
166300d92c66SSrisivasubramanian S 		/* cpt alternate completion address saved earlier */
166400d92c66SSrisivasubramanian S 		req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8);
166500d92c66SSrisivasubramanian S 		*req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT);
166600d92c66SSrisivasubramanian S 		rptr_dma = c_dma - 8;
166700d92c66SSrisivasubramanian S 
166800d92c66SSrisivasubramanian S 		req->ist.ei1 = dptr_dma;
166900d92c66SSrisivasubramanian S 		req->ist.ei2 = rptr_dma;
167000d92c66SSrisivasubramanian S 	}
167100d92c66SSrisivasubramanian S 
167200d92c66SSrisivasubramanian S 	/* vq command w3 */
167300d92c66SSrisivasubramanian S 	vq_cmd_w3.u64 = 0;
167400d92c66SSrisivasubramanian S 	vq_cmd_w3.s.grp = 0;
167500d92c66SSrisivasubramanian S 	vq_cmd_w3.s.cptr = params->ctx_buf.dma_addr +
167600d92c66SSrisivasubramanian S 		offsetof(struct cpt_ctx, zs_ctx);
167700d92c66SSrisivasubramanian S 
167800d92c66SSrisivasubramanian S 	/* 16 byte aligned cpt res address */
167900d92c66SSrisivasubramanian S 	req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr);
168000d92c66SSrisivasubramanian S 	*req->completion_addr = COMPLETION_CODE_INIT;
168100d92c66SSrisivasubramanian S 	req->comp_baddr  = c_dma;
168200d92c66SSrisivasubramanian S 
168300d92c66SSrisivasubramanian S 	/* Fill microcode part of instruction */
168400d92c66SSrisivasubramanian S 	req->ist.ei0 = vq_cmd_w0.u64;
168500d92c66SSrisivasubramanian S 	req->ist.ei3 = vq_cmd_w3.u64;
168600d92c66SSrisivasubramanian S 
168700d92c66SSrisivasubramanian S 	req->op = op;
168800d92c66SSrisivasubramanian S 
168900d92c66SSrisivasubramanian S 	*prep_req = req;
1690f39928e6SAnoob Joseph 	return;
169100d92c66SSrisivasubramanian S }
169200d92c66SSrisivasubramanian S 
1693f39928e6SAnoob Joseph static __rte_always_inline void
169400d92c66SSrisivasubramanian S cpt_zuc_snow3g_dec_prep(uint32_t req_flags,
169500d92c66SSrisivasubramanian S 			uint64_t d_offs,
169600d92c66SSrisivasubramanian S 			uint64_t d_lens,
169700d92c66SSrisivasubramanian S 			fc_params_t *params,
169800d92c66SSrisivasubramanian S 			void *op,
169900d92c66SSrisivasubramanian S 			void **prep_req)
170000d92c66SSrisivasubramanian S {
170100d92c66SSrisivasubramanian S 	uint32_t size;
170200d92c66SSrisivasubramanian S 	int32_t inputlen = 0, outputlen;
170300d92c66SSrisivasubramanian S 	struct cpt_ctx *cpt_ctx;
170400d92c66SSrisivasubramanian S 	uint8_t snow3g, iv_len = 16;
170500d92c66SSrisivasubramanian S 	struct cpt_request_info *req;
170600d92c66SSrisivasubramanian S 	buf_ptr_t *buf_p;
170700d92c66SSrisivasubramanian S 	uint32_t encr_offset;
170800d92c66SSrisivasubramanian S 	uint32_t encr_data_len;
17098de5ede7SAnoob Joseph 	int flags;
171000d92c66SSrisivasubramanian S 	void *m_vaddr, *c_vaddr;
171100d92c66SSrisivasubramanian S 	uint64_t m_dma, c_dma;
171200d92c66SSrisivasubramanian S 	uint64_t *offset_vaddr, offset_dma;
171300d92c66SSrisivasubramanian S 	uint32_t *iv_s, iv[4], j;
171400d92c66SSrisivasubramanian S 	vq_cmd_word0_t vq_cmd_w0;
171500d92c66SSrisivasubramanian S 	vq_cmd_word3_t vq_cmd_w3;
171600d92c66SSrisivasubramanian S 	opcode_info_t opcode;
171700d92c66SSrisivasubramanian S 
171800d92c66SSrisivasubramanian S 	buf_p = &params->meta_buf;
171900d92c66SSrisivasubramanian S 	m_vaddr = buf_p->vaddr;
172000d92c66SSrisivasubramanian S 	m_dma = buf_p->dma_addr;
172100d92c66SSrisivasubramanian S 
172200d92c66SSrisivasubramanian S 	/*
172300d92c66SSrisivasubramanian S 	 * Microcode expects offsets in bytes
172400d92c66SSrisivasubramanian S 	 * TODO: Rounding off
172500d92c66SSrisivasubramanian S 	 */
172600d92c66SSrisivasubramanian S 	encr_offset = ENCR_OFFSET(d_offs) / 8;
172700d92c66SSrisivasubramanian S 	encr_data_len = ENCR_DLEN(d_lens);
172800d92c66SSrisivasubramanian S 
172900d92c66SSrisivasubramanian S 	cpt_ctx = params->ctx_buf.vaddr;
173000d92c66SSrisivasubramanian S 	flags = cpt_ctx->zsk_flags;
173100d92c66SSrisivasubramanian S 	snow3g = cpt_ctx->snow3g;
173200d92c66SSrisivasubramanian S 	/*
173300d92c66SSrisivasubramanian S 	 * Save initial space that followed app data for completion code &
173400d92c66SSrisivasubramanian S 	 * alternate completion code to fall in same cache line as app data
173500d92c66SSrisivasubramanian S 	 */
173600d92c66SSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE;
173700d92c66SSrisivasubramanian S 	m_dma += COMPLETION_CODE_SIZE;
173800d92c66SSrisivasubramanian S 	size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) -
173900d92c66SSrisivasubramanian S 		(uint8_t *)m_vaddr;
174000d92c66SSrisivasubramanian S 
174100d92c66SSrisivasubramanian S 	c_vaddr = (uint8_t *)m_vaddr + size;
174200d92c66SSrisivasubramanian S 	c_dma = m_dma + size;
174300d92c66SSrisivasubramanian S 	size += sizeof(cpt_res_s_t);
174400d92c66SSrisivasubramanian S 
174500d92c66SSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
174600d92c66SSrisivasubramanian S 	m_dma += size;
174700d92c66SSrisivasubramanian S 
174800d92c66SSrisivasubramanian S 	/* Reserve memory for cpt request info */
174900d92c66SSrisivasubramanian S 	req = m_vaddr;
175000d92c66SSrisivasubramanian S 
175100d92c66SSrisivasubramanian S 	size = sizeof(struct cpt_request_info);
175200d92c66SSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
175300d92c66SSrisivasubramanian S 	m_dma += size;
175400d92c66SSrisivasubramanian S 
175500d92c66SSrisivasubramanian S 	opcode.s.major = CPT_MAJOR_OP_ZUC_SNOW3G;
175600d92c66SSrisivasubramanian S 
175700d92c66SSrisivasubramanian S 	/* indicates CPTR ctx, operation type, KEY & IV mode from DPTR */
1758131966f8SAnkur Dwivedi 
1759131966f8SAnkur Dwivedi 	opcode.s.minor = ((1 << 7) | (snow3g << 5) | (0 << 4) |
176000d92c66SSrisivasubramanian S 			  (0 << 3) | (flags & 0x7));
176100d92c66SSrisivasubramanian S 
176200d92c66SSrisivasubramanian S 	/* consider iv len */
176300d92c66SSrisivasubramanian S 	encr_offset += iv_len;
176400d92c66SSrisivasubramanian S 
176500d92c66SSrisivasubramanian S 	inputlen = encr_offset +
176600d92c66SSrisivasubramanian S 		(RTE_ALIGN(encr_data_len, 8) / 8);
176700d92c66SSrisivasubramanian S 	outputlen = inputlen;
176800d92c66SSrisivasubramanian S 
176900d92c66SSrisivasubramanian S 	/* IV */
177000d92c66SSrisivasubramanian S 	iv_s = params->iv_buf;
177100d92c66SSrisivasubramanian S 	if (snow3g) {
177200d92c66SSrisivasubramanian S 		/*
177300d92c66SSrisivasubramanian S 		 * DPDK seems to provide it in form of IV3 IV2 IV1 IV0
177400d92c66SSrisivasubramanian S 		 * and BigEndian, MC needs it as IV0 IV1 IV2 IV3
177500d92c66SSrisivasubramanian S 		 */
177600d92c66SSrisivasubramanian S 
177700d92c66SSrisivasubramanian S 		for (j = 0; j < 4; j++)
177800d92c66SSrisivasubramanian S 			iv[j] = iv_s[3 - j];
177900d92c66SSrisivasubramanian S 	} else {
178000d92c66SSrisivasubramanian S 		/* ZUC doesn't need a swap */
178100d92c66SSrisivasubramanian S 		for (j = 0; j < 4; j++)
178200d92c66SSrisivasubramanian S 			iv[j] = iv_s[j];
178300d92c66SSrisivasubramanian S 	}
178400d92c66SSrisivasubramanian S 
178500d92c66SSrisivasubramanian S 	/*
178600d92c66SSrisivasubramanian S 	 * GP op header, lengths are expected in bits.
178700d92c66SSrisivasubramanian S 	 */
178800d92c66SSrisivasubramanian S 	vq_cmd_w0.u64 = 0;
1789426af86bSAnoob Joseph 	vq_cmd_w0.s.param1 = encr_data_len;
179000d92c66SSrisivasubramanian S 
179100d92c66SSrisivasubramanian S 	/*
179200d92c66SSrisivasubramanian S 	 * In 83XX since we have a limitation of
179300d92c66SSrisivasubramanian S 	 * IV & Offset control word not part of instruction
179400d92c66SSrisivasubramanian S 	 * and need to be part of Data Buffer, we check if
179500d92c66SSrisivasubramanian S 	 * head room is there and then only do the Direct mode processing
179600d92c66SSrisivasubramanian S 	 */
179700d92c66SSrisivasubramanian S 	if (likely((req_flags & SINGLE_BUF_INPLACE) &&
179800d92c66SSrisivasubramanian S 		   (req_flags & SINGLE_BUF_HEADTAILROOM))) {
179900d92c66SSrisivasubramanian S 		void *dm_vaddr = params->bufs[0].vaddr;
180000d92c66SSrisivasubramanian S 		uint64_t dm_dma_addr = params->bufs[0].dma_addr;
180100d92c66SSrisivasubramanian S 		/*
180200d92c66SSrisivasubramanian S 		 * This flag indicates that there is 24 bytes head room and
180300d92c66SSrisivasubramanian S 		 * 8 bytes tail room available, so that we get to do
180400d92c66SSrisivasubramanian S 		 * DIRECT MODE with limitation
180500d92c66SSrisivasubramanian S 		 */
180600d92c66SSrisivasubramanian S 
180700d92c66SSrisivasubramanian S 		offset_vaddr = (uint64_t *)((uint8_t *)dm_vaddr -
180800d92c66SSrisivasubramanian S 					    OFF_CTRL_LEN - iv_len);
180900d92c66SSrisivasubramanian S 		offset_dma = dm_dma_addr - OFF_CTRL_LEN - iv_len;
181000d92c66SSrisivasubramanian S 
181100d92c66SSrisivasubramanian S 		/* DPTR */
181200d92c66SSrisivasubramanian S 		req->ist.ei1 = offset_dma;
181300d92c66SSrisivasubramanian S 		/* RPTR should just exclude offset control word */
181400d92c66SSrisivasubramanian S 		req->ist.ei2 = dm_dma_addr - iv_len;
181500d92c66SSrisivasubramanian S 		req->alternate_caddr = (uint64_t *)((uint8_t *)dm_vaddr
181600d92c66SSrisivasubramanian S 						    + outputlen - iv_len);
181700d92c66SSrisivasubramanian S 
1818426af86bSAnoob Joseph 		vq_cmd_w0.s.dlen = inputlen + OFF_CTRL_LEN;
181900d92c66SSrisivasubramanian S 
1820426af86bSAnoob Joseph 		vq_cmd_w0.s.opcode = opcode.flags;
182100d92c66SSrisivasubramanian S 
182200d92c66SSrisivasubramanian S 		if (likely(iv_len)) {
182300d92c66SSrisivasubramanian S 			uint32_t *iv_d = (uint32_t *)((uint8_t *)offset_vaddr
182400d92c66SSrisivasubramanian S 						      + OFF_CTRL_LEN);
182500d92c66SSrisivasubramanian S 			memcpy(iv_d, iv, 16);
182600d92c66SSrisivasubramanian S 		}
182700d92c66SSrisivasubramanian S 
182800d92c66SSrisivasubramanian S 		/* iv offset is 0 */
182900d92c66SSrisivasubramanian S 		*offset_vaddr = rte_cpu_to_be_64((uint64_t)encr_offset << 16);
183000d92c66SSrisivasubramanian S 	} else {
183100d92c66SSrisivasubramanian S 		uint32_t i, g_size_bytes, s_size_bytes;
183200d92c66SSrisivasubramanian S 		uint64_t dptr_dma, rptr_dma;
183300d92c66SSrisivasubramanian S 		sg_comp_t *gather_comp;
183400d92c66SSrisivasubramanian S 		sg_comp_t *scatter_comp;
183500d92c66SSrisivasubramanian S 		uint8_t *in_buffer;
183600d92c66SSrisivasubramanian S 		uint32_t *iv_d;
183700d92c66SSrisivasubramanian S 
183800d92c66SSrisivasubramanian S 		/* save space for offset and iv... */
183900d92c66SSrisivasubramanian S 		offset_vaddr = m_vaddr;
184000d92c66SSrisivasubramanian S 		offset_dma = m_dma;
184100d92c66SSrisivasubramanian S 
184200d92c66SSrisivasubramanian S 		m_vaddr = (uint8_t *)m_vaddr + OFF_CTRL_LEN + iv_len;
184300d92c66SSrisivasubramanian S 		m_dma += OFF_CTRL_LEN + iv_len;
184400d92c66SSrisivasubramanian S 
184500d92c66SSrisivasubramanian S 		opcode.s.major |= CPT_DMA_MODE;
184600d92c66SSrisivasubramanian S 
1847426af86bSAnoob Joseph 		vq_cmd_w0.s.opcode = opcode.flags;
184800d92c66SSrisivasubramanian S 
184900d92c66SSrisivasubramanian S 		/* DPTR has SG list */
185000d92c66SSrisivasubramanian S 		in_buffer = m_vaddr;
185100d92c66SSrisivasubramanian S 		dptr_dma = m_dma;
185200d92c66SSrisivasubramanian S 
185300d92c66SSrisivasubramanian S 		((uint16_t *)in_buffer)[0] = 0;
185400d92c66SSrisivasubramanian S 		((uint16_t *)in_buffer)[1] = 0;
185500d92c66SSrisivasubramanian S 
185600d92c66SSrisivasubramanian S 		/* TODO Add error check if space will be sufficient */
185700d92c66SSrisivasubramanian S 		gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8);
185800d92c66SSrisivasubramanian S 
185900d92c66SSrisivasubramanian S 		/*
186000d92c66SSrisivasubramanian S 		 * Input Gather List
186100d92c66SSrisivasubramanian S 		 */
186200d92c66SSrisivasubramanian S 		i = 0;
186300d92c66SSrisivasubramanian S 
186400d92c66SSrisivasubramanian S 		/* Offset control word */
186500d92c66SSrisivasubramanian S 
186600d92c66SSrisivasubramanian S 		/* iv offset is 0 */
186700d92c66SSrisivasubramanian S 		*offset_vaddr = rte_cpu_to_be_64((uint64_t)encr_offset << 16);
186800d92c66SSrisivasubramanian S 
186900d92c66SSrisivasubramanian S 		i = fill_sg_comp(gather_comp, i, offset_dma,
187000d92c66SSrisivasubramanian S 				 OFF_CTRL_LEN + iv_len);
187100d92c66SSrisivasubramanian S 
187200d92c66SSrisivasubramanian S 		iv_d = (uint32_t *)((uint8_t *)offset_vaddr + OFF_CTRL_LEN);
187300d92c66SSrisivasubramanian S 		memcpy(iv_d, iv, 16);
187400d92c66SSrisivasubramanian S 
187500d92c66SSrisivasubramanian S 		/* Add input data */
187600d92c66SSrisivasubramanian S 		size = inputlen - iv_len;
187700d92c66SSrisivasubramanian S 		if (size) {
187800d92c66SSrisivasubramanian S 			i = fill_sg_comp_from_iov(gather_comp, i,
187900d92c66SSrisivasubramanian S 						  params->src_iov,
188000d92c66SSrisivasubramanian S 						  0, &size, NULL, 0);
1881f39928e6SAnoob Joseph 			if (unlikely(size)) {
1882f39928e6SAnoob Joseph 				CPT_LOG_DP_ERR("Insufficient buffer space,"
1883f39928e6SAnoob Joseph 					       " size %d needed", size);
1884f39928e6SAnoob Joseph 				return;
1885f39928e6SAnoob Joseph 			}
188600d92c66SSrisivasubramanian S 		}
188700d92c66SSrisivasubramanian S 		((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i);
188800d92c66SSrisivasubramanian S 		g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
188900d92c66SSrisivasubramanian S 
189000d92c66SSrisivasubramanian S 		/*
189100d92c66SSrisivasubramanian S 		 * Output Scatter List
189200d92c66SSrisivasubramanian S 		 */
189300d92c66SSrisivasubramanian S 
189400d92c66SSrisivasubramanian S 		i = 0;
189500d92c66SSrisivasubramanian S 		scatter_comp =
189600d92c66SSrisivasubramanian S 			(sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes);
189700d92c66SSrisivasubramanian S 
189800d92c66SSrisivasubramanian S 		/* IV */
189900d92c66SSrisivasubramanian S 		i = fill_sg_comp(scatter_comp, i,
190000d92c66SSrisivasubramanian S 				 offset_dma + OFF_CTRL_LEN,
190100d92c66SSrisivasubramanian S 				 iv_len);
190200d92c66SSrisivasubramanian S 
190300d92c66SSrisivasubramanian S 		/* Add output data */
190400d92c66SSrisivasubramanian S 		size = outputlen - iv_len;
190500d92c66SSrisivasubramanian S 		if (size) {
190600d92c66SSrisivasubramanian S 			i = fill_sg_comp_from_iov(scatter_comp, i,
190700d92c66SSrisivasubramanian S 						  params->dst_iov, 0,
190800d92c66SSrisivasubramanian S 						  &size, NULL, 0);
190900d92c66SSrisivasubramanian S 
1910f39928e6SAnoob Joseph 			if (unlikely(size)) {
1911f39928e6SAnoob Joseph 				CPT_LOG_DP_ERR("Insufficient buffer space,"
1912f39928e6SAnoob Joseph 					       " size %d needed", size);
1913f39928e6SAnoob Joseph 				return;
1914f39928e6SAnoob Joseph 			}
191500d92c66SSrisivasubramanian S 		}
191600d92c66SSrisivasubramanian S 		((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i);
191700d92c66SSrisivasubramanian S 		s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
191800d92c66SSrisivasubramanian S 
191900d92c66SSrisivasubramanian S 		size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE;
192000d92c66SSrisivasubramanian S 
192100d92c66SSrisivasubramanian S 		/* This is DPTR len incase of SG mode */
1922426af86bSAnoob Joseph 		vq_cmd_w0.s.dlen = size;
192300d92c66SSrisivasubramanian S 
192400d92c66SSrisivasubramanian S 		m_vaddr = (uint8_t *)m_vaddr + size;
192500d92c66SSrisivasubramanian S 		m_dma += size;
192600d92c66SSrisivasubramanian S 
192700d92c66SSrisivasubramanian S 		/* cpt alternate completion address saved earlier */
192800d92c66SSrisivasubramanian S 		req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8);
192900d92c66SSrisivasubramanian S 		*req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT);
193000d92c66SSrisivasubramanian S 		rptr_dma = c_dma - 8;
193100d92c66SSrisivasubramanian S 
193200d92c66SSrisivasubramanian S 		req->ist.ei1 = dptr_dma;
193300d92c66SSrisivasubramanian S 		req->ist.ei2 = rptr_dma;
193400d92c66SSrisivasubramanian S 	}
193500d92c66SSrisivasubramanian S 
193600d92c66SSrisivasubramanian S 	/* vq command w3 */
193700d92c66SSrisivasubramanian S 	vq_cmd_w3.u64 = 0;
193800d92c66SSrisivasubramanian S 	vq_cmd_w3.s.grp = 0;
193900d92c66SSrisivasubramanian S 	vq_cmd_w3.s.cptr = params->ctx_buf.dma_addr +
194000d92c66SSrisivasubramanian S 		offsetof(struct cpt_ctx, zs_ctx);
194100d92c66SSrisivasubramanian S 
194200d92c66SSrisivasubramanian S 	/* 16 byte aligned cpt res address */
194300d92c66SSrisivasubramanian S 	req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr);
194400d92c66SSrisivasubramanian S 	*req->completion_addr = COMPLETION_CODE_INIT;
194500d92c66SSrisivasubramanian S 	req->comp_baddr  = c_dma;
194600d92c66SSrisivasubramanian S 
194700d92c66SSrisivasubramanian S 	/* Fill microcode part of instruction */
194800d92c66SSrisivasubramanian S 	req->ist.ei0 = vq_cmd_w0.u64;
194900d92c66SSrisivasubramanian S 	req->ist.ei3 = vq_cmd_w3.u64;
195000d92c66SSrisivasubramanian S 
195100d92c66SSrisivasubramanian S 	req->op = op;
195200d92c66SSrisivasubramanian S 
195300d92c66SSrisivasubramanian S 	*prep_req = req;
1954f39928e6SAnoob Joseph 	return;
195500d92c66SSrisivasubramanian S }
195600d92c66SSrisivasubramanian S 
1957f39928e6SAnoob Joseph static __rte_always_inline void
1958da39e3ecSSrisivasubramanian S cpt_kasumi_enc_prep(uint32_t req_flags,
1959da39e3ecSSrisivasubramanian S 		    uint64_t d_offs,
1960da39e3ecSSrisivasubramanian S 		    uint64_t d_lens,
1961da39e3ecSSrisivasubramanian S 		    fc_params_t *params,
1962da39e3ecSSrisivasubramanian S 		    void *op,
1963da39e3ecSSrisivasubramanian S 		    void **prep_req)
1964da39e3ecSSrisivasubramanian S {
1965da39e3ecSSrisivasubramanian S 	uint32_t size;
1966da39e3ecSSrisivasubramanian S 	int32_t inputlen = 0, outputlen = 0;
1967da39e3ecSSrisivasubramanian S 	struct cpt_ctx *cpt_ctx;
1968da39e3ecSSrisivasubramanian S 	uint32_t mac_len = 0;
1969da39e3ecSSrisivasubramanian S 	uint8_t i = 0;
1970da39e3ecSSrisivasubramanian S 	struct cpt_request_info *req;
1971da39e3ecSSrisivasubramanian S 	buf_ptr_t *buf_p;
1972da39e3ecSSrisivasubramanian S 	uint32_t encr_offset, auth_offset;
1973da39e3ecSSrisivasubramanian S 	uint32_t encr_data_len, auth_data_len;
19748de5ede7SAnoob Joseph 	int flags;
1975da39e3ecSSrisivasubramanian S 	uint8_t *iv_s, *iv_d, iv_len = 8;
1976da39e3ecSSrisivasubramanian S 	uint8_t dir = 0;
1977da39e3ecSSrisivasubramanian S 	void *m_vaddr, *c_vaddr;
1978da39e3ecSSrisivasubramanian S 	uint64_t m_dma, c_dma;
1979da39e3ecSSrisivasubramanian S 	uint64_t *offset_vaddr, offset_dma;
1980da39e3ecSSrisivasubramanian S 	vq_cmd_word0_t vq_cmd_w0;
1981da39e3ecSSrisivasubramanian S 	vq_cmd_word3_t vq_cmd_w3;
1982da39e3ecSSrisivasubramanian S 	opcode_info_t opcode;
1983da39e3ecSSrisivasubramanian S 	uint8_t *in_buffer;
1984da39e3ecSSrisivasubramanian S 	uint32_t g_size_bytes, s_size_bytes;
1985da39e3ecSSrisivasubramanian S 	uint64_t dptr_dma, rptr_dma;
1986da39e3ecSSrisivasubramanian S 	sg_comp_t *gather_comp;
1987da39e3ecSSrisivasubramanian S 	sg_comp_t *scatter_comp;
1988da39e3ecSSrisivasubramanian S 
1989da39e3ecSSrisivasubramanian S 	buf_p = &params->meta_buf;
1990da39e3ecSSrisivasubramanian S 	m_vaddr = buf_p->vaddr;
1991da39e3ecSSrisivasubramanian S 	m_dma = buf_p->dma_addr;
1992da39e3ecSSrisivasubramanian S 
1993da39e3ecSSrisivasubramanian S 	encr_offset = ENCR_OFFSET(d_offs) / 8;
1994da39e3ecSSrisivasubramanian S 	auth_offset = AUTH_OFFSET(d_offs) / 8;
1995da39e3ecSSrisivasubramanian S 	encr_data_len = ENCR_DLEN(d_lens);
1996da39e3ecSSrisivasubramanian S 	auth_data_len = AUTH_DLEN(d_lens);
1997da39e3ecSSrisivasubramanian S 
1998da39e3ecSSrisivasubramanian S 	cpt_ctx = params->ctx_buf.vaddr;
1999da39e3ecSSrisivasubramanian S 	flags = cpt_ctx->zsk_flags;
2000da39e3ecSSrisivasubramanian S 	mac_len = cpt_ctx->mac_len;
2001da39e3ecSSrisivasubramanian S 
2002da39e3ecSSrisivasubramanian S 	if (flags == 0x0)
2003da39e3ecSSrisivasubramanian S 		iv_s = params->iv_buf;
2004da39e3ecSSrisivasubramanian S 	else
2005da39e3ecSSrisivasubramanian S 		iv_s = params->auth_iv_buf;
2006da39e3ecSSrisivasubramanian S 
2007da39e3ecSSrisivasubramanian S 	dir = iv_s[8] & 0x1;
2008da39e3ecSSrisivasubramanian S 
2009da39e3ecSSrisivasubramanian S 	/*
2010da39e3ecSSrisivasubramanian S 	 * Save initial space that followed app data for completion code &
2011da39e3ecSSrisivasubramanian S 	 * alternate completion code to fall in same cache line as app data
2012da39e3ecSSrisivasubramanian S 	 */
2013da39e3ecSSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE;
2014da39e3ecSSrisivasubramanian S 	m_dma += COMPLETION_CODE_SIZE;
2015da39e3ecSSrisivasubramanian S 	size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) -
2016da39e3ecSSrisivasubramanian S 		(uint8_t *)m_vaddr;
2017da39e3ecSSrisivasubramanian S 
2018da39e3ecSSrisivasubramanian S 	c_vaddr = (uint8_t *)m_vaddr + size;
2019da39e3ecSSrisivasubramanian S 	c_dma = m_dma + size;
2020da39e3ecSSrisivasubramanian S 	size += sizeof(cpt_res_s_t);
2021da39e3ecSSrisivasubramanian S 
2022da39e3ecSSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
2023da39e3ecSSrisivasubramanian S 	m_dma += size;
2024da39e3ecSSrisivasubramanian S 
2025da39e3ecSSrisivasubramanian S 	/* Reserve memory for cpt request info */
2026da39e3ecSSrisivasubramanian S 	req = m_vaddr;
2027da39e3ecSSrisivasubramanian S 
2028da39e3ecSSrisivasubramanian S 	size = sizeof(struct cpt_request_info);
2029da39e3ecSSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
2030da39e3ecSSrisivasubramanian S 	m_dma += size;
2031da39e3ecSSrisivasubramanian S 
2032da39e3ecSSrisivasubramanian S 	opcode.s.major = CPT_MAJOR_OP_KASUMI | CPT_DMA_MODE;
2033da39e3ecSSrisivasubramanian S 
2034da39e3ecSSrisivasubramanian S 	/* indicates ECB/CBC, direction, ctx from cptr, iv from dptr */
2035da39e3ecSSrisivasubramanian S 	opcode.s.minor = ((1 << 6) | (cpt_ctx->k_ecb << 5) |
2036da39e3ecSSrisivasubramanian S 			  (dir << 4) | (0 << 3) | (flags & 0x7));
2037da39e3ecSSrisivasubramanian S 
2038da39e3ecSSrisivasubramanian S 	/*
2039da39e3ecSSrisivasubramanian S 	 * GP op header, lengths are expected in bits.
2040da39e3ecSSrisivasubramanian S 	 */
2041da39e3ecSSrisivasubramanian S 	vq_cmd_w0.u64 = 0;
2042426af86bSAnoob Joseph 	vq_cmd_w0.s.param1 = encr_data_len;
2043426af86bSAnoob Joseph 	vq_cmd_w0.s.param2 = auth_data_len;
2044426af86bSAnoob Joseph 	vq_cmd_w0.s.opcode = opcode.flags;
2045da39e3ecSSrisivasubramanian S 
2046da39e3ecSSrisivasubramanian S 	/* consider iv len */
2047da39e3ecSSrisivasubramanian S 	if (flags == 0x0) {
2048da39e3ecSSrisivasubramanian S 		encr_offset += iv_len;
2049da39e3ecSSrisivasubramanian S 		auth_offset += iv_len;
2050da39e3ecSSrisivasubramanian S 	}
2051da39e3ecSSrisivasubramanian S 
2052da39e3ecSSrisivasubramanian S 	/* save space for offset ctrl and iv */
2053da39e3ecSSrisivasubramanian S 	offset_vaddr = m_vaddr;
2054da39e3ecSSrisivasubramanian S 	offset_dma = m_dma;
2055da39e3ecSSrisivasubramanian S 
2056da39e3ecSSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + OFF_CTRL_LEN + iv_len;
2057da39e3ecSSrisivasubramanian S 	m_dma += OFF_CTRL_LEN + iv_len;
2058da39e3ecSSrisivasubramanian S 
2059da39e3ecSSrisivasubramanian S 	/* DPTR has SG list */
2060da39e3ecSSrisivasubramanian S 	in_buffer = m_vaddr;
2061da39e3ecSSrisivasubramanian S 	dptr_dma = m_dma;
2062da39e3ecSSrisivasubramanian S 
2063da39e3ecSSrisivasubramanian S 	((uint16_t *)in_buffer)[0] = 0;
2064da39e3ecSSrisivasubramanian S 	((uint16_t *)in_buffer)[1] = 0;
2065da39e3ecSSrisivasubramanian S 
2066da39e3ecSSrisivasubramanian S 	/* TODO Add error check if space will be sufficient */
2067da39e3ecSSrisivasubramanian S 	gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8);
2068da39e3ecSSrisivasubramanian S 
2069da39e3ecSSrisivasubramanian S 	/*
2070da39e3ecSSrisivasubramanian S 	 * Input Gather List
2071da39e3ecSSrisivasubramanian S 	 */
2072da39e3ecSSrisivasubramanian S 	i = 0;
2073da39e3ecSSrisivasubramanian S 
2074da39e3ecSSrisivasubramanian S 	/* Offset control word followed by iv */
2075da39e3ecSSrisivasubramanian S 
2076da39e3ecSSrisivasubramanian S 	if (flags == 0x0) {
2077da39e3ecSSrisivasubramanian S 		inputlen = encr_offset + (RTE_ALIGN(encr_data_len, 8) / 8);
2078da39e3ecSSrisivasubramanian S 		outputlen = inputlen;
2079da39e3ecSSrisivasubramanian S 		/* iv offset is 0 */
2080da39e3ecSSrisivasubramanian S 		*offset_vaddr = rte_cpu_to_be_64((uint64_t)encr_offset << 16);
2081da39e3ecSSrisivasubramanian S 	} else {
2082da39e3ecSSrisivasubramanian S 		inputlen = auth_offset + (RTE_ALIGN(auth_data_len, 8) / 8);
2083da39e3ecSSrisivasubramanian S 		outputlen = mac_len;
2084da39e3ecSSrisivasubramanian S 		/* iv offset is 0 */
2085da39e3ecSSrisivasubramanian S 		*offset_vaddr = rte_cpu_to_be_64((uint64_t)auth_offset);
2086da39e3ecSSrisivasubramanian S 	}
2087da39e3ecSSrisivasubramanian S 
2088da39e3ecSSrisivasubramanian S 	i = fill_sg_comp(gather_comp, i, offset_dma, OFF_CTRL_LEN + iv_len);
2089da39e3ecSSrisivasubramanian S 
2090da39e3ecSSrisivasubramanian S 	/* IV */
2091da39e3ecSSrisivasubramanian S 	iv_d = (uint8_t *)offset_vaddr + OFF_CTRL_LEN;
2092da39e3ecSSrisivasubramanian S 	memcpy(iv_d, iv_s, iv_len);
2093da39e3ecSSrisivasubramanian S 
2094da39e3ecSSrisivasubramanian S 	/* input data */
2095da39e3ecSSrisivasubramanian S 	size = inputlen - iv_len;
2096da39e3ecSSrisivasubramanian S 	if (size) {
2097da39e3ecSSrisivasubramanian S 		i = fill_sg_comp_from_iov(gather_comp, i,
2098da39e3ecSSrisivasubramanian S 					  params->src_iov, 0,
2099da39e3ecSSrisivasubramanian S 					  &size, NULL, 0);
2100da39e3ecSSrisivasubramanian S 
2101f39928e6SAnoob Joseph 		if (unlikely(size)) {
2102f39928e6SAnoob Joseph 			CPT_LOG_DP_ERR("Insufficient buffer space,"
2103f39928e6SAnoob Joseph 				       " size %d needed", size);
2104f39928e6SAnoob Joseph 			return;
2105f39928e6SAnoob Joseph 		}
2106da39e3ecSSrisivasubramanian S 	}
2107da39e3ecSSrisivasubramanian S 	((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i);
2108da39e3ecSSrisivasubramanian S 	g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
2109da39e3ecSSrisivasubramanian S 
2110da39e3ecSSrisivasubramanian S 	/*
2111da39e3ecSSrisivasubramanian S 	 * Output Scatter List
2112da39e3ecSSrisivasubramanian S 	 */
2113da39e3ecSSrisivasubramanian S 
2114da39e3ecSSrisivasubramanian S 	i = 0;
2115da39e3ecSSrisivasubramanian S 	scatter_comp = (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes);
2116da39e3ecSSrisivasubramanian S 
2117da39e3ecSSrisivasubramanian S 	if (flags == 0x1) {
2118da39e3ecSSrisivasubramanian S 		/* IV in SLIST only for F8 */
2119da39e3ecSSrisivasubramanian S 		iv_len = 0;
2120da39e3ecSSrisivasubramanian S 	}
2121da39e3ecSSrisivasubramanian S 
2122da39e3ecSSrisivasubramanian S 	/* IV */
2123da39e3ecSSrisivasubramanian S 	if (iv_len) {
2124da39e3ecSSrisivasubramanian S 		i = fill_sg_comp(scatter_comp, i,
2125da39e3ecSSrisivasubramanian S 				 offset_dma + OFF_CTRL_LEN,
2126da39e3ecSSrisivasubramanian S 				 iv_len);
2127da39e3ecSSrisivasubramanian S 	}
2128da39e3ecSSrisivasubramanian S 
2129da39e3ecSSrisivasubramanian S 	/* Add output data */
2130da39e3ecSSrisivasubramanian S 	if (req_flags & VALID_MAC_BUF) {
2131da39e3ecSSrisivasubramanian S 		size = outputlen - iv_len - mac_len;
2132da39e3ecSSrisivasubramanian S 		if (size) {
2133da39e3ecSSrisivasubramanian S 			i = fill_sg_comp_from_iov(scatter_comp, i,
2134da39e3ecSSrisivasubramanian S 						  params->dst_iov, 0,
2135da39e3ecSSrisivasubramanian S 						  &size, NULL, 0);
2136da39e3ecSSrisivasubramanian S 
2137f39928e6SAnoob Joseph 			if (unlikely(size)) {
2138f39928e6SAnoob Joseph 				CPT_LOG_DP_ERR("Insufficient buffer space,"
2139f39928e6SAnoob Joseph 					       " size %d needed", size);
2140f39928e6SAnoob Joseph 				return;
2141f39928e6SAnoob Joseph 			}
2142da39e3ecSSrisivasubramanian S 		}
2143da39e3ecSSrisivasubramanian S 
2144da39e3ecSSrisivasubramanian S 		/* mac data */
2145da39e3ecSSrisivasubramanian S 		if (mac_len) {
2146da39e3ecSSrisivasubramanian S 			i = fill_sg_comp_from_buf(scatter_comp, i,
2147da39e3ecSSrisivasubramanian S 						  &params->mac_buf);
2148da39e3ecSSrisivasubramanian S 		}
2149da39e3ecSSrisivasubramanian S 	} else {
2150da39e3ecSSrisivasubramanian S 		/* Output including mac */
2151da39e3ecSSrisivasubramanian S 		size = outputlen - iv_len;
2152da39e3ecSSrisivasubramanian S 		if (size) {
2153da39e3ecSSrisivasubramanian S 			i = fill_sg_comp_from_iov(scatter_comp, i,
2154da39e3ecSSrisivasubramanian S 						  params->dst_iov, 0,
2155da39e3ecSSrisivasubramanian S 						  &size, NULL, 0);
2156da39e3ecSSrisivasubramanian S 
2157f39928e6SAnoob Joseph 			if (unlikely(size)) {
2158f39928e6SAnoob Joseph 				CPT_LOG_DP_ERR("Insufficient buffer space,"
2159f39928e6SAnoob Joseph 					       " size %d needed", size);
2160f39928e6SAnoob Joseph 				return;
2161f39928e6SAnoob Joseph 			}
2162da39e3ecSSrisivasubramanian S 		}
2163da39e3ecSSrisivasubramanian S 	}
2164da39e3ecSSrisivasubramanian S 	((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i);
2165da39e3ecSSrisivasubramanian S 	s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
2166da39e3ecSSrisivasubramanian S 
2167da39e3ecSSrisivasubramanian S 	size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE;
2168da39e3ecSSrisivasubramanian S 
2169da39e3ecSSrisivasubramanian S 	/* This is DPTR len incase of SG mode */
2170426af86bSAnoob Joseph 	vq_cmd_w0.s.dlen = size;
2171da39e3ecSSrisivasubramanian S 
2172da39e3ecSSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
2173da39e3ecSSrisivasubramanian S 	m_dma += size;
2174da39e3ecSSrisivasubramanian S 
2175da39e3ecSSrisivasubramanian S 	/* cpt alternate completion address saved earlier */
2176da39e3ecSSrisivasubramanian S 	req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8);
2177da39e3ecSSrisivasubramanian S 	*req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT);
2178da39e3ecSSrisivasubramanian S 	rptr_dma = c_dma - 8;
2179da39e3ecSSrisivasubramanian S 
2180da39e3ecSSrisivasubramanian S 	req->ist.ei1 = dptr_dma;
2181da39e3ecSSrisivasubramanian S 	req->ist.ei2 = rptr_dma;
2182da39e3ecSSrisivasubramanian S 
2183da39e3ecSSrisivasubramanian S 	/* vq command w3 */
2184da39e3ecSSrisivasubramanian S 	vq_cmd_w3.u64 = 0;
2185da39e3ecSSrisivasubramanian S 	vq_cmd_w3.s.grp = 0;
2186da39e3ecSSrisivasubramanian S 	vq_cmd_w3.s.cptr = params->ctx_buf.dma_addr +
2187da39e3ecSSrisivasubramanian S 		offsetof(struct cpt_ctx, k_ctx);
2188da39e3ecSSrisivasubramanian S 
2189da39e3ecSSrisivasubramanian S 	/* 16 byte aligned cpt res address */
2190da39e3ecSSrisivasubramanian S 	req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr);
2191da39e3ecSSrisivasubramanian S 	*req->completion_addr = COMPLETION_CODE_INIT;
2192da39e3ecSSrisivasubramanian S 	req->comp_baddr  = c_dma;
2193da39e3ecSSrisivasubramanian S 
2194da39e3ecSSrisivasubramanian S 	/* Fill microcode part of instruction */
2195da39e3ecSSrisivasubramanian S 	req->ist.ei0 = vq_cmd_w0.u64;
2196da39e3ecSSrisivasubramanian S 	req->ist.ei3 = vq_cmd_w3.u64;
2197da39e3ecSSrisivasubramanian S 
2198da39e3ecSSrisivasubramanian S 	req->op = op;
2199da39e3ecSSrisivasubramanian S 
2200da39e3ecSSrisivasubramanian S 	*prep_req = req;
2201f39928e6SAnoob Joseph 	return;
2202da39e3ecSSrisivasubramanian S }
2203da39e3ecSSrisivasubramanian S 
2204f39928e6SAnoob Joseph static __rte_always_inline void
2205da39e3ecSSrisivasubramanian S cpt_kasumi_dec_prep(uint64_t d_offs,
2206da39e3ecSSrisivasubramanian S 		    uint64_t d_lens,
2207da39e3ecSSrisivasubramanian S 		    fc_params_t *params,
2208da39e3ecSSrisivasubramanian S 		    void *op,
2209da39e3ecSSrisivasubramanian S 		    void **prep_req)
2210da39e3ecSSrisivasubramanian S {
2211da39e3ecSSrisivasubramanian S 	uint32_t size;
2212da39e3ecSSrisivasubramanian S 	int32_t inputlen = 0, outputlen;
2213da39e3ecSSrisivasubramanian S 	struct cpt_ctx *cpt_ctx;
2214da39e3ecSSrisivasubramanian S 	uint8_t i = 0, iv_len = 8;
2215da39e3ecSSrisivasubramanian S 	struct cpt_request_info *req;
2216da39e3ecSSrisivasubramanian S 	buf_ptr_t *buf_p;
2217da39e3ecSSrisivasubramanian S 	uint32_t encr_offset;
2218da39e3ecSSrisivasubramanian S 	uint32_t encr_data_len;
22198de5ede7SAnoob Joseph 	int flags;
2220da39e3ecSSrisivasubramanian S 	uint8_t dir = 0;
2221da39e3ecSSrisivasubramanian S 	void *m_vaddr, *c_vaddr;
2222da39e3ecSSrisivasubramanian S 	uint64_t m_dma, c_dma;
2223da39e3ecSSrisivasubramanian S 	uint64_t *offset_vaddr, offset_dma;
2224da39e3ecSSrisivasubramanian S 	vq_cmd_word0_t vq_cmd_w0;
2225da39e3ecSSrisivasubramanian S 	vq_cmd_word3_t vq_cmd_w3;
2226da39e3ecSSrisivasubramanian S 	opcode_info_t opcode;
2227da39e3ecSSrisivasubramanian S 	uint8_t *in_buffer;
2228da39e3ecSSrisivasubramanian S 	uint32_t g_size_bytes, s_size_bytes;
2229da39e3ecSSrisivasubramanian S 	uint64_t dptr_dma, rptr_dma;
2230da39e3ecSSrisivasubramanian S 	sg_comp_t *gather_comp;
2231da39e3ecSSrisivasubramanian S 	sg_comp_t *scatter_comp;
2232da39e3ecSSrisivasubramanian S 
2233da39e3ecSSrisivasubramanian S 	buf_p = &params->meta_buf;
2234da39e3ecSSrisivasubramanian S 	m_vaddr = buf_p->vaddr;
2235da39e3ecSSrisivasubramanian S 	m_dma = buf_p->dma_addr;
2236da39e3ecSSrisivasubramanian S 
2237da39e3ecSSrisivasubramanian S 	encr_offset = ENCR_OFFSET(d_offs) / 8;
2238da39e3ecSSrisivasubramanian S 	encr_data_len = ENCR_DLEN(d_lens);
2239da39e3ecSSrisivasubramanian S 
2240da39e3ecSSrisivasubramanian S 	cpt_ctx = params->ctx_buf.vaddr;
2241da39e3ecSSrisivasubramanian S 	flags = cpt_ctx->zsk_flags;
2242da39e3ecSSrisivasubramanian S 	/*
2243da39e3ecSSrisivasubramanian S 	 * Save initial space that followed app data for completion code &
2244da39e3ecSSrisivasubramanian S 	 * alternate completion code to fall in same cache line as app data
2245da39e3ecSSrisivasubramanian S 	 */
2246da39e3ecSSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE;
2247da39e3ecSSrisivasubramanian S 	m_dma += COMPLETION_CODE_SIZE;
2248da39e3ecSSrisivasubramanian S 	size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) -
2249da39e3ecSSrisivasubramanian S 		(uint8_t *)m_vaddr;
2250da39e3ecSSrisivasubramanian S 
2251da39e3ecSSrisivasubramanian S 	c_vaddr = (uint8_t *)m_vaddr + size;
2252da39e3ecSSrisivasubramanian S 	c_dma = m_dma + size;
2253da39e3ecSSrisivasubramanian S 	size += sizeof(cpt_res_s_t);
2254da39e3ecSSrisivasubramanian S 
2255da39e3ecSSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
2256da39e3ecSSrisivasubramanian S 	m_dma += size;
2257da39e3ecSSrisivasubramanian S 
2258da39e3ecSSrisivasubramanian S 	/* Reserve memory for cpt request info */
2259da39e3ecSSrisivasubramanian S 	req = m_vaddr;
2260da39e3ecSSrisivasubramanian S 
2261da39e3ecSSrisivasubramanian S 	size = sizeof(struct cpt_request_info);
2262da39e3ecSSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
2263da39e3ecSSrisivasubramanian S 	m_dma += size;
2264da39e3ecSSrisivasubramanian S 
2265da39e3ecSSrisivasubramanian S 	opcode.s.major = CPT_MAJOR_OP_KASUMI | CPT_DMA_MODE;
2266da39e3ecSSrisivasubramanian S 
2267da39e3ecSSrisivasubramanian S 	/* indicates ECB/CBC, direction, ctx from cptr, iv from dptr */
2268da39e3ecSSrisivasubramanian S 	opcode.s.minor = ((1 << 6) | (cpt_ctx->k_ecb << 5) |
2269da39e3ecSSrisivasubramanian S 			  (dir << 4) | (0 << 3) | (flags & 0x7));
2270da39e3ecSSrisivasubramanian S 
2271da39e3ecSSrisivasubramanian S 	/*
2272da39e3ecSSrisivasubramanian S 	 * GP op header, lengths are expected in bits.
2273da39e3ecSSrisivasubramanian S 	 */
2274da39e3ecSSrisivasubramanian S 	vq_cmd_w0.u64 = 0;
2275426af86bSAnoob Joseph 	vq_cmd_w0.s.param1 = encr_data_len;
2276426af86bSAnoob Joseph 	vq_cmd_w0.s.opcode = opcode.flags;
2277da39e3ecSSrisivasubramanian S 
2278da39e3ecSSrisivasubramanian S 	/* consider iv len */
2279da39e3ecSSrisivasubramanian S 	encr_offset += iv_len;
2280da39e3ecSSrisivasubramanian S 
2281da39e3ecSSrisivasubramanian S 	inputlen = iv_len + (RTE_ALIGN(encr_data_len, 8) / 8);
2282da39e3ecSSrisivasubramanian S 	outputlen = inputlen;
2283da39e3ecSSrisivasubramanian S 
2284da39e3ecSSrisivasubramanian S 	/* save space for offset ctrl & iv */
2285da39e3ecSSrisivasubramanian S 	offset_vaddr = m_vaddr;
2286da39e3ecSSrisivasubramanian S 	offset_dma = m_dma;
2287da39e3ecSSrisivasubramanian S 
2288da39e3ecSSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + OFF_CTRL_LEN + iv_len;
2289da39e3ecSSrisivasubramanian S 	m_dma += OFF_CTRL_LEN + iv_len;
2290da39e3ecSSrisivasubramanian S 
2291da39e3ecSSrisivasubramanian S 	/* DPTR has SG list */
2292da39e3ecSSrisivasubramanian S 	in_buffer = m_vaddr;
2293da39e3ecSSrisivasubramanian S 	dptr_dma = m_dma;
2294da39e3ecSSrisivasubramanian S 
2295da39e3ecSSrisivasubramanian S 	((uint16_t *)in_buffer)[0] = 0;
2296da39e3ecSSrisivasubramanian S 	((uint16_t *)in_buffer)[1] = 0;
2297da39e3ecSSrisivasubramanian S 
2298da39e3ecSSrisivasubramanian S 	/* TODO Add error check if space will be sufficient */
2299da39e3ecSSrisivasubramanian S 	gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8);
2300da39e3ecSSrisivasubramanian S 
2301da39e3ecSSrisivasubramanian S 	/*
2302da39e3ecSSrisivasubramanian S 	 * Input Gather List
2303da39e3ecSSrisivasubramanian S 	 */
2304da39e3ecSSrisivasubramanian S 	i = 0;
2305da39e3ecSSrisivasubramanian S 
2306da39e3ecSSrisivasubramanian S 	/* Offset control word followed by iv */
2307da39e3ecSSrisivasubramanian S 	*offset_vaddr = rte_cpu_to_be_64((uint64_t)encr_offset << 16);
2308da39e3ecSSrisivasubramanian S 
2309da39e3ecSSrisivasubramanian S 	i = fill_sg_comp(gather_comp, i, offset_dma, OFF_CTRL_LEN + iv_len);
2310da39e3ecSSrisivasubramanian S 
2311da39e3ecSSrisivasubramanian S 	/* IV */
2312da39e3ecSSrisivasubramanian S 	memcpy((uint8_t *)offset_vaddr + OFF_CTRL_LEN,
2313da39e3ecSSrisivasubramanian S 	       params->iv_buf, iv_len);
2314da39e3ecSSrisivasubramanian S 
2315da39e3ecSSrisivasubramanian S 	/* Add input data */
2316da39e3ecSSrisivasubramanian S 	size = inputlen - iv_len;
2317da39e3ecSSrisivasubramanian S 	if (size) {
2318da39e3ecSSrisivasubramanian S 		i = fill_sg_comp_from_iov(gather_comp, i,
2319da39e3ecSSrisivasubramanian S 					  params->src_iov,
2320da39e3ecSSrisivasubramanian S 					  0, &size, NULL, 0);
2321f39928e6SAnoob Joseph 		if (unlikely(size)) {
2322f39928e6SAnoob Joseph 			CPT_LOG_DP_ERR("Insufficient buffer space,"
2323f39928e6SAnoob Joseph 				       " size %d needed", size);
2324f39928e6SAnoob Joseph 			return;
2325f39928e6SAnoob Joseph 		}
2326da39e3ecSSrisivasubramanian S 	}
2327da39e3ecSSrisivasubramanian S 	((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i);
2328da39e3ecSSrisivasubramanian S 	g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
2329da39e3ecSSrisivasubramanian S 
2330da39e3ecSSrisivasubramanian S 	/*
2331da39e3ecSSrisivasubramanian S 	 * Output Scatter List
2332da39e3ecSSrisivasubramanian S 	 */
2333da39e3ecSSrisivasubramanian S 
2334da39e3ecSSrisivasubramanian S 	i = 0;
2335da39e3ecSSrisivasubramanian S 	scatter_comp = (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes);
2336da39e3ecSSrisivasubramanian S 
2337da39e3ecSSrisivasubramanian S 	/* IV */
2338da39e3ecSSrisivasubramanian S 	i = fill_sg_comp(scatter_comp, i,
2339da39e3ecSSrisivasubramanian S 			 offset_dma + OFF_CTRL_LEN,
2340da39e3ecSSrisivasubramanian S 			 iv_len);
2341da39e3ecSSrisivasubramanian S 
2342da39e3ecSSrisivasubramanian S 	/* Add output data */
2343da39e3ecSSrisivasubramanian S 	size = outputlen - iv_len;
2344da39e3ecSSrisivasubramanian S 	if (size) {
2345da39e3ecSSrisivasubramanian S 		i = fill_sg_comp_from_iov(scatter_comp, i,
2346da39e3ecSSrisivasubramanian S 					  params->dst_iov, 0,
2347da39e3ecSSrisivasubramanian S 					  &size, NULL, 0);
2348f39928e6SAnoob Joseph 		if (unlikely(size)) {
2349f39928e6SAnoob Joseph 			CPT_LOG_DP_ERR("Insufficient buffer space,"
2350f39928e6SAnoob Joseph 				       " size %d needed", size);
2351f39928e6SAnoob Joseph 			return;
2352f39928e6SAnoob Joseph 		}
2353da39e3ecSSrisivasubramanian S 	}
2354da39e3ecSSrisivasubramanian S 	((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i);
2355da39e3ecSSrisivasubramanian S 	s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
2356da39e3ecSSrisivasubramanian S 
2357da39e3ecSSrisivasubramanian S 	size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE;
2358da39e3ecSSrisivasubramanian S 
2359da39e3ecSSrisivasubramanian S 	/* This is DPTR len incase of SG mode */
2360426af86bSAnoob Joseph 	vq_cmd_w0.s.dlen = size;
2361da39e3ecSSrisivasubramanian S 
2362da39e3ecSSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
2363da39e3ecSSrisivasubramanian S 	m_dma += size;
2364da39e3ecSSrisivasubramanian S 
2365da39e3ecSSrisivasubramanian S 	/* cpt alternate completion address saved earlier */
2366da39e3ecSSrisivasubramanian S 	req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8);
2367da39e3ecSSrisivasubramanian S 	*req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT);
2368da39e3ecSSrisivasubramanian S 	rptr_dma = c_dma - 8;
2369da39e3ecSSrisivasubramanian S 
2370da39e3ecSSrisivasubramanian S 	req->ist.ei1 = dptr_dma;
2371da39e3ecSSrisivasubramanian S 	req->ist.ei2 = rptr_dma;
2372da39e3ecSSrisivasubramanian S 
2373da39e3ecSSrisivasubramanian S 	/* vq command w3 */
2374da39e3ecSSrisivasubramanian S 	vq_cmd_w3.u64 = 0;
2375da39e3ecSSrisivasubramanian S 	vq_cmd_w3.s.grp = 0;
2376da39e3ecSSrisivasubramanian S 	vq_cmd_w3.s.cptr = params->ctx_buf.dma_addr +
2377da39e3ecSSrisivasubramanian S 		offsetof(struct cpt_ctx, k_ctx);
2378da39e3ecSSrisivasubramanian S 
2379da39e3ecSSrisivasubramanian S 	/* 16 byte aligned cpt res address */
2380da39e3ecSSrisivasubramanian S 	req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr);
2381da39e3ecSSrisivasubramanian S 	*req->completion_addr = COMPLETION_CODE_INIT;
2382da39e3ecSSrisivasubramanian S 	req->comp_baddr  = c_dma;
2383da39e3ecSSrisivasubramanian S 
2384da39e3ecSSrisivasubramanian S 	/* Fill microcode part of instruction */
2385da39e3ecSSrisivasubramanian S 	req->ist.ei0 = vq_cmd_w0.u64;
2386da39e3ecSSrisivasubramanian S 	req->ist.ei3 = vq_cmd_w3.u64;
2387da39e3ecSSrisivasubramanian S 
2388da39e3ecSSrisivasubramanian S 	req->op = op;
2389da39e3ecSSrisivasubramanian S 
2390da39e3ecSSrisivasubramanian S 	*prep_req = req;
2391f39928e6SAnoob Joseph 	return;
2392da39e3ecSSrisivasubramanian S }
2393da39e3ecSSrisivasubramanian S 
2394177b41ceSRagothaman Jayaraman static __rte_always_inline void *
2395177b41ceSRagothaman Jayaraman cpt_fc_dec_hmac_prep(uint32_t flags,
2396177b41ceSRagothaman Jayaraman 		     uint64_t d_offs,
2397177b41ceSRagothaman Jayaraman 		     uint64_t d_lens,
2398177b41ceSRagothaman Jayaraman 		     fc_params_t *fc_params,
2399f39928e6SAnoob Joseph 		     void *op)
2400177b41ceSRagothaman Jayaraman {
2401177b41ceSRagothaman Jayaraman 	struct cpt_ctx *ctx = fc_params->ctx_buf.vaddr;
2402177b41ceSRagothaman Jayaraman 	uint8_t fc_type;
2403177b41ceSRagothaman Jayaraman 	void *prep_req = NULL;
2404177b41ceSRagothaman Jayaraman 
2405177b41ceSRagothaman Jayaraman 	fc_type = ctx->fc_type;
2406177b41ceSRagothaman Jayaraman 
2407177b41ceSRagothaman Jayaraman 	if (likely(fc_type == FC_GEN)) {
2408f39928e6SAnoob Joseph 		cpt_dec_hmac_prep(flags, d_offs, d_lens, fc_params, op,
2409da39e3ecSSrisivasubramanian S 				  &prep_req);
2410f39928e6SAnoob Joseph 	} else if (fc_type == ZUC_SNOW3G) {
2411f39928e6SAnoob Joseph 		cpt_zuc_snow3g_dec_prep(flags, d_offs, d_lens, fc_params, op,
2412f39928e6SAnoob Joseph 					&prep_req);
2413f39928e6SAnoob Joseph 	} else if (fc_type == KASUMI) {
2414f39928e6SAnoob Joseph 		cpt_kasumi_dec_prep(d_offs, d_lens, fc_params, op, &prep_req);
2415f39928e6SAnoob Joseph 	}
2416f39928e6SAnoob Joseph 
2417177b41ceSRagothaman Jayaraman 	/*
2418177b41ceSRagothaman Jayaraman 	 * For AUTH_ONLY case,
2419177b41ceSRagothaman Jayaraman 	 * MC only supports digest generation and verification
2420177b41ceSRagothaman Jayaraman 	 * should be done in software by memcmp()
2421177b41ceSRagothaman Jayaraman 	 */
2422177b41ceSRagothaman Jayaraman 
2423177b41ceSRagothaman Jayaraman 	return prep_req;
2424177b41ceSRagothaman Jayaraman }
2425177b41ceSRagothaman Jayaraman 
2426e3866e73SThomas Monjalon static __rte_always_inline void *__rte_hot
2427b74652f3SRagothaman Jayaraman cpt_fc_enc_hmac_prep(uint32_t flags, uint64_t d_offs, uint64_t d_lens,
2428f39928e6SAnoob Joseph 		     fc_params_t *fc_params, void *op)
2429b74652f3SRagothaman Jayaraman {
2430b74652f3SRagothaman Jayaraman 	struct cpt_ctx *ctx = fc_params->ctx_buf.vaddr;
2431b74652f3SRagothaman Jayaraman 	uint8_t fc_type;
2432b74652f3SRagothaman Jayaraman 	void *prep_req = NULL;
2433b74652f3SRagothaman Jayaraman 
2434b74652f3SRagothaman Jayaraman 	fc_type = ctx->fc_type;
2435b74652f3SRagothaman Jayaraman 
2436b74652f3SRagothaman Jayaraman 	/* Common api for rest of the ops */
2437b74652f3SRagothaman Jayaraman 	if (likely(fc_type == FC_GEN)) {
2438f39928e6SAnoob Joseph 		cpt_enc_hmac_prep(flags, d_offs, d_lens, fc_params, op,
2439351fbee2SSrisivasubramanian S 				  &prep_req);
2440f39928e6SAnoob Joseph 	} else if (fc_type == ZUC_SNOW3G) {
2441f39928e6SAnoob Joseph 		cpt_zuc_snow3g_enc_prep(flags, d_offs, d_lens, fc_params, op,
2442f39928e6SAnoob Joseph 					&prep_req);
2443f39928e6SAnoob Joseph 	} else if (fc_type == KASUMI) {
2444f39928e6SAnoob Joseph 		cpt_kasumi_enc_prep(flags, d_offs, d_lens, fc_params, op,
2445f39928e6SAnoob Joseph 				    &prep_req);
2446f39928e6SAnoob Joseph 	} else if (fc_type == HASH_HMAC) {
2447f39928e6SAnoob Joseph 		cpt_digest_gen_prep(flags, d_lens, fc_params, op, &prep_req);
2448b74652f3SRagothaman Jayaraman 	}
2449b74652f3SRagothaman Jayaraman 
2450b74652f3SRagothaman Jayaraman 	return prep_req;
2451b74652f3SRagothaman Jayaraman }
2452b74652f3SRagothaman Jayaraman 
24536cc54096SNithin Dabilpuram static __rte_always_inline int
2454186b14d6SFan Zhang cpt_fc_auth_set_key(void *ctx, auth_type_t type, const uint8_t *key,
24556cc54096SNithin Dabilpuram 		    uint16_t key_len, uint16_t mac_len)
24566cc54096SNithin Dabilpuram {
24576cc54096SNithin Dabilpuram 	struct cpt_ctx *cpt_ctx = ctx;
24586cc54096SNithin Dabilpuram 	mc_fc_context_t *fctx = &cpt_ctx->fctx;
24596cc54096SNithin Dabilpuram 
24606cc54096SNithin Dabilpuram 	if ((type >= ZUC_EIA3) && (type <= KASUMI_F9_ECB)) {
24616cc54096SNithin Dabilpuram 		uint32_t keyx[4];
24626cc54096SNithin Dabilpuram 
24636cc54096SNithin Dabilpuram 		if (key_len != 16)
24646cc54096SNithin Dabilpuram 			return -1;
24656cc54096SNithin Dabilpuram 		/* No support for AEAD yet */
24666cc54096SNithin Dabilpuram 		if (cpt_ctx->enc_cipher)
24676cc54096SNithin Dabilpuram 			return -1;
24686cc54096SNithin Dabilpuram 		/* For ZUC/SNOW3G/Kasumi */
24696cc54096SNithin Dabilpuram 		switch (type) {
24706cc54096SNithin Dabilpuram 		case SNOW3G_UIA2:
24716cc54096SNithin Dabilpuram 			cpt_ctx->snow3g = 1;
24726cc54096SNithin Dabilpuram 			gen_key_snow3g(key, keyx);
24736cc54096SNithin Dabilpuram 			memcpy(cpt_ctx->zs_ctx.ci_key, keyx, key_len);
24746cc54096SNithin Dabilpuram 			cpt_ctx->fc_type = ZUC_SNOW3G;
24756cc54096SNithin Dabilpuram 			cpt_ctx->zsk_flags = 0x1;
24766cc54096SNithin Dabilpuram 			break;
24776cc54096SNithin Dabilpuram 		case ZUC_EIA3:
24786cc54096SNithin Dabilpuram 			cpt_ctx->snow3g = 0;
24796cc54096SNithin Dabilpuram 			memcpy(cpt_ctx->zs_ctx.ci_key, key, key_len);
24806cc54096SNithin Dabilpuram 			memcpy(cpt_ctx->zs_ctx.zuc_const, zuc_d, 32);
24816cc54096SNithin Dabilpuram 			cpt_ctx->fc_type = ZUC_SNOW3G;
24826cc54096SNithin Dabilpuram 			cpt_ctx->zsk_flags = 0x1;
24836cc54096SNithin Dabilpuram 			break;
24846cc54096SNithin Dabilpuram 		case KASUMI_F9_ECB:
24856cc54096SNithin Dabilpuram 			/* Kasumi ECB mode */
24866cc54096SNithin Dabilpuram 			cpt_ctx->k_ecb = 1;
24876cc54096SNithin Dabilpuram 			memcpy(cpt_ctx->k_ctx.ci_key, key, key_len);
24886cc54096SNithin Dabilpuram 			cpt_ctx->fc_type = KASUMI;
24896cc54096SNithin Dabilpuram 			cpt_ctx->zsk_flags = 0x1;
24906cc54096SNithin Dabilpuram 			break;
24916cc54096SNithin Dabilpuram 		case KASUMI_F9_CBC:
24926cc54096SNithin Dabilpuram 			memcpy(cpt_ctx->k_ctx.ci_key, key, key_len);
24936cc54096SNithin Dabilpuram 			cpt_ctx->fc_type = KASUMI;
24946cc54096SNithin Dabilpuram 			cpt_ctx->zsk_flags = 0x1;
24956cc54096SNithin Dabilpuram 			break;
24966cc54096SNithin Dabilpuram 		default:
24976cc54096SNithin Dabilpuram 			return -1;
24986cc54096SNithin Dabilpuram 		}
24996cc54096SNithin Dabilpuram 		cpt_ctx->mac_len = 4;
25006cc54096SNithin Dabilpuram 		cpt_ctx->hash_type = type;
25016cc54096SNithin Dabilpuram 		return 0;
25026cc54096SNithin Dabilpuram 	}
25036cc54096SNithin Dabilpuram 
25046cc54096SNithin Dabilpuram 	if (!(cpt_ctx->fc_type == FC_GEN && !type)) {
25056cc54096SNithin Dabilpuram 		if (!cpt_ctx->fc_type || !cpt_ctx->enc_cipher)
25066cc54096SNithin Dabilpuram 			cpt_ctx->fc_type = HASH_HMAC;
25076cc54096SNithin Dabilpuram 	}
25086cc54096SNithin Dabilpuram 
25092839a8abSSucharitha Sarananaga 	if (cpt_ctx->fc_type == FC_GEN && key_len > 64)
25102839a8abSSucharitha Sarananaga 		return -1;
25112839a8abSSucharitha Sarananaga 
25126cc54096SNithin Dabilpuram 	/* For GMAC auth, cipher must be NULL */
25136cc54096SNithin Dabilpuram 	if (type == GMAC_TYPE)
2514c3d0bc45SAnoob Joseph 		fctx->enc.enc_cipher = 0;
25156cc54096SNithin Dabilpuram 
2516c3d0bc45SAnoob Joseph 	fctx->enc.hash_type = cpt_ctx->hash_type = type;
2517c3d0bc45SAnoob Joseph 	fctx->enc.mac_len = cpt_ctx->mac_len = mac_len;
25186cc54096SNithin Dabilpuram 
25196cc54096SNithin Dabilpuram 	if (key_len) {
25206cc54096SNithin Dabilpuram 		cpt_ctx->hmac = 1;
25216cc54096SNithin Dabilpuram 		memset(cpt_ctx->auth_key, 0, sizeof(cpt_ctx->auth_key));
25226cc54096SNithin Dabilpuram 		memcpy(cpt_ctx->auth_key, key, key_len);
25236cc54096SNithin Dabilpuram 		cpt_ctx->auth_key_len = key_len;
25246cc54096SNithin Dabilpuram 		memset(fctx->hmac.ipad, 0, sizeof(fctx->hmac.ipad));
25256cc54096SNithin Dabilpuram 		memset(fctx->hmac.opad, 0, sizeof(fctx->hmac.opad));
25262839a8abSSucharitha Sarananaga 
25272839a8abSSucharitha Sarananaga 		if (key_len <= 64)
25286cc54096SNithin Dabilpuram 			memcpy(fctx->hmac.opad, key, key_len);
2529c3d0bc45SAnoob Joseph 		fctx->enc.auth_input_type = 1;
25306cc54096SNithin Dabilpuram 	}
25316cc54096SNithin Dabilpuram 	return 0;
25326cc54096SNithin Dabilpuram }
25336cc54096SNithin Dabilpuram 
25346cc54096SNithin Dabilpuram static __rte_always_inline int
25356cc54096SNithin Dabilpuram fill_sess_aead(struct rte_crypto_sym_xform *xform,
25366cc54096SNithin Dabilpuram 		 struct cpt_sess_misc *sess)
25376cc54096SNithin Dabilpuram {
25386cc54096SNithin Dabilpuram 	struct rte_crypto_aead_xform *aead_form;
25396cc54096SNithin Dabilpuram 	cipher_type_t enc_type = 0; /* NULL Cipher type */
25406cc54096SNithin Dabilpuram 	auth_type_t auth_type = 0; /* NULL Auth type */
25416cc54096SNithin Dabilpuram 	uint32_t cipher_key_len = 0;
25428de5ede7SAnoob Joseph 	uint8_t aes_gcm = 0;
25436cc54096SNithin Dabilpuram 	aead_form = &xform->aead;
25448de5ede7SAnoob Joseph 	void *ctx = SESS_PRIV(sess);
25456cc54096SNithin Dabilpuram 
2546*cb7842f2STejasree Kondoj 	if (aead_form->op == RTE_CRYPTO_AEAD_OP_ENCRYPT) {
25476cc54096SNithin Dabilpuram 		sess->cpt_op |= CPT_OP_CIPHER_ENCRYPT;
25486cc54096SNithin Dabilpuram 		sess->cpt_op |= CPT_OP_AUTH_GENERATE;
2549*cb7842f2STejasree Kondoj 	} else if (aead_form->op == RTE_CRYPTO_AEAD_OP_DECRYPT) {
25506cc54096SNithin Dabilpuram 		sess->cpt_op |= CPT_OP_CIPHER_DECRYPT;
25516cc54096SNithin Dabilpuram 		sess->cpt_op |= CPT_OP_AUTH_VERIFY;
25526cc54096SNithin Dabilpuram 	} else {
2553*cb7842f2STejasree Kondoj 		CPT_LOG_DP_ERR("Unknown aead operation\n");
25546cc54096SNithin Dabilpuram 		return -1;
25556cc54096SNithin Dabilpuram 	}
25566cc54096SNithin Dabilpuram 	switch (aead_form->algo) {
25576cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AEAD_AES_GCM:
25586cc54096SNithin Dabilpuram 		enc_type = AES_GCM;
25596cc54096SNithin Dabilpuram 		cipher_key_len = 16;
25606cc54096SNithin Dabilpuram 		aes_gcm = 1;
25616cc54096SNithin Dabilpuram 		break;
25626cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AEAD_AES_CCM:
25636cc54096SNithin Dabilpuram 		CPT_LOG_DP_ERR("Crypto: Unsupported cipher algo %u",
25646cc54096SNithin Dabilpuram 			       aead_form->algo);
25656cc54096SNithin Dabilpuram 		return -1;
2566*cb7842f2STejasree Kondoj 	case RTE_CRYPTO_AEAD_CHACHA20_POLY1305:
2567*cb7842f2STejasree Kondoj 		enc_type = CHACHA20;
2568*cb7842f2STejasree Kondoj 		auth_type = POLY1305;
2569*cb7842f2STejasree Kondoj 		cipher_key_len = 32;
2570*cb7842f2STejasree Kondoj 		sess->chacha_poly = 1;
2571*cb7842f2STejasree Kondoj 		break;
25726cc54096SNithin Dabilpuram 	default:
25736cc54096SNithin Dabilpuram 		CPT_LOG_DP_ERR("Crypto: Undefined cipher algo %u specified",
25746cc54096SNithin Dabilpuram 			       aead_form->algo);
25756cc54096SNithin Dabilpuram 		return -1;
25766cc54096SNithin Dabilpuram 	}
25776cc54096SNithin Dabilpuram 	if (aead_form->key.length < cipher_key_len) {
25786cc54096SNithin Dabilpuram 		CPT_LOG_DP_ERR("Invalid cipher params keylen %lu",
25796cc54096SNithin Dabilpuram 			       (unsigned int long)aead_form->key.length);
25806cc54096SNithin Dabilpuram 		return -1;
25816cc54096SNithin Dabilpuram 	}
25828de5ede7SAnoob Joseph 	sess->zsk_flag = 0;
25836cc54096SNithin Dabilpuram 	sess->aes_gcm = aes_gcm;
25846cc54096SNithin Dabilpuram 	sess->mac_len = aead_form->digest_length;
25856cc54096SNithin Dabilpuram 	sess->iv_offset = aead_form->iv.offset;
25866cc54096SNithin Dabilpuram 	sess->iv_length = aead_form->iv.length;
25876cc54096SNithin Dabilpuram 	sess->aad_length = aead_form->aad_length;
25886cc54096SNithin Dabilpuram 
2589e40175c5SArchana Muniganti 	if (unlikely(cpt_fc_ciph_set_key(ctx, enc_type, aead_form->key.data,
2590e40175c5SArchana Muniganti 			aead_form->key.length, NULL)))
2591e40175c5SArchana Muniganti 		return -1;
25926cc54096SNithin Dabilpuram 
2593e40175c5SArchana Muniganti 	if (unlikely(cpt_fc_auth_set_key(ctx, auth_type, NULL, 0,
2594e40175c5SArchana Muniganti 			aead_form->digest_length)))
2595e40175c5SArchana Muniganti 		return -1;
25966cc54096SNithin Dabilpuram 
25976cc54096SNithin Dabilpuram 	return 0;
25986cc54096SNithin Dabilpuram }
25996cc54096SNithin Dabilpuram 
26006cc54096SNithin Dabilpuram static __rte_always_inline int
26016cc54096SNithin Dabilpuram fill_sess_cipher(struct rte_crypto_sym_xform *xform,
26026cc54096SNithin Dabilpuram 		 struct cpt_sess_misc *sess)
26036cc54096SNithin Dabilpuram {
26046cc54096SNithin Dabilpuram 	struct rte_crypto_cipher_xform *c_form;
26056cc54096SNithin Dabilpuram 	cipher_type_t enc_type = 0; /* NULL Cipher type */
26066cc54096SNithin Dabilpuram 	uint32_t cipher_key_len = 0;
26078de5ede7SAnoob Joseph 	uint8_t zsk_flag = 0, aes_ctr = 0, is_null = 0;
26086cc54096SNithin Dabilpuram 
26096cc54096SNithin Dabilpuram 	c_form = &xform->cipher;
26106cc54096SNithin Dabilpuram 
26116cc54096SNithin Dabilpuram 	if (c_form->op == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
26126cc54096SNithin Dabilpuram 		sess->cpt_op |= CPT_OP_CIPHER_ENCRYPT;
26136cc54096SNithin Dabilpuram 	else if (c_form->op == RTE_CRYPTO_CIPHER_OP_DECRYPT)
26146cc54096SNithin Dabilpuram 		sess->cpt_op |= CPT_OP_CIPHER_DECRYPT;
26156cc54096SNithin Dabilpuram 	else {
26166cc54096SNithin Dabilpuram 		CPT_LOG_DP_ERR("Unknown cipher operation\n");
26176cc54096SNithin Dabilpuram 		return -1;
26186cc54096SNithin Dabilpuram 	}
26196cc54096SNithin Dabilpuram 
26206cc54096SNithin Dabilpuram 	switch (c_form->algo) {
26216cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_AES_CBC:
26226cc54096SNithin Dabilpuram 		enc_type = AES_CBC;
26236cc54096SNithin Dabilpuram 		cipher_key_len = 16;
26246cc54096SNithin Dabilpuram 		break;
26256cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_3DES_CBC:
26266cc54096SNithin Dabilpuram 		enc_type = DES3_CBC;
26276cc54096SNithin Dabilpuram 		cipher_key_len = 24;
26286cc54096SNithin Dabilpuram 		break;
26296cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_DES_CBC:
26306cc54096SNithin Dabilpuram 		/* DES is implemented using 3DES in hardware */
26316cc54096SNithin Dabilpuram 		enc_type = DES3_CBC;
26326cc54096SNithin Dabilpuram 		cipher_key_len = 8;
26336cc54096SNithin Dabilpuram 		break;
26346cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_AES_CTR:
26356cc54096SNithin Dabilpuram 		enc_type = AES_CTR;
26366cc54096SNithin Dabilpuram 		cipher_key_len = 16;
26376cc54096SNithin Dabilpuram 		aes_ctr = 1;
26386cc54096SNithin Dabilpuram 		break;
26396cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_NULL:
26406cc54096SNithin Dabilpuram 		enc_type = 0;
26416cc54096SNithin Dabilpuram 		is_null = 1;
26426cc54096SNithin Dabilpuram 		break;
26436cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_KASUMI_F8:
26446cc54096SNithin Dabilpuram 		enc_type = KASUMI_F8_ECB;
26456cc54096SNithin Dabilpuram 		cipher_key_len = 16;
26466cc54096SNithin Dabilpuram 		zsk_flag = K_F8;
26476cc54096SNithin Dabilpuram 		break;
26486cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_SNOW3G_UEA2:
26496cc54096SNithin Dabilpuram 		enc_type = SNOW3G_UEA2;
26506cc54096SNithin Dabilpuram 		cipher_key_len = 16;
26516cc54096SNithin Dabilpuram 		zsk_flag = ZS_EA;
26526cc54096SNithin Dabilpuram 		break;
26536cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_ZUC_EEA3:
26546cc54096SNithin Dabilpuram 		enc_type = ZUC_EEA3;
26556cc54096SNithin Dabilpuram 		cipher_key_len = 16;
26566cc54096SNithin Dabilpuram 		zsk_flag = ZS_EA;
26576cc54096SNithin Dabilpuram 		break;
26586cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_AES_XTS:
26596cc54096SNithin Dabilpuram 		enc_type = AES_XTS;
26606cc54096SNithin Dabilpuram 		cipher_key_len = 16;
26616cc54096SNithin Dabilpuram 		break;
26626cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_3DES_ECB:
26636cc54096SNithin Dabilpuram 		enc_type = DES3_ECB;
26646cc54096SNithin Dabilpuram 		cipher_key_len = 24;
26656cc54096SNithin Dabilpuram 		break;
26666cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_AES_ECB:
26676cc54096SNithin Dabilpuram 		enc_type = AES_ECB;
26686cc54096SNithin Dabilpuram 		cipher_key_len = 16;
26696cc54096SNithin Dabilpuram 		break;
26706cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_3DES_CTR:
26716cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_AES_F8:
26726cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_ARC4:
26736cc54096SNithin Dabilpuram 		CPT_LOG_DP_ERR("Crypto: Unsupported cipher algo %u",
26746cc54096SNithin Dabilpuram 			       c_form->algo);
26756cc54096SNithin Dabilpuram 		return -1;
26766cc54096SNithin Dabilpuram 	default:
26776cc54096SNithin Dabilpuram 		CPT_LOG_DP_ERR("Crypto: Undefined cipher algo %u specified",
26786cc54096SNithin Dabilpuram 			       c_form->algo);
26796cc54096SNithin Dabilpuram 		return -1;
26806cc54096SNithin Dabilpuram 	}
26816cc54096SNithin Dabilpuram 
26826cc54096SNithin Dabilpuram 	if (c_form->key.length < cipher_key_len) {
26836cc54096SNithin Dabilpuram 		CPT_LOG_DP_ERR("Invalid cipher params keylen %lu",
26846cc54096SNithin Dabilpuram 			       (unsigned long) c_form->key.length);
26856cc54096SNithin Dabilpuram 		return -1;
26866cc54096SNithin Dabilpuram 	}
26876cc54096SNithin Dabilpuram 
26886cc54096SNithin Dabilpuram 	sess->zsk_flag = zsk_flag;
26898de5ede7SAnoob Joseph 	sess->aes_gcm = 0;
26906cc54096SNithin Dabilpuram 	sess->aes_ctr = aes_ctr;
26916cc54096SNithin Dabilpuram 	sess->iv_offset = c_form->iv.offset;
26926cc54096SNithin Dabilpuram 	sess->iv_length = c_form->iv.length;
26936cc54096SNithin Dabilpuram 	sess->is_null = is_null;
26946cc54096SNithin Dabilpuram 
2695e40175c5SArchana Muniganti 	if (unlikely(cpt_fc_ciph_set_key(SESS_PRIV(sess), enc_type,
2696e40175c5SArchana Muniganti 			c_form->key.data, c_form->key.length, NULL)))
2697e40175c5SArchana Muniganti 		return -1;
26986cc54096SNithin Dabilpuram 
26996cc54096SNithin Dabilpuram 	return 0;
27006cc54096SNithin Dabilpuram }
27016cc54096SNithin Dabilpuram 
27026cc54096SNithin Dabilpuram static __rte_always_inline int
27036cc54096SNithin Dabilpuram fill_sess_auth(struct rte_crypto_sym_xform *xform,
27046cc54096SNithin Dabilpuram 	       struct cpt_sess_misc *sess)
27056cc54096SNithin Dabilpuram {
27066cc54096SNithin Dabilpuram 	struct rte_crypto_auth_xform *a_form;
27076cc54096SNithin Dabilpuram 	auth_type_t auth_type = 0; /* NULL Auth type */
27086cc54096SNithin Dabilpuram 	uint8_t zsk_flag = 0, aes_gcm = 0, is_null = 0;
27096cc54096SNithin Dabilpuram 
27106cc54096SNithin Dabilpuram 	a_form = &xform->auth;
27116cc54096SNithin Dabilpuram 
27126cc54096SNithin Dabilpuram 	if (a_form->op == RTE_CRYPTO_AUTH_OP_VERIFY)
27136cc54096SNithin Dabilpuram 		sess->cpt_op |= CPT_OP_AUTH_VERIFY;
27146cc54096SNithin Dabilpuram 	else if (a_form->op == RTE_CRYPTO_AUTH_OP_GENERATE)
27156cc54096SNithin Dabilpuram 		sess->cpt_op |= CPT_OP_AUTH_GENERATE;
27166cc54096SNithin Dabilpuram 	else {
27176cc54096SNithin Dabilpuram 		CPT_LOG_DP_ERR("Unknown auth operation");
27186cc54096SNithin Dabilpuram 		return -1;
27196cc54096SNithin Dabilpuram 	}
27206cc54096SNithin Dabilpuram 
27216cc54096SNithin Dabilpuram 	switch (a_form->algo) {
27226cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_SHA1_HMAC:
27236cc54096SNithin Dabilpuram 		/* Fall through */
27246cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_SHA1:
27256cc54096SNithin Dabilpuram 		auth_type = SHA1_TYPE;
27266cc54096SNithin Dabilpuram 		break;
27276cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_SHA256_HMAC:
27286cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_SHA256:
27296cc54096SNithin Dabilpuram 		auth_type = SHA2_SHA256;
27306cc54096SNithin Dabilpuram 		break;
27316cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_SHA512_HMAC:
27326cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_SHA512:
27336cc54096SNithin Dabilpuram 		auth_type = SHA2_SHA512;
27346cc54096SNithin Dabilpuram 		break;
27356cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_AES_GMAC:
27366cc54096SNithin Dabilpuram 		auth_type = GMAC_TYPE;
27376cc54096SNithin Dabilpuram 		aes_gcm = 1;
27386cc54096SNithin Dabilpuram 		break;
27396cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_SHA224_HMAC:
27406cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_SHA224:
27416cc54096SNithin Dabilpuram 		auth_type = SHA2_SHA224;
27426cc54096SNithin Dabilpuram 		break;
27436cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_SHA384_HMAC:
27446cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_SHA384:
27456cc54096SNithin Dabilpuram 		auth_type = SHA2_SHA384;
27466cc54096SNithin Dabilpuram 		break;
27476cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_MD5_HMAC:
27486cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_MD5:
27496cc54096SNithin Dabilpuram 		auth_type = MD5_TYPE;
27506cc54096SNithin Dabilpuram 		break;
27516cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_KASUMI_F9:
27526cc54096SNithin Dabilpuram 		auth_type = KASUMI_F9_ECB;
27536cc54096SNithin Dabilpuram 		/*
27546cc54096SNithin Dabilpuram 		 * Indicate that direction needs to be taken out
27556cc54096SNithin Dabilpuram 		 * from end of src
27566cc54096SNithin Dabilpuram 		 */
27576cc54096SNithin Dabilpuram 		zsk_flag = K_F9;
27586cc54096SNithin Dabilpuram 		break;
27596cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_SNOW3G_UIA2:
27606cc54096SNithin Dabilpuram 		auth_type = SNOW3G_UIA2;
27616cc54096SNithin Dabilpuram 		zsk_flag = ZS_IA;
27626cc54096SNithin Dabilpuram 		break;
27636cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_ZUC_EIA3:
27646cc54096SNithin Dabilpuram 		auth_type = ZUC_EIA3;
27656cc54096SNithin Dabilpuram 		zsk_flag = ZS_IA;
27666cc54096SNithin Dabilpuram 		break;
27676cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_NULL:
27686cc54096SNithin Dabilpuram 		auth_type = 0;
27696cc54096SNithin Dabilpuram 		is_null = 1;
27706cc54096SNithin Dabilpuram 		break;
27716cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
27726cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_AES_CMAC:
27736cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_AES_CBC_MAC:
27746cc54096SNithin Dabilpuram 		CPT_LOG_DP_ERR("Crypto: Unsupported hash algo %u",
27756cc54096SNithin Dabilpuram 			       a_form->algo);
27768de5ede7SAnoob Joseph 		return -1;
27776cc54096SNithin Dabilpuram 	default:
27786cc54096SNithin Dabilpuram 		CPT_LOG_DP_ERR("Crypto: Undefined Hash algo %u specified",
27796cc54096SNithin Dabilpuram 			       a_form->algo);
27808de5ede7SAnoob Joseph 		return -1;
27816cc54096SNithin Dabilpuram 	}
27826cc54096SNithin Dabilpuram 
27836cc54096SNithin Dabilpuram 	sess->zsk_flag = zsk_flag;
27846cc54096SNithin Dabilpuram 	sess->aes_gcm = aes_gcm;
27856cc54096SNithin Dabilpuram 	sess->mac_len = a_form->digest_length;
27866cc54096SNithin Dabilpuram 	sess->is_null = is_null;
27876cc54096SNithin Dabilpuram 	if (zsk_flag) {
27886cc54096SNithin Dabilpuram 		sess->auth_iv_offset = a_form->iv.offset;
27896cc54096SNithin Dabilpuram 		sess->auth_iv_length = a_form->iv.length;
27906cc54096SNithin Dabilpuram 	}
2791e40175c5SArchana Muniganti 	if (unlikely(cpt_fc_auth_set_key(SESS_PRIV(sess), auth_type,
2792e40175c5SArchana Muniganti 			a_form->key.data, a_form->key.length,
2793e40175c5SArchana Muniganti 			a_form->digest_length)))
2794e40175c5SArchana Muniganti 		return -1;
27956cc54096SNithin Dabilpuram 
27966cc54096SNithin Dabilpuram 	return 0;
27976cc54096SNithin Dabilpuram }
27986cc54096SNithin Dabilpuram 
27996cc54096SNithin Dabilpuram static __rte_always_inline int
28006cc54096SNithin Dabilpuram fill_sess_gmac(struct rte_crypto_sym_xform *xform,
28016cc54096SNithin Dabilpuram 		 struct cpt_sess_misc *sess)
28026cc54096SNithin Dabilpuram {
28036cc54096SNithin Dabilpuram 	struct rte_crypto_auth_xform *a_form;
28046cc54096SNithin Dabilpuram 	cipher_type_t enc_type = 0; /* NULL Cipher type */
28056cc54096SNithin Dabilpuram 	auth_type_t auth_type = 0; /* NULL Auth type */
28068de5ede7SAnoob Joseph 	void *ctx = SESS_PRIV(sess);
28076cc54096SNithin Dabilpuram 
28086cc54096SNithin Dabilpuram 	a_form = &xform->auth;
28096cc54096SNithin Dabilpuram 
28106cc54096SNithin Dabilpuram 	if (a_form->op == RTE_CRYPTO_AUTH_OP_GENERATE)
28116cc54096SNithin Dabilpuram 		sess->cpt_op |= CPT_OP_ENCODE;
28126cc54096SNithin Dabilpuram 	else if (a_form->op == RTE_CRYPTO_AUTH_OP_VERIFY)
28136cc54096SNithin Dabilpuram 		sess->cpt_op |= CPT_OP_DECODE;
28146cc54096SNithin Dabilpuram 	else {
28156cc54096SNithin Dabilpuram 		CPT_LOG_DP_ERR("Unknown auth operation");
28166cc54096SNithin Dabilpuram 		return -1;
28176cc54096SNithin Dabilpuram 	}
28186cc54096SNithin Dabilpuram 
28196cc54096SNithin Dabilpuram 	switch (a_form->algo) {
28206cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_AES_GMAC:
28216cc54096SNithin Dabilpuram 		enc_type = AES_GCM;
28226cc54096SNithin Dabilpuram 		auth_type = GMAC_TYPE;
28236cc54096SNithin Dabilpuram 		break;
28246cc54096SNithin Dabilpuram 	default:
28256cc54096SNithin Dabilpuram 		CPT_LOG_DP_ERR("Crypto: Undefined cipher algo %u specified",
28266cc54096SNithin Dabilpuram 			       a_form->algo);
28276cc54096SNithin Dabilpuram 		return -1;
28286cc54096SNithin Dabilpuram 	}
28296cc54096SNithin Dabilpuram 
28308de5ede7SAnoob Joseph 	sess->zsk_flag = 0;
28318de5ede7SAnoob Joseph 	sess->aes_gcm = 0;
28326cc54096SNithin Dabilpuram 	sess->is_gmac = 1;
28336cc54096SNithin Dabilpuram 	sess->iv_offset = a_form->iv.offset;
28346cc54096SNithin Dabilpuram 	sess->iv_length = a_form->iv.length;
28356cc54096SNithin Dabilpuram 	sess->mac_len = a_form->digest_length;
28366cc54096SNithin Dabilpuram 
2837e40175c5SArchana Muniganti 	if (unlikely(cpt_fc_ciph_set_key(ctx, enc_type, a_form->key.data,
2838e40175c5SArchana Muniganti 			a_form->key.length, NULL)))
2839e40175c5SArchana Muniganti 		return -1;
2840e40175c5SArchana Muniganti 
2841e40175c5SArchana Muniganti 	if (unlikely(cpt_fc_auth_set_key(ctx, auth_type, NULL, 0,
2842e40175c5SArchana Muniganti 			a_form->digest_length)))
2843e40175c5SArchana Muniganti 		return -1;
28446cc54096SNithin Dabilpuram 
28456cc54096SNithin Dabilpuram 	return 0;
28466cc54096SNithin Dabilpuram }
28476cc54096SNithin Dabilpuram 
2848b74652f3SRagothaman Jayaraman static __rte_always_inline void *
2849b74652f3SRagothaman Jayaraman alloc_op_meta(struct rte_mbuf *m_src,
2850b74652f3SRagothaman Jayaraman 	      buf_ptr_t *buf,
2851b74652f3SRagothaman Jayaraman 	      int32_t len,
2852b74652f3SRagothaman Jayaraman 	      struct rte_mempool *cpt_meta_pool)
2853b74652f3SRagothaman Jayaraman {
2854b74652f3SRagothaman Jayaraman 	uint8_t *mdata;
2855b74652f3SRagothaman Jayaraman 
2856b74652f3SRagothaman Jayaraman #ifndef CPT_ALWAYS_USE_SEPARATE_BUF
2857b74652f3SRagothaman Jayaraman 	if (likely(m_src && (m_src->nb_segs == 1))) {
2858b74652f3SRagothaman Jayaraman 		int32_t tailroom;
2859b74652f3SRagothaman Jayaraman 		phys_addr_t mphys;
2860b74652f3SRagothaman Jayaraman 
2861b74652f3SRagothaman Jayaraman 		/* Check if tailroom is sufficient to hold meta data */
2862b74652f3SRagothaman Jayaraman 		tailroom = rte_pktmbuf_tailroom(m_src);
2863b74652f3SRagothaman Jayaraman 		if (likely(tailroom > len + 8)) {
2864b74652f3SRagothaman Jayaraman 			mdata = (uint8_t *)m_src->buf_addr + m_src->buf_len;
2865b74652f3SRagothaman Jayaraman 			mphys = m_src->buf_physaddr + m_src->buf_len;
2866b74652f3SRagothaman Jayaraman 			mdata -= len;
2867b74652f3SRagothaman Jayaraman 			mphys -= len;
2868b74652f3SRagothaman Jayaraman 			buf->vaddr = mdata;
2869b74652f3SRagothaman Jayaraman 			buf->dma_addr = mphys;
2870b74652f3SRagothaman Jayaraman 			buf->size = len;
2871b74652f3SRagothaman Jayaraman 			/* Indicate that this is a mbuf allocated mdata */
2872b74652f3SRagothaman Jayaraman 			mdata = (uint8_t *)((uint64_t)mdata | 1ull);
2873b74652f3SRagothaman Jayaraman 			return mdata;
2874b74652f3SRagothaman Jayaraman 		}
2875b74652f3SRagothaman Jayaraman 	}
2876b74652f3SRagothaman Jayaraman #else
2877b74652f3SRagothaman Jayaraman 	RTE_SET_USED(m_src);
2878b74652f3SRagothaman Jayaraman #endif
2879b74652f3SRagothaman Jayaraman 
2880b74652f3SRagothaman Jayaraman 	if (unlikely(rte_mempool_get(cpt_meta_pool, (void **)&mdata) < 0))
2881b74652f3SRagothaman Jayaraman 		return NULL;
2882b74652f3SRagothaman Jayaraman 
2883b74652f3SRagothaman Jayaraman 	buf->vaddr = mdata;
2884b74652f3SRagothaman Jayaraman 	buf->dma_addr = rte_mempool_virt2iova(mdata);
2885b74652f3SRagothaman Jayaraman 	buf->size = len;
2886b74652f3SRagothaman Jayaraman 
2887b74652f3SRagothaman Jayaraman 	return mdata;
2888b74652f3SRagothaman Jayaraman }
2889b74652f3SRagothaman Jayaraman 
2890b74652f3SRagothaman Jayaraman /**
2891b74652f3SRagothaman Jayaraman  * cpt_free_metabuf - free metabuf to mempool.
2892b74652f3SRagothaman Jayaraman  * @param instance: pointer to instance.
2893b74652f3SRagothaman Jayaraman  * @param objp: pointer to the metabuf.
2894b74652f3SRagothaman Jayaraman  */
2895b74652f3SRagothaman Jayaraman static __rte_always_inline void
2896b74652f3SRagothaman Jayaraman free_op_meta(void *mdata, struct rte_mempool *cpt_meta_pool)
2897b74652f3SRagothaman Jayaraman {
2898b74652f3SRagothaman Jayaraman 	bool nofree = ((uintptr_t)mdata & 1ull);
2899b74652f3SRagothaman Jayaraman 
2900b74652f3SRagothaman Jayaraman 	if (likely(nofree))
2901b74652f3SRagothaman Jayaraman 		return;
2902b74652f3SRagothaman Jayaraman 	rte_mempool_put(cpt_meta_pool, mdata);
2903b74652f3SRagothaman Jayaraman }
2904b74652f3SRagothaman Jayaraman 
2905b74652f3SRagothaman Jayaraman static __rte_always_inline uint32_t
2906b74652f3SRagothaman Jayaraman prepare_iov_from_pkt(struct rte_mbuf *pkt,
2907b74652f3SRagothaman Jayaraman 		     iov_ptr_t *iovec, uint32_t start_offset)
2908b74652f3SRagothaman Jayaraman {
2909b74652f3SRagothaman Jayaraman 	uint16_t index = 0;
2910b74652f3SRagothaman Jayaraman 	void *seg_data = NULL;
2911b74652f3SRagothaman Jayaraman 	phys_addr_t seg_phys;
2912b74652f3SRagothaman Jayaraman 	int32_t seg_size = 0;
2913b74652f3SRagothaman Jayaraman 
2914b74652f3SRagothaman Jayaraman 	if (!pkt) {
2915b74652f3SRagothaman Jayaraman 		iovec->buf_cnt = 0;
2916b74652f3SRagothaman Jayaraman 		return 0;
2917b74652f3SRagothaman Jayaraman 	}
2918b74652f3SRagothaman Jayaraman 
2919b74652f3SRagothaman Jayaraman 	if (!start_offset) {
2920b74652f3SRagothaman Jayaraman 		seg_data = rte_pktmbuf_mtod(pkt, void *);
2921b74652f3SRagothaman Jayaraman 		seg_phys = rte_pktmbuf_mtophys(pkt);
2922b74652f3SRagothaman Jayaraman 		seg_size = pkt->data_len;
2923b74652f3SRagothaman Jayaraman 	} else {
2924b74652f3SRagothaman Jayaraman 		while (start_offset >= pkt->data_len) {
2925b74652f3SRagothaman Jayaraman 			start_offset -= pkt->data_len;
2926b74652f3SRagothaman Jayaraman 			pkt = pkt->next;
2927b74652f3SRagothaman Jayaraman 		}
2928b74652f3SRagothaman Jayaraman 
2929b74652f3SRagothaman Jayaraman 		seg_data = rte_pktmbuf_mtod_offset(pkt, void *, start_offset);
2930b74652f3SRagothaman Jayaraman 		seg_phys = rte_pktmbuf_mtophys_offset(pkt, start_offset);
2931b74652f3SRagothaman Jayaraman 		seg_size = pkt->data_len - start_offset;
2932b74652f3SRagothaman Jayaraman 		if (!seg_size)
2933b74652f3SRagothaman Jayaraman 			return 1;
2934b74652f3SRagothaman Jayaraman 	}
2935b74652f3SRagothaman Jayaraman 
2936b74652f3SRagothaman Jayaraman 	/* first seg */
2937b74652f3SRagothaman Jayaraman 	iovec->bufs[index].vaddr = seg_data;
2938b74652f3SRagothaman Jayaraman 	iovec->bufs[index].dma_addr = seg_phys;
2939b74652f3SRagothaman Jayaraman 	iovec->bufs[index].size = seg_size;
2940b74652f3SRagothaman Jayaraman 	index++;
2941b74652f3SRagothaman Jayaraman 	pkt = pkt->next;
2942b74652f3SRagothaman Jayaraman 
2943b74652f3SRagothaman Jayaraman 	while (unlikely(pkt != NULL)) {
2944b74652f3SRagothaman Jayaraman 		seg_data = rte_pktmbuf_mtod(pkt, void *);
2945b74652f3SRagothaman Jayaraman 		seg_phys = rte_pktmbuf_mtophys(pkt);
2946b74652f3SRagothaman Jayaraman 		seg_size = pkt->data_len;
2947b74652f3SRagothaman Jayaraman 		if (!seg_size)
2948b74652f3SRagothaman Jayaraman 			break;
2949b74652f3SRagothaman Jayaraman 
2950b74652f3SRagothaman Jayaraman 		iovec->bufs[index].vaddr = seg_data;
2951b74652f3SRagothaman Jayaraman 		iovec->bufs[index].dma_addr = seg_phys;
2952b74652f3SRagothaman Jayaraman 		iovec->bufs[index].size = seg_size;
2953b74652f3SRagothaman Jayaraman 
2954b74652f3SRagothaman Jayaraman 		index++;
2955b74652f3SRagothaman Jayaraman 
2956b74652f3SRagothaman Jayaraman 		pkt = pkt->next;
2957b74652f3SRagothaman Jayaraman 	}
2958b74652f3SRagothaman Jayaraman 
2959b74652f3SRagothaman Jayaraman 	iovec->buf_cnt = index;
2960b74652f3SRagothaman Jayaraman 	return 0;
2961b74652f3SRagothaman Jayaraman }
2962b74652f3SRagothaman Jayaraman 
2963b74652f3SRagothaman Jayaraman static __rte_always_inline uint32_t
2964b74652f3SRagothaman Jayaraman prepare_iov_from_pkt_inplace(struct rte_mbuf *pkt,
2965b74652f3SRagothaman Jayaraman 			     fc_params_t *param,
2966b74652f3SRagothaman Jayaraman 			     uint32_t *flags)
2967b74652f3SRagothaman Jayaraman {
2968b74652f3SRagothaman Jayaraman 	uint16_t index = 0;
2969b74652f3SRagothaman Jayaraman 	void *seg_data = NULL;
2970b74652f3SRagothaman Jayaraman 	phys_addr_t seg_phys;
2971b74652f3SRagothaman Jayaraman 	uint32_t seg_size = 0;
2972b74652f3SRagothaman Jayaraman 	iov_ptr_t *iovec;
2973b74652f3SRagothaman Jayaraman 
2974b74652f3SRagothaman Jayaraman 	seg_data = rte_pktmbuf_mtod(pkt, void *);
2975b74652f3SRagothaman Jayaraman 	seg_phys = rte_pktmbuf_mtophys(pkt);
2976b74652f3SRagothaman Jayaraman 	seg_size = pkt->data_len;
2977b74652f3SRagothaman Jayaraman 
2978b74652f3SRagothaman Jayaraman 	/* first seg */
2979b74652f3SRagothaman Jayaraman 	if (likely(!pkt->next)) {
2980b74652f3SRagothaman Jayaraman 		uint32_t headroom, tailroom;
2981b74652f3SRagothaman Jayaraman 
2982b74652f3SRagothaman Jayaraman 		*flags |= SINGLE_BUF_INPLACE;
2983b74652f3SRagothaman Jayaraman 		headroom = rte_pktmbuf_headroom(pkt);
2984b74652f3SRagothaman Jayaraman 		tailroom = rte_pktmbuf_tailroom(pkt);
2985b74652f3SRagothaman Jayaraman 		if (likely((headroom >= 24) &&
2986b74652f3SRagothaman Jayaraman 		    (tailroom >= 8))) {
2987b74652f3SRagothaman Jayaraman 			/* In 83XX this is prerequivisit for Direct mode */
2988b74652f3SRagothaman Jayaraman 			*flags |= SINGLE_BUF_HEADTAILROOM;
2989b74652f3SRagothaman Jayaraman 		}
2990b74652f3SRagothaman Jayaraman 		param->bufs[0].vaddr = seg_data;
2991b74652f3SRagothaman Jayaraman 		param->bufs[0].dma_addr = seg_phys;
2992b74652f3SRagothaman Jayaraman 		param->bufs[0].size = seg_size;
2993b74652f3SRagothaman Jayaraman 		return 0;
2994b74652f3SRagothaman Jayaraman 	}
2995b74652f3SRagothaman Jayaraman 	iovec = param->src_iov;
2996b74652f3SRagothaman Jayaraman 	iovec->bufs[index].vaddr = seg_data;
2997b74652f3SRagothaman Jayaraman 	iovec->bufs[index].dma_addr = seg_phys;
2998b74652f3SRagothaman Jayaraman 	iovec->bufs[index].size = seg_size;
2999b74652f3SRagothaman Jayaraman 	index++;
3000b74652f3SRagothaman Jayaraman 	pkt = pkt->next;
3001b74652f3SRagothaman Jayaraman 
3002b74652f3SRagothaman Jayaraman 	while (unlikely(pkt != NULL)) {
3003b74652f3SRagothaman Jayaraman 		seg_data = rte_pktmbuf_mtod(pkt, void *);
3004b74652f3SRagothaman Jayaraman 		seg_phys = rte_pktmbuf_mtophys(pkt);
3005b74652f3SRagothaman Jayaraman 		seg_size = pkt->data_len;
3006b74652f3SRagothaman Jayaraman 
3007b74652f3SRagothaman Jayaraman 		if (!seg_size)
3008b74652f3SRagothaman Jayaraman 			break;
3009b74652f3SRagothaman Jayaraman 
3010b74652f3SRagothaman Jayaraman 		iovec->bufs[index].vaddr = seg_data;
3011b74652f3SRagothaman Jayaraman 		iovec->bufs[index].dma_addr = seg_phys;
3012b74652f3SRagothaman Jayaraman 		iovec->bufs[index].size = seg_size;
3013b74652f3SRagothaman Jayaraman 
3014b74652f3SRagothaman Jayaraman 		index++;
3015b74652f3SRagothaman Jayaraman 
3016b74652f3SRagothaman Jayaraman 		pkt = pkt->next;
3017b74652f3SRagothaman Jayaraman 	}
3018b74652f3SRagothaman Jayaraman 
3019b74652f3SRagothaman Jayaraman 	iovec->buf_cnt = index;
3020b74652f3SRagothaman Jayaraman 	return 0;
3021b74652f3SRagothaman Jayaraman }
3022b74652f3SRagothaman Jayaraman 
3023f39928e6SAnoob Joseph static __rte_always_inline int
3024b74652f3SRagothaman Jayaraman fill_fc_params(struct rte_crypto_op *cop,
3025b74652f3SRagothaman Jayaraman 	       struct cpt_sess_misc *sess_misc,
3026ec54bc9dSAnoob Joseph 	       struct cpt_qp_meta_info *m_info,
3027b74652f3SRagothaman Jayaraman 	       void **mdata_ptr,
3028f39928e6SAnoob Joseph 	       void **prep_req)
3029b74652f3SRagothaman Jayaraman {
3030b74652f3SRagothaman Jayaraman 	uint32_t space = 0;
3031b74652f3SRagothaman Jayaraman 	struct rte_crypto_sym_op *sym_op = cop->sym;
3032f39928e6SAnoob Joseph 	void *mdata = NULL;
3033b74652f3SRagothaman Jayaraman 	uintptr_t *op;
3034b74652f3SRagothaman Jayaraman 	uint32_t mc_hash_off;
3035b74652f3SRagothaman Jayaraman 	uint32_t flags = 0;
3036b74652f3SRagothaman Jayaraman 	uint64_t d_offs, d_lens;
3037b74652f3SRagothaman Jayaraman 	struct rte_mbuf *m_src, *m_dst;
3038b74652f3SRagothaman Jayaraman 	uint8_t cpt_op = sess_misc->cpt_op;
3039b74652f3SRagothaman Jayaraman #ifdef CPT_ALWAYS_USE_SG_MODE
3040b74652f3SRagothaman Jayaraman 	uint8_t inplace = 0;
3041b74652f3SRagothaman Jayaraman #else
3042b74652f3SRagothaman Jayaraman 	uint8_t inplace = 1;
3043b74652f3SRagothaman Jayaraman #endif
3044b74652f3SRagothaman Jayaraman 	fc_params_t fc_params;
3045b74652f3SRagothaman Jayaraman 	char src[SRC_IOV_SIZE];
3046b74652f3SRagothaman Jayaraman 	char dst[SRC_IOV_SIZE];
3047b74652f3SRagothaman Jayaraman 	uint32_t iv_buf[4];
3048f39928e6SAnoob Joseph 	int ret;
3049b74652f3SRagothaman Jayaraman 
3050b74652f3SRagothaman Jayaraman 	if (likely(sess_misc->iv_length)) {
3051b74652f3SRagothaman Jayaraman 		flags |= VALID_IV_BUF;
3052b74652f3SRagothaman Jayaraman 		fc_params.iv_buf = rte_crypto_op_ctod_offset(cop,
3053b74652f3SRagothaman Jayaraman 				   uint8_t *, sess_misc->iv_offset);
3054b74652f3SRagothaman Jayaraman 		if (sess_misc->aes_ctr &&
3055b74652f3SRagothaman Jayaraman 		    unlikely(sess_misc->iv_length != 16)) {
3056b74652f3SRagothaman Jayaraman 			memcpy((uint8_t *)iv_buf,
3057b74652f3SRagothaman Jayaraman 				rte_crypto_op_ctod_offset(cop,
3058b74652f3SRagothaman Jayaraman 				uint8_t *, sess_misc->iv_offset), 12);
3059b74652f3SRagothaman Jayaraman 			iv_buf[3] = rte_cpu_to_be_32(0x1);
3060b74652f3SRagothaman Jayaraman 			fc_params.iv_buf = iv_buf;
3061b74652f3SRagothaman Jayaraman 		}
3062b74652f3SRagothaman Jayaraman 	}
3063b74652f3SRagothaman Jayaraman 
30648de5ede7SAnoob Joseph 	if (sess_misc->zsk_flag) {
3065b74652f3SRagothaman Jayaraman 		fc_params.auth_iv_buf = rte_crypto_op_ctod_offset(cop,
3066b74652f3SRagothaman Jayaraman 					uint8_t *,
3067b74652f3SRagothaman Jayaraman 					sess_misc->auth_iv_offset);
30688de5ede7SAnoob Joseph 		if (sess_misc->zsk_flag != ZS_EA)
3069b74652f3SRagothaman Jayaraman 			inplace = 0;
3070b74652f3SRagothaman Jayaraman 	}
3071b74652f3SRagothaman Jayaraman 	m_src = sym_op->m_src;
3072b74652f3SRagothaman Jayaraman 	m_dst = sym_op->m_dst;
3073b74652f3SRagothaman Jayaraman 
3074*cb7842f2STejasree Kondoj 	if (sess_misc->aes_gcm || sess_misc->chacha_poly) {
3075b74652f3SRagothaman Jayaraman 		uint8_t *salt;
3076b74652f3SRagothaman Jayaraman 		uint8_t *aad_data;
3077b74652f3SRagothaman Jayaraman 		uint16_t aad_len;
3078b74652f3SRagothaman Jayaraman 
3079b74652f3SRagothaman Jayaraman 		d_offs = sym_op->aead.data.offset;
3080b74652f3SRagothaman Jayaraman 		d_lens = sym_op->aead.data.length;
3081b74652f3SRagothaman Jayaraman 		mc_hash_off = sym_op->aead.data.offset +
3082b74652f3SRagothaman Jayaraman 			      sym_op->aead.data.length;
3083b74652f3SRagothaman Jayaraman 
3084b74652f3SRagothaman Jayaraman 		aad_data = sym_op->aead.aad.data;
3085b74652f3SRagothaman Jayaraman 		aad_len = sess_misc->aad_length;
3086b74652f3SRagothaman Jayaraman 		if (likely((aad_data + aad_len) ==
3087b74652f3SRagothaman Jayaraman 			   rte_pktmbuf_mtod_offset(m_src,
3088b74652f3SRagothaman Jayaraman 				uint8_t *,
3089b74652f3SRagothaman Jayaraman 				sym_op->aead.data.offset))) {
3090b74652f3SRagothaman Jayaraman 			d_offs = (d_offs - aad_len) | (d_offs << 16);
3091b74652f3SRagothaman Jayaraman 			d_lens = (d_lens + aad_len) | (d_lens << 32);
3092b74652f3SRagothaman Jayaraman 		} else {
3093b74652f3SRagothaman Jayaraman 			fc_params.aad_buf.vaddr = sym_op->aead.aad.data;
3094b74652f3SRagothaman Jayaraman 			fc_params.aad_buf.dma_addr = sym_op->aead.aad.phys_addr;
3095b74652f3SRagothaman Jayaraman 			fc_params.aad_buf.size = aad_len;
3096b74652f3SRagothaman Jayaraman 			flags |= VALID_AAD_BUF;
3097b74652f3SRagothaman Jayaraman 			inplace = 0;
3098b74652f3SRagothaman Jayaraman 			d_offs = d_offs << 16;
3099b74652f3SRagothaman Jayaraman 			d_lens = d_lens << 32;
3100b74652f3SRagothaman Jayaraman 		}
3101b74652f3SRagothaman Jayaraman 
3102b74652f3SRagothaman Jayaraman 		salt = fc_params.iv_buf;
3103b74652f3SRagothaman Jayaraman 		if (unlikely(*(uint32_t *)salt != sess_misc->salt)) {
3104b74652f3SRagothaman Jayaraman 			cpt_fc_salt_update(SESS_PRIV(sess_misc), salt);
3105b74652f3SRagothaman Jayaraman 			sess_misc->salt = *(uint32_t *)salt;
3106b74652f3SRagothaman Jayaraman 		}
3107b74652f3SRagothaman Jayaraman 		fc_params.iv_buf = salt + 4;
31088de5ede7SAnoob Joseph 		if (likely(sess_misc->mac_len)) {
3109b74652f3SRagothaman Jayaraman 			struct rte_mbuf *m = (cpt_op & CPT_OP_ENCODE) ? m_dst :
3110b74652f3SRagothaman Jayaraman 					     m_src;
3111b74652f3SRagothaman Jayaraman 
3112b74652f3SRagothaman Jayaraman 			if (!m)
3113b74652f3SRagothaman Jayaraman 				m = m_src;
3114b74652f3SRagothaman Jayaraman 
3115b74652f3SRagothaman Jayaraman 			/* hmac immediately following data is best case */
3116b74652f3SRagothaman Jayaraman 			if (unlikely(rte_pktmbuf_mtod(m, uint8_t *) +
3117b74652f3SRagothaman Jayaraman 			    mc_hash_off !=
3118b74652f3SRagothaman Jayaraman 			    (uint8_t *)sym_op->aead.digest.data)) {
3119b74652f3SRagothaman Jayaraman 				flags |= VALID_MAC_BUF;
3120b74652f3SRagothaman Jayaraman 				fc_params.mac_buf.size = sess_misc->mac_len;
3121b74652f3SRagothaman Jayaraman 				fc_params.mac_buf.vaddr =
3122b74652f3SRagothaman Jayaraman 				  sym_op->aead.digest.data;
3123b74652f3SRagothaman Jayaraman 				fc_params.mac_buf.dma_addr =
3124b74652f3SRagothaman Jayaraman 				 sym_op->aead.digest.phys_addr;
3125b74652f3SRagothaman Jayaraman 				inplace = 0;
3126b74652f3SRagothaman Jayaraman 			}
3127b74652f3SRagothaman Jayaraman 		}
3128b74652f3SRagothaman Jayaraman 	} else {
3129b74652f3SRagothaman Jayaraman 		d_offs = sym_op->cipher.data.offset;
3130b74652f3SRagothaman Jayaraman 		d_lens = sym_op->cipher.data.length;
3131b74652f3SRagothaman Jayaraman 		mc_hash_off = sym_op->cipher.data.offset +
3132b74652f3SRagothaman Jayaraman 			      sym_op->cipher.data.length;
3133b74652f3SRagothaman Jayaraman 		d_offs = (d_offs << 16) | sym_op->auth.data.offset;
3134b74652f3SRagothaman Jayaraman 		d_lens = (d_lens << 32) | sym_op->auth.data.length;
3135b74652f3SRagothaman Jayaraman 
3136b74652f3SRagothaman Jayaraman 		if (mc_hash_off < (sym_op->auth.data.offset +
3137b74652f3SRagothaman Jayaraman 				   sym_op->auth.data.length)){
3138b74652f3SRagothaman Jayaraman 			mc_hash_off = (sym_op->auth.data.offset +
3139b74652f3SRagothaman Jayaraman 				       sym_op->auth.data.length);
3140b74652f3SRagothaman Jayaraman 		}
3141b74652f3SRagothaman Jayaraman 		/* for gmac, salt should be updated like in gcm */
3142b74652f3SRagothaman Jayaraman 		if (unlikely(sess_misc->is_gmac)) {
3143b74652f3SRagothaman Jayaraman 			uint8_t *salt;
3144b74652f3SRagothaman Jayaraman 			salt = fc_params.iv_buf;
3145b74652f3SRagothaman Jayaraman 			if (unlikely(*(uint32_t *)salt != sess_misc->salt)) {
3146b74652f3SRagothaman Jayaraman 				cpt_fc_salt_update(SESS_PRIV(sess_misc), salt);
3147b74652f3SRagothaman Jayaraman 				sess_misc->salt = *(uint32_t *)salt;
3148b74652f3SRagothaman Jayaraman 			}
3149b74652f3SRagothaman Jayaraman 			fc_params.iv_buf = salt + 4;
3150b74652f3SRagothaman Jayaraman 		}
31518de5ede7SAnoob Joseph 		if (likely(sess_misc->mac_len)) {
3152b74652f3SRagothaman Jayaraman 			struct rte_mbuf *m;
3153b74652f3SRagothaman Jayaraman 
3154b74652f3SRagothaman Jayaraman 			m = (cpt_op & CPT_OP_ENCODE) ? m_dst : m_src;
3155b74652f3SRagothaman Jayaraman 			if (!m)
3156b74652f3SRagothaman Jayaraman 				m = m_src;
3157b74652f3SRagothaman Jayaraman 
3158b74652f3SRagothaman Jayaraman 			/* hmac immediately following data is best case */
3159b74652f3SRagothaman Jayaraman 			if (unlikely(rte_pktmbuf_mtod(m, uint8_t *) +
3160b74652f3SRagothaman Jayaraman 			    mc_hash_off !=
3161b74652f3SRagothaman Jayaraman 			     (uint8_t *)sym_op->auth.digest.data)) {
3162b74652f3SRagothaman Jayaraman 				flags |= VALID_MAC_BUF;
3163b74652f3SRagothaman Jayaraman 				fc_params.mac_buf.size =
3164b74652f3SRagothaman Jayaraman 					sess_misc->mac_len;
3165b74652f3SRagothaman Jayaraman 				fc_params.mac_buf.vaddr =
3166b74652f3SRagothaman Jayaraman 					sym_op->auth.digest.data;
3167b74652f3SRagothaman Jayaraman 				fc_params.mac_buf.dma_addr =
3168b74652f3SRagothaman Jayaraman 				sym_op->auth.digest.phys_addr;
3169b74652f3SRagothaman Jayaraman 				inplace = 0;
3170b74652f3SRagothaman Jayaraman 			}
3171b74652f3SRagothaman Jayaraman 		}
3172b74652f3SRagothaman Jayaraman 	}
3173b74652f3SRagothaman Jayaraman 	fc_params.ctx_buf.vaddr = SESS_PRIV(sess_misc);
3174b74652f3SRagothaman Jayaraman 	fc_params.ctx_buf.dma_addr = sess_misc->ctx_dma_addr;
3175b74652f3SRagothaman Jayaraman 
3176b74652f3SRagothaman Jayaraman 	if (unlikely(sess_misc->is_null || sess_misc->cpt_op == CPT_OP_DECODE))
3177b74652f3SRagothaman Jayaraman 		inplace = 0;
3178b74652f3SRagothaman Jayaraman 
3179b74652f3SRagothaman Jayaraman 	if (likely(!m_dst && inplace)) {
3180b74652f3SRagothaman Jayaraman 		/* Case of single buffer without AAD buf or
3181b74652f3SRagothaman Jayaraman 		 * separate mac buf in place and
3182b74652f3SRagothaman Jayaraman 		 * not air crypto
3183b74652f3SRagothaman Jayaraman 		 */
3184b74652f3SRagothaman Jayaraman 		fc_params.dst_iov = fc_params.src_iov = (void *)src;
3185b74652f3SRagothaman Jayaraman 
3186b74652f3SRagothaman Jayaraman 		if (unlikely(prepare_iov_from_pkt_inplace(m_src,
3187b74652f3SRagothaman Jayaraman 							  &fc_params,
3188b74652f3SRagothaman Jayaraman 							  &flags))) {
3189b74652f3SRagothaman Jayaraman 			CPT_LOG_DP_ERR("Prepare inplace src iov failed");
3190f39928e6SAnoob Joseph 			ret = -EINVAL;
3191f39928e6SAnoob Joseph 			goto err_exit;
3192b74652f3SRagothaman Jayaraman 		}
3193b74652f3SRagothaman Jayaraman 
3194b74652f3SRagothaman Jayaraman 	} else {
3195b74652f3SRagothaman Jayaraman 		/* Out of place processing */
3196b74652f3SRagothaman Jayaraman 		fc_params.src_iov = (void *)src;
3197b74652f3SRagothaman Jayaraman 		fc_params.dst_iov = (void *)dst;
3198b74652f3SRagothaman Jayaraman 
3199b74652f3SRagothaman Jayaraman 		/* Store SG I/O in the api for reuse */
3200b74652f3SRagothaman Jayaraman 		if (prepare_iov_from_pkt(m_src, fc_params.src_iov, 0)) {
3201b74652f3SRagothaman Jayaraman 			CPT_LOG_DP_ERR("Prepare src iov failed");
3202f39928e6SAnoob Joseph 			ret = -EINVAL;
3203f39928e6SAnoob Joseph 			goto err_exit;
3204b74652f3SRagothaman Jayaraman 		}
3205b74652f3SRagothaman Jayaraman 
3206b74652f3SRagothaman Jayaraman 		if (unlikely(m_dst != NULL)) {
3207b74652f3SRagothaman Jayaraman 			uint32_t pkt_len;
3208b74652f3SRagothaman Jayaraman 
3209b74652f3SRagothaman Jayaraman 			/* Try to make room as much as src has */
3210b74652f3SRagothaman Jayaraman 			pkt_len = rte_pktmbuf_pkt_len(m_dst);
3211b74652f3SRagothaman Jayaraman 
3212b74652f3SRagothaman Jayaraman 			if (unlikely(pkt_len < rte_pktmbuf_pkt_len(m_src))) {
3213b74652f3SRagothaman Jayaraman 				pkt_len = rte_pktmbuf_pkt_len(m_src) - pkt_len;
3214b74652f3SRagothaman Jayaraman 				if (!rte_pktmbuf_append(m_dst, pkt_len)) {
3215b74652f3SRagothaman Jayaraman 					CPT_LOG_DP_ERR("Not enough space in "
3216b74652f3SRagothaman Jayaraman 						       "m_dst %p, need %u"
3217b74652f3SRagothaman Jayaraman 						       " more",
3218b74652f3SRagothaman Jayaraman 						       m_dst, pkt_len);
3219f39928e6SAnoob Joseph 					ret = -EINVAL;
3220f39928e6SAnoob Joseph 					goto err_exit;
3221b74652f3SRagothaman Jayaraman 				}
3222b74652f3SRagothaman Jayaraman 			}
3223b74652f3SRagothaman Jayaraman 
3224b74652f3SRagothaman Jayaraman 			if (prepare_iov_from_pkt(m_dst, fc_params.dst_iov, 0)) {
3225b74652f3SRagothaman Jayaraman 				CPT_LOG_DP_ERR("Prepare dst iov failed for "
3226b74652f3SRagothaman Jayaraman 					       "m_dst %p", m_dst);
3227f39928e6SAnoob Joseph 				ret = -EINVAL;
3228f39928e6SAnoob Joseph 				goto err_exit;
3229b74652f3SRagothaman Jayaraman 			}
3230b74652f3SRagothaman Jayaraman 		} else {
3231b74652f3SRagothaman Jayaraman 			fc_params.dst_iov = (void *)src;
3232b74652f3SRagothaman Jayaraman 		}
3233b74652f3SRagothaman Jayaraman 	}
3234b74652f3SRagothaman Jayaraman 
3235b74652f3SRagothaman Jayaraman 	if (likely(flags & SINGLE_BUF_HEADTAILROOM))
3236ec54bc9dSAnoob Joseph 		mdata = alloc_op_meta(m_src, &fc_params.meta_buf,
3237ec54bc9dSAnoob Joseph 				      m_info->lb_mlen, m_info->pool);
3238b74652f3SRagothaman Jayaraman 	else
3239ec54bc9dSAnoob Joseph 		mdata = alloc_op_meta(NULL, &fc_params.meta_buf,
3240ec54bc9dSAnoob Joseph 				      m_info->sg_mlen, m_info->pool);
3241b74652f3SRagothaman Jayaraman 
3242b74652f3SRagothaman Jayaraman 	if (unlikely(mdata == NULL)) {
3243b74652f3SRagothaman Jayaraman 		CPT_LOG_DP_ERR("Error allocating meta buffer for request");
3244f39928e6SAnoob Joseph 		ret = -ENOMEM;
3245f39928e6SAnoob Joseph 		goto err_exit;
3246b74652f3SRagothaman Jayaraman 	}
3247b74652f3SRagothaman Jayaraman 
3248b74652f3SRagothaman Jayaraman 	op = (uintptr_t *)((uintptr_t)mdata & (uintptr_t)~1ull);
3249b74652f3SRagothaman Jayaraman 	op[0] = (uintptr_t)mdata;
3250b74652f3SRagothaman Jayaraman 	op[1] = (uintptr_t)cop;
3251b74652f3SRagothaman Jayaraman 	op[2] = op[3] = 0; /* Used to indicate auth verify */
3252b74652f3SRagothaman Jayaraman 	space += 4 * sizeof(uint64_t);
3253b74652f3SRagothaman Jayaraman 
3254b74652f3SRagothaman Jayaraman 	fc_params.meta_buf.vaddr = (uint8_t *)op + space;
3255b74652f3SRagothaman Jayaraman 	fc_params.meta_buf.dma_addr += space;
3256b74652f3SRagothaman Jayaraman 	fc_params.meta_buf.size -= space;
3257b74652f3SRagothaman Jayaraman 
3258b74652f3SRagothaman Jayaraman 	/* Finally prepare the instruction */
3259b74652f3SRagothaman Jayaraman 	if (cpt_op & CPT_OP_ENCODE)
3260f39928e6SAnoob Joseph 		*prep_req = cpt_fc_enc_hmac_prep(flags, d_offs, d_lens,
3261f39928e6SAnoob Joseph 						 &fc_params, op);
3262177b41ceSRagothaman Jayaraman 	else
3263f39928e6SAnoob Joseph 		*prep_req = cpt_fc_dec_hmac_prep(flags, d_offs, d_lens,
3264f39928e6SAnoob Joseph 						 &fc_params, op);
3265b74652f3SRagothaman Jayaraman 
3266f39928e6SAnoob Joseph 	if (unlikely(*prep_req == NULL)) {
3267f39928e6SAnoob Joseph 		CPT_LOG_DP_ERR("Preparing request failed due to bad input arg");
3268f39928e6SAnoob Joseph 		ret = -EINVAL;
3269f39928e6SAnoob Joseph 		goto free_mdata_and_exit;
3270f39928e6SAnoob Joseph 	}
3271f39928e6SAnoob Joseph 
3272b74652f3SRagothaman Jayaraman 	*mdata_ptr = mdata;
3273f39928e6SAnoob Joseph 
3274f39928e6SAnoob Joseph 	return 0;
3275f39928e6SAnoob Joseph 
3276f39928e6SAnoob Joseph free_mdata_and_exit:
3277ec54bc9dSAnoob Joseph 	free_op_meta(mdata, m_info->pool);
3278f39928e6SAnoob Joseph err_exit:
3279f39928e6SAnoob Joseph 	return ret;
3280b74652f3SRagothaman Jayaraman }
3281b74652f3SRagothaman Jayaraman 
328289f1a8d6STejasree Kondoj static __rte_always_inline void
328389f1a8d6STejasree Kondoj compl_auth_verify(struct rte_crypto_op *op,
328489f1a8d6STejasree Kondoj 		      uint8_t *gen_mac,
328589f1a8d6STejasree Kondoj 		      uint64_t mac_len)
328689f1a8d6STejasree Kondoj {
328789f1a8d6STejasree Kondoj 	uint8_t *mac;
328889f1a8d6STejasree Kondoj 	struct rte_crypto_sym_op *sym_op = op->sym;
328989f1a8d6STejasree Kondoj 
329089f1a8d6STejasree Kondoj 	if (sym_op->auth.digest.data)
329189f1a8d6STejasree Kondoj 		mac = sym_op->auth.digest.data;
329289f1a8d6STejasree Kondoj 	else
329389f1a8d6STejasree Kondoj 		mac = rte_pktmbuf_mtod_offset(sym_op->m_src,
329489f1a8d6STejasree Kondoj 					      uint8_t *,
329589f1a8d6STejasree Kondoj 					      sym_op->auth.data.length +
329689f1a8d6STejasree Kondoj 					      sym_op->auth.data.offset);
329789f1a8d6STejasree Kondoj 	if (!mac) {
329889f1a8d6STejasree Kondoj 		op->status = RTE_CRYPTO_OP_STATUS_ERROR;
329989f1a8d6STejasree Kondoj 		return;
330089f1a8d6STejasree Kondoj 	}
330189f1a8d6STejasree Kondoj 
330289f1a8d6STejasree Kondoj 	if (memcmp(mac, gen_mac, mac_len))
330389f1a8d6STejasree Kondoj 		op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
330489f1a8d6STejasree Kondoj 	else
330589f1a8d6STejasree Kondoj 		op->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
330689f1a8d6STejasree Kondoj }
330789f1a8d6STejasree Kondoj 
3308351fbee2SSrisivasubramanian S static __rte_always_inline void
3309351fbee2SSrisivasubramanian S find_kasumif9_direction_and_length(uint8_t *src,
3310351fbee2SSrisivasubramanian S 				   uint32_t counter_num_bytes,
3311351fbee2SSrisivasubramanian S 				   uint32_t *addr_length_in_bits,
3312351fbee2SSrisivasubramanian S 				   uint8_t *addr_direction)
3313351fbee2SSrisivasubramanian S {
3314351fbee2SSrisivasubramanian S 	uint8_t found = 0;
3315f9494b67SAnkur Dwivedi 	uint32_t pos;
3316f9494b67SAnkur Dwivedi 	uint8_t last_byte;
3317351fbee2SSrisivasubramanian S 	while (!found && counter_num_bytes > 0) {
3318351fbee2SSrisivasubramanian S 		counter_num_bytes--;
3319351fbee2SSrisivasubramanian S 		if (src[counter_num_bytes] == 0x00)
3320351fbee2SSrisivasubramanian S 			continue;
3321f9494b67SAnkur Dwivedi 		pos = rte_bsf32(src[counter_num_bytes]);
3322f9494b67SAnkur Dwivedi 		if (pos == 7) {
3323f9494b67SAnkur Dwivedi 			if (likely(counter_num_bytes > 0)) {
3324f9494b67SAnkur Dwivedi 				last_byte = src[counter_num_bytes - 1];
3325f9494b67SAnkur Dwivedi 				*addr_direction  =  last_byte & 0x1;
3326f9494b67SAnkur Dwivedi 				*addr_length_in_bits = counter_num_bytes * 8
3327f9494b67SAnkur Dwivedi 							- 1;
3328f9494b67SAnkur Dwivedi 			}
3329351fbee2SSrisivasubramanian S 		} else {
3330f9494b67SAnkur Dwivedi 			last_byte = src[counter_num_bytes];
3331f9494b67SAnkur Dwivedi 			*addr_direction = (last_byte >> (pos + 1)) & 0x1;
3332f9494b67SAnkur Dwivedi 			*addr_length_in_bits = counter_num_bytes * 8
3333f9494b67SAnkur Dwivedi 						+ (8 - (pos + 2));
3334f9494b67SAnkur Dwivedi 		}
3335351fbee2SSrisivasubramanian S 		found = 1;
3336351fbee2SSrisivasubramanian S 	}
3337351fbee2SSrisivasubramanian S }
3338351fbee2SSrisivasubramanian S 
3339351fbee2SSrisivasubramanian S /*
3340351fbee2SSrisivasubramanian S  * This handles all auth only except AES_GMAC
3341351fbee2SSrisivasubramanian S  */
3342f39928e6SAnoob Joseph static __rte_always_inline int
3343351fbee2SSrisivasubramanian S fill_digest_params(struct rte_crypto_op *cop,
3344351fbee2SSrisivasubramanian S 		   struct cpt_sess_misc *sess,
3345ec54bc9dSAnoob Joseph 		   struct cpt_qp_meta_info *m_info,
3346351fbee2SSrisivasubramanian S 		   void **mdata_ptr,
3347f39928e6SAnoob Joseph 		   void **prep_req)
3348351fbee2SSrisivasubramanian S {
3349351fbee2SSrisivasubramanian S 	uint32_t space = 0;
3350351fbee2SSrisivasubramanian S 	struct rte_crypto_sym_op *sym_op = cop->sym;
3351351fbee2SSrisivasubramanian S 	void *mdata;
3352351fbee2SSrisivasubramanian S 	phys_addr_t mphys;
3353351fbee2SSrisivasubramanian S 	uint64_t *op;
3354351fbee2SSrisivasubramanian S 	uint32_t auth_range_off;
3355351fbee2SSrisivasubramanian S 	uint32_t flags = 0;
3356351fbee2SSrisivasubramanian S 	uint64_t d_offs = 0, d_lens;
3357351fbee2SSrisivasubramanian S 	struct rte_mbuf *m_src, *m_dst;
3358351fbee2SSrisivasubramanian S 	uint16_t auth_op = sess->cpt_op & CPT_OP_AUTH_MASK;
3359351fbee2SSrisivasubramanian S 	uint16_t mac_len = sess->mac_len;
3360351fbee2SSrisivasubramanian S 	fc_params_t params;
3361351fbee2SSrisivasubramanian S 	char src[SRC_IOV_SIZE];
3362351fbee2SSrisivasubramanian S 	uint8_t iv_buf[16];
3363f39928e6SAnoob Joseph 	int ret;
3364f39928e6SAnoob Joseph 
3365351fbee2SSrisivasubramanian S 	memset(&params, 0, sizeof(fc_params_t));
3366351fbee2SSrisivasubramanian S 
3367351fbee2SSrisivasubramanian S 	m_src = sym_op->m_src;
3368351fbee2SSrisivasubramanian S 
3369351fbee2SSrisivasubramanian S 	/* For just digest lets force mempool alloc */
3370ec54bc9dSAnoob Joseph 	mdata = alloc_op_meta(NULL, &params.meta_buf, m_info->sg_mlen,
3371ec54bc9dSAnoob Joseph 			      m_info->pool);
3372351fbee2SSrisivasubramanian S 	if (mdata == NULL) {
3373f39928e6SAnoob Joseph 		ret = -ENOMEM;
3374f39928e6SAnoob Joseph 		goto err_exit;
3375351fbee2SSrisivasubramanian S 	}
3376351fbee2SSrisivasubramanian S 
3377351fbee2SSrisivasubramanian S 	mphys = params.meta_buf.dma_addr;
3378351fbee2SSrisivasubramanian S 
3379351fbee2SSrisivasubramanian S 	op = mdata;
3380351fbee2SSrisivasubramanian S 	op[0] = (uintptr_t)mdata;
3381351fbee2SSrisivasubramanian S 	op[1] = (uintptr_t)cop;
3382351fbee2SSrisivasubramanian S 	op[2] = op[3] = 0; /* Used to indicate auth verify */
3383351fbee2SSrisivasubramanian S 	space += 4 * sizeof(uint64_t);
3384351fbee2SSrisivasubramanian S 
3385351fbee2SSrisivasubramanian S 	auth_range_off = sym_op->auth.data.offset;
3386351fbee2SSrisivasubramanian S 
3387351fbee2SSrisivasubramanian S 	flags = VALID_MAC_BUF;
3388351fbee2SSrisivasubramanian S 	params.src_iov = (void *)src;
33898de5ede7SAnoob Joseph 	if (unlikely(sess->zsk_flag)) {
3390351fbee2SSrisivasubramanian S 		/*
3391351fbee2SSrisivasubramanian S 		 * Since for Zuc, Kasumi, Snow3g offsets are in bits
3392351fbee2SSrisivasubramanian S 		 * we will send pass through even for auth only case,
3393351fbee2SSrisivasubramanian S 		 * let MC handle it
3394351fbee2SSrisivasubramanian S 		 */
3395351fbee2SSrisivasubramanian S 		d_offs = auth_range_off;
3396351fbee2SSrisivasubramanian S 		auth_range_off = 0;
3397351fbee2SSrisivasubramanian S 		params.auth_iv_buf = rte_crypto_op_ctod_offset(cop,
3398351fbee2SSrisivasubramanian S 					uint8_t *, sess->auth_iv_offset);
33998de5ede7SAnoob Joseph 		if (sess->zsk_flag == K_F9) {
3400351fbee2SSrisivasubramanian S 			uint32_t length_in_bits, num_bytes;
3401351fbee2SSrisivasubramanian S 			uint8_t *src, direction = 0;
3402351fbee2SSrisivasubramanian S 
3403351fbee2SSrisivasubramanian S 			memcpy(iv_buf, rte_pktmbuf_mtod(cop->sym->m_src,
3404351fbee2SSrisivasubramanian S 							uint8_t *), 8);
3405351fbee2SSrisivasubramanian S 			/*
3406351fbee2SSrisivasubramanian S 			 * This is kasumi f9, take direction from
3407351fbee2SSrisivasubramanian S 			 * source buffer
3408351fbee2SSrisivasubramanian S 			 */
3409351fbee2SSrisivasubramanian S 			length_in_bits = cop->sym->auth.data.length;
3410351fbee2SSrisivasubramanian S 			num_bytes = (length_in_bits >> 3);
3411351fbee2SSrisivasubramanian S 			src = rte_pktmbuf_mtod(cop->sym->m_src, uint8_t *);
3412351fbee2SSrisivasubramanian S 			find_kasumif9_direction_and_length(src,
34138de5ede7SAnoob Joseph 						num_bytes,
3414351fbee2SSrisivasubramanian S 						&length_in_bits,
3415351fbee2SSrisivasubramanian S 						&direction);
3416351fbee2SSrisivasubramanian S 			length_in_bits -= 64;
3417351fbee2SSrisivasubramanian S 			cop->sym->auth.data.offset += 64;
3418351fbee2SSrisivasubramanian S 			d_offs = cop->sym->auth.data.offset;
3419351fbee2SSrisivasubramanian S 			auth_range_off = d_offs / 8;
3420351fbee2SSrisivasubramanian S 			cop->sym->auth.data.length = length_in_bits;
3421351fbee2SSrisivasubramanian S 
3422351fbee2SSrisivasubramanian S 			/* Store it at end of auth iv */
3423351fbee2SSrisivasubramanian S 			iv_buf[8] = direction;
3424351fbee2SSrisivasubramanian S 			params.auth_iv_buf = iv_buf;
3425351fbee2SSrisivasubramanian S 		}
3426351fbee2SSrisivasubramanian S 	}
3427351fbee2SSrisivasubramanian S 
3428351fbee2SSrisivasubramanian S 	d_lens = sym_op->auth.data.length;
3429351fbee2SSrisivasubramanian S 
3430351fbee2SSrisivasubramanian S 	params.ctx_buf.vaddr = SESS_PRIV(sess);
3431351fbee2SSrisivasubramanian S 	params.ctx_buf.dma_addr = sess->ctx_dma_addr;
3432351fbee2SSrisivasubramanian S 
3433351fbee2SSrisivasubramanian S 	if (auth_op == CPT_OP_AUTH_GENERATE) {
3434351fbee2SSrisivasubramanian S 		if (sym_op->auth.digest.data) {
3435351fbee2SSrisivasubramanian S 			/*
3436351fbee2SSrisivasubramanian S 			 * Digest to be generated
3437351fbee2SSrisivasubramanian S 			 * in separate buffer
3438351fbee2SSrisivasubramanian S 			 */
3439351fbee2SSrisivasubramanian S 			params.mac_buf.size =
3440351fbee2SSrisivasubramanian S 				sess->mac_len;
3441351fbee2SSrisivasubramanian S 			params.mac_buf.vaddr =
3442351fbee2SSrisivasubramanian S 				sym_op->auth.digest.data;
3443351fbee2SSrisivasubramanian S 			params.mac_buf.dma_addr =
3444351fbee2SSrisivasubramanian S 				sym_op->auth.digest.phys_addr;
3445351fbee2SSrisivasubramanian S 		} else {
3446351fbee2SSrisivasubramanian S 			uint32_t off = sym_op->auth.data.offset +
3447351fbee2SSrisivasubramanian S 				sym_op->auth.data.length;
3448351fbee2SSrisivasubramanian S 			int32_t dlen, space;
3449351fbee2SSrisivasubramanian S 
3450351fbee2SSrisivasubramanian S 			m_dst = sym_op->m_dst ?
3451351fbee2SSrisivasubramanian S 				sym_op->m_dst : sym_op->m_src;
3452351fbee2SSrisivasubramanian S 			dlen = rte_pktmbuf_pkt_len(m_dst);
3453351fbee2SSrisivasubramanian S 
3454351fbee2SSrisivasubramanian S 			space = off + mac_len - dlen;
3455351fbee2SSrisivasubramanian S 			if (space > 0)
3456351fbee2SSrisivasubramanian S 				if (!rte_pktmbuf_append(m_dst, space)) {
3457351fbee2SSrisivasubramanian S 					CPT_LOG_DP_ERR("Failed to extend "
3458351fbee2SSrisivasubramanian S 						       "mbuf by %uB", space);
3459f39928e6SAnoob Joseph 					ret = -EINVAL;
3460f39928e6SAnoob Joseph 					goto free_mdata_and_exit;
3461351fbee2SSrisivasubramanian S 				}
3462351fbee2SSrisivasubramanian S 
3463351fbee2SSrisivasubramanian S 			params.mac_buf.vaddr =
3464351fbee2SSrisivasubramanian S 				rte_pktmbuf_mtod_offset(m_dst, void *, off);
3465351fbee2SSrisivasubramanian S 			params.mac_buf.dma_addr =
3466351fbee2SSrisivasubramanian S 				rte_pktmbuf_mtophys_offset(m_dst, off);
3467351fbee2SSrisivasubramanian S 			params.mac_buf.size = mac_len;
3468351fbee2SSrisivasubramanian S 		}
3469351fbee2SSrisivasubramanian S 	} else {
3470351fbee2SSrisivasubramanian S 		/* Need space for storing generated mac */
3471351fbee2SSrisivasubramanian S 		params.mac_buf.vaddr = (uint8_t *)mdata + space;
3472351fbee2SSrisivasubramanian S 		params.mac_buf.dma_addr = mphys + space;
3473351fbee2SSrisivasubramanian S 		params.mac_buf.size = mac_len;
3474351fbee2SSrisivasubramanian S 		space += RTE_ALIGN_CEIL(mac_len, 8);
3475351fbee2SSrisivasubramanian S 		op[2] = (uintptr_t)params.mac_buf.vaddr;
3476351fbee2SSrisivasubramanian S 		op[3] = mac_len;
3477351fbee2SSrisivasubramanian S 	}
3478351fbee2SSrisivasubramanian S 
3479351fbee2SSrisivasubramanian S 	params.meta_buf.vaddr = (uint8_t *)mdata + space;
3480351fbee2SSrisivasubramanian S 	params.meta_buf.dma_addr = mphys + space;
3481351fbee2SSrisivasubramanian S 	params.meta_buf.size -= space;
3482351fbee2SSrisivasubramanian S 
3483351fbee2SSrisivasubramanian S 	/* Out of place processing */
3484351fbee2SSrisivasubramanian S 	params.src_iov = (void *)src;
3485351fbee2SSrisivasubramanian S 
3486351fbee2SSrisivasubramanian S 	/*Store SG I/O in the api for reuse */
3487351fbee2SSrisivasubramanian S 	if (prepare_iov_from_pkt(m_src, params.src_iov, auth_range_off)) {
3488351fbee2SSrisivasubramanian S 		CPT_LOG_DP_ERR("Prepare src iov failed");
3489f39928e6SAnoob Joseph 		ret = -EINVAL;
3490f39928e6SAnoob Joseph 		goto free_mdata_and_exit;
3491351fbee2SSrisivasubramanian S 	}
3492351fbee2SSrisivasubramanian S 
3493f39928e6SAnoob Joseph 	*prep_req = cpt_fc_enc_hmac_prep(flags, d_offs, d_lens, &params, op);
3494f39928e6SAnoob Joseph 	if (unlikely(*prep_req == NULL)) {
3495f39928e6SAnoob Joseph 		ret = -EINVAL;
3496f39928e6SAnoob Joseph 		goto free_mdata_and_exit;
3497f39928e6SAnoob Joseph 	}
3498f39928e6SAnoob Joseph 
3499351fbee2SSrisivasubramanian S 	*mdata_ptr = mdata;
3500f39928e6SAnoob Joseph 
3501f39928e6SAnoob Joseph 	return 0;
3502f39928e6SAnoob Joseph 
3503f39928e6SAnoob Joseph free_mdata_and_exit:
3504ec54bc9dSAnoob Joseph 	free_op_meta(mdata, m_info->pool);
3505f39928e6SAnoob Joseph err_exit:
3506f39928e6SAnoob Joseph 	return ret;
3507351fbee2SSrisivasubramanian S }
3508351fbee2SSrisivasubramanian S 
350943d01767SNithin Dabilpuram #endif /*_CPT_UCODE_H_ */
3510