xref: /dpdk/drivers/common/cpt/cpt_ucode.h (revision f665790a5dbad7b645ff46f31d65e977324e7bfc)
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 
387293bae1SArchana Muniganti static __rte_always_inline int
397293bae1SArchana Muniganti cpt_mac_len_verify(struct rte_crypto_auth_xform *auth)
407293bae1SArchana Muniganti {
417293bae1SArchana Muniganti 	uint16_t mac_len = auth->digest_length;
427293bae1SArchana Muniganti 	int ret;
437293bae1SArchana Muniganti 
448d8afdecSTejasree Kondoj 	if ((auth->algo != RTE_CRYPTO_AUTH_NULL) && (mac_len == 0))
458d8afdecSTejasree Kondoj 		return -1;
468d8afdecSTejasree Kondoj 
477293bae1SArchana Muniganti 	switch (auth->algo) {
487293bae1SArchana Muniganti 	case RTE_CRYPTO_AUTH_MD5:
497293bae1SArchana Muniganti 	case RTE_CRYPTO_AUTH_MD5_HMAC:
508d8afdecSTejasree Kondoj 		ret = (mac_len <= 16) ? 0 : -1;
517293bae1SArchana Muniganti 		break;
527293bae1SArchana Muniganti 	case RTE_CRYPTO_AUTH_SHA1:
537293bae1SArchana Muniganti 	case RTE_CRYPTO_AUTH_SHA1_HMAC:
548d8afdecSTejasree Kondoj 		ret = (mac_len <= 20) ? 0 : -1;
557293bae1SArchana Muniganti 		break;
567293bae1SArchana Muniganti 	case RTE_CRYPTO_AUTH_SHA224:
577293bae1SArchana Muniganti 	case RTE_CRYPTO_AUTH_SHA224_HMAC:
588d8afdecSTejasree Kondoj 		ret = (mac_len <= 28) ? 0 : -1;
597293bae1SArchana Muniganti 		break;
607293bae1SArchana Muniganti 	case RTE_CRYPTO_AUTH_SHA256:
617293bae1SArchana Muniganti 	case RTE_CRYPTO_AUTH_SHA256_HMAC:
628d8afdecSTejasree Kondoj 		ret = (mac_len <= 32) ? 0 : -1;
637293bae1SArchana Muniganti 		break;
647293bae1SArchana Muniganti 	case RTE_CRYPTO_AUTH_SHA384:
657293bae1SArchana Muniganti 	case RTE_CRYPTO_AUTH_SHA384_HMAC:
668d8afdecSTejasree Kondoj 		ret = (mac_len <= 48) ? 0 : -1;
677293bae1SArchana Muniganti 		break;
687293bae1SArchana Muniganti 	case RTE_CRYPTO_AUTH_SHA512:
697293bae1SArchana Muniganti 	case RTE_CRYPTO_AUTH_SHA512_HMAC:
708d8afdecSTejasree Kondoj 		ret = (mac_len <= 64) ? 0 : -1;
717293bae1SArchana Muniganti 		break;
727293bae1SArchana Muniganti 	case RTE_CRYPTO_AUTH_NULL:
737293bae1SArchana Muniganti 		ret = 0;
747293bae1SArchana Muniganti 		break;
757293bae1SArchana Muniganti 	default:
767293bae1SArchana Muniganti 		ret = -1;
777293bae1SArchana Muniganti 	}
787293bae1SArchana Muniganti 
797293bae1SArchana Muniganti 	return ret;
807293bae1SArchana Muniganti }
817293bae1SArchana Muniganti 
82b74652f3SRagothaman Jayaraman static __rte_always_inline void
836045c06aSArchana Muniganti cpt_fc_salt_update(struct cpt_ctx *cpt_ctx,
84b74652f3SRagothaman Jayaraman 		   uint8_t *salt)
85b74652f3SRagothaman Jayaraman {
866045c06aSArchana Muniganti 	mc_fc_context_t *fctx = &cpt_ctx->mc_ctx.fctx;
876045c06aSArchana Muniganti 	memcpy(fctx->enc.encr_iv, salt, 4);
88b74652f3SRagothaman Jayaraman }
89b74652f3SRagothaman Jayaraman 
906cc54096SNithin Dabilpuram static __rte_always_inline int
916cc54096SNithin Dabilpuram cpt_fc_ciph_validate_key_aes(uint16_t key_len)
926cc54096SNithin Dabilpuram {
936cc54096SNithin Dabilpuram 	switch (key_len) {
94b67ecf3eSArchana Muniganti 	case 16:
95b67ecf3eSArchana Muniganti 	case 24:
96b67ecf3eSArchana Muniganti 	case 32:
976cc54096SNithin Dabilpuram 		return 0;
986cc54096SNithin Dabilpuram 	default:
996cc54096SNithin Dabilpuram 		return -1;
1006cc54096SNithin Dabilpuram 	}
1016cc54096SNithin Dabilpuram }
1026cc54096SNithin Dabilpuram 
1036cc54096SNithin Dabilpuram static __rte_always_inline int
1048de5ede7SAnoob Joseph cpt_fc_ciph_set_type(cipher_type_t type, struct cpt_ctx *ctx, uint16_t key_len)
1056cc54096SNithin Dabilpuram {
1066cc54096SNithin Dabilpuram 	int fc_type = 0;
1076cc54096SNithin Dabilpuram 	switch (type) {
1086cc54096SNithin Dabilpuram 	case PASSTHROUGH:
1096cc54096SNithin Dabilpuram 		fc_type = FC_GEN;
1106cc54096SNithin Dabilpuram 		break;
1116cc54096SNithin Dabilpuram 	case DES3_CBC:
1126cc54096SNithin Dabilpuram 	case DES3_ECB:
1136cc54096SNithin Dabilpuram 		fc_type = FC_GEN;
1146cc54096SNithin Dabilpuram 		break;
1156cc54096SNithin Dabilpuram 	case AES_CBC:
1166cc54096SNithin Dabilpuram 	case AES_ECB:
1176cc54096SNithin Dabilpuram 	case AES_CFB:
1186cc54096SNithin Dabilpuram 	case AES_CTR:
1196cc54096SNithin Dabilpuram 	case AES_GCM:
1206cc54096SNithin Dabilpuram 		if (unlikely(cpt_fc_ciph_validate_key_aes(key_len) != 0))
1216cc54096SNithin Dabilpuram 			return -1;
1226cc54096SNithin Dabilpuram 		fc_type = FC_GEN;
1236cc54096SNithin Dabilpuram 		break;
124cb7842f2STejasree Kondoj 	case CHACHA20:
125cb7842f2STejasree Kondoj 		fc_type = FC_GEN;
126cb7842f2STejasree Kondoj 		break;
1276cc54096SNithin Dabilpuram 	case AES_XTS:
1286cc54096SNithin Dabilpuram 		key_len = key_len / 2;
129b67ecf3eSArchana Muniganti 		if (unlikely(key_len == 24)) {
1306cc54096SNithin Dabilpuram 			CPT_LOG_DP_ERR("Invalid AES key len for XTS");
1316cc54096SNithin Dabilpuram 			return -1;
1326cc54096SNithin Dabilpuram 		}
1336cc54096SNithin Dabilpuram 		if (unlikely(cpt_fc_ciph_validate_key_aes(key_len) != 0))
1346cc54096SNithin Dabilpuram 			return -1;
1356cc54096SNithin Dabilpuram 		fc_type = FC_GEN;
1366cc54096SNithin Dabilpuram 		break;
1376cc54096SNithin Dabilpuram 	case ZUC_EEA3:
1386cc54096SNithin Dabilpuram 	case SNOW3G_UEA2:
1396cc54096SNithin Dabilpuram 		if (unlikely(key_len != 16))
1406cc54096SNithin Dabilpuram 			return -1;
1416cc54096SNithin Dabilpuram 		/* No support for AEAD yet */
1428de5ede7SAnoob Joseph 		if (unlikely(ctx->hash_type))
1436cc54096SNithin Dabilpuram 			return -1;
1446cc54096SNithin Dabilpuram 		fc_type = ZUC_SNOW3G;
1456cc54096SNithin Dabilpuram 		break;
1466cc54096SNithin Dabilpuram 	case KASUMI_F8_CBC:
1476cc54096SNithin Dabilpuram 	case KASUMI_F8_ECB:
1486cc54096SNithin Dabilpuram 		if (unlikely(key_len != 16))
1496cc54096SNithin Dabilpuram 			return -1;
1506cc54096SNithin Dabilpuram 		/* No support for AEAD yet */
1518de5ede7SAnoob Joseph 		if (unlikely(ctx->hash_type))
1526cc54096SNithin Dabilpuram 			return -1;
1536cc54096SNithin Dabilpuram 		fc_type = KASUMI;
1546cc54096SNithin Dabilpuram 		break;
1556cc54096SNithin Dabilpuram 	default:
1566cc54096SNithin Dabilpuram 		return -1;
1576cc54096SNithin Dabilpuram 	}
1588de5ede7SAnoob Joseph 
1598de5ede7SAnoob Joseph 	ctx->fc_type = fc_type;
1608de5ede7SAnoob Joseph 	return 0;
1616cc54096SNithin Dabilpuram }
1626cc54096SNithin Dabilpuram 
1636cc54096SNithin Dabilpuram static __rte_always_inline void
1646cc54096SNithin Dabilpuram cpt_fc_ciph_set_key_passthrough(struct cpt_ctx *cpt_ctx, mc_fc_context_t *fctx)
1656cc54096SNithin Dabilpuram {
1666cc54096SNithin Dabilpuram 	cpt_ctx->enc_cipher = 0;
167c3d0bc45SAnoob Joseph 	fctx->enc.enc_cipher = 0;
1686cc54096SNithin Dabilpuram }
1696cc54096SNithin Dabilpuram 
1706cc54096SNithin Dabilpuram static __rte_always_inline void
1716cc54096SNithin Dabilpuram cpt_fc_ciph_set_key_set_aes_key_type(mc_fc_context_t *fctx, uint16_t key_len)
1726cc54096SNithin Dabilpuram {
1736cc54096SNithin Dabilpuram 	mc_aes_type_t aes_key_type = 0;
1746cc54096SNithin Dabilpuram 	switch (key_len) {
175b67ecf3eSArchana Muniganti 	case 16:
1766cc54096SNithin Dabilpuram 		aes_key_type = AES_128_BIT;
1776cc54096SNithin Dabilpuram 		break;
178b67ecf3eSArchana Muniganti 	case 24:
1796cc54096SNithin Dabilpuram 		aes_key_type = AES_192_BIT;
1806cc54096SNithin Dabilpuram 		break;
181b67ecf3eSArchana Muniganti 	case 32:
1826cc54096SNithin Dabilpuram 		aes_key_type = AES_256_BIT;
1836cc54096SNithin Dabilpuram 		break;
1846cc54096SNithin Dabilpuram 	default:
1856cc54096SNithin Dabilpuram 		/* This should not happen */
1866cc54096SNithin Dabilpuram 		CPT_LOG_DP_ERR("Invalid AES key len");
1876cc54096SNithin Dabilpuram 		return;
1886cc54096SNithin Dabilpuram 	}
189c3d0bc45SAnoob Joseph 	fctx->enc.aes_key = aes_key_type;
1906cc54096SNithin Dabilpuram }
1916cc54096SNithin Dabilpuram 
1926cc54096SNithin Dabilpuram static __rte_always_inline void
193186b14d6SFan Zhang cpt_fc_ciph_set_key_snow3g_uea2(struct cpt_ctx *cpt_ctx, const uint8_t *key,
1946cc54096SNithin Dabilpuram 		uint16_t key_len)
1956cc54096SNithin Dabilpuram {
1966045c06aSArchana Muniganti 	mc_zuc_snow3g_ctx_t *zs_ctx = &cpt_ctx->mc_ctx.zs_ctx;
1976cc54096SNithin Dabilpuram 	uint32_t keyx[4];
1986045c06aSArchana Muniganti 
1996cc54096SNithin Dabilpuram 	cpt_ctx->snow3g = 1;
2006cc54096SNithin Dabilpuram 	gen_key_snow3g(key, keyx);
2016045c06aSArchana Muniganti 	memcpy(zs_ctx->ci_key, keyx, key_len);
2026cc54096SNithin Dabilpuram 	cpt_ctx->zsk_flags = 0;
2036cc54096SNithin Dabilpuram }
2046cc54096SNithin Dabilpuram 
2056cc54096SNithin Dabilpuram static __rte_always_inline void
206186b14d6SFan Zhang cpt_fc_ciph_set_key_zuc_eea3(struct cpt_ctx *cpt_ctx, const uint8_t *key,
2076cc54096SNithin Dabilpuram 		uint16_t key_len)
2086cc54096SNithin Dabilpuram {
2096045c06aSArchana Muniganti 	mc_zuc_snow3g_ctx_t *zs_ctx = &cpt_ctx->mc_ctx.zs_ctx;
2106045c06aSArchana Muniganti 
2116cc54096SNithin Dabilpuram 	cpt_ctx->snow3g = 0;
2126045c06aSArchana Muniganti 	memcpy(zs_ctx->ci_key, key, key_len);
2136045c06aSArchana Muniganti 	memcpy(zs_ctx->zuc_const, zuc_d, 32);
2146cc54096SNithin Dabilpuram 	cpt_ctx->zsk_flags = 0;
2156cc54096SNithin Dabilpuram }
2166cc54096SNithin Dabilpuram 
2176cc54096SNithin Dabilpuram static __rte_always_inline void
218186b14d6SFan Zhang cpt_fc_ciph_set_key_kasumi_f8_ecb(struct cpt_ctx *cpt_ctx, const uint8_t *key,
2196cc54096SNithin Dabilpuram 		uint16_t key_len)
2206cc54096SNithin Dabilpuram {
2216045c06aSArchana Muniganti 	mc_kasumi_ctx_t *k_ctx = &cpt_ctx->mc_ctx.k_ctx;
2226045c06aSArchana Muniganti 
2236cc54096SNithin Dabilpuram 	cpt_ctx->k_ecb = 1;
2246045c06aSArchana Muniganti 	memcpy(k_ctx->ci_key, key, key_len);
2256cc54096SNithin Dabilpuram 	cpt_ctx->zsk_flags = 0;
2266cc54096SNithin Dabilpuram }
2276cc54096SNithin Dabilpuram 
2286cc54096SNithin Dabilpuram static __rte_always_inline void
229186b14d6SFan Zhang cpt_fc_ciph_set_key_kasumi_f8_cbc(struct cpt_ctx *cpt_ctx, const uint8_t *key,
2306cc54096SNithin Dabilpuram 		uint16_t key_len)
2316cc54096SNithin Dabilpuram {
2326045c06aSArchana Muniganti 	mc_kasumi_ctx_t *k_ctx = &cpt_ctx->mc_ctx.k_ctx;
2336045c06aSArchana Muniganti 
2346045c06aSArchana Muniganti 	memcpy(k_ctx->ci_key, key, key_len);
2356cc54096SNithin Dabilpuram 	cpt_ctx->zsk_flags = 0;
2366cc54096SNithin Dabilpuram }
2376cc54096SNithin Dabilpuram 
2386cc54096SNithin Dabilpuram static __rte_always_inline int
2396045c06aSArchana Muniganti cpt_fc_ciph_set_key(struct cpt_ctx *cpt_ctx, cipher_type_t type,
2406045c06aSArchana Muniganti 		    const uint8_t *key, uint16_t key_len, uint8_t *salt)
2416cc54096SNithin Dabilpuram {
2426045c06aSArchana Muniganti 	mc_fc_context_t *fctx = &cpt_ctx->mc_ctx.fctx;
2438de5ede7SAnoob Joseph 	int ret;
2446cc54096SNithin Dabilpuram 
2458de5ede7SAnoob Joseph 	ret = cpt_fc_ciph_set_type(type, cpt_ctx, key_len);
2468de5ede7SAnoob Joseph 	if (unlikely(ret))
2476cc54096SNithin Dabilpuram 		return -1;
2486cc54096SNithin Dabilpuram 
2498de5ede7SAnoob Joseph 	if (cpt_ctx->fc_type == FC_GEN) {
2506cc54096SNithin Dabilpuram 		/*
2516cc54096SNithin Dabilpuram 		 * We need to always say IV is from DPTR as user can
2527be78d02SJosh Soref 		 * sometimes override IV per operation.
2536cc54096SNithin Dabilpuram 		 */
254c3d0bc45SAnoob Joseph 		fctx->enc.iv_source = CPT_FROM_DPTR;
2552839a8abSSucharitha Sarananaga 
2562839a8abSSucharitha Sarananaga 		if (cpt_ctx->auth_key_len > 64)
2572839a8abSSucharitha Sarananaga 			return -1;
2586cc54096SNithin Dabilpuram 	}
2596cc54096SNithin Dabilpuram 
2606cc54096SNithin Dabilpuram 	switch (type) {
2616cc54096SNithin Dabilpuram 	case PASSTHROUGH:
2626cc54096SNithin Dabilpuram 		cpt_fc_ciph_set_key_passthrough(cpt_ctx, fctx);
263c3d0bc45SAnoob Joseph 		goto success;
2646cc54096SNithin Dabilpuram 	case DES3_CBC:
2656cc54096SNithin Dabilpuram 		/* CPT performs DES using 3DES with the 8B DES-key
2666cc54096SNithin Dabilpuram 		 * replicated 2 more times to match the 24B 3DES-key.
2676cc54096SNithin Dabilpuram 		 * Eg. If org. key is "0x0a 0x0b", then new key is
2686cc54096SNithin Dabilpuram 		 * "0x0a 0x0b 0x0a 0x0b 0x0a 0x0b"
2696cc54096SNithin Dabilpuram 		 */
2706cc54096SNithin Dabilpuram 		if (key_len == 8) {
2716cc54096SNithin Dabilpuram 			/* Skipping the first 8B as it will be copied
2726cc54096SNithin Dabilpuram 			 * in the regular code flow
2736cc54096SNithin Dabilpuram 			 */
2746cc54096SNithin Dabilpuram 			memcpy(fctx->enc.encr_key+key_len, key, key_len);
2756cc54096SNithin Dabilpuram 			memcpy(fctx->enc.encr_key+2*key_len, key, key_len);
2766cc54096SNithin Dabilpuram 		}
2776cc54096SNithin Dabilpuram 		break;
2786cc54096SNithin Dabilpuram 	case DES3_ECB:
2796cc54096SNithin Dabilpuram 		/* For DES3_ECB IV need to be from CTX. */
280c3d0bc45SAnoob Joseph 		fctx->enc.iv_source = CPT_FROM_CTX;
2816cc54096SNithin Dabilpuram 		break;
2826cc54096SNithin Dabilpuram 	case AES_CBC:
2836cc54096SNithin Dabilpuram 	case AES_ECB:
2846cc54096SNithin Dabilpuram 	case AES_CFB:
2856cc54096SNithin Dabilpuram 	case AES_CTR:
286cb7842f2STejasree Kondoj 	case CHACHA20:
2876cc54096SNithin Dabilpuram 		cpt_fc_ciph_set_key_set_aes_key_type(fctx, key_len);
2886cc54096SNithin Dabilpuram 		break;
2896cc54096SNithin Dabilpuram 	case AES_GCM:
2906cc54096SNithin Dabilpuram 		/* Even though iv source is from dptr,
2916cc54096SNithin Dabilpuram 		 * aes_gcm salt is taken from ctx
2926cc54096SNithin Dabilpuram 		 */
2936cc54096SNithin Dabilpuram 		if (salt) {
2946cc54096SNithin Dabilpuram 			memcpy(fctx->enc.encr_iv, salt, 4);
2956cc54096SNithin Dabilpuram 			/* Assuming it was just salt update
2966cc54096SNithin Dabilpuram 			 * and nothing else
2976cc54096SNithin Dabilpuram 			 */
2986cc54096SNithin Dabilpuram 			if (!key)
299c3d0bc45SAnoob Joseph 				goto success;
3006cc54096SNithin Dabilpuram 		}
3016cc54096SNithin Dabilpuram 		cpt_fc_ciph_set_key_set_aes_key_type(fctx, key_len);
3026cc54096SNithin Dabilpuram 		break;
3036cc54096SNithin Dabilpuram 	case AES_XTS:
3046cc54096SNithin Dabilpuram 		key_len = key_len / 2;
3056cc54096SNithin Dabilpuram 		cpt_fc_ciph_set_key_set_aes_key_type(fctx, key_len);
3066cc54096SNithin Dabilpuram 
3076cc54096SNithin Dabilpuram 		/* Copy key2 for XTS into ipad */
3086cc54096SNithin Dabilpuram 		memset(fctx->hmac.ipad, 0, sizeof(fctx->hmac.ipad));
3096cc54096SNithin Dabilpuram 		memcpy(fctx->hmac.ipad, &key[key_len], key_len);
3106cc54096SNithin Dabilpuram 		break;
3116cc54096SNithin Dabilpuram 	case SNOW3G_UEA2:
3126cc54096SNithin Dabilpuram 		cpt_fc_ciph_set_key_snow3g_uea2(cpt_ctx, key, key_len);
3136cc54096SNithin Dabilpuram 		goto success;
3146cc54096SNithin Dabilpuram 	case ZUC_EEA3:
3156cc54096SNithin Dabilpuram 		cpt_fc_ciph_set_key_zuc_eea3(cpt_ctx, key, key_len);
3166cc54096SNithin Dabilpuram 		goto success;
3176cc54096SNithin Dabilpuram 	case KASUMI_F8_ECB:
3186cc54096SNithin Dabilpuram 		cpt_fc_ciph_set_key_kasumi_f8_ecb(cpt_ctx, key, key_len);
3196cc54096SNithin Dabilpuram 		goto success;
3206cc54096SNithin Dabilpuram 	case KASUMI_F8_CBC:
3216cc54096SNithin Dabilpuram 		cpt_fc_ciph_set_key_kasumi_f8_cbc(cpt_ctx, key, key_len);
3226cc54096SNithin Dabilpuram 		goto success;
3236cc54096SNithin Dabilpuram 	default:
324e40175c5SArchana Muniganti 		return -1;
3256cc54096SNithin Dabilpuram 	}
3266cc54096SNithin Dabilpuram 
3276cc54096SNithin Dabilpuram 	/* Only for FC_GEN case */
3286cc54096SNithin Dabilpuram 
3296cc54096SNithin Dabilpuram 	/* For GMAC auth, cipher must be NULL */
3306cc54096SNithin Dabilpuram 	if (cpt_ctx->hash_type != GMAC_TYPE)
331c3d0bc45SAnoob Joseph 		fctx->enc.enc_cipher = type;
3326cc54096SNithin Dabilpuram 
3336cc54096SNithin Dabilpuram 	memcpy(fctx->enc.encr_key, key, key_len);
3346cc54096SNithin Dabilpuram 
3356cc54096SNithin Dabilpuram success:
3366cc54096SNithin Dabilpuram 	cpt_ctx->enc_cipher = type;
3376cc54096SNithin Dabilpuram 
3386cc54096SNithin Dabilpuram 	return 0;
3396cc54096SNithin Dabilpuram }
3406cc54096SNithin Dabilpuram 
341b74652f3SRagothaman Jayaraman static __rte_always_inline uint32_t
342b74652f3SRagothaman Jayaraman fill_sg_comp(sg_comp_t *list,
343b74652f3SRagothaman Jayaraman 	     uint32_t i,
344b74652f3SRagothaman Jayaraman 	     phys_addr_t dma_addr,
345b74652f3SRagothaman Jayaraman 	     uint32_t size)
346b74652f3SRagothaman Jayaraman {
347b74652f3SRagothaman Jayaraman 	sg_comp_t *to = &list[i>>2];
348b74652f3SRagothaman Jayaraman 
349b74652f3SRagothaman Jayaraman 	to->u.s.len[i%4] = rte_cpu_to_be_16(size);
350b74652f3SRagothaman Jayaraman 	to->ptr[i%4] = rte_cpu_to_be_64(dma_addr);
351b74652f3SRagothaman Jayaraman 	i++;
352b74652f3SRagothaman Jayaraman 	return i;
353b74652f3SRagothaman Jayaraman }
354b74652f3SRagothaman Jayaraman 
355b74652f3SRagothaman Jayaraman static __rte_always_inline uint32_t
356b74652f3SRagothaman Jayaraman fill_sg_comp_from_buf(sg_comp_t *list,
357b74652f3SRagothaman Jayaraman 		      uint32_t i,
358b74652f3SRagothaman Jayaraman 		      buf_ptr_t *from)
359b74652f3SRagothaman Jayaraman {
360b74652f3SRagothaman Jayaraman 	sg_comp_t *to = &list[i>>2];
361b74652f3SRagothaman Jayaraman 
362b74652f3SRagothaman Jayaraman 	to->u.s.len[i%4] = rte_cpu_to_be_16(from->size);
363b74652f3SRagothaman Jayaraman 	to->ptr[i%4] = rte_cpu_to_be_64(from->dma_addr);
364b74652f3SRagothaman Jayaraman 	i++;
365b74652f3SRagothaman Jayaraman 	return i;
366b74652f3SRagothaman Jayaraman }
367b74652f3SRagothaman Jayaraman 
368b74652f3SRagothaman Jayaraman static __rte_always_inline uint32_t
369b74652f3SRagothaman Jayaraman fill_sg_comp_from_buf_min(sg_comp_t *list,
370b74652f3SRagothaman Jayaraman 			  uint32_t i,
371b74652f3SRagothaman Jayaraman 			  buf_ptr_t *from,
372b74652f3SRagothaman Jayaraman 			  uint32_t *psize)
373b74652f3SRagothaman Jayaraman {
374b74652f3SRagothaman Jayaraman 	sg_comp_t *to = &list[i >> 2];
375b74652f3SRagothaman Jayaraman 	uint32_t size = *psize;
376b74652f3SRagothaman Jayaraman 	uint32_t e_len;
377b74652f3SRagothaman Jayaraman 
378b74652f3SRagothaman Jayaraman 	e_len = (size > from->size) ? from->size : size;
379b74652f3SRagothaman Jayaraman 	to->u.s.len[i % 4] = rte_cpu_to_be_16(e_len);
380b74652f3SRagothaman Jayaraman 	to->ptr[i % 4] = rte_cpu_to_be_64(from->dma_addr);
381b74652f3SRagothaman Jayaraman 	*psize -= e_len;
382b74652f3SRagothaman Jayaraman 	i++;
383b74652f3SRagothaman Jayaraman 	return i;
384b74652f3SRagothaman Jayaraman }
385b74652f3SRagothaman Jayaraman 
386b74652f3SRagothaman Jayaraman /*
387b74652f3SRagothaman Jayaraman  * This fills the MC expected SGIO list
388b74652f3SRagothaman Jayaraman  * from IOV given by user.
389b74652f3SRagothaman Jayaraman  */
390b74652f3SRagothaman Jayaraman static __rte_always_inline uint32_t
391b74652f3SRagothaman Jayaraman fill_sg_comp_from_iov(sg_comp_t *list,
392b74652f3SRagothaman Jayaraman 		      uint32_t i,
393b74652f3SRagothaman Jayaraman 		      iov_ptr_t *from, uint32_t from_offset,
394b74652f3SRagothaman Jayaraman 		      uint32_t *psize, buf_ptr_t *extra_buf,
395b74652f3SRagothaman Jayaraman 		      uint32_t extra_offset)
396b74652f3SRagothaman Jayaraman {
397b74652f3SRagothaman Jayaraman 	int32_t j;
398b74652f3SRagothaman Jayaraman 	uint32_t extra_len = extra_buf ? extra_buf->size : 0;
3990022ae1eSArchana Muniganti 	uint32_t size = *psize;
400b74652f3SRagothaman Jayaraman 
401b74652f3SRagothaman Jayaraman 	for (j = 0; (j < from->buf_cnt) && size; j++) {
4023aa16821SAnkur Dwivedi 		phys_addr_t dma_addr = from->bufs[j].dma_addr;
4033aa16821SAnkur Dwivedi 		uint32_t buf_sz = from->bufs[j].size;
4043aa16821SAnkur Dwivedi 		sg_comp_t *to = &list[i >> 2];
405b74652f3SRagothaman Jayaraman 		phys_addr_t e_dma_addr;
406b74652f3SRagothaman Jayaraman 		uint32_t e_len;
407b74652f3SRagothaman Jayaraman 
408b74652f3SRagothaman Jayaraman 		if (unlikely(from_offset)) {
4093aa16821SAnkur Dwivedi 			if (from_offset >= buf_sz) {
4103aa16821SAnkur Dwivedi 				from_offset -= buf_sz;
411b74652f3SRagothaman Jayaraman 				continue;
412b74652f3SRagothaman Jayaraman 			}
4133aa16821SAnkur Dwivedi 			e_dma_addr = dma_addr + from_offset;
4143aa16821SAnkur Dwivedi 			e_len = (size > (buf_sz - from_offset)) ?
4153aa16821SAnkur Dwivedi 				(buf_sz - from_offset) : size;
416b74652f3SRagothaman Jayaraman 			from_offset = 0;
417b74652f3SRagothaman Jayaraman 		} else {
4183aa16821SAnkur Dwivedi 			e_dma_addr = dma_addr;
4193aa16821SAnkur Dwivedi 			e_len = (size > buf_sz) ? buf_sz : size;
420b74652f3SRagothaman Jayaraman 		}
421b74652f3SRagothaman Jayaraman 
422b74652f3SRagothaman Jayaraman 		to->u.s.len[i % 4] = rte_cpu_to_be_16(e_len);
423b74652f3SRagothaman Jayaraman 		to->ptr[i % 4] = rte_cpu_to_be_64(e_dma_addr);
424b74652f3SRagothaman Jayaraman 
425b74652f3SRagothaman Jayaraman 		if (extra_len && (e_len >= extra_offset)) {
426b74652f3SRagothaman Jayaraman 			/* Break the data at given offset */
427b74652f3SRagothaman Jayaraman 			uint32_t next_len = e_len - extra_offset;
428b74652f3SRagothaman Jayaraman 			phys_addr_t next_dma = e_dma_addr + extra_offset;
429b74652f3SRagothaman Jayaraman 
430b74652f3SRagothaman Jayaraman 			if (!extra_offset) {
431b74652f3SRagothaman Jayaraman 				i--;
432b74652f3SRagothaman Jayaraman 			} else {
433b74652f3SRagothaman Jayaraman 				e_len = extra_offset;
434b74652f3SRagothaman Jayaraman 				size -= e_len;
435b74652f3SRagothaman Jayaraman 				to->u.s.len[i % 4] = rte_cpu_to_be_16(e_len);
436b74652f3SRagothaman Jayaraman 			}
437b74652f3SRagothaman Jayaraman 
4380022ae1eSArchana Muniganti 			extra_len = RTE_MIN(extra_len, size);
439b74652f3SRagothaman Jayaraman 			/* Insert extra data ptr */
440b74652f3SRagothaman Jayaraman 			if (extra_len) {
441b74652f3SRagothaman Jayaraman 				i++;
442b74652f3SRagothaman Jayaraman 				to = &list[i >> 2];
443b74652f3SRagothaman Jayaraman 				to->u.s.len[i % 4] =
4440022ae1eSArchana Muniganti 					rte_cpu_to_be_16(extra_len);
445b74652f3SRagothaman Jayaraman 				to->ptr[i % 4] =
446b74652f3SRagothaman Jayaraman 					rte_cpu_to_be_64(extra_buf->dma_addr);
4470022ae1eSArchana Muniganti 				size -= extra_len;
448b74652f3SRagothaman Jayaraman 			}
449b74652f3SRagothaman Jayaraman 
4500022ae1eSArchana Muniganti 			next_len = RTE_MIN(next_len, size);
451b74652f3SRagothaman Jayaraman 			/* insert the rest of the data */
452b74652f3SRagothaman Jayaraman 			if (next_len) {
453b74652f3SRagothaman Jayaraman 				i++;
454b74652f3SRagothaman Jayaraman 				to = &list[i >> 2];
455b74652f3SRagothaman Jayaraman 				to->u.s.len[i % 4] = rte_cpu_to_be_16(next_len);
456b74652f3SRagothaman Jayaraman 				to->ptr[i % 4] = rte_cpu_to_be_64(next_dma);
457b74652f3SRagothaman Jayaraman 				size -= next_len;
458b74652f3SRagothaman Jayaraman 			}
459b74652f3SRagothaman Jayaraman 			extra_len = 0;
460b74652f3SRagothaman Jayaraman 
461b74652f3SRagothaman Jayaraman 		} else {
462b74652f3SRagothaman Jayaraman 			size -= e_len;
463b74652f3SRagothaman Jayaraman 		}
464b74652f3SRagothaman Jayaraman 		if (extra_offset)
465b74652f3SRagothaman Jayaraman 			extra_offset -= size;
466b74652f3SRagothaman Jayaraman 		i++;
467b74652f3SRagothaman Jayaraman 	}
468b74652f3SRagothaman Jayaraman 
469b74652f3SRagothaman Jayaraman 	*psize = size;
470b74652f3SRagothaman Jayaraman 	return (uint32_t)i;
471b74652f3SRagothaman Jayaraman }
472b74652f3SRagothaman Jayaraman 
473f39928e6SAnoob Joseph static __rte_always_inline void
474351fbee2SSrisivasubramanian S cpt_digest_gen_prep(uint32_t flags,
475351fbee2SSrisivasubramanian S 		    uint64_t d_lens,
476351fbee2SSrisivasubramanian S 		    digest_params_t *params,
477351fbee2SSrisivasubramanian S 		    void *op,
478351fbee2SSrisivasubramanian S 		    void **prep_req)
479351fbee2SSrisivasubramanian S {
480351fbee2SSrisivasubramanian S 	struct cpt_request_info *req;
481351fbee2SSrisivasubramanian S 	uint32_t size, i;
482351fbee2SSrisivasubramanian S 	uint16_t data_len, mac_len, key_len;
483351fbee2SSrisivasubramanian S 	auth_type_t hash_type;
484351fbee2SSrisivasubramanian S 	buf_ptr_t *meta_p;
485351fbee2SSrisivasubramanian S 	struct cpt_ctx *ctx;
486351fbee2SSrisivasubramanian S 	sg_comp_t *gather_comp;
487351fbee2SSrisivasubramanian S 	sg_comp_t *scatter_comp;
488351fbee2SSrisivasubramanian S 	uint8_t *in_buffer;
489351fbee2SSrisivasubramanian S 	uint32_t g_size_bytes, s_size_bytes;
490351fbee2SSrisivasubramanian S 	uint64_t dptr_dma, rptr_dma;
491351fbee2SSrisivasubramanian S 	vq_cmd_word0_t vq_cmd_w0;
492351fbee2SSrisivasubramanian S 	void *c_vaddr, *m_vaddr;
493351fbee2SSrisivasubramanian S 	uint64_t c_dma, m_dma;
494351fbee2SSrisivasubramanian S 
495351fbee2SSrisivasubramanian S 	ctx = params->ctx_buf.vaddr;
496351fbee2SSrisivasubramanian S 	meta_p = &params->meta_buf;
497351fbee2SSrisivasubramanian S 
498351fbee2SSrisivasubramanian S 	m_vaddr = meta_p->vaddr;
499351fbee2SSrisivasubramanian S 	m_dma = meta_p->dma_addr;
500351fbee2SSrisivasubramanian S 
501351fbee2SSrisivasubramanian S 	/*
502351fbee2SSrisivasubramanian S 	 * Save initial space that followed app data for completion code &
503351fbee2SSrisivasubramanian S 	 * alternate completion code to fall in same cache line as app data
504351fbee2SSrisivasubramanian S 	 */
505351fbee2SSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE;
506351fbee2SSrisivasubramanian S 	m_dma += COMPLETION_CODE_SIZE;
507351fbee2SSrisivasubramanian S 	size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) -
508351fbee2SSrisivasubramanian S 		(uint8_t *)m_vaddr;
509351fbee2SSrisivasubramanian S 	c_vaddr = (uint8_t *)m_vaddr + size;
510351fbee2SSrisivasubramanian S 	c_dma = m_dma + size;
511351fbee2SSrisivasubramanian S 	size += sizeof(cpt_res_s_t);
512351fbee2SSrisivasubramanian S 
513351fbee2SSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
514351fbee2SSrisivasubramanian S 	m_dma += size;
515351fbee2SSrisivasubramanian S 
516351fbee2SSrisivasubramanian S 	req = m_vaddr;
517351fbee2SSrisivasubramanian S 
518351fbee2SSrisivasubramanian S 	size = sizeof(struct cpt_request_info);
519351fbee2SSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
520351fbee2SSrisivasubramanian S 	m_dma += size;
521351fbee2SSrisivasubramanian S 
522351fbee2SSrisivasubramanian S 	hash_type = ctx->hash_type;
523351fbee2SSrisivasubramanian S 	mac_len = ctx->mac_len;
524351fbee2SSrisivasubramanian S 	key_len = ctx->auth_key_len;
525351fbee2SSrisivasubramanian S 	data_len = AUTH_DLEN(d_lens);
526351fbee2SSrisivasubramanian S 
527351fbee2SSrisivasubramanian S 	/*GP op header */
528629ac988SArchana Muniganti 	vq_cmd_w0.s.opcode.minor = 0;
5298d8afdecSTejasree Kondoj 	vq_cmd_w0.s.param2 = ((uint16_t)hash_type << 8) | mac_len;
530351fbee2SSrisivasubramanian S 	if (ctx->hmac) {
531629ac988SArchana Muniganti 		vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_HMAC | CPT_DMA_MODE;
532426af86bSAnoob Joseph 		vq_cmd_w0.s.param1 = key_len;
533ecd070acSArchana Muniganti 		vq_cmd_w0.s.dlen = data_len + RTE_ALIGN_CEIL(key_len, 8);
534351fbee2SSrisivasubramanian S 	} else {
535629ac988SArchana Muniganti 		vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_HASH | CPT_DMA_MODE;
536351fbee2SSrisivasubramanian S 		vq_cmd_w0.s.param1 = 0;
537426af86bSAnoob Joseph 		vq_cmd_w0.s.dlen = data_len;
538351fbee2SSrisivasubramanian S 	}
539351fbee2SSrisivasubramanian S 
540351fbee2SSrisivasubramanian S 	/* Null auth only case enters the if */
541351fbee2SSrisivasubramanian S 	if (unlikely(!hash_type && !ctx->enc_cipher)) {
542629ac988SArchana Muniganti 		vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_MISC;
543351fbee2SSrisivasubramanian S 		/* Minor op is passthrough */
544629ac988SArchana Muniganti 		vq_cmd_w0.s.opcode.minor = 0x03;
545351fbee2SSrisivasubramanian S 		/* Send out completion code only */
546426af86bSAnoob Joseph 		vq_cmd_w0.s.param2 = 0x1;
547351fbee2SSrisivasubramanian S 	}
548351fbee2SSrisivasubramanian S 
549351fbee2SSrisivasubramanian S 	/* DPTR has SG list */
550351fbee2SSrisivasubramanian S 	in_buffer = m_vaddr;
551351fbee2SSrisivasubramanian S 	dptr_dma = m_dma;
552351fbee2SSrisivasubramanian S 
553351fbee2SSrisivasubramanian S 	((uint16_t *)in_buffer)[0] = 0;
554351fbee2SSrisivasubramanian S 	((uint16_t *)in_buffer)[1] = 0;
555351fbee2SSrisivasubramanian S 
556351fbee2SSrisivasubramanian S 	/* TODO Add error check if space will be sufficient */
557351fbee2SSrisivasubramanian S 	gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8);
558351fbee2SSrisivasubramanian S 
559351fbee2SSrisivasubramanian S 	/*
560351fbee2SSrisivasubramanian S 	 * Input gather list
561351fbee2SSrisivasubramanian S 	 */
562351fbee2SSrisivasubramanian S 
563351fbee2SSrisivasubramanian S 	i = 0;
564351fbee2SSrisivasubramanian S 
565351fbee2SSrisivasubramanian S 	if (ctx->hmac) {
566db06451bSAnoob Joseph 		uint64_t k_dma = ctx->auth_key_iova;
567351fbee2SSrisivasubramanian S 		/* Key */
568ecd070acSArchana Muniganti 		i = fill_sg_comp(gather_comp, i, k_dma,
569ecd070acSArchana Muniganti 				 RTE_ALIGN_CEIL(key_len, 8));
570351fbee2SSrisivasubramanian S 	}
571351fbee2SSrisivasubramanian S 
572351fbee2SSrisivasubramanian S 	/* input data */
573351fbee2SSrisivasubramanian S 	size = data_len;
574351fbee2SSrisivasubramanian S 	if (size) {
575351fbee2SSrisivasubramanian S 		i = fill_sg_comp_from_iov(gather_comp, i, params->src_iov,
576351fbee2SSrisivasubramanian S 					  0, &size, NULL, 0);
577f39928e6SAnoob Joseph 		if (unlikely(size)) {
578351fbee2SSrisivasubramanian S 			CPT_LOG_DP_DEBUG("Insufficient dst IOV size, short"
579351fbee2SSrisivasubramanian S 					 " by %dB", size);
580f39928e6SAnoob Joseph 			return;
581351fbee2SSrisivasubramanian S 		}
582351fbee2SSrisivasubramanian S 	} else {
583351fbee2SSrisivasubramanian S 		/*
584351fbee2SSrisivasubramanian S 		 * Looks like we need to support zero data
585351fbee2SSrisivasubramanian S 		 * gather ptr in case of hash & hmac
586351fbee2SSrisivasubramanian S 		 */
587351fbee2SSrisivasubramanian S 		i++;
588351fbee2SSrisivasubramanian S 	}
589351fbee2SSrisivasubramanian S 	((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i);
590351fbee2SSrisivasubramanian S 	g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
591351fbee2SSrisivasubramanian S 
592351fbee2SSrisivasubramanian S 	/*
593351fbee2SSrisivasubramanian S 	 * Output Gather list
594351fbee2SSrisivasubramanian S 	 */
595351fbee2SSrisivasubramanian S 
596351fbee2SSrisivasubramanian S 	i = 0;
597351fbee2SSrisivasubramanian S 	scatter_comp = (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes);
598351fbee2SSrisivasubramanian S 
599351fbee2SSrisivasubramanian S 	if (flags & VALID_MAC_BUF) {
600f39928e6SAnoob Joseph 		if (unlikely(params->mac_buf.size < mac_len)) {
601f39928e6SAnoob Joseph 			CPT_LOG_DP_ERR("Insufficient MAC size");
602f39928e6SAnoob Joseph 			return;
603f39928e6SAnoob Joseph 		}
604351fbee2SSrisivasubramanian S 
605351fbee2SSrisivasubramanian S 		size = mac_len;
606351fbee2SSrisivasubramanian S 		i = fill_sg_comp_from_buf_min(scatter_comp, i,
607351fbee2SSrisivasubramanian S 					      &params->mac_buf, &size);
608351fbee2SSrisivasubramanian S 	} else {
609351fbee2SSrisivasubramanian S 		size = mac_len;
610351fbee2SSrisivasubramanian S 		i = fill_sg_comp_from_iov(scatter_comp, i,
611351fbee2SSrisivasubramanian S 					  params->src_iov, data_len,
612351fbee2SSrisivasubramanian S 					  &size, NULL, 0);
613f39928e6SAnoob Joseph 		if (unlikely(size)) {
614f39928e6SAnoob Joseph 			CPT_LOG_DP_ERR("Insufficient dst IOV size, short by"
615351fbee2SSrisivasubramanian S 				       " %dB", size);
616f39928e6SAnoob Joseph 			return;
617351fbee2SSrisivasubramanian S 		}
618351fbee2SSrisivasubramanian S 	}
619351fbee2SSrisivasubramanian S 
620351fbee2SSrisivasubramanian S 	((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i);
621351fbee2SSrisivasubramanian S 	s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
622351fbee2SSrisivasubramanian S 
623351fbee2SSrisivasubramanian S 	size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE;
624351fbee2SSrisivasubramanian S 
625351fbee2SSrisivasubramanian S 	/* This is DPTR len incase of SG mode */
626426af86bSAnoob Joseph 	vq_cmd_w0.s.dlen = size;
627351fbee2SSrisivasubramanian S 
628351fbee2SSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
629351fbee2SSrisivasubramanian S 	m_dma += size;
630351fbee2SSrisivasubramanian S 
631351fbee2SSrisivasubramanian S 	/* cpt alternate completion address saved earlier */
632351fbee2SSrisivasubramanian S 	req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8);
633351fbee2SSrisivasubramanian S 	*req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT);
634351fbee2SSrisivasubramanian S 	rptr_dma = c_dma - 8;
635351fbee2SSrisivasubramanian S 
636351fbee2SSrisivasubramanian S 	req->ist.ei1 = dptr_dma;
637351fbee2SSrisivasubramanian S 	req->ist.ei2 = rptr_dma;
638351fbee2SSrisivasubramanian S 
639351fbee2SSrisivasubramanian S 	/* 16 byte aligned cpt res address */
640351fbee2SSrisivasubramanian S 	req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr);
641351fbee2SSrisivasubramanian S 	*req->completion_addr = COMPLETION_CODE_INIT;
642351fbee2SSrisivasubramanian S 	req->comp_baddr  = c_dma;
643351fbee2SSrisivasubramanian S 
644351fbee2SSrisivasubramanian S 	/* Fill microcode part of instruction */
645351fbee2SSrisivasubramanian S 	req->ist.ei0 = vq_cmd_w0.u64;
646351fbee2SSrisivasubramanian S 
647351fbee2SSrisivasubramanian S 	req->op = op;
648351fbee2SSrisivasubramanian S 
649351fbee2SSrisivasubramanian S 	*prep_req = req;
650f39928e6SAnoob Joseph 	return;
651351fbee2SSrisivasubramanian S }
652351fbee2SSrisivasubramanian S 
653f39928e6SAnoob Joseph static __rte_always_inline void
654b74652f3SRagothaman Jayaraman cpt_enc_hmac_prep(uint32_t flags,
655b74652f3SRagothaman Jayaraman 		  uint64_t d_offs,
656b74652f3SRagothaman Jayaraman 		  uint64_t d_lens,
657b74652f3SRagothaman Jayaraman 		  fc_params_t *fc_params,
658b74652f3SRagothaman Jayaraman 		  void *op,
659b74652f3SRagothaman Jayaraman 		  void **prep_req)
660b74652f3SRagothaman Jayaraman {
661b74652f3SRagothaman Jayaraman 	uint32_t iv_offset = 0;
662b74652f3SRagothaman Jayaraman 	int32_t inputlen, outputlen, enc_dlen, auth_dlen;
663b74652f3SRagothaman Jayaraman 	struct cpt_ctx *cpt_ctx;
664b74652f3SRagothaman Jayaraman 	uint32_t cipher_type, hash_type;
665b74652f3SRagothaman Jayaraman 	uint32_t mac_len, size;
666b74652f3SRagothaman Jayaraman 	uint8_t iv_len = 16;
667b74652f3SRagothaman Jayaraman 	struct cpt_request_info *req;
668b74652f3SRagothaman Jayaraman 	buf_ptr_t *meta_p, *aad_buf = NULL;
669b74652f3SRagothaman Jayaraman 	uint32_t encr_offset, auth_offset;
670b74652f3SRagothaman Jayaraman 	uint32_t encr_data_len, auth_data_len, aad_len = 0;
671b74652f3SRagothaman Jayaraman 	uint32_t passthrough_len = 0;
672b74652f3SRagothaman Jayaraman 	void *m_vaddr, *offset_vaddr;
6736045c06aSArchana Muniganti 	uint64_t m_dma, offset_dma;
674b74652f3SRagothaman Jayaraman 	vq_cmd_word0_t vq_cmd_w0;
675b74652f3SRagothaman Jayaraman 	void *c_vaddr;
676b74652f3SRagothaman Jayaraman 	uint64_t c_dma;
677b74652f3SRagothaman Jayaraman 
678b74652f3SRagothaman Jayaraman 	meta_p = &fc_params->meta_buf;
679b74652f3SRagothaman Jayaraman 	m_vaddr = meta_p->vaddr;
680b74652f3SRagothaman Jayaraman 	m_dma = meta_p->dma_addr;
681b74652f3SRagothaman Jayaraman 
682b74652f3SRagothaman Jayaraman 	encr_offset = ENCR_OFFSET(d_offs);
683b74652f3SRagothaman Jayaraman 	auth_offset = AUTH_OFFSET(d_offs);
684b74652f3SRagothaman Jayaraman 	encr_data_len = ENCR_DLEN(d_lens);
685b74652f3SRagothaman Jayaraman 	auth_data_len = AUTH_DLEN(d_lens);
686b74652f3SRagothaman Jayaraman 	if (unlikely(flags & VALID_AAD_BUF)) {
687b74652f3SRagothaman Jayaraman 		/*
688b74652f3SRagothaman Jayaraman 		 * We dont support both aad
689b74652f3SRagothaman Jayaraman 		 * and auth data separately
690b74652f3SRagothaman Jayaraman 		 */
691b74652f3SRagothaman Jayaraman 		auth_data_len = 0;
692b74652f3SRagothaman Jayaraman 		auth_offset = 0;
693b74652f3SRagothaman Jayaraman 		aad_len = fc_params->aad_buf.size;
694b74652f3SRagothaman Jayaraman 		aad_buf = &fc_params->aad_buf;
695b74652f3SRagothaman Jayaraman 	}
696b74652f3SRagothaman Jayaraman 	cpt_ctx = fc_params->ctx_buf.vaddr;
697b74652f3SRagothaman Jayaraman 	cipher_type = cpt_ctx->enc_cipher;
698b74652f3SRagothaman Jayaraman 	hash_type = cpt_ctx->hash_type;
699b74652f3SRagothaman Jayaraman 	mac_len = cpt_ctx->mac_len;
700b74652f3SRagothaman Jayaraman 
701b74652f3SRagothaman Jayaraman 	/*
702b74652f3SRagothaman Jayaraman 	 * Save initial space that followed app data for completion code &
703b74652f3SRagothaman Jayaraman 	 * alternate completion code to fall in same cache line as app data
704b74652f3SRagothaman Jayaraman 	 */
705b74652f3SRagothaman Jayaraman 	m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE;
706b74652f3SRagothaman Jayaraman 	m_dma += COMPLETION_CODE_SIZE;
707b74652f3SRagothaman Jayaraman 	size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) -
708b74652f3SRagothaman Jayaraman 		(uint8_t *)m_vaddr;
709b74652f3SRagothaman Jayaraman 
710b74652f3SRagothaman Jayaraman 	c_vaddr = (uint8_t *)m_vaddr + size;
711b74652f3SRagothaman Jayaraman 	c_dma = m_dma + size;
712b74652f3SRagothaman Jayaraman 	size += sizeof(cpt_res_s_t);
713b74652f3SRagothaman Jayaraman 
714b74652f3SRagothaman Jayaraman 	m_vaddr = (uint8_t *)m_vaddr + size;
715b74652f3SRagothaman Jayaraman 	m_dma += size;
716b74652f3SRagothaman Jayaraman 
717b74652f3SRagothaman Jayaraman 	/* start cpt request info struct at 8 byte boundary */
718b74652f3SRagothaman Jayaraman 	size = (uint8_t *)RTE_PTR_ALIGN(m_vaddr, 8) -
719b74652f3SRagothaman Jayaraman 		(uint8_t *)m_vaddr;
720b74652f3SRagothaman Jayaraman 
721b74652f3SRagothaman Jayaraman 	req = (struct cpt_request_info *)((uint8_t *)m_vaddr + size);
722b74652f3SRagothaman Jayaraman 
723b74652f3SRagothaman Jayaraman 	size += sizeof(struct cpt_request_info);
724b74652f3SRagothaman Jayaraman 	m_vaddr = (uint8_t *)m_vaddr + size;
725b74652f3SRagothaman Jayaraman 	m_dma += size;
726b74652f3SRagothaman Jayaraman 
727b74652f3SRagothaman Jayaraman 	if (unlikely(!(flags & VALID_IV_BUF))) {
728b74652f3SRagothaman Jayaraman 		iv_len = 0;
729b74652f3SRagothaman Jayaraman 		iv_offset = ENCR_IV_OFFSET(d_offs);
730b74652f3SRagothaman Jayaraman 	}
731b74652f3SRagothaman Jayaraman 
732b74652f3SRagothaman Jayaraman 	if (unlikely(flags & VALID_AAD_BUF)) {
733b74652f3SRagothaman Jayaraman 		/*
734b74652f3SRagothaman Jayaraman 		 * When AAD is given, data above encr_offset is pass through
735b74652f3SRagothaman Jayaraman 		 * Since AAD is given as separate pointer and not as offset,
736b74652f3SRagothaman Jayaraman 		 * this is a special case as we need to fragment input data
737b74652f3SRagothaman Jayaraman 		 * into passthrough + encr_data and then insert AAD in between.
738b74652f3SRagothaman Jayaraman 		 */
739b74652f3SRagothaman Jayaraman 		if (hash_type != GMAC_TYPE) {
740b74652f3SRagothaman Jayaraman 			passthrough_len = encr_offset;
741b74652f3SRagothaman Jayaraman 			auth_offset = passthrough_len + iv_len;
742b74652f3SRagothaman Jayaraman 			encr_offset = passthrough_len + aad_len + iv_len;
743b74652f3SRagothaman Jayaraman 			auth_data_len = aad_len + encr_data_len;
744b74652f3SRagothaman Jayaraman 		} else {
745b74652f3SRagothaman Jayaraman 			passthrough_len = 16 + aad_len;
746b74652f3SRagothaman Jayaraman 			auth_offset = passthrough_len + iv_len;
747b74652f3SRagothaman Jayaraman 			auth_data_len = aad_len;
748b74652f3SRagothaman Jayaraman 		}
749b74652f3SRagothaman Jayaraman 	} else {
750b74652f3SRagothaman Jayaraman 		encr_offset += iv_len;
751b74652f3SRagothaman Jayaraman 		auth_offset += iv_len;
752b74652f3SRagothaman Jayaraman 	}
753b74652f3SRagothaman Jayaraman 
754b74652f3SRagothaman Jayaraman 	/* Encryption */
755629ac988SArchana Muniganti 	vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_FC;
756de5eb0a6STejasree Kondoj 	vq_cmd_w0.s.opcode.minor = CPT_FC_MINOR_OP_ENCRYPT;
757de5eb0a6STejasree Kondoj 	vq_cmd_w0.s.opcode.minor |= (cpt_ctx->auth_enc <<
758de5eb0a6STejasree Kondoj 					CPT_HMAC_FIRST_BIT_POS);
759b74652f3SRagothaman Jayaraman 
7600058f305SAnkur Dwivedi 	if (hash_type == GMAC_TYPE) {
7610058f305SAnkur Dwivedi 		encr_offset = 0;
7620058f305SAnkur Dwivedi 		encr_data_len = 0;
7630058f305SAnkur Dwivedi 	}
7640058f305SAnkur Dwivedi 
765b74652f3SRagothaman Jayaraman 	auth_dlen = auth_offset + auth_data_len;
766b74652f3SRagothaman Jayaraman 	enc_dlen = encr_data_len + encr_offset;
767b74652f3SRagothaman Jayaraman 	if (unlikely(encr_data_len & 0xf)) {
768b74652f3SRagothaman Jayaraman 		if ((cipher_type == DES3_CBC) || (cipher_type == DES3_ECB))
769ecd070acSArchana Muniganti 			enc_dlen = RTE_ALIGN_CEIL(encr_data_len, 8) +
770ecd070acSArchana Muniganti 					encr_offset;
771b74652f3SRagothaman Jayaraman 		else if (likely((cipher_type == AES_CBC) ||
772b74652f3SRagothaman Jayaraman 				(cipher_type == AES_ECB)))
773ecd070acSArchana Muniganti 			enc_dlen = RTE_ALIGN_CEIL(encr_data_len, 8) +
774ecd070acSArchana Muniganti 					encr_offset;
775b74652f3SRagothaman Jayaraman 	}
776b74652f3SRagothaman Jayaraman 
777b74652f3SRagothaman Jayaraman 	if (unlikely(auth_dlen > enc_dlen)) {
778b74652f3SRagothaman Jayaraman 		inputlen = auth_dlen;
779b74652f3SRagothaman Jayaraman 		outputlen = auth_dlen + mac_len;
780b74652f3SRagothaman Jayaraman 	} else {
781b74652f3SRagothaman Jayaraman 		inputlen = enc_dlen;
782b74652f3SRagothaman Jayaraman 		outputlen = enc_dlen + mac_len;
783b74652f3SRagothaman Jayaraman 	}
784b74652f3SRagothaman Jayaraman 
785de5eb0a6STejasree Kondoj 	if (cpt_ctx->auth_enc != 0)
786de5eb0a6STejasree Kondoj 		outputlen = enc_dlen;
787de5eb0a6STejasree Kondoj 
788b74652f3SRagothaman Jayaraman 	/* GP op header */
789426af86bSAnoob Joseph 	vq_cmd_w0.s.param1 = encr_data_len;
790426af86bSAnoob Joseph 	vq_cmd_w0.s.param2 = auth_data_len;
791b74652f3SRagothaman Jayaraman 	/*
792b74652f3SRagothaman Jayaraman 	 * In 83XX since we have a limitation of
793b74652f3SRagothaman Jayaraman 	 * IV & Offset control word not part of instruction
794b74652f3SRagothaman Jayaraman 	 * and need to be part of Data Buffer, we check if
795b74652f3SRagothaman Jayaraman 	 * head room is there and then only do the Direct mode processing
796b74652f3SRagothaman Jayaraman 	 */
797b74652f3SRagothaman Jayaraman 	if (likely((flags & SINGLE_BUF_INPLACE) &&
798b74652f3SRagothaman Jayaraman 		   (flags & SINGLE_BUF_HEADTAILROOM))) {
799b74652f3SRagothaman Jayaraman 		void *dm_vaddr = fc_params->bufs[0].vaddr;
800b74652f3SRagothaman Jayaraman 		uint64_t dm_dma_addr = fc_params->bufs[0].dma_addr;
801b74652f3SRagothaman Jayaraman 		/*
802b74652f3SRagothaman Jayaraman 		 * This flag indicates that there is 24 bytes head room and
803b74652f3SRagothaman Jayaraman 		 * 8 bytes tail room available, so that we get to do
804b74652f3SRagothaman Jayaraman 		 * DIRECT MODE with limitation
805b74652f3SRagothaman Jayaraman 		 */
806b74652f3SRagothaman Jayaraman 
807b74652f3SRagothaman Jayaraman 		offset_vaddr = (uint8_t *)dm_vaddr - OFF_CTRL_LEN - iv_len;
808b74652f3SRagothaman Jayaraman 		offset_dma = dm_dma_addr - OFF_CTRL_LEN - iv_len;
809b74652f3SRagothaman Jayaraman 
810b74652f3SRagothaman Jayaraman 		/* DPTR */
811b74652f3SRagothaman Jayaraman 		req->ist.ei1 = offset_dma;
812b74652f3SRagothaman Jayaraman 		/* RPTR should just exclude offset control word */
813b74652f3SRagothaman Jayaraman 		req->ist.ei2 = dm_dma_addr - iv_len;
814b74652f3SRagothaman Jayaraman 		req->alternate_caddr = (uint64_t *)((uint8_t *)dm_vaddr
815b74652f3SRagothaman Jayaraman 						    + outputlen - iv_len);
816b74652f3SRagothaman Jayaraman 
817426af86bSAnoob Joseph 		vq_cmd_w0.s.dlen = inputlen + OFF_CTRL_LEN;
818b74652f3SRagothaman Jayaraman 
819b74652f3SRagothaman Jayaraman 		if (likely(iv_len)) {
820b74652f3SRagothaman Jayaraman 			uint64_t *dest = (uint64_t *)((uint8_t *)offset_vaddr
821b74652f3SRagothaman Jayaraman 						      + OFF_CTRL_LEN);
822b74652f3SRagothaman Jayaraman 			uint64_t *src = fc_params->iv_buf;
823b74652f3SRagothaman Jayaraman 			dest[0] = src[0];
824b74652f3SRagothaman Jayaraman 			dest[1] = src[1];
825b74652f3SRagothaman Jayaraman 		}
826b74652f3SRagothaman Jayaraman 
827b74652f3SRagothaman Jayaraman 		*(uint64_t *)offset_vaddr =
828b74652f3SRagothaman Jayaraman 			rte_cpu_to_be_64(((uint64_t)encr_offset << 16) |
829b74652f3SRagothaman Jayaraman 				((uint64_t)iv_offset << 8) |
830b74652f3SRagothaman Jayaraman 				((uint64_t)auth_offset));
831b74652f3SRagothaman Jayaraman 
832b74652f3SRagothaman Jayaraman 	} else {
833b74652f3SRagothaman Jayaraman 		uint32_t i, g_size_bytes, s_size_bytes;
834b74652f3SRagothaman Jayaraman 		uint64_t dptr_dma, rptr_dma;
835b74652f3SRagothaman Jayaraman 		sg_comp_t *gather_comp;
836b74652f3SRagothaman Jayaraman 		sg_comp_t *scatter_comp;
837b74652f3SRagothaman Jayaraman 		uint8_t *in_buffer;
838b74652f3SRagothaman Jayaraman 
839b74652f3SRagothaman Jayaraman 		/* This falls under strict SG mode */
840b74652f3SRagothaman Jayaraman 		offset_vaddr = m_vaddr;
841b74652f3SRagothaman Jayaraman 		offset_dma = m_dma;
842b74652f3SRagothaman Jayaraman 		size = OFF_CTRL_LEN + iv_len;
843b74652f3SRagothaman Jayaraman 
844b74652f3SRagothaman Jayaraman 		m_vaddr = (uint8_t *)m_vaddr + size;
845b74652f3SRagothaman Jayaraman 		m_dma += size;
846b74652f3SRagothaman Jayaraman 
847629ac988SArchana Muniganti 		vq_cmd_w0.s.opcode.major |= CPT_DMA_MODE;
848b74652f3SRagothaman Jayaraman 
849b74652f3SRagothaman Jayaraman 		if (likely(iv_len)) {
850b74652f3SRagothaman Jayaraman 			uint64_t *dest = (uint64_t *)((uint8_t *)offset_vaddr
851b74652f3SRagothaman Jayaraman 						      + OFF_CTRL_LEN);
852b74652f3SRagothaman Jayaraman 			uint64_t *src = fc_params->iv_buf;
853b74652f3SRagothaman Jayaraman 			dest[0] = src[0];
854b74652f3SRagothaman Jayaraman 			dest[1] = src[1];
855b74652f3SRagothaman Jayaraman 		}
856b74652f3SRagothaman Jayaraman 
857b74652f3SRagothaman Jayaraman 		*(uint64_t *)offset_vaddr =
858b74652f3SRagothaman Jayaraman 			rte_cpu_to_be_64(((uint64_t)encr_offset << 16) |
859b74652f3SRagothaman Jayaraman 				((uint64_t)iv_offset << 8) |
860b74652f3SRagothaman Jayaraman 				((uint64_t)auth_offset));
861b74652f3SRagothaman Jayaraman 
862b74652f3SRagothaman Jayaraman 		/* DPTR has SG list */
863b74652f3SRagothaman Jayaraman 		in_buffer = m_vaddr;
864b74652f3SRagothaman Jayaraman 		dptr_dma = m_dma;
865b74652f3SRagothaman Jayaraman 
866b74652f3SRagothaman Jayaraman 		((uint16_t *)in_buffer)[0] = 0;
867b74652f3SRagothaman Jayaraman 		((uint16_t *)in_buffer)[1] = 0;
868b74652f3SRagothaman Jayaraman 
869b74652f3SRagothaman Jayaraman 		/* TODO Add error check if space will be sufficient */
870b74652f3SRagothaman Jayaraman 		gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8);
871b74652f3SRagothaman Jayaraman 
872b74652f3SRagothaman Jayaraman 		/*
873b74652f3SRagothaman Jayaraman 		 * Input Gather List
874b74652f3SRagothaman Jayaraman 		 */
875b74652f3SRagothaman Jayaraman 
876b74652f3SRagothaman Jayaraman 		i = 0;
877b74652f3SRagothaman Jayaraman 
878b74652f3SRagothaman Jayaraman 		/* Offset control word that includes iv */
879b74652f3SRagothaman Jayaraman 		i = fill_sg_comp(gather_comp, i, offset_dma,
880b74652f3SRagothaman Jayaraman 				 OFF_CTRL_LEN + iv_len);
881b74652f3SRagothaman Jayaraman 
882b74652f3SRagothaman Jayaraman 		/* Add input data */
883b74652f3SRagothaman Jayaraman 		size = inputlen - iv_len;
884b74652f3SRagothaman Jayaraman 		if (likely(size)) {
885b74652f3SRagothaman Jayaraman 			uint32_t aad_offset = aad_len ? passthrough_len : 0;
886b74652f3SRagothaman Jayaraman 
887b74652f3SRagothaman Jayaraman 			if (unlikely(flags & SINGLE_BUF_INPLACE)) {
888b74652f3SRagothaman Jayaraman 				i = fill_sg_comp_from_buf_min(gather_comp, i,
889b74652f3SRagothaman Jayaraman 							      fc_params->bufs,
890b74652f3SRagothaman Jayaraman 							      &size);
891b74652f3SRagothaman Jayaraman 			} else {
892b74652f3SRagothaman Jayaraman 				i = fill_sg_comp_from_iov(gather_comp, i,
893b74652f3SRagothaman Jayaraman 							  fc_params->src_iov,
894b74652f3SRagothaman Jayaraman 							  0, &size,
895b74652f3SRagothaman Jayaraman 							  aad_buf, aad_offset);
896b74652f3SRagothaman Jayaraman 			}
897b74652f3SRagothaman Jayaraman 
898b74652f3SRagothaman Jayaraman 			if (unlikely(size)) {
899b74652f3SRagothaman Jayaraman 				CPT_LOG_DP_ERR("Insufficient buffer space,"
900b74652f3SRagothaman Jayaraman 					       " size %d needed", size);
901f39928e6SAnoob Joseph 				return;
902b74652f3SRagothaman Jayaraman 			}
903b74652f3SRagothaman Jayaraman 		}
904b74652f3SRagothaman Jayaraman 		((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i);
905b74652f3SRagothaman Jayaraman 		g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
906b74652f3SRagothaman Jayaraman 
907b74652f3SRagothaman Jayaraman 		/*
908b74652f3SRagothaman Jayaraman 		 * Output Scatter list
909b74652f3SRagothaman Jayaraman 		 */
910b74652f3SRagothaman Jayaraman 		i = 0;
911b74652f3SRagothaman Jayaraman 		scatter_comp =
912b74652f3SRagothaman Jayaraman 			(sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes);
913b74652f3SRagothaman Jayaraman 
914b74652f3SRagothaman Jayaraman 		/* Add IV */
915b74652f3SRagothaman Jayaraman 		if (likely(iv_len)) {
916b74652f3SRagothaman Jayaraman 			i = fill_sg_comp(scatter_comp, i,
917b74652f3SRagothaman Jayaraman 					 offset_dma + OFF_CTRL_LEN,
918b74652f3SRagothaman Jayaraman 					 iv_len);
919b74652f3SRagothaman Jayaraman 		}
920b74652f3SRagothaman Jayaraman 
921b74652f3SRagothaman Jayaraman 		/* output data or output data + digest*/
922b74652f3SRagothaman Jayaraman 		if (unlikely(flags & VALID_MAC_BUF)) {
923b74652f3SRagothaman Jayaraman 			size = outputlen - iv_len - mac_len;
924b74652f3SRagothaman Jayaraman 			if (size) {
925b74652f3SRagothaman Jayaraman 				uint32_t aad_offset =
926b74652f3SRagothaman Jayaraman 					aad_len ? passthrough_len : 0;
927b74652f3SRagothaman Jayaraman 
928b74652f3SRagothaman Jayaraman 				if (unlikely(flags & SINGLE_BUF_INPLACE)) {
929b74652f3SRagothaman Jayaraman 					i = fill_sg_comp_from_buf_min(
930b74652f3SRagothaman Jayaraman 							scatter_comp,
931b74652f3SRagothaman Jayaraman 							i,
932b74652f3SRagothaman Jayaraman 							fc_params->bufs,
933b74652f3SRagothaman Jayaraman 							&size);
934b74652f3SRagothaman Jayaraman 				} else {
935b74652f3SRagothaman Jayaraman 					i = fill_sg_comp_from_iov(scatter_comp,
936b74652f3SRagothaman Jayaraman 							i,
937b74652f3SRagothaman Jayaraman 							fc_params->dst_iov,
938b74652f3SRagothaman Jayaraman 							0,
939b74652f3SRagothaman Jayaraman 							&size,
940b74652f3SRagothaman Jayaraman 							aad_buf,
941b74652f3SRagothaman Jayaraman 							aad_offset);
942b74652f3SRagothaman Jayaraman 				}
943f39928e6SAnoob Joseph 				if (unlikely(size)) {
944f39928e6SAnoob Joseph 					CPT_LOG_DP_ERR("Insufficient buffer"
945f39928e6SAnoob Joseph 						       " space, size %d needed",
946f39928e6SAnoob Joseph 						       size);
947f39928e6SAnoob Joseph 					return;
948f39928e6SAnoob Joseph 				}
949b74652f3SRagothaman Jayaraman 			}
950b74652f3SRagothaman Jayaraman 			/* mac_data */
951b74652f3SRagothaman Jayaraman 			if (mac_len) {
952b74652f3SRagothaman Jayaraman 				i = fill_sg_comp_from_buf(scatter_comp, i,
953b74652f3SRagothaman Jayaraman 							  &fc_params->mac_buf);
954b74652f3SRagothaman Jayaraman 			}
955b74652f3SRagothaman Jayaraman 		} else {
956b74652f3SRagothaman Jayaraman 			/* Output including mac */
957b74652f3SRagothaman Jayaraman 			size = outputlen - iv_len;
958b74652f3SRagothaman Jayaraman 			if (likely(size)) {
959b74652f3SRagothaman Jayaraman 				uint32_t aad_offset =
960b74652f3SRagothaman Jayaraman 					aad_len ? passthrough_len : 0;
961b74652f3SRagothaman Jayaraman 
962b74652f3SRagothaman Jayaraman 				if (unlikely(flags & SINGLE_BUF_INPLACE)) {
963b74652f3SRagothaman Jayaraman 					i = fill_sg_comp_from_buf_min(
964b74652f3SRagothaman Jayaraman 							scatter_comp,
965b74652f3SRagothaman Jayaraman 							i,
966b74652f3SRagothaman Jayaraman 							fc_params->bufs,
967b74652f3SRagothaman Jayaraman 							&size);
968b74652f3SRagothaman Jayaraman 				} else {
969b74652f3SRagothaman Jayaraman 					i = fill_sg_comp_from_iov(scatter_comp,
970b74652f3SRagothaman Jayaraman 							i,
971b74652f3SRagothaman Jayaraman 							fc_params->dst_iov,
972b74652f3SRagothaman Jayaraman 							0,
973b74652f3SRagothaman Jayaraman 							&size,
974b74652f3SRagothaman Jayaraman 							aad_buf,
975b74652f3SRagothaman Jayaraman 							aad_offset);
976b74652f3SRagothaman Jayaraman 				}
977b74652f3SRagothaman Jayaraman 				if (unlikely(size)) {
978b74652f3SRagothaman Jayaraman 					CPT_LOG_DP_ERR("Insufficient buffer"
979b74652f3SRagothaman Jayaraman 						       " space, size %d needed",
980b74652f3SRagothaman Jayaraman 						       size);
981f39928e6SAnoob Joseph 					return;
982b74652f3SRagothaman Jayaraman 				}
983b74652f3SRagothaman Jayaraman 			}
984b74652f3SRagothaman Jayaraman 		}
985b74652f3SRagothaman Jayaraman 		((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i);
986b74652f3SRagothaman Jayaraman 		s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
987b74652f3SRagothaman Jayaraman 
988b74652f3SRagothaman Jayaraman 		size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE;
989b74652f3SRagothaman Jayaraman 
990b74652f3SRagothaman Jayaraman 		/* This is DPTR len incase of SG mode */
991426af86bSAnoob Joseph 		vq_cmd_w0.s.dlen = size;
992b74652f3SRagothaman Jayaraman 
993b74652f3SRagothaman Jayaraman 		m_vaddr = (uint8_t *)m_vaddr + size;
994b74652f3SRagothaman Jayaraman 		m_dma += size;
995b74652f3SRagothaman Jayaraman 
996b74652f3SRagothaman Jayaraman 		/* cpt alternate completion address saved earlier */
997b74652f3SRagothaman Jayaraman 		req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8);
998b74652f3SRagothaman Jayaraman 		*req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT);
999b74652f3SRagothaman Jayaraman 		rptr_dma = c_dma - 8;
1000b74652f3SRagothaman Jayaraman 
1001b74652f3SRagothaman Jayaraman 		req->ist.ei1 = dptr_dma;
1002b74652f3SRagothaman Jayaraman 		req->ist.ei2 = rptr_dma;
1003b74652f3SRagothaman Jayaraman 	}
1004b74652f3SRagothaman Jayaraman 
10052a6c7922SAnoob Joseph 	if (unlikely((encr_offset >> 16) ||
10062a6c7922SAnoob Joseph 		     (iv_offset >> 8) ||
10072a6c7922SAnoob Joseph 		     (auth_offset >> 8))) {
10082a6c7922SAnoob Joseph 		CPT_LOG_DP_ERR("Offset not supported");
10092a6c7922SAnoob Joseph 		CPT_LOG_DP_ERR("enc_offset: %d", encr_offset);
10102a6c7922SAnoob Joseph 		CPT_LOG_DP_ERR("iv_offset : %d", iv_offset);
10112a6c7922SAnoob Joseph 		CPT_LOG_DP_ERR("auth_offset: %d", auth_offset);
10122a6c7922SAnoob Joseph 		return;
10132a6c7922SAnoob Joseph 	}
10142a6c7922SAnoob Joseph 
1015b74652f3SRagothaman Jayaraman 	/* 16 byte aligned cpt res address */
1016b74652f3SRagothaman Jayaraman 	req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr);
1017b74652f3SRagothaman Jayaraman 	*req->completion_addr = COMPLETION_CODE_INIT;
1018b74652f3SRagothaman Jayaraman 	req->comp_baddr  = c_dma;
1019b74652f3SRagothaman Jayaraman 
1020b74652f3SRagothaman Jayaraman 	/* Fill microcode part of instruction */
1021b74652f3SRagothaman Jayaraman 	req->ist.ei0 = vq_cmd_w0.u64;
1022b74652f3SRagothaman Jayaraman 
1023b74652f3SRagothaman Jayaraman 	req->op  = op;
1024b74652f3SRagothaman Jayaraman 
1025b74652f3SRagothaman Jayaraman 	*prep_req = req;
1026f39928e6SAnoob Joseph 	return;
1027b74652f3SRagothaman Jayaraman }
1028b74652f3SRagothaman Jayaraman 
1029f39928e6SAnoob Joseph static __rte_always_inline void
1030177b41ceSRagothaman Jayaraman cpt_dec_hmac_prep(uint32_t flags,
1031177b41ceSRagothaman Jayaraman 		  uint64_t d_offs,
1032177b41ceSRagothaman Jayaraman 		  uint64_t d_lens,
1033177b41ceSRagothaman Jayaraman 		  fc_params_t *fc_params,
1034177b41ceSRagothaman Jayaraman 		  void *op,
1035177b41ceSRagothaman Jayaraman 		  void **prep_req)
1036177b41ceSRagothaman Jayaraman {
1037177b41ceSRagothaman Jayaraman 	uint32_t iv_offset = 0, size;
1038177b41ceSRagothaman Jayaraman 	int32_t inputlen, outputlen, enc_dlen, auth_dlen;
1039177b41ceSRagothaman Jayaraman 	struct cpt_ctx *cpt_ctx;
10408de5ede7SAnoob Joseph 	int32_t hash_type, mac_len;
1041177b41ceSRagothaman Jayaraman 	uint8_t iv_len = 16;
1042177b41ceSRagothaman Jayaraman 	struct cpt_request_info *req;
1043177b41ceSRagothaman Jayaraman 	buf_ptr_t *meta_p, *aad_buf = NULL;
1044177b41ceSRagothaman Jayaraman 	uint32_t encr_offset, auth_offset;
1045177b41ceSRagothaman Jayaraman 	uint32_t encr_data_len, auth_data_len, aad_len = 0;
1046177b41ceSRagothaman Jayaraman 	uint32_t passthrough_len = 0;
1047177b41ceSRagothaman Jayaraman 	void *m_vaddr, *offset_vaddr;
10486045c06aSArchana Muniganti 	uint64_t m_dma, offset_dma;
1049177b41ceSRagothaman Jayaraman 	vq_cmd_word0_t vq_cmd_w0;
1050177b41ceSRagothaman Jayaraman 	void *c_vaddr;
1051177b41ceSRagothaman Jayaraman 	uint64_t c_dma;
1052177b41ceSRagothaman Jayaraman 
1053177b41ceSRagothaman Jayaraman 	meta_p = &fc_params->meta_buf;
1054177b41ceSRagothaman Jayaraman 	m_vaddr = meta_p->vaddr;
1055177b41ceSRagothaman Jayaraman 	m_dma = meta_p->dma_addr;
1056177b41ceSRagothaman Jayaraman 
1057177b41ceSRagothaman Jayaraman 	encr_offset = ENCR_OFFSET(d_offs);
1058177b41ceSRagothaman Jayaraman 	auth_offset = AUTH_OFFSET(d_offs);
1059177b41ceSRagothaman Jayaraman 	encr_data_len = ENCR_DLEN(d_lens);
1060177b41ceSRagothaman Jayaraman 	auth_data_len = AUTH_DLEN(d_lens);
1061177b41ceSRagothaman Jayaraman 
1062177b41ceSRagothaman Jayaraman 	if (unlikely(flags & VALID_AAD_BUF)) {
1063177b41ceSRagothaman Jayaraman 		/*
1064177b41ceSRagothaman Jayaraman 		 * We dont support both aad
1065177b41ceSRagothaman Jayaraman 		 * and auth data separately
1066177b41ceSRagothaman Jayaraman 		 */
1067177b41ceSRagothaman Jayaraman 		auth_data_len = 0;
1068177b41ceSRagothaman Jayaraman 		auth_offset = 0;
1069177b41ceSRagothaman Jayaraman 		aad_len = fc_params->aad_buf.size;
1070177b41ceSRagothaman Jayaraman 		aad_buf = &fc_params->aad_buf;
1071177b41ceSRagothaman Jayaraman 	}
1072177b41ceSRagothaman Jayaraman 
1073177b41ceSRagothaman Jayaraman 	cpt_ctx = fc_params->ctx_buf.vaddr;
1074177b41ceSRagothaman Jayaraman 	hash_type = cpt_ctx->hash_type;
1075177b41ceSRagothaman Jayaraman 	mac_len = cpt_ctx->mac_len;
1076177b41ceSRagothaman Jayaraman 
1077177b41ceSRagothaman Jayaraman 	if (unlikely(!(flags & VALID_IV_BUF))) {
1078177b41ceSRagothaman Jayaraman 		iv_len = 0;
1079177b41ceSRagothaman Jayaraman 		iv_offset = ENCR_IV_OFFSET(d_offs);
1080177b41ceSRagothaman Jayaraman 	}
1081177b41ceSRagothaman Jayaraman 
1082177b41ceSRagothaman Jayaraman 	if (unlikely(flags & VALID_AAD_BUF)) {
1083177b41ceSRagothaman Jayaraman 		/*
1084177b41ceSRagothaman Jayaraman 		 * When AAD is given, data above encr_offset is pass through
1085177b41ceSRagothaman Jayaraman 		 * Since AAD is given as separate pointer and not as offset,
1086177b41ceSRagothaman Jayaraman 		 * this is a special case as we need to fragment input data
1087177b41ceSRagothaman Jayaraman 		 * into passthrough + encr_data and then insert AAD in between.
1088177b41ceSRagothaman Jayaraman 		 */
1089177b41ceSRagothaman Jayaraman 		if (hash_type != GMAC_TYPE) {
1090177b41ceSRagothaman Jayaraman 			passthrough_len = encr_offset;
1091177b41ceSRagothaman Jayaraman 			auth_offset = passthrough_len + iv_len;
1092177b41ceSRagothaman Jayaraman 			encr_offset = passthrough_len + aad_len + iv_len;
1093177b41ceSRagothaman Jayaraman 			auth_data_len = aad_len + encr_data_len;
1094177b41ceSRagothaman Jayaraman 		} else {
1095177b41ceSRagothaman Jayaraman 			passthrough_len = 16 + aad_len;
1096177b41ceSRagothaman Jayaraman 			auth_offset = passthrough_len + iv_len;
1097177b41ceSRagothaman Jayaraman 			auth_data_len = aad_len;
1098177b41ceSRagothaman Jayaraman 		}
1099177b41ceSRagothaman Jayaraman 	} else {
1100177b41ceSRagothaman Jayaraman 		encr_offset += iv_len;
1101177b41ceSRagothaman Jayaraman 		auth_offset += iv_len;
1102177b41ceSRagothaman Jayaraman 	}
1103177b41ceSRagothaman Jayaraman 
1104177b41ceSRagothaman Jayaraman 	/*
1105177b41ceSRagothaman Jayaraman 	 * Save initial space that followed app data for completion code &
1106177b41ceSRagothaman Jayaraman 	 * alternate completion code to fall in same cache line as app data
1107177b41ceSRagothaman Jayaraman 	 */
1108177b41ceSRagothaman Jayaraman 	m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE;
1109177b41ceSRagothaman Jayaraman 	m_dma += COMPLETION_CODE_SIZE;
1110177b41ceSRagothaman Jayaraman 	size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) -
1111177b41ceSRagothaman Jayaraman 	       (uint8_t *)m_vaddr;
1112177b41ceSRagothaman Jayaraman 	c_vaddr = (uint8_t *)m_vaddr + size;
1113177b41ceSRagothaman Jayaraman 	c_dma = m_dma + size;
1114177b41ceSRagothaman Jayaraman 	size += sizeof(cpt_res_s_t);
1115177b41ceSRagothaman Jayaraman 
1116177b41ceSRagothaman Jayaraman 	m_vaddr = (uint8_t *)m_vaddr + size;
1117177b41ceSRagothaman Jayaraman 	m_dma += size;
1118177b41ceSRagothaman Jayaraman 
1119177b41ceSRagothaman Jayaraman 	/* start cpt request info structure at 8 byte alignment */
1120177b41ceSRagothaman Jayaraman 	size = (uint8_t *)RTE_PTR_ALIGN(m_vaddr, 8) -
1121177b41ceSRagothaman Jayaraman 		(uint8_t *)m_vaddr;
1122177b41ceSRagothaman Jayaraman 
1123177b41ceSRagothaman Jayaraman 	req = (struct cpt_request_info *)((uint8_t *)m_vaddr + size);
1124177b41ceSRagothaman Jayaraman 
1125177b41ceSRagothaman Jayaraman 	size += sizeof(struct cpt_request_info);
1126177b41ceSRagothaman Jayaraman 	m_vaddr = (uint8_t *)m_vaddr + size;
1127177b41ceSRagothaman Jayaraman 	m_dma += size;
1128177b41ceSRagothaman Jayaraman 
1129177b41ceSRagothaman Jayaraman 	/* Decryption */
1130629ac988SArchana Muniganti 	vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_FC;
1131de5eb0a6STejasree Kondoj 	vq_cmd_w0.s.opcode.minor = CPT_FC_MINOR_OP_DECRYPT;
1132de5eb0a6STejasree Kondoj 	vq_cmd_w0.s.opcode.minor |= (cpt_ctx->dec_auth <<
1133de5eb0a6STejasree Kondoj 					CPT_HMAC_FIRST_BIT_POS);
1134177b41ceSRagothaman Jayaraman 
11350058f305SAnkur Dwivedi 	if (hash_type == GMAC_TYPE) {
11360058f305SAnkur Dwivedi 		encr_offset = 0;
11370058f305SAnkur Dwivedi 		encr_data_len = 0;
11380058f305SAnkur Dwivedi 	}
11390058f305SAnkur Dwivedi 
1140177b41ceSRagothaman Jayaraman 	enc_dlen = encr_offset + encr_data_len;
1141177b41ceSRagothaman Jayaraman 	auth_dlen = auth_offset + auth_data_len;
1142177b41ceSRagothaman Jayaraman 
1143177b41ceSRagothaman Jayaraman 	if (auth_dlen > enc_dlen) {
1144177b41ceSRagothaman Jayaraman 		inputlen = auth_dlen + mac_len;
1145177b41ceSRagothaman Jayaraman 		outputlen = auth_dlen;
1146177b41ceSRagothaman Jayaraman 	} else {
1147177b41ceSRagothaman Jayaraman 		inputlen = enc_dlen + mac_len;
1148177b41ceSRagothaman Jayaraman 		outputlen = enc_dlen;
1149177b41ceSRagothaman Jayaraman 	}
1150177b41ceSRagothaman Jayaraman 
1151de5eb0a6STejasree Kondoj 	if (cpt_ctx->dec_auth != 0)
1152de5eb0a6STejasree Kondoj 		outputlen = inputlen = enc_dlen;
1153de5eb0a6STejasree Kondoj 
1154426af86bSAnoob Joseph 	vq_cmd_w0.s.param1 = encr_data_len;
1155426af86bSAnoob Joseph 	vq_cmd_w0.s.param2 = auth_data_len;
1156177b41ceSRagothaman Jayaraman 
1157177b41ceSRagothaman Jayaraman 	/*
1158177b41ceSRagothaman Jayaraman 	 * In 83XX since we have a limitation of
1159177b41ceSRagothaman Jayaraman 	 * IV & Offset control word not part of instruction
1160177b41ceSRagothaman Jayaraman 	 * and need to be part of Data Buffer, we check if
1161177b41ceSRagothaman Jayaraman 	 * head room is there and then only do the Direct mode processing
1162177b41ceSRagothaman Jayaraman 	 */
1163177b41ceSRagothaman Jayaraman 	if (likely((flags & SINGLE_BUF_INPLACE) &&
1164177b41ceSRagothaman Jayaraman 		   (flags & SINGLE_BUF_HEADTAILROOM))) {
1165177b41ceSRagothaman Jayaraman 		void *dm_vaddr = fc_params->bufs[0].vaddr;
1166177b41ceSRagothaman Jayaraman 		uint64_t dm_dma_addr = fc_params->bufs[0].dma_addr;
1167177b41ceSRagothaman Jayaraman 		/*
1168177b41ceSRagothaman Jayaraman 		 * This flag indicates that there is 24 bytes head room and
1169177b41ceSRagothaman Jayaraman 		 * 8 bytes tail room available, so that we get to do
1170177b41ceSRagothaman Jayaraman 		 * DIRECT MODE with limitation
1171177b41ceSRagothaman Jayaraman 		 */
1172177b41ceSRagothaman Jayaraman 
1173177b41ceSRagothaman Jayaraman 		offset_vaddr = (uint8_t *)dm_vaddr - OFF_CTRL_LEN - iv_len;
1174177b41ceSRagothaman Jayaraman 		offset_dma = dm_dma_addr - OFF_CTRL_LEN - iv_len;
1175177b41ceSRagothaman Jayaraman 		req->ist.ei1 = offset_dma;
1176177b41ceSRagothaman Jayaraman 
1177177b41ceSRagothaman Jayaraman 		/* RPTR should just exclude offset control word */
1178177b41ceSRagothaman Jayaraman 		req->ist.ei2 = dm_dma_addr - iv_len;
1179177b41ceSRagothaman Jayaraman 
1180177b41ceSRagothaman Jayaraman 		req->alternate_caddr = (uint64_t *)((uint8_t *)dm_vaddr +
1181177b41ceSRagothaman Jayaraman 					outputlen - iv_len);
1182177b41ceSRagothaman Jayaraman 		/* since this is decryption,
1183177b41ceSRagothaman Jayaraman 		 * don't touch the content of
1184177b41ceSRagothaman Jayaraman 		 * alternate ccode space as it contains
1185177b41ceSRagothaman Jayaraman 		 * hmac.
1186177b41ceSRagothaman Jayaraman 		 */
1187177b41ceSRagothaman Jayaraman 
1188426af86bSAnoob Joseph 		vq_cmd_w0.s.dlen = inputlen + OFF_CTRL_LEN;
1189177b41ceSRagothaman Jayaraman 
1190177b41ceSRagothaman Jayaraman 		if (likely(iv_len)) {
1191177b41ceSRagothaman Jayaraman 			uint64_t *dest = (uint64_t *)((uint8_t *)offset_vaddr +
1192177b41ceSRagothaman Jayaraman 						      OFF_CTRL_LEN);
1193177b41ceSRagothaman Jayaraman 			uint64_t *src = fc_params->iv_buf;
1194177b41ceSRagothaman Jayaraman 			dest[0] = src[0];
1195177b41ceSRagothaman Jayaraman 			dest[1] = src[1];
1196177b41ceSRagothaman Jayaraman 		}
1197177b41ceSRagothaman Jayaraman 
11982a6c7922SAnoob Joseph 		if (unlikely((encr_offset >> 16) ||
11992a6c7922SAnoob Joseph 			     (iv_offset >> 8) ||
12002a6c7922SAnoob Joseph 			     (auth_offset >> 8))) {
12012a6c7922SAnoob Joseph 			CPT_LOG_DP_ERR("Offset not supported");
12022a6c7922SAnoob Joseph 			CPT_LOG_DP_ERR("enc_offset: %d", encr_offset);
12032a6c7922SAnoob Joseph 			CPT_LOG_DP_ERR("iv_offset : %d", iv_offset);
12042a6c7922SAnoob Joseph 			CPT_LOG_DP_ERR("auth_offset: %d", auth_offset);
12052a6c7922SAnoob Joseph 			return;
12062a6c7922SAnoob Joseph 		}
12072a6c7922SAnoob Joseph 
1208177b41ceSRagothaman Jayaraman 		*(uint64_t *)offset_vaddr =
1209177b41ceSRagothaman Jayaraman 			rte_cpu_to_be_64(((uint64_t)encr_offset << 16) |
1210177b41ceSRagothaman Jayaraman 				((uint64_t)iv_offset << 8) |
1211177b41ceSRagothaman Jayaraman 				((uint64_t)auth_offset));
1212177b41ceSRagothaman Jayaraman 
1213177b41ceSRagothaman Jayaraman 	} else {
1214177b41ceSRagothaman Jayaraman 		uint64_t dptr_dma, rptr_dma;
1215177b41ceSRagothaman Jayaraman 		uint32_t g_size_bytes, s_size_bytes;
1216177b41ceSRagothaman Jayaraman 		sg_comp_t *gather_comp;
1217177b41ceSRagothaman Jayaraman 		sg_comp_t *scatter_comp;
1218177b41ceSRagothaman Jayaraman 		uint8_t *in_buffer;
1219177b41ceSRagothaman Jayaraman 		uint8_t i = 0;
1220177b41ceSRagothaman Jayaraman 
1221177b41ceSRagothaman Jayaraman 		/* This falls under strict SG mode */
1222177b41ceSRagothaman Jayaraman 		offset_vaddr = m_vaddr;
1223177b41ceSRagothaman Jayaraman 		offset_dma = m_dma;
1224177b41ceSRagothaman Jayaraman 		size = OFF_CTRL_LEN + iv_len;
1225177b41ceSRagothaman Jayaraman 
1226177b41ceSRagothaman Jayaraman 		m_vaddr = (uint8_t *)m_vaddr + size;
1227177b41ceSRagothaman Jayaraman 		m_dma += size;
1228177b41ceSRagothaman Jayaraman 
1229629ac988SArchana Muniganti 		vq_cmd_w0.s.opcode.major |= CPT_DMA_MODE;
1230177b41ceSRagothaman Jayaraman 
1231177b41ceSRagothaman Jayaraman 		if (likely(iv_len)) {
1232177b41ceSRagothaman Jayaraman 			uint64_t *dest = (uint64_t *)((uint8_t *)offset_vaddr +
1233177b41ceSRagothaman Jayaraman 						      OFF_CTRL_LEN);
1234177b41ceSRagothaman Jayaraman 			uint64_t *src = fc_params->iv_buf;
1235177b41ceSRagothaman Jayaraman 			dest[0] = src[0];
1236177b41ceSRagothaman Jayaraman 			dest[1] = src[1];
1237177b41ceSRagothaman Jayaraman 		}
1238177b41ceSRagothaman Jayaraman 
12392a6c7922SAnoob Joseph 		if (unlikely((encr_offset >> 16) ||
12402a6c7922SAnoob Joseph 			     (iv_offset >> 8) ||
12412a6c7922SAnoob Joseph 			     (auth_offset >> 8))) {
12422a6c7922SAnoob Joseph 			CPT_LOG_DP_ERR("Offset not supported");
12432a6c7922SAnoob Joseph 			CPT_LOG_DP_ERR("enc_offset: %d", encr_offset);
12442a6c7922SAnoob Joseph 			CPT_LOG_DP_ERR("iv_offset : %d", iv_offset);
12452a6c7922SAnoob Joseph 			CPT_LOG_DP_ERR("auth_offset: %d", auth_offset);
12462a6c7922SAnoob Joseph 			return;
12472a6c7922SAnoob Joseph 		}
12482a6c7922SAnoob Joseph 
1249177b41ceSRagothaman Jayaraman 		*(uint64_t *)offset_vaddr =
1250177b41ceSRagothaman Jayaraman 			rte_cpu_to_be_64(((uint64_t)encr_offset << 16) |
1251177b41ceSRagothaman Jayaraman 				((uint64_t)iv_offset << 8) |
1252177b41ceSRagothaman Jayaraman 				((uint64_t)auth_offset));
1253177b41ceSRagothaman Jayaraman 
1254177b41ceSRagothaman Jayaraman 		/* DPTR has SG list */
1255177b41ceSRagothaman Jayaraman 		in_buffer = m_vaddr;
1256177b41ceSRagothaman Jayaraman 		dptr_dma = m_dma;
1257177b41ceSRagothaman Jayaraman 
1258177b41ceSRagothaman Jayaraman 		((uint16_t *)in_buffer)[0] = 0;
1259177b41ceSRagothaman Jayaraman 		((uint16_t *)in_buffer)[1] = 0;
1260177b41ceSRagothaman Jayaraman 
1261177b41ceSRagothaman Jayaraman 		/* TODO Add error check if space will be sufficient */
1262177b41ceSRagothaman Jayaraman 		gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8);
1263177b41ceSRagothaman Jayaraman 
1264177b41ceSRagothaman Jayaraman 		/*
1265177b41ceSRagothaman Jayaraman 		 * Input Gather List
1266177b41ceSRagothaman Jayaraman 		 */
1267177b41ceSRagothaman Jayaraman 		i = 0;
1268177b41ceSRagothaman Jayaraman 
1269177b41ceSRagothaman Jayaraman 		/* Offset control word that includes iv */
1270177b41ceSRagothaman Jayaraman 		i = fill_sg_comp(gather_comp, i, offset_dma,
1271177b41ceSRagothaman Jayaraman 				 OFF_CTRL_LEN + iv_len);
1272177b41ceSRagothaman Jayaraman 
1273177b41ceSRagothaman Jayaraman 		/* Add input data */
1274177b41ceSRagothaman Jayaraman 		if (flags & VALID_MAC_BUF) {
1275177b41ceSRagothaman Jayaraman 			size = inputlen - iv_len - mac_len;
1276177b41ceSRagothaman Jayaraman 			if (size) {
1277177b41ceSRagothaman Jayaraman 				/* input data only */
1278177b41ceSRagothaman Jayaraman 				if (unlikely(flags & SINGLE_BUF_INPLACE)) {
1279177b41ceSRagothaman Jayaraman 					i = fill_sg_comp_from_buf_min(
1280177b41ceSRagothaman Jayaraman 							gather_comp, i,
1281177b41ceSRagothaman Jayaraman 							fc_params->bufs,
1282177b41ceSRagothaman Jayaraman 							&size);
1283177b41ceSRagothaman Jayaraman 				} else {
1284177b41ceSRagothaman Jayaraman 					uint32_t aad_offset = aad_len ?
1285177b41ceSRagothaman Jayaraman 						passthrough_len : 0;
1286177b41ceSRagothaman Jayaraman 
1287177b41ceSRagothaman Jayaraman 					i = fill_sg_comp_from_iov(gather_comp,
1288177b41ceSRagothaman Jayaraman 							i,
1289177b41ceSRagothaman Jayaraman 							fc_params->src_iov,
1290177b41ceSRagothaman Jayaraman 							0, &size,
1291177b41ceSRagothaman Jayaraman 							aad_buf,
1292177b41ceSRagothaman Jayaraman 							aad_offset);
1293177b41ceSRagothaman Jayaraman 				}
1294f39928e6SAnoob Joseph 				if (unlikely(size)) {
1295f39928e6SAnoob Joseph 					CPT_LOG_DP_ERR("Insufficient buffer"
1296f39928e6SAnoob Joseph 						       " space, size %d needed",
1297f39928e6SAnoob Joseph 						       size);
1298f39928e6SAnoob Joseph 					return;
1299f39928e6SAnoob Joseph 				}
1300177b41ceSRagothaman Jayaraman 			}
1301177b41ceSRagothaman Jayaraman 
1302177b41ceSRagothaman Jayaraman 			/* mac data */
1303177b41ceSRagothaman Jayaraman 			if (mac_len) {
1304177b41ceSRagothaman Jayaraman 				i = fill_sg_comp_from_buf(gather_comp, i,
1305177b41ceSRagothaman Jayaraman 							  &fc_params->mac_buf);
1306177b41ceSRagothaman Jayaraman 			}
1307177b41ceSRagothaman Jayaraman 		} else {
1308177b41ceSRagothaman Jayaraman 			/* input data + mac */
1309177b41ceSRagothaman Jayaraman 			size = inputlen - iv_len;
1310177b41ceSRagothaman Jayaraman 			if (size) {
1311177b41ceSRagothaman Jayaraman 				if (unlikely(flags & SINGLE_BUF_INPLACE)) {
1312177b41ceSRagothaman Jayaraman 					i = fill_sg_comp_from_buf_min(
1313177b41ceSRagothaman Jayaraman 							gather_comp, i,
1314177b41ceSRagothaman Jayaraman 							fc_params->bufs,
1315177b41ceSRagothaman Jayaraman 							&size);
1316177b41ceSRagothaman Jayaraman 				} else {
1317177b41ceSRagothaman Jayaraman 					uint32_t aad_offset = aad_len ?
1318177b41ceSRagothaman Jayaraman 						passthrough_len : 0;
1319177b41ceSRagothaman Jayaraman 
1320f39928e6SAnoob Joseph 					if (unlikely(!fc_params->src_iov)) {
1321f39928e6SAnoob Joseph 						CPT_LOG_DP_ERR("Bad input args");
1322f39928e6SAnoob Joseph 						return;
1323f39928e6SAnoob Joseph 					}
1324177b41ceSRagothaman Jayaraman 
1325177b41ceSRagothaman Jayaraman 					i = fill_sg_comp_from_iov(
1326177b41ceSRagothaman Jayaraman 							gather_comp, i,
1327177b41ceSRagothaman Jayaraman 							fc_params->src_iov,
1328177b41ceSRagothaman Jayaraman 							0, &size,
1329177b41ceSRagothaman Jayaraman 							aad_buf,
1330177b41ceSRagothaman Jayaraman 							aad_offset);
1331177b41ceSRagothaman Jayaraman 				}
1332177b41ceSRagothaman Jayaraman 
1333f39928e6SAnoob Joseph 				if (unlikely(size)) {
1334f39928e6SAnoob Joseph 					CPT_LOG_DP_ERR("Insufficient buffer"
1335f39928e6SAnoob Joseph 						       " space, size %d needed",
1336f39928e6SAnoob Joseph 						       size);
1337f39928e6SAnoob Joseph 					return;
1338f39928e6SAnoob Joseph 				}
1339177b41ceSRagothaman Jayaraman 			}
1340177b41ceSRagothaman Jayaraman 		}
1341177b41ceSRagothaman Jayaraman 		((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i);
1342177b41ceSRagothaman Jayaraman 		g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
1343177b41ceSRagothaman Jayaraman 
1344177b41ceSRagothaman Jayaraman 		/*
1345177b41ceSRagothaman Jayaraman 		 * Output Scatter List
1346177b41ceSRagothaman Jayaraman 		 */
1347177b41ceSRagothaman Jayaraman 
1348177b41ceSRagothaman Jayaraman 		i = 0;
1349177b41ceSRagothaman Jayaraman 		scatter_comp =
1350177b41ceSRagothaman Jayaraman 			(sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes);
1351177b41ceSRagothaman Jayaraman 
1352177b41ceSRagothaman Jayaraman 		/* Add iv */
1353177b41ceSRagothaman Jayaraman 		if (iv_len) {
1354177b41ceSRagothaman Jayaraman 			i = fill_sg_comp(scatter_comp, i,
1355177b41ceSRagothaman Jayaraman 					 offset_dma + OFF_CTRL_LEN,
1356177b41ceSRagothaman Jayaraman 					 iv_len);
1357177b41ceSRagothaman Jayaraman 		}
1358177b41ceSRagothaman Jayaraman 
1359177b41ceSRagothaman Jayaraman 		/* Add output data */
1360177b41ceSRagothaman Jayaraman 		size = outputlen - iv_len;
1361177b41ceSRagothaman Jayaraman 		if (size) {
1362177b41ceSRagothaman Jayaraman 			if (unlikely(flags & SINGLE_BUF_INPLACE)) {
1363177b41ceSRagothaman Jayaraman 				/* handle single buffer here */
1364177b41ceSRagothaman Jayaraman 				i = fill_sg_comp_from_buf_min(scatter_comp, i,
1365177b41ceSRagothaman Jayaraman 							      fc_params->bufs,
1366177b41ceSRagothaman Jayaraman 							      &size);
1367177b41ceSRagothaman Jayaraman 			} else {
1368177b41ceSRagothaman Jayaraman 				uint32_t aad_offset = aad_len ?
1369177b41ceSRagothaman Jayaraman 					passthrough_len : 0;
1370177b41ceSRagothaman Jayaraman 
1371f39928e6SAnoob Joseph 				if (unlikely(!fc_params->dst_iov)) {
1372f39928e6SAnoob Joseph 					CPT_LOG_DP_ERR("Bad input args");
1373f39928e6SAnoob Joseph 					return;
1374f39928e6SAnoob Joseph 				}
1375177b41ceSRagothaman Jayaraman 
1376177b41ceSRagothaman Jayaraman 				i = fill_sg_comp_from_iov(scatter_comp, i,
1377177b41ceSRagothaman Jayaraman 							  fc_params->dst_iov, 0,
1378177b41ceSRagothaman Jayaraman 							  &size, aad_buf,
1379177b41ceSRagothaman Jayaraman 							  aad_offset);
1380177b41ceSRagothaman Jayaraman 			}
1381177b41ceSRagothaman Jayaraman 
1382f39928e6SAnoob Joseph 			if (unlikely(size)) {
1383f39928e6SAnoob Joseph 				CPT_LOG_DP_ERR("Insufficient buffer space,"
1384f39928e6SAnoob Joseph 					       " size %d needed", size);
1385f39928e6SAnoob Joseph 				return;
1386f39928e6SAnoob Joseph 			}
1387177b41ceSRagothaman Jayaraman 		}
1388177b41ceSRagothaman Jayaraman 
1389177b41ceSRagothaman Jayaraman 		((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i);
1390177b41ceSRagothaman Jayaraman 		s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
1391177b41ceSRagothaman Jayaraman 
1392177b41ceSRagothaman Jayaraman 		size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE;
1393177b41ceSRagothaman Jayaraman 
1394177b41ceSRagothaman Jayaraman 		/* This is DPTR len incase of SG mode */
1395426af86bSAnoob Joseph 		vq_cmd_w0.s.dlen = size;
1396177b41ceSRagothaman Jayaraman 
1397177b41ceSRagothaman Jayaraman 		m_vaddr = (uint8_t *)m_vaddr + size;
1398177b41ceSRagothaman Jayaraman 		m_dma += size;
1399177b41ceSRagothaman Jayaraman 
1400177b41ceSRagothaman Jayaraman 		/* cpt alternate completion address saved earlier */
1401177b41ceSRagothaman Jayaraman 		req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8);
1402177b41ceSRagothaman Jayaraman 		*req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT);
1403177b41ceSRagothaman Jayaraman 		rptr_dma = c_dma - 8;
1404177b41ceSRagothaman Jayaraman 		size += COMPLETION_CODE_SIZE;
1405177b41ceSRagothaman Jayaraman 
1406177b41ceSRagothaman Jayaraman 		req->ist.ei1 = dptr_dma;
1407177b41ceSRagothaman Jayaraman 		req->ist.ei2 = rptr_dma;
1408177b41ceSRagothaman Jayaraman 	}
1409177b41ceSRagothaman Jayaraman 
1410177b41ceSRagothaman Jayaraman 	/* 16 byte aligned cpt res address */
1411177b41ceSRagothaman Jayaraman 	req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr);
1412177b41ceSRagothaman Jayaraman 	*req->completion_addr = COMPLETION_CODE_INIT;
1413177b41ceSRagothaman Jayaraman 	req->comp_baddr  = c_dma;
1414177b41ceSRagothaman Jayaraman 
1415177b41ceSRagothaman Jayaraman 	/* Fill microcode part of instruction */
1416177b41ceSRagothaman Jayaraman 	req->ist.ei0 = vq_cmd_w0.u64;
1417177b41ceSRagothaman Jayaraman 
1418177b41ceSRagothaman Jayaraman 	req->op = op;
1419177b41ceSRagothaman Jayaraman 
1420177b41ceSRagothaman Jayaraman 	*prep_req = req;
1421f39928e6SAnoob Joseph 	return;
1422177b41ceSRagothaman Jayaraman }
1423177b41ceSRagothaman Jayaraman 
1424f39928e6SAnoob Joseph static __rte_always_inline void
142500d92c66SSrisivasubramanian S cpt_zuc_snow3g_enc_prep(uint32_t req_flags,
142600d92c66SSrisivasubramanian S 			uint64_t d_offs,
142700d92c66SSrisivasubramanian S 			uint64_t d_lens,
142800d92c66SSrisivasubramanian S 			fc_params_t *params,
142900d92c66SSrisivasubramanian S 			void *op,
143000d92c66SSrisivasubramanian S 			void **prep_req)
143100d92c66SSrisivasubramanian S {
143200d92c66SSrisivasubramanian S 	uint32_t size;
143300d92c66SSrisivasubramanian S 	int32_t inputlen, outputlen;
143400d92c66SSrisivasubramanian S 	struct cpt_ctx *cpt_ctx;
143500d92c66SSrisivasubramanian S 	uint32_t mac_len = 0;
143600d92c66SSrisivasubramanian S 	uint8_t snow3g, j;
143700d92c66SSrisivasubramanian S 	struct cpt_request_info *req;
143800d92c66SSrisivasubramanian S 	buf_ptr_t *buf_p;
143900d92c66SSrisivasubramanian S 	uint32_t encr_offset = 0, auth_offset = 0;
144000d92c66SSrisivasubramanian S 	uint32_t encr_data_len = 0, auth_data_len = 0;
14418de5ede7SAnoob Joseph 	int flags, iv_len = 16;
144200d92c66SSrisivasubramanian S 	void *m_vaddr, *c_vaddr;
144300d92c66SSrisivasubramanian S 	uint64_t m_dma, c_dma, offset_ctrl;
144400d92c66SSrisivasubramanian S 	uint64_t *offset_vaddr, offset_dma;
144500d92c66SSrisivasubramanian S 	uint32_t *iv_s, iv[4];
144600d92c66SSrisivasubramanian S 	vq_cmd_word0_t vq_cmd_w0;
144700d92c66SSrisivasubramanian S 
144800d92c66SSrisivasubramanian S 	buf_p = &params->meta_buf;
144900d92c66SSrisivasubramanian S 	m_vaddr = buf_p->vaddr;
145000d92c66SSrisivasubramanian S 	m_dma = buf_p->dma_addr;
145100d92c66SSrisivasubramanian S 
145200d92c66SSrisivasubramanian S 	cpt_ctx = params->ctx_buf.vaddr;
145300d92c66SSrisivasubramanian S 	flags = cpt_ctx->zsk_flags;
145400d92c66SSrisivasubramanian S 	mac_len = cpt_ctx->mac_len;
145500d92c66SSrisivasubramanian S 	snow3g = cpt_ctx->snow3g;
145600d92c66SSrisivasubramanian S 
145700d92c66SSrisivasubramanian S 	/*
145800d92c66SSrisivasubramanian S 	 * Save initial space that followed app data for completion code &
145900d92c66SSrisivasubramanian S 	 * alternate completion code to fall in same cache line as app data
146000d92c66SSrisivasubramanian S 	 */
146100d92c66SSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE;
146200d92c66SSrisivasubramanian S 	m_dma += COMPLETION_CODE_SIZE;
146300d92c66SSrisivasubramanian S 	size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) -
146400d92c66SSrisivasubramanian S 		(uint8_t *)m_vaddr;
146500d92c66SSrisivasubramanian S 
146600d92c66SSrisivasubramanian S 	c_vaddr = (uint8_t *)m_vaddr + size;
146700d92c66SSrisivasubramanian S 	c_dma = m_dma + size;
146800d92c66SSrisivasubramanian S 	size += sizeof(cpt_res_s_t);
146900d92c66SSrisivasubramanian S 
147000d92c66SSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
147100d92c66SSrisivasubramanian S 	m_dma += size;
147200d92c66SSrisivasubramanian S 
147300d92c66SSrisivasubramanian S 	/* Reserve memory for cpt request info */
147400d92c66SSrisivasubramanian S 	req = m_vaddr;
147500d92c66SSrisivasubramanian S 
147600d92c66SSrisivasubramanian S 	size = sizeof(struct cpt_request_info);
147700d92c66SSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
147800d92c66SSrisivasubramanian S 	m_dma += size;
147900d92c66SSrisivasubramanian S 
1480629ac988SArchana Muniganti 	vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_ZUC_SNOW3G;
148100d92c66SSrisivasubramanian S 
148200d92c66SSrisivasubramanian S 	/* indicates CPTR ctx, operation type, KEY & IV mode from DPTR */
1483131966f8SAnkur Dwivedi 
1484629ac988SArchana Muniganti 	vq_cmd_w0.s.opcode.minor = ((1 << 7) | (snow3g << 5) | (0 << 4) |
148500d92c66SSrisivasubramanian S 			  (0 << 3) | (flags & 0x7));
148600d92c66SSrisivasubramanian S 
148700d92c66SSrisivasubramanian S 	if (flags == 0x1) {
148800d92c66SSrisivasubramanian S 		/*
148900d92c66SSrisivasubramanian S 		 * Microcode expects offsets in bytes
149000d92c66SSrisivasubramanian S 		 * TODO: Rounding off
149100d92c66SSrisivasubramanian S 		 */
149200d92c66SSrisivasubramanian S 		auth_data_len = AUTH_DLEN(d_lens);
149300d92c66SSrisivasubramanian S 
149400d92c66SSrisivasubramanian S 		/* EIA3 or UIA2 */
149500d92c66SSrisivasubramanian S 		auth_offset = AUTH_OFFSET(d_offs);
149600d92c66SSrisivasubramanian S 		auth_offset = auth_offset / 8;
149700d92c66SSrisivasubramanian S 
149800d92c66SSrisivasubramanian S 		/* consider iv len */
149900d92c66SSrisivasubramanian S 		auth_offset += iv_len;
150000d92c66SSrisivasubramanian S 
150100d92c66SSrisivasubramanian S 		inputlen = auth_offset + (RTE_ALIGN(auth_data_len, 8) / 8);
150200d92c66SSrisivasubramanian S 		outputlen = mac_len;
150300d92c66SSrisivasubramanian S 
150400d92c66SSrisivasubramanian S 		offset_ctrl = rte_cpu_to_be_64((uint64_t)auth_offset);
150500d92c66SSrisivasubramanian S 
150600d92c66SSrisivasubramanian S 	} else {
150700d92c66SSrisivasubramanian S 		/* EEA3 or UEA2 */
150800d92c66SSrisivasubramanian S 		/*
150900d92c66SSrisivasubramanian S 		 * Microcode expects offsets in bytes
151000d92c66SSrisivasubramanian S 		 * TODO: Rounding off
151100d92c66SSrisivasubramanian S 		 */
151200d92c66SSrisivasubramanian S 		encr_data_len = ENCR_DLEN(d_lens);
151300d92c66SSrisivasubramanian S 
151400d92c66SSrisivasubramanian S 		encr_offset = ENCR_OFFSET(d_offs);
151500d92c66SSrisivasubramanian S 		encr_offset = encr_offset / 8;
151600d92c66SSrisivasubramanian S 		/* consider iv len */
151700d92c66SSrisivasubramanian S 		encr_offset += iv_len;
151800d92c66SSrisivasubramanian S 
151900d92c66SSrisivasubramanian S 		inputlen = encr_offset + (RTE_ALIGN(encr_data_len, 8) / 8);
152000d92c66SSrisivasubramanian S 		outputlen = inputlen;
152100d92c66SSrisivasubramanian S 
152200d92c66SSrisivasubramanian S 		/* iv offset is 0 */
152300d92c66SSrisivasubramanian S 		offset_ctrl = rte_cpu_to_be_64((uint64_t)encr_offset << 16);
152400d92c66SSrisivasubramanian S 	}
152500d92c66SSrisivasubramanian S 
15262a6c7922SAnoob Joseph 	if (unlikely((encr_offset >> 16) ||
15272a6c7922SAnoob Joseph 		     (auth_offset >> 8))) {
15282a6c7922SAnoob Joseph 		CPT_LOG_DP_ERR("Offset not supported");
15292a6c7922SAnoob Joseph 		CPT_LOG_DP_ERR("enc_offset: %d", encr_offset);
15302a6c7922SAnoob Joseph 		CPT_LOG_DP_ERR("auth_offset: %d", auth_offset);
15312a6c7922SAnoob Joseph 		return;
15322a6c7922SAnoob Joseph 	}
15332a6c7922SAnoob Joseph 
153400d92c66SSrisivasubramanian S 	/* IV */
153500d92c66SSrisivasubramanian S 	iv_s = (flags == 0x1) ? params->auth_iv_buf :
153600d92c66SSrisivasubramanian S 		params->iv_buf;
153700d92c66SSrisivasubramanian S 
153800d92c66SSrisivasubramanian S 	if (snow3g) {
153900d92c66SSrisivasubramanian S 		/*
154000d92c66SSrisivasubramanian S 		 * DPDK seems to provide it in form of IV3 IV2 IV1 IV0
154100d92c66SSrisivasubramanian S 		 * and BigEndian, MC needs it as IV0 IV1 IV2 IV3
154200d92c66SSrisivasubramanian S 		 */
154300d92c66SSrisivasubramanian S 
154400d92c66SSrisivasubramanian S 		for (j = 0; j < 4; j++)
154500d92c66SSrisivasubramanian S 			iv[j] = iv_s[3 - j];
154600d92c66SSrisivasubramanian S 	} else {
154700d92c66SSrisivasubramanian S 		/* ZUC doesn't need a swap */
154800d92c66SSrisivasubramanian S 		for (j = 0; j < 4; j++)
154900d92c66SSrisivasubramanian S 			iv[j] = iv_s[j];
155000d92c66SSrisivasubramanian S 	}
155100d92c66SSrisivasubramanian S 
155200d92c66SSrisivasubramanian S 	/*
155300d92c66SSrisivasubramanian S 	 * GP op header, lengths are expected in bits.
155400d92c66SSrisivasubramanian S 	 */
1555426af86bSAnoob Joseph 	vq_cmd_w0.s.param1 = encr_data_len;
1556426af86bSAnoob Joseph 	vq_cmd_w0.s.param2 = auth_data_len;
155700d92c66SSrisivasubramanian S 
155800d92c66SSrisivasubramanian S 	/*
155900d92c66SSrisivasubramanian S 	 * In 83XX since we have a limitation of
156000d92c66SSrisivasubramanian S 	 * IV & Offset control word not part of instruction
156100d92c66SSrisivasubramanian S 	 * and need to be part of Data Buffer, we check if
156200d92c66SSrisivasubramanian S 	 * head room is there and then only do the Direct mode processing
156300d92c66SSrisivasubramanian S 	 */
156400d92c66SSrisivasubramanian S 	if (likely((req_flags & SINGLE_BUF_INPLACE) &&
156500d92c66SSrisivasubramanian S 		   (req_flags & SINGLE_BUF_HEADTAILROOM))) {
156600d92c66SSrisivasubramanian S 		void *dm_vaddr = params->bufs[0].vaddr;
156700d92c66SSrisivasubramanian S 		uint64_t dm_dma_addr = params->bufs[0].dma_addr;
156800d92c66SSrisivasubramanian S 		/*
156900d92c66SSrisivasubramanian S 		 * This flag indicates that there is 24 bytes head room and
157000d92c66SSrisivasubramanian S 		 * 8 bytes tail room available, so that we get to do
157100d92c66SSrisivasubramanian S 		 * DIRECT MODE with limitation
157200d92c66SSrisivasubramanian S 		 */
157300d92c66SSrisivasubramanian S 
157400d92c66SSrisivasubramanian S 		offset_vaddr = (uint64_t *)((uint8_t *)dm_vaddr -
157500d92c66SSrisivasubramanian S 					    OFF_CTRL_LEN - iv_len);
157600d92c66SSrisivasubramanian S 		offset_dma = dm_dma_addr - OFF_CTRL_LEN - iv_len;
157700d92c66SSrisivasubramanian S 
157800d92c66SSrisivasubramanian S 		/* DPTR */
157900d92c66SSrisivasubramanian S 		req->ist.ei1 = offset_dma;
158000d92c66SSrisivasubramanian S 		/* RPTR should just exclude offset control word */
158100d92c66SSrisivasubramanian S 		req->ist.ei2 = dm_dma_addr - iv_len;
158200d92c66SSrisivasubramanian S 		req->alternate_caddr = (uint64_t *)((uint8_t *)dm_vaddr
158300d92c66SSrisivasubramanian S 						    + outputlen - iv_len);
158400d92c66SSrisivasubramanian S 
1585426af86bSAnoob Joseph 		vq_cmd_w0.s.dlen = inputlen + OFF_CTRL_LEN;
158600d92c66SSrisivasubramanian S 
158700d92c66SSrisivasubramanian S 		if (likely(iv_len)) {
158800d92c66SSrisivasubramanian S 			uint32_t *iv_d = (uint32_t *)((uint8_t *)offset_vaddr
158900d92c66SSrisivasubramanian S 						      + OFF_CTRL_LEN);
159000d92c66SSrisivasubramanian S 			memcpy(iv_d, iv, 16);
159100d92c66SSrisivasubramanian S 		}
159200d92c66SSrisivasubramanian S 
159300d92c66SSrisivasubramanian S 		*offset_vaddr = offset_ctrl;
159400d92c66SSrisivasubramanian S 	} else {
159500d92c66SSrisivasubramanian S 		uint32_t i, g_size_bytes, s_size_bytes;
159600d92c66SSrisivasubramanian S 		uint64_t dptr_dma, rptr_dma;
159700d92c66SSrisivasubramanian S 		sg_comp_t *gather_comp;
159800d92c66SSrisivasubramanian S 		sg_comp_t *scatter_comp;
159900d92c66SSrisivasubramanian S 		uint8_t *in_buffer;
160000d92c66SSrisivasubramanian S 		uint32_t *iv_d;
160100d92c66SSrisivasubramanian S 
160200d92c66SSrisivasubramanian S 		/* save space for iv */
160300d92c66SSrisivasubramanian S 		offset_vaddr = m_vaddr;
160400d92c66SSrisivasubramanian S 		offset_dma = m_dma;
160500d92c66SSrisivasubramanian S 
160600d92c66SSrisivasubramanian S 		m_vaddr = (uint8_t *)m_vaddr + OFF_CTRL_LEN + iv_len;
160700d92c66SSrisivasubramanian S 		m_dma += OFF_CTRL_LEN + iv_len;
160800d92c66SSrisivasubramanian S 
1609629ac988SArchana Muniganti 		vq_cmd_w0.s.opcode.major |= CPT_DMA_MODE;
161000d92c66SSrisivasubramanian S 
161100d92c66SSrisivasubramanian S 		/* DPTR has SG list */
161200d92c66SSrisivasubramanian S 		in_buffer = m_vaddr;
161300d92c66SSrisivasubramanian S 		dptr_dma = m_dma;
161400d92c66SSrisivasubramanian S 
161500d92c66SSrisivasubramanian S 		((uint16_t *)in_buffer)[0] = 0;
161600d92c66SSrisivasubramanian S 		((uint16_t *)in_buffer)[1] = 0;
161700d92c66SSrisivasubramanian S 
161800d92c66SSrisivasubramanian S 		/* TODO Add error check if space will be sufficient */
161900d92c66SSrisivasubramanian S 		gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8);
162000d92c66SSrisivasubramanian S 
162100d92c66SSrisivasubramanian S 		/*
162200d92c66SSrisivasubramanian S 		 * Input Gather List
162300d92c66SSrisivasubramanian S 		 */
162400d92c66SSrisivasubramanian S 		i = 0;
162500d92c66SSrisivasubramanian S 
162600d92c66SSrisivasubramanian S 		/* Offset control word followed by iv */
162700d92c66SSrisivasubramanian S 
162800d92c66SSrisivasubramanian S 		i = fill_sg_comp(gather_comp, i, offset_dma,
162900d92c66SSrisivasubramanian S 				 OFF_CTRL_LEN + iv_len);
163000d92c66SSrisivasubramanian S 
163100d92c66SSrisivasubramanian S 		/* iv offset is 0 */
163200d92c66SSrisivasubramanian S 		*offset_vaddr = offset_ctrl;
163300d92c66SSrisivasubramanian S 
163400d92c66SSrisivasubramanian S 		iv_d = (uint32_t *)((uint8_t *)offset_vaddr + OFF_CTRL_LEN);
163500d92c66SSrisivasubramanian S 		memcpy(iv_d, iv, 16);
163600d92c66SSrisivasubramanian S 
163700d92c66SSrisivasubramanian S 		/* input data */
163800d92c66SSrisivasubramanian S 		size = inputlen - iv_len;
163900d92c66SSrisivasubramanian S 		if (size) {
164000d92c66SSrisivasubramanian S 			i = fill_sg_comp_from_iov(gather_comp, i,
164100d92c66SSrisivasubramanian S 						  params->src_iov,
164200d92c66SSrisivasubramanian S 						  0, &size, NULL, 0);
1643f39928e6SAnoob Joseph 			if (unlikely(size)) {
1644f39928e6SAnoob Joseph 				CPT_LOG_DP_ERR("Insufficient buffer space,"
1645f39928e6SAnoob Joseph 					       " size %d needed", size);
1646f39928e6SAnoob Joseph 				return;
1647f39928e6SAnoob Joseph 			}
164800d92c66SSrisivasubramanian S 		}
164900d92c66SSrisivasubramanian S 		((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i);
165000d92c66SSrisivasubramanian S 		g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
165100d92c66SSrisivasubramanian S 
165200d92c66SSrisivasubramanian S 		/*
165300d92c66SSrisivasubramanian S 		 * Output Scatter List
165400d92c66SSrisivasubramanian S 		 */
165500d92c66SSrisivasubramanian S 
165600d92c66SSrisivasubramanian S 		i = 0;
165700d92c66SSrisivasubramanian S 		scatter_comp =
165800d92c66SSrisivasubramanian S 			(sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes);
165900d92c66SSrisivasubramanian S 
166000d92c66SSrisivasubramanian S 		if (flags == 0x1) {
166100d92c66SSrisivasubramanian S 			/* IV in SLIST only for EEA3 & UEA2 */
166200d92c66SSrisivasubramanian S 			iv_len = 0;
166300d92c66SSrisivasubramanian S 		}
166400d92c66SSrisivasubramanian S 
166500d92c66SSrisivasubramanian S 		if (iv_len) {
166600d92c66SSrisivasubramanian S 			i = fill_sg_comp(scatter_comp, i,
166700d92c66SSrisivasubramanian S 					 offset_dma + OFF_CTRL_LEN, iv_len);
166800d92c66SSrisivasubramanian S 		}
166900d92c66SSrisivasubramanian S 
167000d92c66SSrisivasubramanian S 		/* Add output data */
167100d92c66SSrisivasubramanian S 		if (req_flags & VALID_MAC_BUF) {
167200d92c66SSrisivasubramanian S 			size = outputlen - iv_len - mac_len;
167300d92c66SSrisivasubramanian S 			if (size) {
167400d92c66SSrisivasubramanian S 				i = fill_sg_comp_from_iov(scatter_comp, i,
167500d92c66SSrisivasubramanian S 							  params->dst_iov, 0,
167600d92c66SSrisivasubramanian S 							  &size, NULL, 0);
167700d92c66SSrisivasubramanian S 
1678f39928e6SAnoob Joseph 				if (unlikely(size)) {
1679f39928e6SAnoob Joseph 					CPT_LOG_DP_ERR("Insufficient buffer space,"
1680f39928e6SAnoob Joseph 						       " size %d needed", size);
1681f39928e6SAnoob Joseph 					return;
1682f39928e6SAnoob Joseph 				}
168300d92c66SSrisivasubramanian S 			}
168400d92c66SSrisivasubramanian S 
168500d92c66SSrisivasubramanian S 			/* mac data */
168600d92c66SSrisivasubramanian S 			if (mac_len) {
168700d92c66SSrisivasubramanian S 				i = fill_sg_comp_from_buf(scatter_comp, i,
168800d92c66SSrisivasubramanian S 							  &params->mac_buf);
168900d92c66SSrisivasubramanian S 			}
169000d92c66SSrisivasubramanian S 		} else {
169100d92c66SSrisivasubramanian S 			/* Output including mac */
169200d92c66SSrisivasubramanian S 			size = outputlen - iv_len;
169300d92c66SSrisivasubramanian S 			if (size) {
169400d92c66SSrisivasubramanian S 				i = fill_sg_comp_from_iov(scatter_comp, i,
169500d92c66SSrisivasubramanian S 							  params->dst_iov, 0,
169600d92c66SSrisivasubramanian S 							  &size, NULL, 0);
169700d92c66SSrisivasubramanian S 
1698f39928e6SAnoob Joseph 				if (unlikely(size)) {
1699f39928e6SAnoob Joseph 					CPT_LOG_DP_ERR("Insufficient buffer space,"
1700f39928e6SAnoob Joseph 						       " size %d needed", size);
1701f39928e6SAnoob Joseph 					return;
1702f39928e6SAnoob Joseph 				}
170300d92c66SSrisivasubramanian S 			}
170400d92c66SSrisivasubramanian S 		}
170500d92c66SSrisivasubramanian S 		((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i);
170600d92c66SSrisivasubramanian S 		s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
170700d92c66SSrisivasubramanian S 
170800d92c66SSrisivasubramanian S 		size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE;
170900d92c66SSrisivasubramanian S 
171000d92c66SSrisivasubramanian S 		/* This is DPTR len incase of SG mode */
1711426af86bSAnoob Joseph 		vq_cmd_w0.s.dlen = size;
171200d92c66SSrisivasubramanian S 
171300d92c66SSrisivasubramanian S 		m_vaddr = (uint8_t *)m_vaddr + size;
171400d92c66SSrisivasubramanian S 		m_dma += size;
171500d92c66SSrisivasubramanian S 
171600d92c66SSrisivasubramanian S 		/* cpt alternate completion address saved earlier */
171700d92c66SSrisivasubramanian S 		req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8);
171800d92c66SSrisivasubramanian S 		*req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT);
171900d92c66SSrisivasubramanian S 		rptr_dma = c_dma - 8;
172000d92c66SSrisivasubramanian S 
172100d92c66SSrisivasubramanian S 		req->ist.ei1 = dptr_dma;
172200d92c66SSrisivasubramanian S 		req->ist.ei2 = rptr_dma;
172300d92c66SSrisivasubramanian S 	}
172400d92c66SSrisivasubramanian S 
172500d92c66SSrisivasubramanian S 	/* 16 byte aligned cpt res address */
172600d92c66SSrisivasubramanian S 	req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr);
172700d92c66SSrisivasubramanian S 	*req->completion_addr = COMPLETION_CODE_INIT;
172800d92c66SSrisivasubramanian S 	req->comp_baddr  = c_dma;
172900d92c66SSrisivasubramanian S 
173000d92c66SSrisivasubramanian S 	/* Fill microcode part of instruction */
173100d92c66SSrisivasubramanian S 	req->ist.ei0 = vq_cmd_w0.u64;
173200d92c66SSrisivasubramanian S 
173300d92c66SSrisivasubramanian S 	req->op = op;
173400d92c66SSrisivasubramanian S 
173500d92c66SSrisivasubramanian S 	*prep_req = req;
1736f39928e6SAnoob Joseph 	return;
173700d92c66SSrisivasubramanian S }
173800d92c66SSrisivasubramanian S 
1739f39928e6SAnoob Joseph static __rte_always_inline void
174000d92c66SSrisivasubramanian S cpt_zuc_snow3g_dec_prep(uint32_t req_flags,
174100d92c66SSrisivasubramanian S 			uint64_t d_offs,
174200d92c66SSrisivasubramanian S 			uint64_t d_lens,
174300d92c66SSrisivasubramanian S 			fc_params_t *params,
174400d92c66SSrisivasubramanian S 			void *op,
174500d92c66SSrisivasubramanian S 			void **prep_req)
174600d92c66SSrisivasubramanian S {
174700d92c66SSrisivasubramanian S 	uint32_t size;
174800d92c66SSrisivasubramanian S 	int32_t inputlen = 0, outputlen;
174900d92c66SSrisivasubramanian S 	struct cpt_ctx *cpt_ctx;
175000d92c66SSrisivasubramanian S 	uint8_t snow3g, iv_len = 16;
175100d92c66SSrisivasubramanian S 	struct cpt_request_info *req;
175200d92c66SSrisivasubramanian S 	buf_ptr_t *buf_p;
175300d92c66SSrisivasubramanian S 	uint32_t encr_offset;
175400d92c66SSrisivasubramanian S 	uint32_t encr_data_len;
17558de5ede7SAnoob Joseph 	int flags;
175600d92c66SSrisivasubramanian S 	void *m_vaddr, *c_vaddr;
175700d92c66SSrisivasubramanian S 	uint64_t m_dma, c_dma;
175800d92c66SSrisivasubramanian S 	uint64_t *offset_vaddr, offset_dma;
175900d92c66SSrisivasubramanian S 	uint32_t *iv_s, iv[4], j;
176000d92c66SSrisivasubramanian S 	vq_cmd_word0_t vq_cmd_w0;
176100d92c66SSrisivasubramanian S 
176200d92c66SSrisivasubramanian S 	buf_p = &params->meta_buf;
176300d92c66SSrisivasubramanian S 	m_vaddr = buf_p->vaddr;
176400d92c66SSrisivasubramanian S 	m_dma = buf_p->dma_addr;
176500d92c66SSrisivasubramanian S 
176600d92c66SSrisivasubramanian S 	/*
176700d92c66SSrisivasubramanian S 	 * Microcode expects offsets in bytes
176800d92c66SSrisivasubramanian S 	 * TODO: Rounding off
176900d92c66SSrisivasubramanian S 	 */
177000d92c66SSrisivasubramanian S 	encr_offset = ENCR_OFFSET(d_offs) / 8;
177100d92c66SSrisivasubramanian S 	encr_data_len = ENCR_DLEN(d_lens);
177200d92c66SSrisivasubramanian S 
177300d92c66SSrisivasubramanian S 	cpt_ctx = params->ctx_buf.vaddr;
177400d92c66SSrisivasubramanian S 	flags = cpt_ctx->zsk_flags;
177500d92c66SSrisivasubramanian S 	snow3g = cpt_ctx->snow3g;
177600d92c66SSrisivasubramanian S 	/*
177700d92c66SSrisivasubramanian S 	 * Save initial space that followed app data for completion code &
177800d92c66SSrisivasubramanian S 	 * alternate completion code to fall in same cache line as app data
177900d92c66SSrisivasubramanian S 	 */
178000d92c66SSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE;
178100d92c66SSrisivasubramanian S 	m_dma += COMPLETION_CODE_SIZE;
178200d92c66SSrisivasubramanian S 	size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) -
178300d92c66SSrisivasubramanian S 		(uint8_t *)m_vaddr;
178400d92c66SSrisivasubramanian S 
178500d92c66SSrisivasubramanian S 	c_vaddr = (uint8_t *)m_vaddr + size;
178600d92c66SSrisivasubramanian S 	c_dma = m_dma + size;
178700d92c66SSrisivasubramanian S 	size += sizeof(cpt_res_s_t);
178800d92c66SSrisivasubramanian S 
178900d92c66SSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
179000d92c66SSrisivasubramanian S 	m_dma += size;
179100d92c66SSrisivasubramanian S 
179200d92c66SSrisivasubramanian S 	/* Reserve memory for cpt request info */
179300d92c66SSrisivasubramanian S 	req = m_vaddr;
179400d92c66SSrisivasubramanian S 
179500d92c66SSrisivasubramanian S 	size = sizeof(struct cpt_request_info);
179600d92c66SSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
179700d92c66SSrisivasubramanian S 	m_dma += size;
179800d92c66SSrisivasubramanian S 
1799629ac988SArchana Muniganti 	vq_cmd_w0.u64 = 0;
1800629ac988SArchana Muniganti 	vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_ZUC_SNOW3G;
180100d92c66SSrisivasubramanian S 
180200d92c66SSrisivasubramanian S 	/* indicates CPTR ctx, operation type, KEY & IV mode from DPTR */
1803131966f8SAnkur Dwivedi 
1804629ac988SArchana Muniganti 	vq_cmd_w0.s.opcode.minor = ((1 << 7) | (snow3g << 5) | (0 << 4) |
180500d92c66SSrisivasubramanian S 			  (0 << 3) | (flags & 0x7));
180600d92c66SSrisivasubramanian S 
180700d92c66SSrisivasubramanian S 	/* consider iv len */
180800d92c66SSrisivasubramanian S 	encr_offset += iv_len;
180900d92c66SSrisivasubramanian S 
181000d92c66SSrisivasubramanian S 	inputlen = encr_offset +
181100d92c66SSrisivasubramanian S 		(RTE_ALIGN(encr_data_len, 8) / 8);
181200d92c66SSrisivasubramanian S 	outputlen = inputlen;
181300d92c66SSrisivasubramanian S 
181400d92c66SSrisivasubramanian S 	/* IV */
181500d92c66SSrisivasubramanian S 	iv_s = params->iv_buf;
181600d92c66SSrisivasubramanian S 	if (snow3g) {
181700d92c66SSrisivasubramanian S 		/*
181800d92c66SSrisivasubramanian S 		 * DPDK seems to provide it in form of IV3 IV2 IV1 IV0
181900d92c66SSrisivasubramanian S 		 * and BigEndian, MC needs it as IV0 IV1 IV2 IV3
182000d92c66SSrisivasubramanian S 		 */
182100d92c66SSrisivasubramanian S 
182200d92c66SSrisivasubramanian S 		for (j = 0; j < 4; j++)
182300d92c66SSrisivasubramanian S 			iv[j] = iv_s[3 - j];
182400d92c66SSrisivasubramanian S 	} else {
182500d92c66SSrisivasubramanian S 		/* ZUC doesn't need a swap */
182600d92c66SSrisivasubramanian S 		for (j = 0; j < 4; j++)
182700d92c66SSrisivasubramanian S 			iv[j] = iv_s[j];
182800d92c66SSrisivasubramanian S 	}
182900d92c66SSrisivasubramanian S 
183000d92c66SSrisivasubramanian S 	/*
183100d92c66SSrisivasubramanian S 	 * GP op header, lengths are expected in bits.
183200d92c66SSrisivasubramanian S 	 */
1833426af86bSAnoob Joseph 	vq_cmd_w0.s.param1 = encr_data_len;
183400d92c66SSrisivasubramanian S 
183500d92c66SSrisivasubramanian S 	/*
183600d92c66SSrisivasubramanian S 	 * In 83XX since we have a limitation of
183700d92c66SSrisivasubramanian S 	 * IV & Offset control word not part of instruction
183800d92c66SSrisivasubramanian S 	 * and need to be part of Data Buffer, we check if
183900d92c66SSrisivasubramanian S 	 * head room is there and then only do the Direct mode processing
184000d92c66SSrisivasubramanian S 	 */
184100d92c66SSrisivasubramanian S 	if (likely((req_flags & SINGLE_BUF_INPLACE) &&
184200d92c66SSrisivasubramanian S 		   (req_flags & SINGLE_BUF_HEADTAILROOM))) {
184300d92c66SSrisivasubramanian S 		void *dm_vaddr = params->bufs[0].vaddr;
184400d92c66SSrisivasubramanian S 		uint64_t dm_dma_addr = params->bufs[0].dma_addr;
184500d92c66SSrisivasubramanian S 		/*
184600d92c66SSrisivasubramanian S 		 * This flag indicates that there is 24 bytes head room and
184700d92c66SSrisivasubramanian S 		 * 8 bytes tail room available, so that we get to do
184800d92c66SSrisivasubramanian S 		 * DIRECT MODE with limitation
184900d92c66SSrisivasubramanian S 		 */
185000d92c66SSrisivasubramanian S 
185100d92c66SSrisivasubramanian S 		offset_vaddr = (uint64_t *)((uint8_t *)dm_vaddr -
185200d92c66SSrisivasubramanian S 					    OFF_CTRL_LEN - iv_len);
185300d92c66SSrisivasubramanian S 		offset_dma = dm_dma_addr - OFF_CTRL_LEN - iv_len;
185400d92c66SSrisivasubramanian S 
185500d92c66SSrisivasubramanian S 		/* DPTR */
185600d92c66SSrisivasubramanian S 		req->ist.ei1 = offset_dma;
185700d92c66SSrisivasubramanian S 		/* RPTR should just exclude offset control word */
185800d92c66SSrisivasubramanian S 		req->ist.ei2 = dm_dma_addr - iv_len;
185900d92c66SSrisivasubramanian S 		req->alternate_caddr = (uint64_t *)((uint8_t *)dm_vaddr
186000d92c66SSrisivasubramanian S 						    + outputlen - iv_len);
186100d92c66SSrisivasubramanian S 
1862426af86bSAnoob Joseph 		vq_cmd_w0.s.dlen = inputlen + OFF_CTRL_LEN;
186300d92c66SSrisivasubramanian S 
186400d92c66SSrisivasubramanian S 		if (likely(iv_len)) {
186500d92c66SSrisivasubramanian S 			uint32_t *iv_d = (uint32_t *)((uint8_t *)offset_vaddr
186600d92c66SSrisivasubramanian S 						      + OFF_CTRL_LEN);
186700d92c66SSrisivasubramanian S 			memcpy(iv_d, iv, 16);
186800d92c66SSrisivasubramanian S 		}
186900d92c66SSrisivasubramanian S 
187000d92c66SSrisivasubramanian S 		/* iv offset is 0 */
187100d92c66SSrisivasubramanian S 		*offset_vaddr = rte_cpu_to_be_64((uint64_t)encr_offset << 16);
187200d92c66SSrisivasubramanian S 	} else {
187300d92c66SSrisivasubramanian S 		uint32_t i, g_size_bytes, s_size_bytes;
187400d92c66SSrisivasubramanian S 		uint64_t dptr_dma, rptr_dma;
187500d92c66SSrisivasubramanian S 		sg_comp_t *gather_comp;
187600d92c66SSrisivasubramanian S 		sg_comp_t *scatter_comp;
187700d92c66SSrisivasubramanian S 		uint8_t *in_buffer;
187800d92c66SSrisivasubramanian S 		uint32_t *iv_d;
187900d92c66SSrisivasubramanian S 
188000d92c66SSrisivasubramanian S 		/* save space for offset and iv... */
188100d92c66SSrisivasubramanian S 		offset_vaddr = m_vaddr;
188200d92c66SSrisivasubramanian S 		offset_dma = m_dma;
188300d92c66SSrisivasubramanian S 
188400d92c66SSrisivasubramanian S 		m_vaddr = (uint8_t *)m_vaddr + OFF_CTRL_LEN + iv_len;
188500d92c66SSrisivasubramanian S 		m_dma += OFF_CTRL_LEN + iv_len;
188600d92c66SSrisivasubramanian S 
1887629ac988SArchana Muniganti 		vq_cmd_w0.s.opcode.major |= CPT_DMA_MODE;
188800d92c66SSrisivasubramanian S 
188900d92c66SSrisivasubramanian S 		/* DPTR has SG list */
189000d92c66SSrisivasubramanian S 		in_buffer = m_vaddr;
189100d92c66SSrisivasubramanian S 		dptr_dma = m_dma;
189200d92c66SSrisivasubramanian S 
189300d92c66SSrisivasubramanian S 		((uint16_t *)in_buffer)[0] = 0;
189400d92c66SSrisivasubramanian S 		((uint16_t *)in_buffer)[1] = 0;
189500d92c66SSrisivasubramanian S 
189600d92c66SSrisivasubramanian S 		/* TODO Add error check if space will be sufficient */
189700d92c66SSrisivasubramanian S 		gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8);
189800d92c66SSrisivasubramanian S 
189900d92c66SSrisivasubramanian S 		/*
190000d92c66SSrisivasubramanian S 		 * Input Gather List
190100d92c66SSrisivasubramanian S 		 */
190200d92c66SSrisivasubramanian S 		i = 0;
190300d92c66SSrisivasubramanian S 
190400d92c66SSrisivasubramanian S 		/* Offset control word */
190500d92c66SSrisivasubramanian S 
190600d92c66SSrisivasubramanian S 		/* iv offset is 0 */
190700d92c66SSrisivasubramanian S 		*offset_vaddr = rte_cpu_to_be_64((uint64_t)encr_offset << 16);
190800d92c66SSrisivasubramanian S 
190900d92c66SSrisivasubramanian S 		i = fill_sg_comp(gather_comp, i, offset_dma,
191000d92c66SSrisivasubramanian S 				 OFF_CTRL_LEN + iv_len);
191100d92c66SSrisivasubramanian S 
191200d92c66SSrisivasubramanian S 		iv_d = (uint32_t *)((uint8_t *)offset_vaddr + OFF_CTRL_LEN);
191300d92c66SSrisivasubramanian S 		memcpy(iv_d, iv, 16);
191400d92c66SSrisivasubramanian S 
191500d92c66SSrisivasubramanian S 		/* Add input data */
191600d92c66SSrisivasubramanian S 		size = inputlen - iv_len;
191700d92c66SSrisivasubramanian S 		if (size) {
191800d92c66SSrisivasubramanian S 			i = fill_sg_comp_from_iov(gather_comp, i,
191900d92c66SSrisivasubramanian S 						  params->src_iov,
192000d92c66SSrisivasubramanian S 						  0, &size, NULL, 0);
1921f39928e6SAnoob Joseph 			if (unlikely(size)) {
1922f39928e6SAnoob Joseph 				CPT_LOG_DP_ERR("Insufficient buffer space,"
1923f39928e6SAnoob Joseph 					       " size %d needed", size);
1924f39928e6SAnoob Joseph 				return;
1925f39928e6SAnoob Joseph 			}
192600d92c66SSrisivasubramanian S 		}
192700d92c66SSrisivasubramanian S 		((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i);
192800d92c66SSrisivasubramanian S 		g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
192900d92c66SSrisivasubramanian S 
193000d92c66SSrisivasubramanian S 		/*
193100d92c66SSrisivasubramanian S 		 * Output Scatter List
193200d92c66SSrisivasubramanian S 		 */
193300d92c66SSrisivasubramanian S 
193400d92c66SSrisivasubramanian S 		i = 0;
193500d92c66SSrisivasubramanian S 		scatter_comp =
193600d92c66SSrisivasubramanian S 			(sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes);
193700d92c66SSrisivasubramanian S 
193800d92c66SSrisivasubramanian S 		/* IV */
193900d92c66SSrisivasubramanian S 		i = fill_sg_comp(scatter_comp, i,
194000d92c66SSrisivasubramanian S 				 offset_dma + OFF_CTRL_LEN,
194100d92c66SSrisivasubramanian S 				 iv_len);
194200d92c66SSrisivasubramanian S 
194300d92c66SSrisivasubramanian S 		/* Add output data */
194400d92c66SSrisivasubramanian S 		size = outputlen - iv_len;
194500d92c66SSrisivasubramanian S 		if (size) {
194600d92c66SSrisivasubramanian S 			i = fill_sg_comp_from_iov(scatter_comp, i,
194700d92c66SSrisivasubramanian S 						  params->dst_iov, 0,
194800d92c66SSrisivasubramanian S 						  &size, NULL, 0);
194900d92c66SSrisivasubramanian S 
1950f39928e6SAnoob Joseph 			if (unlikely(size)) {
1951f39928e6SAnoob Joseph 				CPT_LOG_DP_ERR("Insufficient buffer space,"
1952f39928e6SAnoob Joseph 					       " size %d needed", size);
1953f39928e6SAnoob Joseph 				return;
1954f39928e6SAnoob Joseph 			}
195500d92c66SSrisivasubramanian S 		}
195600d92c66SSrisivasubramanian S 		((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i);
195700d92c66SSrisivasubramanian S 		s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
195800d92c66SSrisivasubramanian S 
195900d92c66SSrisivasubramanian S 		size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE;
196000d92c66SSrisivasubramanian S 
196100d92c66SSrisivasubramanian S 		/* This is DPTR len incase of SG mode */
1962426af86bSAnoob Joseph 		vq_cmd_w0.s.dlen = size;
196300d92c66SSrisivasubramanian S 
196400d92c66SSrisivasubramanian S 		m_vaddr = (uint8_t *)m_vaddr + size;
196500d92c66SSrisivasubramanian S 		m_dma += size;
196600d92c66SSrisivasubramanian S 
196700d92c66SSrisivasubramanian S 		/* cpt alternate completion address saved earlier */
196800d92c66SSrisivasubramanian S 		req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8);
196900d92c66SSrisivasubramanian S 		*req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT);
197000d92c66SSrisivasubramanian S 		rptr_dma = c_dma - 8;
197100d92c66SSrisivasubramanian S 
197200d92c66SSrisivasubramanian S 		req->ist.ei1 = dptr_dma;
197300d92c66SSrisivasubramanian S 		req->ist.ei2 = rptr_dma;
197400d92c66SSrisivasubramanian S 	}
197500d92c66SSrisivasubramanian S 
19762a6c7922SAnoob Joseph 	if (unlikely((encr_offset >> 16))) {
19772a6c7922SAnoob Joseph 		CPT_LOG_DP_ERR("Offset not supported");
19782a6c7922SAnoob Joseph 		CPT_LOG_DP_ERR("enc_offset: %d", encr_offset);
19792a6c7922SAnoob Joseph 		return;
19802a6c7922SAnoob Joseph 	}
19812a6c7922SAnoob Joseph 
198200d92c66SSrisivasubramanian S 	/* 16 byte aligned cpt res address */
198300d92c66SSrisivasubramanian S 	req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr);
198400d92c66SSrisivasubramanian S 	*req->completion_addr = COMPLETION_CODE_INIT;
198500d92c66SSrisivasubramanian S 	req->comp_baddr  = c_dma;
198600d92c66SSrisivasubramanian S 
198700d92c66SSrisivasubramanian S 	/* Fill microcode part of instruction */
198800d92c66SSrisivasubramanian S 	req->ist.ei0 = vq_cmd_w0.u64;
198900d92c66SSrisivasubramanian S 
199000d92c66SSrisivasubramanian S 	req->op = op;
199100d92c66SSrisivasubramanian S 
199200d92c66SSrisivasubramanian S 	*prep_req = req;
1993f39928e6SAnoob Joseph 	return;
199400d92c66SSrisivasubramanian S }
199500d92c66SSrisivasubramanian S 
1996f39928e6SAnoob Joseph static __rte_always_inline void
1997da39e3ecSSrisivasubramanian S cpt_kasumi_enc_prep(uint32_t req_flags,
1998da39e3ecSSrisivasubramanian S 		    uint64_t d_offs,
1999da39e3ecSSrisivasubramanian S 		    uint64_t d_lens,
2000da39e3ecSSrisivasubramanian S 		    fc_params_t *params,
2001da39e3ecSSrisivasubramanian S 		    void *op,
2002da39e3ecSSrisivasubramanian S 		    void **prep_req)
2003da39e3ecSSrisivasubramanian S {
2004da39e3ecSSrisivasubramanian S 	uint32_t size;
2005da39e3ecSSrisivasubramanian S 	int32_t inputlen = 0, outputlen = 0;
2006da39e3ecSSrisivasubramanian S 	struct cpt_ctx *cpt_ctx;
2007da39e3ecSSrisivasubramanian S 	uint32_t mac_len = 0;
2008da39e3ecSSrisivasubramanian S 	uint8_t i = 0;
2009da39e3ecSSrisivasubramanian S 	struct cpt_request_info *req;
2010da39e3ecSSrisivasubramanian S 	buf_ptr_t *buf_p;
2011da39e3ecSSrisivasubramanian S 	uint32_t encr_offset, auth_offset;
2012da39e3ecSSrisivasubramanian S 	uint32_t encr_data_len, auth_data_len;
20138de5ede7SAnoob Joseph 	int flags;
2014da39e3ecSSrisivasubramanian S 	uint8_t *iv_s, *iv_d, iv_len = 8;
2015da39e3ecSSrisivasubramanian S 	uint8_t dir = 0;
2016da39e3ecSSrisivasubramanian S 	void *m_vaddr, *c_vaddr;
2017da39e3ecSSrisivasubramanian S 	uint64_t m_dma, c_dma;
2018da39e3ecSSrisivasubramanian S 	uint64_t *offset_vaddr, offset_dma;
2019da39e3ecSSrisivasubramanian S 	vq_cmd_word0_t vq_cmd_w0;
2020da39e3ecSSrisivasubramanian S 	uint8_t *in_buffer;
2021da39e3ecSSrisivasubramanian S 	uint32_t g_size_bytes, s_size_bytes;
2022da39e3ecSSrisivasubramanian S 	uint64_t dptr_dma, rptr_dma;
2023da39e3ecSSrisivasubramanian S 	sg_comp_t *gather_comp;
2024da39e3ecSSrisivasubramanian S 	sg_comp_t *scatter_comp;
2025da39e3ecSSrisivasubramanian S 
2026da39e3ecSSrisivasubramanian S 	buf_p = &params->meta_buf;
2027da39e3ecSSrisivasubramanian S 	m_vaddr = buf_p->vaddr;
2028da39e3ecSSrisivasubramanian S 	m_dma = buf_p->dma_addr;
2029da39e3ecSSrisivasubramanian S 
2030da39e3ecSSrisivasubramanian S 	encr_offset = ENCR_OFFSET(d_offs) / 8;
2031da39e3ecSSrisivasubramanian S 	auth_offset = AUTH_OFFSET(d_offs) / 8;
2032da39e3ecSSrisivasubramanian S 	encr_data_len = ENCR_DLEN(d_lens);
2033da39e3ecSSrisivasubramanian S 	auth_data_len = AUTH_DLEN(d_lens);
2034da39e3ecSSrisivasubramanian S 
2035da39e3ecSSrisivasubramanian S 	cpt_ctx = params->ctx_buf.vaddr;
2036da39e3ecSSrisivasubramanian S 	flags = cpt_ctx->zsk_flags;
2037da39e3ecSSrisivasubramanian S 	mac_len = cpt_ctx->mac_len;
2038da39e3ecSSrisivasubramanian S 
2039da39e3ecSSrisivasubramanian S 	if (flags == 0x0)
2040da39e3ecSSrisivasubramanian S 		iv_s = params->iv_buf;
2041da39e3ecSSrisivasubramanian S 	else
2042da39e3ecSSrisivasubramanian S 		iv_s = params->auth_iv_buf;
2043da39e3ecSSrisivasubramanian S 
2044da39e3ecSSrisivasubramanian S 	dir = iv_s[8] & 0x1;
2045da39e3ecSSrisivasubramanian S 
2046da39e3ecSSrisivasubramanian S 	/*
2047da39e3ecSSrisivasubramanian S 	 * Save initial space that followed app data for completion code &
2048da39e3ecSSrisivasubramanian S 	 * alternate completion code to fall in same cache line as app data
2049da39e3ecSSrisivasubramanian S 	 */
2050da39e3ecSSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE;
2051da39e3ecSSrisivasubramanian S 	m_dma += COMPLETION_CODE_SIZE;
2052da39e3ecSSrisivasubramanian S 	size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) -
2053da39e3ecSSrisivasubramanian S 		(uint8_t *)m_vaddr;
2054da39e3ecSSrisivasubramanian S 
2055da39e3ecSSrisivasubramanian S 	c_vaddr = (uint8_t *)m_vaddr + size;
2056da39e3ecSSrisivasubramanian S 	c_dma = m_dma + size;
2057da39e3ecSSrisivasubramanian S 	size += sizeof(cpt_res_s_t);
2058da39e3ecSSrisivasubramanian S 
2059da39e3ecSSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
2060da39e3ecSSrisivasubramanian S 	m_dma += size;
2061da39e3ecSSrisivasubramanian S 
2062da39e3ecSSrisivasubramanian S 	/* Reserve memory for cpt request info */
2063da39e3ecSSrisivasubramanian S 	req = m_vaddr;
2064da39e3ecSSrisivasubramanian S 
2065da39e3ecSSrisivasubramanian S 	size = sizeof(struct cpt_request_info);
2066da39e3ecSSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
2067da39e3ecSSrisivasubramanian S 	m_dma += size;
2068da39e3ecSSrisivasubramanian S 
2069629ac988SArchana Muniganti 	vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_KASUMI | CPT_DMA_MODE;
2070da39e3ecSSrisivasubramanian S 
2071da39e3ecSSrisivasubramanian S 	/* indicates ECB/CBC, direction, ctx from cptr, iv from dptr */
2072629ac988SArchana Muniganti 	vq_cmd_w0.s.opcode.minor = ((1 << 6) | (cpt_ctx->k_ecb << 5) |
2073da39e3ecSSrisivasubramanian S 			  (dir << 4) | (0 << 3) | (flags & 0x7));
2074da39e3ecSSrisivasubramanian S 
2075da39e3ecSSrisivasubramanian S 	/*
2076da39e3ecSSrisivasubramanian S 	 * GP op header, lengths are expected in bits.
2077da39e3ecSSrisivasubramanian S 	 */
2078426af86bSAnoob Joseph 	vq_cmd_w0.s.param1 = encr_data_len;
2079426af86bSAnoob Joseph 	vq_cmd_w0.s.param2 = auth_data_len;
2080da39e3ecSSrisivasubramanian S 
2081da39e3ecSSrisivasubramanian S 	/* consider iv len */
2082da39e3ecSSrisivasubramanian S 	if (flags == 0x0) {
2083da39e3ecSSrisivasubramanian S 		encr_offset += iv_len;
2084da39e3ecSSrisivasubramanian S 		auth_offset += iv_len;
2085da39e3ecSSrisivasubramanian S 	}
2086da39e3ecSSrisivasubramanian S 
2087da39e3ecSSrisivasubramanian S 	/* save space for offset ctrl and iv */
2088da39e3ecSSrisivasubramanian S 	offset_vaddr = m_vaddr;
2089da39e3ecSSrisivasubramanian S 	offset_dma = m_dma;
2090da39e3ecSSrisivasubramanian S 
2091da39e3ecSSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + OFF_CTRL_LEN + iv_len;
2092da39e3ecSSrisivasubramanian S 	m_dma += OFF_CTRL_LEN + iv_len;
2093da39e3ecSSrisivasubramanian S 
2094da39e3ecSSrisivasubramanian S 	/* DPTR has SG list */
2095da39e3ecSSrisivasubramanian S 	in_buffer = m_vaddr;
2096da39e3ecSSrisivasubramanian S 	dptr_dma = m_dma;
2097da39e3ecSSrisivasubramanian S 
2098da39e3ecSSrisivasubramanian S 	((uint16_t *)in_buffer)[0] = 0;
2099da39e3ecSSrisivasubramanian S 	((uint16_t *)in_buffer)[1] = 0;
2100da39e3ecSSrisivasubramanian S 
2101da39e3ecSSrisivasubramanian S 	/* TODO Add error check if space will be sufficient */
2102da39e3ecSSrisivasubramanian S 	gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8);
2103da39e3ecSSrisivasubramanian S 
2104da39e3ecSSrisivasubramanian S 	/*
2105da39e3ecSSrisivasubramanian S 	 * Input Gather List
2106da39e3ecSSrisivasubramanian S 	 */
2107da39e3ecSSrisivasubramanian S 	i = 0;
2108da39e3ecSSrisivasubramanian S 
2109da39e3ecSSrisivasubramanian S 	/* Offset control word followed by iv */
2110da39e3ecSSrisivasubramanian S 
2111da39e3ecSSrisivasubramanian S 	if (flags == 0x0) {
2112da39e3ecSSrisivasubramanian S 		inputlen = encr_offset + (RTE_ALIGN(encr_data_len, 8) / 8);
2113da39e3ecSSrisivasubramanian S 		outputlen = inputlen;
2114da39e3ecSSrisivasubramanian S 		/* iv offset is 0 */
2115da39e3ecSSrisivasubramanian S 		*offset_vaddr = rte_cpu_to_be_64((uint64_t)encr_offset << 16);
21162a6c7922SAnoob Joseph 		if (unlikely((encr_offset >> 16))) {
21172a6c7922SAnoob Joseph 			CPT_LOG_DP_ERR("Offset not supported");
21182a6c7922SAnoob Joseph 			CPT_LOG_DP_ERR("enc_offset: %d", encr_offset);
21192a6c7922SAnoob Joseph 			return;
21202a6c7922SAnoob Joseph 		}
2121da39e3ecSSrisivasubramanian S 	} else {
2122da39e3ecSSrisivasubramanian S 		inputlen = auth_offset + (RTE_ALIGN(auth_data_len, 8) / 8);
2123da39e3ecSSrisivasubramanian S 		outputlen = mac_len;
2124da39e3ecSSrisivasubramanian S 		/* iv offset is 0 */
2125da39e3ecSSrisivasubramanian S 		*offset_vaddr = rte_cpu_to_be_64((uint64_t)auth_offset);
21262a6c7922SAnoob Joseph 		if (unlikely((auth_offset >> 8))) {
21272a6c7922SAnoob Joseph 			CPT_LOG_DP_ERR("Offset not supported");
21282a6c7922SAnoob Joseph 			CPT_LOG_DP_ERR("auth_offset: %d", auth_offset);
21292a6c7922SAnoob Joseph 			return;
21302a6c7922SAnoob Joseph 		}
2131da39e3ecSSrisivasubramanian S 	}
2132da39e3ecSSrisivasubramanian S 
2133da39e3ecSSrisivasubramanian S 	i = fill_sg_comp(gather_comp, i, offset_dma, OFF_CTRL_LEN + iv_len);
2134da39e3ecSSrisivasubramanian S 
2135da39e3ecSSrisivasubramanian S 	/* IV */
2136da39e3ecSSrisivasubramanian S 	iv_d = (uint8_t *)offset_vaddr + OFF_CTRL_LEN;
2137da39e3ecSSrisivasubramanian S 	memcpy(iv_d, iv_s, iv_len);
2138da39e3ecSSrisivasubramanian S 
2139da39e3ecSSrisivasubramanian S 	/* input data */
2140da39e3ecSSrisivasubramanian S 	size = inputlen - iv_len;
2141da39e3ecSSrisivasubramanian S 	if (size) {
2142da39e3ecSSrisivasubramanian S 		i = fill_sg_comp_from_iov(gather_comp, i,
2143da39e3ecSSrisivasubramanian S 					  params->src_iov, 0,
2144da39e3ecSSrisivasubramanian S 					  &size, NULL, 0);
2145da39e3ecSSrisivasubramanian S 
2146f39928e6SAnoob Joseph 		if (unlikely(size)) {
2147f39928e6SAnoob Joseph 			CPT_LOG_DP_ERR("Insufficient buffer space,"
2148f39928e6SAnoob Joseph 				       " size %d needed", size);
2149f39928e6SAnoob Joseph 			return;
2150f39928e6SAnoob Joseph 		}
2151da39e3ecSSrisivasubramanian S 	}
2152da39e3ecSSrisivasubramanian S 	((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i);
2153da39e3ecSSrisivasubramanian S 	g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
2154da39e3ecSSrisivasubramanian S 
2155da39e3ecSSrisivasubramanian S 	/*
2156da39e3ecSSrisivasubramanian S 	 * Output Scatter List
2157da39e3ecSSrisivasubramanian S 	 */
2158da39e3ecSSrisivasubramanian S 
2159da39e3ecSSrisivasubramanian S 	i = 0;
2160da39e3ecSSrisivasubramanian S 	scatter_comp = (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes);
2161da39e3ecSSrisivasubramanian S 
2162da39e3ecSSrisivasubramanian S 	if (flags == 0x1) {
2163da39e3ecSSrisivasubramanian S 		/* IV in SLIST only for F8 */
2164da39e3ecSSrisivasubramanian S 		iv_len = 0;
2165da39e3ecSSrisivasubramanian S 	}
2166da39e3ecSSrisivasubramanian S 
2167da39e3ecSSrisivasubramanian S 	/* IV */
2168da39e3ecSSrisivasubramanian S 	if (iv_len) {
2169da39e3ecSSrisivasubramanian S 		i = fill_sg_comp(scatter_comp, i,
2170da39e3ecSSrisivasubramanian S 				 offset_dma + OFF_CTRL_LEN,
2171da39e3ecSSrisivasubramanian S 				 iv_len);
2172da39e3ecSSrisivasubramanian S 	}
2173da39e3ecSSrisivasubramanian S 
2174da39e3ecSSrisivasubramanian S 	/* Add output data */
2175da39e3ecSSrisivasubramanian S 	if (req_flags & VALID_MAC_BUF) {
2176da39e3ecSSrisivasubramanian S 		size = outputlen - iv_len - mac_len;
2177da39e3ecSSrisivasubramanian S 		if (size) {
2178da39e3ecSSrisivasubramanian S 			i = fill_sg_comp_from_iov(scatter_comp, i,
2179da39e3ecSSrisivasubramanian S 						  params->dst_iov, 0,
2180da39e3ecSSrisivasubramanian S 						  &size, NULL, 0);
2181da39e3ecSSrisivasubramanian S 
2182f39928e6SAnoob Joseph 			if (unlikely(size)) {
2183f39928e6SAnoob Joseph 				CPT_LOG_DP_ERR("Insufficient buffer space,"
2184f39928e6SAnoob Joseph 					       " size %d needed", size);
2185f39928e6SAnoob Joseph 				return;
2186f39928e6SAnoob Joseph 			}
2187da39e3ecSSrisivasubramanian S 		}
2188da39e3ecSSrisivasubramanian S 
2189da39e3ecSSrisivasubramanian S 		/* mac data */
2190da39e3ecSSrisivasubramanian S 		if (mac_len) {
2191da39e3ecSSrisivasubramanian S 			i = fill_sg_comp_from_buf(scatter_comp, i,
2192da39e3ecSSrisivasubramanian S 						  &params->mac_buf);
2193da39e3ecSSrisivasubramanian S 		}
2194da39e3ecSSrisivasubramanian S 	} else {
2195da39e3ecSSrisivasubramanian S 		/* Output including mac */
2196da39e3ecSSrisivasubramanian S 		size = outputlen - iv_len;
2197da39e3ecSSrisivasubramanian S 		if (size) {
2198da39e3ecSSrisivasubramanian S 			i = fill_sg_comp_from_iov(scatter_comp, i,
2199da39e3ecSSrisivasubramanian S 						  params->dst_iov, 0,
2200da39e3ecSSrisivasubramanian S 						  &size, NULL, 0);
2201da39e3ecSSrisivasubramanian S 
2202f39928e6SAnoob Joseph 			if (unlikely(size)) {
2203f39928e6SAnoob Joseph 				CPT_LOG_DP_ERR("Insufficient buffer space,"
2204f39928e6SAnoob Joseph 					       " size %d needed", size);
2205f39928e6SAnoob Joseph 				return;
2206f39928e6SAnoob Joseph 			}
2207da39e3ecSSrisivasubramanian S 		}
2208da39e3ecSSrisivasubramanian S 	}
2209da39e3ecSSrisivasubramanian S 	((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i);
2210da39e3ecSSrisivasubramanian S 	s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
2211da39e3ecSSrisivasubramanian S 
2212da39e3ecSSrisivasubramanian S 	size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE;
2213da39e3ecSSrisivasubramanian S 
2214da39e3ecSSrisivasubramanian S 	/* This is DPTR len incase of SG mode */
2215426af86bSAnoob Joseph 	vq_cmd_w0.s.dlen = size;
2216da39e3ecSSrisivasubramanian S 
2217da39e3ecSSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
2218da39e3ecSSrisivasubramanian S 	m_dma += size;
2219da39e3ecSSrisivasubramanian S 
2220da39e3ecSSrisivasubramanian S 	/* cpt alternate completion address saved earlier */
2221da39e3ecSSrisivasubramanian S 	req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8);
2222da39e3ecSSrisivasubramanian S 	*req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT);
2223da39e3ecSSrisivasubramanian S 	rptr_dma = c_dma - 8;
2224da39e3ecSSrisivasubramanian S 
2225da39e3ecSSrisivasubramanian S 	req->ist.ei1 = dptr_dma;
2226da39e3ecSSrisivasubramanian S 	req->ist.ei2 = rptr_dma;
2227da39e3ecSSrisivasubramanian S 
2228da39e3ecSSrisivasubramanian S 	/* 16 byte aligned cpt res address */
2229da39e3ecSSrisivasubramanian S 	req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr);
2230da39e3ecSSrisivasubramanian S 	*req->completion_addr = COMPLETION_CODE_INIT;
2231da39e3ecSSrisivasubramanian S 	req->comp_baddr  = c_dma;
2232da39e3ecSSrisivasubramanian S 
2233da39e3ecSSrisivasubramanian S 	/* Fill microcode part of instruction */
2234da39e3ecSSrisivasubramanian S 	req->ist.ei0 = vq_cmd_w0.u64;
2235da39e3ecSSrisivasubramanian S 
2236da39e3ecSSrisivasubramanian S 	req->op = op;
2237da39e3ecSSrisivasubramanian S 
2238da39e3ecSSrisivasubramanian S 	*prep_req = req;
2239f39928e6SAnoob Joseph 	return;
2240da39e3ecSSrisivasubramanian S }
2241da39e3ecSSrisivasubramanian S 
2242f39928e6SAnoob Joseph static __rte_always_inline void
2243da39e3ecSSrisivasubramanian S cpt_kasumi_dec_prep(uint64_t d_offs,
2244da39e3ecSSrisivasubramanian S 		    uint64_t d_lens,
2245da39e3ecSSrisivasubramanian S 		    fc_params_t *params,
2246da39e3ecSSrisivasubramanian S 		    void *op,
2247da39e3ecSSrisivasubramanian S 		    void **prep_req)
2248da39e3ecSSrisivasubramanian S {
2249da39e3ecSSrisivasubramanian S 	uint32_t size;
2250da39e3ecSSrisivasubramanian S 	int32_t inputlen = 0, outputlen;
2251da39e3ecSSrisivasubramanian S 	struct cpt_ctx *cpt_ctx;
2252da39e3ecSSrisivasubramanian S 	uint8_t i = 0, iv_len = 8;
2253da39e3ecSSrisivasubramanian S 	struct cpt_request_info *req;
2254da39e3ecSSrisivasubramanian S 	buf_ptr_t *buf_p;
2255da39e3ecSSrisivasubramanian S 	uint32_t encr_offset;
2256da39e3ecSSrisivasubramanian S 	uint32_t encr_data_len;
22578de5ede7SAnoob Joseph 	int flags;
2258da39e3ecSSrisivasubramanian S 	uint8_t dir = 0;
2259da39e3ecSSrisivasubramanian S 	void *m_vaddr, *c_vaddr;
2260da39e3ecSSrisivasubramanian S 	uint64_t m_dma, c_dma;
2261da39e3ecSSrisivasubramanian S 	uint64_t *offset_vaddr, offset_dma;
2262da39e3ecSSrisivasubramanian S 	vq_cmd_word0_t vq_cmd_w0;
2263da39e3ecSSrisivasubramanian S 	uint8_t *in_buffer;
2264da39e3ecSSrisivasubramanian S 	uint32_t g_size_bytes, s_size_bytes;
2265da39e3ecSSrisivasubramanian S 	uint64_t dptr_dma, rptr_dma;
2266da39e3ecSSrisivasubramanian S 	sg_comp_t *gather_comp;
2267da39e3ecSSrisivasubramanian S 	sg_comp_t *scatter_comp;
2268da39e3ecSSrisivasubramanian S 
2269da39e3ecSSrisivasubramanian S 	buf_p = &params->meta_buf;
2270da39e3ecSSrisivasubramanian S 	m_vaddr = buf_p->vaddr;
2271da39e3ecSSrisivasubramanian S 	m_dma = buf_p->dma_addr;
2272da39e3ecSSrisivasubramanian S 
2273da39e3ecSSrisivasubramanian S 	encr_offset = ENCR_OFFSET(d_offs) / 8;
2274da39e3ecSSrisivasubramanian S 	encr_data_len = ENCR_DLEN(d_lens);
2275da39e3ecSSrisivasubramanian S 
2276da39e3ecSSrisivasubramanian S 	cpt_ctx = params->ctx_buf.vaddr;
2277da39e3ecSSrisivasubramanian S 	flags = cpt_ctx->zsk_flags;
2278da39e3ecSSrisivasubramanian S 	/*
2279da39e3ecSSrisivasubramanian S 	 * Save initial space that followed app data for completion code &
2280da39e3ecSSrisivasubramanian S 	 * alternate completion code to fall in same cache line as app data
2281da39e3ecSSrisivasubramanian S 	 */
2282da39e3ecSSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE;
2283da39e3ecSSrisivasubramanian S 	m_dma += COMPLETION_CODE_SIZE;
2284da39e3ecSSrisivasubramanian S 	size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) -
2285da39e3ecSSrisivasubramanian S 		(uint8_t *)m_vaddr;
2286da39e3ecSSrisivasubramanian S 
2287da39e3ecSSrisivasubramanian S 	c_vaddr = (uint8_t *)m_vaddr + size;
2288da39e3ecSSrisivasubramanian S 	c_dma = m_dma + size;
2289da39e3ecSSrisivasubramanian S 	size += sizeof(cpt_res_s_t);
2290da39e3ecSSrisivasubramanian S 
2291da39e3ecSSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
2292da39e3ecSSrisivasubramanian S 	m_dma += size;
2293da39e3ecSSrisivasubramanian S 
2294da39e3ecSSrisivasubramanian S 	/* Reserve memory for cpt request info */
2295da39e3ecSSrisivasubramanian S 	req = m_vaddr;
2296da39e3ecSSrisivasubramanian S 
2297da39e3ecSSrisivasubramanian S 	size = sizeof(struct cpt_request_info);
2298da39e3ecSSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
2299da39e3ecSSrisivasubramanian S 	m_dma += size;
2300da39e3ecSSrisivasubramanian S 
2301629ac988SArchana Muniganti 	vq_cmd_w0.u64 = 0;
2302629ac988SArchana Muniganti 	vq_cmd_w0.s.opcode.major = CPT_MAJOR_OP_KASUMI | CPT_DMA_MODE;
2303da39e3ecSSrisivasubramanian S 
2304da39e3ecSSrisivasubramanian S 	/* indicates ECB/CBC, direction, ctx from cptr, iv from dptr */
2305629ac988SArchana Muniganti 	vq_cmd_w0.s.opcode.minor = ((1 << 6) | (cpt_ctx->k_ecb << 5) |
2306da39e3ecSSrisivasubramanian S 			  (dir << 4) | (0 << 3) | (flags & 0x7));
2307da39e3ecSSrisivasubramanian S 
2308da39e3ecSSrisivasubramanian S 	/*
2309da39e3ecSSrisivasubramanian S 	 * GP op header, lengths are expected in bits.
2310da39e3ecSSrisivasubramanian S 	 */
2311426af86bSAnoob Joseph 	vq_cmd_w0.s.param1 = encr_data_len;
2312da39e3ecSSrisivasubramanian S 
2313da39e3ecSSrisivasubramanian S 	/* consider iv len */
2314da39e3ecSSrisivasubramanian S 	encr_offset += iv_len;
2315da39e3ecSSrisivasubramanian S 
2316d937e872SAnoob Joseph 	inputlen = encr_offset + (RTE_ALIGN(encr_data_len, 8) / 8);
2317da39e3ecSSrisivasubramanian S 	outputlen = inputlen;
2318da39e3ecSSrisivasubramanian S 
2319da39e3ecSSrisivasubramanian S 	/* save space for offset ctrl & iv */
2320da39e3ecSSrisivasubramanian S 	offset_vaddr = m_vaddr;
2321da39e3ecSSrisivasubramanian S 	offset_dma = m_dma;
2322da39e3ecSSrisivasubramanian S 
2323da39e3ecSSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + OFF_CTRL_LEN + iv_len;
2324da39e3ecSSrisivasubramanian S 	m_dma += OFF_CTRL_LEN + iv_len;
2325da39e3ecSSrisivasubramanian S 
2326da39e3ecSSrisivasubramanian S 	/* DPTR has SG list */
2327da39e3ecSSrisivasubramanian S 	in_buffer = m_vaddr;
2328da39e3ecSSrisivasubramanian S 	dptr_dma = m_dma;
2329da39e3ecSSrisivasubramanian S 
2330da39e3ecSSrisivasubramanian S 	((uint16_t *)in_buffer)[0] = 0;
2331da39e3ecSSrisivasubramanian S 	((uint16_t *)in_buffer)[1] = 0;
2332da39e3ecSSrisivasubramanian S 
2333da39e3ecSSrisivasubramanian S 	/* TODO Add error check if space will be sufficient */
2334da39e3ecSSrisivasubramanian S 	gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8);
2335da39e3ecSSrisivasubramanian S 
2336da39e3ecSSrisivasubramanian S 	/*
2337da39e3ecSSrisivasubramanian S 	 * Input Gather List
2338da39e3ecSSrisivasubramanian S 	 */
2339da39e3ecSSrisivasubramanian S 	i = 0;
2340da39e3ecSSrisivasubramanian S 
2341da39e3ecSSrisivasubramanian S 	/* Offset control word followed by iv */
2342da39e3ecSSrisivasubramanian S 	*offset_vaddr = rte_cpu_to_be_64((uint64_t)encr_offset << 16);
23432a6c7922SAnoob Joseph 	if (unlikely((encr_offset >> 16))) {
23442a6c7922SAnoob Joseph 		CPT_LOG_DP_ERR("Offset not supported");
23452a6c7922SAnoob Joseph 		CPT_LOG_DP_ERR("enc_offset: %d", encr_offset);
23462a6c7922SAnoob Joseph 		return;
23472a6c7922SAnoob Joseph 	}
2348da39e3ecSSrisivasubramanian S 
2349da39e3ecSSrisivasubramanian S 	i = fill_sg_comp(gather_comp, i, offset_dma, OFF_CTRL_LEN + iv_len);
2350da39e3ecSSrisivasubramanian S 
2351da39e3ecSSrisivasubramanian S 	/* IV */
2352da39e3ecSSrisivasubramanian S 	memcpy((uint8_t *)offset_vaddr + OFF_CTRL_LEN,
2353da39e3ecSSrisivasubramanian S 	       params->iv_buf, iv_len);
2354da39e3ecSSrisivasubramanian S 
2355da39e3ecSSrisivasubramanian S 	/* Add input data */
2356da39e3ecSSrisivasubramanian S 	size = inputlen - iv_len;
2357da39e3ecSSrisivasubramanian S 	if (size) {
2358da39e3ecSSrisivasubramanian S 		i = fill_sg_comp_from_iov(gather_comp, i,
2359da39e3ecSSrisivasubramanian S 					  params->src_iov,
2360da39e3ecSSrisivasubramanian S 					  0, &size, NULL, 0);
2361f39928e6SAnoob Joseph 		if (unlikely(size)) {
2362f39928e6SAnoob Joseph 			CPT_LOG_DP_ERR("Insufficient buffer space,"
2363f39928e6SAnoob Joseph 				       " size %d needed", size);
2364f39928e6SAnoob Joseph 			return;
2365f39928e6SAnoob Joseph 		}
2366da39e3ecSSrisivasubramanian S 	}
2367da39e3ecSSrisivasubramanian S 	((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i);
2368da39e3ecSSrisivasubramanian S 	g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
2369da39e3ecSSrisivasubramanian S 
2370da39e3ecSSrisivasubramanian S 	/*
2371da39e3ecSSrisivasubramanian S 	 * Output Scatter List
2372da39e3ecSSrisivasubramanian S 	 */
2373da39e3ecSSrisivasubramanian S 
2374da39e3ecSSrisivasubramanian S 	i = 0;
2375da39e3ecSSrisivasubramanian S 	scatter_comp = (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes);
2376da39e3ecSSrisivasubramanian S 
2377da39e3ecSSrisivasubramanian S 	/* IV */
2378da39e3ecSSrisivasubramanian S 	i = fill_sg_comp(scatter_comp, i,
2379da39e3ecSSrisivasubramanian S 			 offset_dma + OFF_CTRL_LEN,
2380da39e3ecSSrisivasubramanian S 			 iv_len);
2381da39e3ecSSrisivasubramanian S 
2382da39e3ecSSrisivasubramanian S 	/* Add output data */
2383da39e3ecSSrisivasubramanian S 	size = outputlen - iv_len;
2384da39e3ecSSrisivasubramanian S 	if (size) {
2385da39e3ecSSrisivasubramanian S 		i = fill_sg_comp_from_iov(scatter_comp, i,
2386da39e3ecSSrisivasubramanian S 					  params->dst_iov, 0,
2387da39e3ecSSrisivasubramanian S 					  &size, NULL, 0);
2388f39928e6SAnoob Joseph 		if (unlikely(size)) {
2389f39928e6SAnoob Joseph 			CPT_LOG_DP_ERR("Insufficient buffer space,"
2390f39928e6SAnoob Joseph 				       " size %d needed", size);
2391f39928e6SAnoob Joseph 			return;
2392f39928e6SAnoob Joseph 		}
2393da39e3ecSSrisivasubramanian S 	}
2394da39e3ecSSrisivasubramanian S 	((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i);
2395da39e3ecSSrisivasubramanian S 	s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t);
2396da39e3ecSSrisivasubramanian S 
2397da39e3ecSSrisivasubramanian S 	size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE;
2398da39e3ecSSrisivasubramanian S 
2399da39e3ecSSrisivasubramanian S 	/* This is DPTR len incase of SG mode */
2400426af86bSAnoob Joseph 	vq_cmd_w0.s.dlen = size;
2401da39e3ecSSrisivasubramanian S 
2402da39e3ecSSrisivasubramanian S 	m_vaddr = (uint8_t *)m_vaddr + size;
2403da39e3ecSSrisivasubramanian S 	m_dma += size;
2404da39e3ecSSrisivasubramanian S 
2405da39e3ecSSrisivasubramanian S 	/* cpt alternate completion address saved earlier */
2406da39e3ecSSrisivasubramanian S 	req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8);
2407da39e3ecSSrisivasubramanian S 	*req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT);
2408da39e3ecSSrisivasubramanian S 	rptr_dma = c_dma - 8;
2409da39e3ecSSrisivasubramanian S 
2410da39e3ecSSrisivasubramanian S 	req->ist.ei1 = dptr_dma;
2411da39e3ecSSrisivasubramanian S 	req->ist.ei2 = rptr_dma;
2412da39e3ecSSrisivasubramanian S 
2413da39e3ecSSrisivasubramanian S 	/* 16 byte aligned cpt res address */
2414da39e3ecSSrisivasubramanian S 	req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr);
2415da39e3ecSSrisivasubramanian S 	*req->completion_addr = COMPLETION_CODE_INIT;
2416da39e3ecSSrisivasubramanian S 	req->comp_baddr  = c_dma;
2417da39e3ecSSrisivasubramanian S 
2418da39e3ecSSrisivasubramanian S 	/* Fill microcode part of instruction */
2419da39e3ecSSrisivasubramanian S 	req->ist.ei0 = vq_cmd_w0.u64;
2420da39e3ecSSrisivasubramanian S 
2421da39e3ecSSrisivasubramanian S 	req->op = op;
2422da39e3ecSSrisivasubramanian S 
2423da39e3ecSSrisivasubramanian S 	*prep_req = req;
2424f39928e6SAnoob Joseph 	return;
2425da39e3ecSSrisivasubramanian S }
2426da39e3ecSSrisivasubramanian S 
2427177b41ceSRagothaman Jayaraman static __rte_always_inline void *
2428177b41ceSRagothaman Jayaraman cpt_fc_dec_hmac_prep(uint32_t flags,
2429177b41ceSRagothaman Jayaraman 		     uint64_t d_offs,
2430177b41ceSRagothaman Jayaraman 		     uint64_t d_lens,
2431177b41ceSRagothaman Jayaraman 		     fc_params_t *fc_params,
2432f39928e6SAnoob Joseph 		     void *op)
2433177b41ceSRagothaman Jayaraman {
2434177b41ceSRagothaman Jayaraman 	struct cpt_ctx *ctx = fc_params->ctx_buf.vaddr;
2435177b41ceSRagothaman Jayaraman 	uint8_t fc_type;
2436177b41ceSRagothaman Jayaraman 	void *prep_req = NULL;
2437177b41ceSRagothaman Jayaraman 
2438177b41ceSRagothaman Jayaraman 	fc_type = ctx->fc_type;
2439177b41ceSRagothaman Jayaraman 
2440177b41ceSRagothaman Jayaraman 	if (likely(fc_type == FC_GEN)) {
2441f39928e6SAnoob Joseph 		cpt_dec_hmac_prep(flags, d_offs, d_lens, fc_params, op,
2442da39e3ecSSrisivasubramanian S 				  &prep_req);
2443f39928e6SAnoob Joseph 	} else if (fc_type == ZUC_SNOW3G) {
2444f39928e6SAnoob Joseph 		cpt_zuc_snow3g_dec_prep(flags, d_offs, d_lens, fc_params, op,
2445f39928e6SAnoob Joseph 					&prep_req);
2446f39928e6SAnoob Joseph 	} else if (fc_type == KASUMI) {
2447f39928e6SAnoob Joseph 		cpt_kasumi_dec_prep(d_offs, d_lens, fc_params, op, &prep_req);
2448f39928e6SAnoob Joseph 	}
2449f39928e6SAnoob Joseph 
2450177b41ceSRagothaman Jayaraman 	/*
2451177b41ceSRagothaman Jayaraman 	 * For AUTH_ONLY case,
2452177b41ceSRagothaman Jayaraman 	 * MC only supports digest generation and verification
2453177b41ceSRagothaman Jayaraman 	 * should be done in software by memcmp()
2454177b41ceSRagothaman Jayaraman 	 */
2455177b41ceSRagothaman Jayaraman 
2456177b41ceSRagothaman Jayaraman 	return prep_req;
2457177b41ceSRagothaman Jayaraman }
2458177b41ceSRagothaman Jayaraman 
2459e3866e73SThomas Monjalon static __rte_always_inline void *__rte_hot
2460b74652f3SRagothaman Jayaraman cpt_fc_enc_hmac_prep(uint32_t flags, uint64_t d_offs, uint64_t d_lens,
2461f39928e6SAnoob Joseph 		     fc_params_t *fc_params, void *op)
2462b74652f3SRagothaman Jayaraman {
2463b74652f3SRagothaman Jayaraman 	struct cpt_ctx *ctx = fc_params->ctx_buf.vaddr;
2464b74652f3SRagothaman Jayaraman 	uint8_t fc_type;
2465b74652f3SRagothaman Jayaraman 	void *prep_req = NULL;
2466b74652f3SRagothaman Jayaraman 
2467b74652f3SRagothaman Jayaraman 	fc_type = ctx->fc_type;
2468b74652f3SRagothaman Jayaraman 
2469b74652f3SRagothaman Jayaraman 	/* Common api for rest of the ops */
2470b74652f3SRagothaman Jayaraman 	if (likely(fc_type == FC_GEN)) {
2471f39928e6SAnoob Joseph 		cpt_enc_hmac_prep(flags, d_offs, d_lens, fc_params, op,
2472351fbee2SSrisivasubramanian S 				  &prep_req);
2473f39928e6SAnoob Joseph 	} else if (fc_type == ZUC_SNOW3G) {
2474f39928e6SAnoob Joseph 		cpt_zuc_snow3g_enc_prep(flags, d_offs, d_lens, fc_params, op,
2475f39928e6SAnoob Joseph 					&prep_req);
2476f39928e6SAnoob Joseph 	} else if (fc_type == KASUMI) {
2477f39928e6SAnoob Joseph 		cpt_kasumi_enc_prep(flags, d_offs, d_lens, fc_params, op,
2478f39928e6SAnoob Joseph 				    &prep_req);
2479f39928e6SAnoob Joseph 	} else if (fc_type == HASH_HMAC) {
2480f39928e6SAnoob Joseph 		cpt_digest_gen_prep(flags, d_lens, fc_params, op, &prep_req);
2481b74652f3SRagothaman Jayaraman 	}
2482b74652f3SRagothaman Jayaraman 
2483b74652f3SRagothaman Jayaraman 	return prep_req;
2484b74652f3SRagothaman Jayaraman }
2485b74652f3SRagothaman Jayaraman 
24866cc54096SNithin Dabilpuram static __rte_always_inline int
24876045c06aSArchana Muniganti cpt_fc_auth_set_key(struct cpt_ctx *cpt_ctx, auth_type_t type,
24886045c06aSArchana Muniganti 		    const uint8_t *key, uint16_t key_len, uint16_t mac_len)
24896cc54096SNithin Dabilpuram {
24906045c06aSArchana Muniganti 	mc_fc_context_t *fctx = &cpt_ctx->mc_ctx.fctx;
24916045c06aSArchana Muniganti 	mc_zuc_snow3g_ctx_t *zs_ctx = &cpt_ctx->mc_ctx.zs_ctx;
24926045c06aSArchana Muniganti 	mc_kasumi_ctx_t *k_ctx = &cpt_ctx->mc_ctx.k_ctx;
24936cc54096SNithin Dabilpuram 
24946cc54096SNithin Dabilpuram 	if ((type >= ZUC_EIA3) && (type <= KASUMI_F9_ECB)) {
24956cc54096SNithin Dabilpuram 		uint32_t keyx[4];
24966cc54096SNithin Dabilpuram 
24976cc54096SNithin Dabilpuram 		if (key_len != 16)
24986cc54096SNithin Dabilpuram 			return -1;
24996cc54096SNithin Dabilpuram 		/* No support for AEAD yet */
25006cc54096SNithin Dabilpuram 		if (cpt_ctx->enc_cipher)
25016cc54096SNithin Dabilpuram 			return -1;
25026cc54096SNithin Dabilpuram 		/* For ZUC/SNOW3G/Kasumi */
25036cc54096SNithin Dabilpuram 		switch (type) {
25046cc54096SNithin Dabilpuram 		case SNOW3G_UIA2:
25056cc54096SNithin Dabilpuram 			cpt_ctx->snow3g = 1;
25066cc54096SNithin Dabilpuram 			gen_key_snow3g(key, keyx);
25076045c06aSArchana Muniganti 			memcpy(zs_ctx->ci_key, keyx, key_len);
25086cc54096SNithin Dabilpuram 			cpt_ctx->fc_type = ZUC_SNOW3G;
25096cc54096SNithin Dabilpuram 			cpt_ctx->zsk_flags = 0x1;
25106cc54096SNithin Dabilpuram 			break;
25116cc54096SNithin Dabilpuram 		case ZUC_EIA3:
25126cc54096SNithin Dabilpuram 			cpt_ctx->snow3g = 0;
25136045c06aSArchana Muniganti 			memcpy(zs_ctx->ci_key, key, key_len);
25146045c06aSArchana Muniganti 			memcpy(zs_ctx->zuc_const, zuc_d, 32);
25156cc54096SNithin Dabilpuram 			cpt_ctx->fc_type = ZUC_SNOW3G;
25166cc54096SNithin Dabilpuram 			cpt_ctx->zsk_flags = 0x1;
25176cc54096SNithin Dabilpuram 			break;
25186cc54096SNithin Dabilpuram 		case KASUMI_F9_ECB:
25196cc54096SNithin Dabilpuram 			/* Kasumi ECB mode */
25206cc54096SNithin Dabilpuram 			cpt_ctx->k_ecb = 1;
25216045c06aSArchana Muniganti 			memcpy(k_ctx->ci_key, key, key_len);
25226cc54096SNithin Dabilpuram 			cpt_ctx->fc_type = KASUMI;
25236cc54096SNithin Dabilpuram 			cpt_ctx->zsk_flags = 0x1;
25246cc54096SNithin Dabilpuram 			break;
25256cc54096SNithin Dabilpuram 		case KASUMI_F9_CBC:
25266045c06aSArchana Muniganti 			memcpy(k_ctx->ci_key, key, key_len);
25276cc54096SNithin Dabilpuram 			cpt_ctx->fc_type = KASUMI;
25286cc54096SNithin Dabilpuram 			cpt_ctx->zsk_flags = 0x1;
25296cc54096SNithin Dabilpuram 			break;
25306cc54096SNithin Dabilpuram 		default:
25316cc54096SNithin Dabilpuram 			return -1;
25326cc54096SNithin Dabilpuram 		}
25336cc54096SNithin Dabilpuram 		cpt_ctx->mac_len = 4;
25346cc54096SNithin Dabilpuram 		cpt_ctx->hash_type = type;
25356cc54096SNithin Dabilpuram 		return 0;
25366cc54096SNithin Dabilpuram 	}
25376cc54096SNithin Dabilpuram 
25386cc54096SNithin Dabilpuram 	if (!(cpt_ctx->fc_type == FC_GEN && !type)) {
25396cc54096SNithin Dabilpuram 		if (!cpt_ctx->fc_type || !cpt_ctx->enc_cipher)
25406cc54096SNithin Dabilpuram 			cpt_ctx->fc_type = HASH_HMAC;
25416cc54096SNithin Dabilpuram 	}
25426cc54096SNithin Dabilpuram 
25432839a8abSSucharitha Sarananaga 	if (cpt_ctx->fc_type == FC_GEN && key_len > 64)
25442839a8abSSucharitha Sarananaga 		return -1;
25452839a8abSSucharitha Sarananaga 
25466cc54096SNithin Dabilpuram 	/* For GMAC auth, cipher must be NULL */
25476cc54096SNithin Dabilpuram 	if (type == GMAC_TYPE)
2548c3d0bc45SAnoob Joseph 		fctx->enc.enc_cipher = 0;
25496cc54096SNithin Dabilpuram 
2550c3d0bc45SAnoob Joseph 	fctx->enc.hash_type = cpt_ctx->hash_type = type;
2551c3d0bc45SAnoob Joseph 	fctx->enc.mac_len = cpt_ctx->mac_len = mac_len;
25526cc54096SNithin Dabilpuram 
25536cc54096SNithin Dabilpuram 	if (key_len) {
25546cc54096SNithin Dabilpuram 		cpt_ctx->hmac = 1;
2555db06451bSAnoob Joseph 
2556db06451bSAnoob Joseph 		cpt_ctx->auth_key = rte_zmalloc(NULL, key_len, 8);
2557db06451bSAnoob Joseph 		if (cpt_ctx->auth_key == NULL)
2558db06451bSAnoob Joseph 			return -1;
2559db06451bSAnoob Joseph 
2560db06451bSAnoob Joseph 		cpt_ctx->auth_key_iova = rte_mem_virt2iova(cpt_ctx->auth_key);
25616cc54096SNithin Dabilpuram 		memcpy(cpt_ctx->auth_key, key, key_len);
25626cc54096SNithin Dabilpuram 		cpt_ctx->auth_key_len = key_len;
25636cc54096SNithin Dabilpuram 		memset(fctx->hmac.ipad, 0, sizeof(fctx->hmac.ipad));
25646cc54096SNithin Dabilpuram 		memset(fctx->hmac.opad, 0, sizeof(fctx->hmac.opad));
25652839a8abSSucharitha Sarananaga 
25662839a8abSSucharitha Sarananaga 		if (key_len <= 64)
25676cc54096SNithin Dabilpuram 			memcpy(fctx->hmac.opad, key, key_len);
2568c3d0bc45SAnoob Joseph 		fctx->enc.auth_input_type = 1;
25696cc54096SNithin Dabilpuram 	}
25706cc54096SNithin Dabilpuram 	return 0;
25716cc54096SNithin Dabilpuram }
25726cc54096SNithin Dabilpuram 
25736cc54096SNithin Dabilpuram static __rte_always_inline int
25746cc54096SNithin Dabilpuram fill_sess_aead(struct rte_crypto_sym_xform *xform,
25756cc54096SNithin Dabilpuram 		 struct cpt_sess_misc *sess)
25766cc54096SNithin Dabilpuram {
25776cc54096SNithin Dabilpuram 	struct rte_crypto_aead_xform *aead_form;
25786cc54096SNithin Dabilpuram 	cipher_type_t enc_type = 0; /* NULL Cipher type */
25796cc54096SNithin Dabilpuram 	auth_type_t auth_type = 0; /* NULL Auth type */
25806cc54096SNithin Dabilpuram 	uint32_t cipher_key_len = 0;
25818de5ede7SAnoob Joseph 	uint8_t aes_gcm = 0;
25826cc54096SNithin Dabilpuram 	aead_form = &xform->aead;
25838de5ede7SAnoob Joseph 	void *ctx = SESS_PRIV(sess);
25846cc54096SNithin Dabilpuram 
2585cb7842f2STejasree Kondoj 	if (aead_form->op == RTE_CRYPTO_AEAD_OP_ENCRYPT) {
25866cc54096SNithin Dabilpuram 		sess->cpt_op |= CPT_OP_CIPHER_ENCRYPT;
25876cc54096SNithin Dabilpuram 		sess->cpt_op |= CPT_OP_AUTH_GENERATE;
2588cb7842f2STejasree Kondoj 	} else if (aead_form->op == RTE_CRYPTO_AEAD_OP_DECRYPT) {
25896cc54096SNithin Dabilpuram 		sess->cpt_op |= CPT_OP_CIPHER_DECRYPT;
25906cc54096SNithin Dabilpuram 		sess->cpt_op |= CPT_OP_AUTH_VERIFY;
25916cc54096SNithin Dabilpuram 	} else {
2592*f665790aSDavid Marchand 		CPT_LOG_DP_ERR("Unknown aead operation");
25936cc54096SNithin Dabilpuram 		return -1;
25946cc54096SNithin Dabilpuram 	}
25956cc54096SNithin Dabilpuram 	switch (aead_form->algo) {
25966cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AEAD_AES_GCM:
25976cc54096SNithin Dabilpuram 		enc_type = AES_GCM;
25986cc54096SNithin Dabilpuram 		cipher_key_len = 16;
25996cc54096SNithin Dabilpuram 		aes_gcm = 1;
26006cc54096SNithin Dabilpuram 		break;
26016cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AEAD_AES_CCM:
26026cc54096SNithin Dabilpuram 		CPT_LOG_DP_ERR("Crypto: Unsupported cipher algo %u",
26036cc54096SNithin Dabilpuram 			       aead_form->algo);
26046cc54096SNithin Dabilpuram 		return -1;
2605cb7842f2STejasree Kondoj 	case RTE_CRYPTO_AEAD_CHACHA20_POLY1305:
2606cb7842f2STejasree Kondoj 		enc_type = CHACHA20;
2607cb7842f2STejasree Kondoj 		auth_type = POLY1305;
2608cb7842f2STejasree Kondoj 		cipher_key_len = 32;
2609cb7842f2STejasree Kondoj 		sess->chacha_poly = 1;
2610cb7842f2STejasree Kondoj 		break;
26116cc54096SNithin Dabilpuram 	default:
26126cc54096SNithin Dabilpuram 		CPT_LOG_DP_ERR("Crypto: Undefined cipher algo %u specified",
26136cc54096SNithin Dabilpuram 			       aead_form->algo);
26146cc54096SNithin Dabilpuram 		return -1;
26156cc54096SNithin Dabilpuram 	}
26166cc54096SNithin Dabilpuram 	if (aead_form->key.length < cipher_key_len) {
26176cc54096SNithin Dabilpuram 		CPT_LOG_DP_ERR("Invalid cipher params keylen %lu",
26186cc54096SNithin Dabilpuram 			       (unsigned int long)aead_form->key.length);
26196cc54096SNithin Dabilpuram 		return -1;
26206cc54096SNithin Dabilpuram 	}
26218de5ede7SAnoob Joseph 	sess->zsk_flag = 0;
26226cc54096SNithin Dabilpuram 	sess->aes_gcm = aes_gcm;
26236cc54096SNithin Dabilpuram 	sess->mac_len = aead_form->digest_length;
26246cc54096SNithin Dabilpuram 	sess->iv_offset = aead_form->iv.offset;
26256cc54096SNithin Dabilpuram 	sess->iv_length = aead_form->iv.length;
26266cc54096SNithin Dabilpuram 	sess->aad_length = aead_form->aad_length;
26276cc54096SNithin Dabilpuram 
2628e40175c5SArchana Muniganti 	if (unlikely(cpt_fc_ciph_set_key(ctx, enc_type, aead_form->key.data,
2629e40175c5SArchana Muniganti 			aead_form->key.length, NULL)))
2630e40175c5SArchana Muniganti 		return -1;
26316cc54096SNithin Dabilpuram 
2632e40175c5SArchana Muniganti 	if (unlikely(cpt_fc_auth_set_key(ctx, auth_type, NULL, 0,
2633e40175c5SArchana Muniganti 			aead_form->digest_length)))
2634e40175c5SArchana Muniganti 		return -1;
26356cc54096SNithin Dabilpuram 
26366cc54096SNithin Dabilpuram 	return 0;
26376cc54096SNithin Dabilpuram }
26386cc54096SNithin Dabilpuram 
26396cc54096SNithin Dabilpuram static __rte_always_inline int
26406cc54096SNithin Dabilpuram fill_sess_cipher(struct rte_crypto_sym_xform *xform,
26416cc54096SNithin Dabilpuram 		 struct cpt_sess_misc *sess)
26426cc54096SNithin Dabilpuram {
26436cc54096SNithin Dabilpuram 	struct rte_crypto_cipher_xform *c_form;
2644de5eb0a6STejasree Kondoj 	struct cpt_ctx *ctx = SESS_PRIV(sess);
26456cc54096SNithin Dabilpuram 	cipher_type_t enc_type = 0; /* NULL Cipher type */
26466cc54096SNithin Dabilpuram 	uint32_t cipher_key_len = 0;
26478de5ede7SAnoob Joseph 	uint8_t zsk_flag = 0, aes_ctr = 0, is_null = 0;
26486cc54096SNithin Dabilpuram 
26496cc54096SNithin Dabilpuram 	c_form = &xform->cipher;
26506cc54096SNithin Dabilpuram 
26516cc54096SNithin Dabilpuram 	if (c_form->op == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
26526cc54096SNithin Dabilpuram 		sess->cpt_op |= CPT_OP_CIPHER_ENCRYPT;
2653de5eb0a6STejasree Kondoj 	else if (c_form->op == RTE_CRYPTO_CIPHER_OP_DECRYPT) {
26546cc54096SNithin Dabilpuram 		sess->cpt_op |= CPT_OP_CIPHER_DECRYPT;
2655de5eb0a6STejasree Kondoj 		if (xform->next != NULL &&
2656de5eb0a6STejasree Kondoj 		    xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
2657de5eb0a6STejasree Kondoj 			/* Perform decryption followed by auth verify */
2658de5eb0a6STejasree Kondoj 			ctx->dec_auth = 1;
2659de5eb0a6STejasree Kondoj 		}
2660de5eb0a6STejasree Kondoj 	} else {
2661*f665790aSDavid Marchand 		CPT_LOG_DP_ERR("Unknown cipher operation");
26626cc54096SNithin Dabilpuram 		return -1;
26636cc54096SNithin Dabilpuram 	}
26646cc54096SNithin Dabilpuram 
26656cc54096SNithin Dabilpuram 	switch (c_form->algo) {
26666cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_AES_CBC:
26676cc54096SNithin Dabilpuram 		enc_type = AES_CBC;
26686cc54096SNithin Dabilpuram 		cipher_key_len = 16;
26696cc54096SNithin Dabilpuram 		break;
26706cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_3DES_CBC:
26716cc54096SNithin Dabilpuram 		enc_type = DES3_CBC;
26726cc54096SNithin Dabilpuram 		cipher_key_len = 24;
26736cc54096SNithin Dabilpuram 		break;
26746cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_DES_CBC:
26756cc54096SNithin Dabilpuram 		/* DES is implemented using 3DES in hardware */
26766cc54096SNithin Dabilpuram 		enc_type = DES3_CBC;
26776cc54096SNithin Dabilpuram 		cipher_key_len = 8;
26786cc54096SNithin Dabilpuram 		break;
26796cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_AES_CTR:
26806cc54096SNithin Dabilpuram 		enc_type = AES_CTR;
26816cc54096SNithin Dabilpuram 		cipher_key_len = 16;
26826cc54096SNithin Dabilpuram 		aes_ctr = 1;
26836cc54096SNithin Dabilpuram 		break;
26846cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_NULL:
26856cc54096SNithin Dabilpuram 		enc_type = 0;
26866cc54096SNithin Dabilpuram 		is_null = 1;
26876cc54096SNithin Dabilpuram 		break;
26886cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_KASUMI_F8:
26896cc54096SNithin Dabilpuram 		enc_type = KASUMI_F8_ECB;
26906cc54096SNithin Dabilpuram 		cipher_key_len = 16;
26916cc54096SNithin Dabilpuram 		zsk_flag = K_F8;
26926cc54096SNithin Dabilpuram 		break;
26936cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_SNOW3G_UEA2:
26946cc54096SNithin Dabilpuram 		enc_type = SNOW3G_UEA2;
26956cc54096SNithin Dabilpuram 		cipher_key_len = 16;
26966cc54096SNithin Dabilpuram 		zsk_flag = ZS_EA;
26976cc54096SNithin Dabilpuram 		break;
26986cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_ZUC_EEA3:
26996cc54096SNithin Dabilpuram 		enc_type = ZUC_EEA3;
27006cc54096SNithin Dabilpuram 		cipher_key_len = 16;
27016cc54096SNithin Dabilpuram 		zsk_flag = ZS_EA;
27026cc54096SNithin Dabilpuram 		break;
27036cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_AES_XTS:
27046cc54096SNithin Dabilpuram 		enc_type = AES_XTS;
27056cc54096SNithin Dabilpuram 		cipher_key_len = 16;
27066cc54096SNithin Dabilpuram 		break;
27076cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_3DES_ECB:
27086cc54096SNithin Dabilpuram 		enc_type = DES3_ECB;
27096cc54096SNithin Dabilpuram 		cipher_key_len = 24;
27106cc54096SNithin Dabilpuram 		break;
27116cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_AES_ECB:
27126cc54096SNithin Dabilpuram 		enc_type = AES_ECB;
27136cc54096SNithin Dabilpuram 		cipher_key_len = 16;
27146cc54096SNithin Dabilpuram 		break;
27156cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_3DES_CTR:
27166cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_AES_F8:
27176cc54096SNithin Dabilpuram 	case RTE_CRYPTO_CIPHER_ARC4:
27186cc54096SNithin Dabilpuram 		CPT_LOG_DP_ERR("Crypto: Unsupported cipher algo %u",
27196cc54096SNithin Dabilpuram 			       c_form->algo);
27206cc54096SNithin Dabilpuram 		return -1;
27216cc54096SNithin Dabilpuram 	default:
27226cc54096SNithin Dabilpuram 		CPT_LOG_DP_ERR("Crypto: Undefined cipher algo %u specified",
27236cc54096SNithin Dabilpuram 			       c_form->algo);
27246cc54096SNithin Dabilpuram 		return -1;
27256cc54096SNithin Dabilpuram 	}
27266cc54096SNithin Dabilpuram 
27276cc54096SNithin Dabilpuram 	if (c_form->key.length < cipher_key_len) {
27286cc54096SNithin Dabilpuram 		CPT_LOG_DP_ERR("Invalid cipher params keylen %lu",
27296cc54096SNithin Dabilpuram 			       (unsigned long) c_form->key.length);
27306cc54096SNithin Dabilpuram 		return -1;
27316cc54096SNithin Dabilpuram 	}
27326cc54096SNithin Dabilpuram 
27336cc54096SNithin Dabilpuram 	sess->zsk_flag = zsk_flag;
27348de5ede7SAnoob Joseph 	sess->aes_gcm = 0;
27356cc54096SNithin Dabilpuram 	sess->aes_ctr = aes_ctr;
27366cc54096SNithin Dabilpuram 	sess->iv_offset = c_form->iv.offset;
27376cc54096SNithin Dabilpuram 	sess->iv_length = c_form->iv.length;
27386cc54096SNithin Dabilpuram 	sess->is_null = is_null;
27396cc54096SNithin Dabilpuram 
2740e40175c5SArchana Muniganti 	if (unlikely(cpt_fc_ciph_set_key(SESS_PRIV(sess), enc_type,
2741e40175c5SArchana Muniganti 			c_form->key.data, c_form->key.length, NULL)))
2742e40175c5SArchana Muniganti 		return -1;
27436cc54096SNithin Dabilpuram 
27446cc54096SNithin Dabilpuram 	return 0;
27456cc54096SNithin Dabilpuram }
27466cc54096SNithin Dabilpuram 
27476cc54096SNithin Dabilpuram static __rte_always_inline int
27486cc54096SNithin Dabilpuram fill_sess_auth(struct rte_crypto_sym_xform *xform,
27496cc54096SNithin Dabilpuram 	       struct cpt_sess_misc *sess)
27506cc54096SNithin Dabilpuram {
2751de5eb0a6STejasree Kondoj 	struct cpt_ctx *ctx = SESS_PRIV(sess);
27526cc54096SNithin Dabilpuram 	struct rte_crypto_auth_xform *a_form;
27536cc54096SNithin Dabilpuram 	auth_type_t auth_type = 0; /* NULL Auth type */
27546cc54096SNithin Dabilpuram 	uint8_t zsk_flag = 0, aes_gcm = 0, is_null = 0;
27556cc54096SNithin Dabilpuram 
2756de5eb0a6STejasree Kondoj 	if (xform->next != NULL &&
2757de5eb0a6STejasree Kondoj 	    xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER &&
2758de5eb0a6STejasree Kondoj 	    xform->next->cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
2759de5eb0a6STejasree Kondoj 		/* Perform auth followed by encryption */
2760de5eb0a6STejasree Kondoj 		ctx->auth_enc = 1;
2761de5eb0a6STejasree Kondoj 	}
2762de5eb0a6STejasree Kondoj 
27636cc54096SNithin Dabilpuram 	a_form = &xform->auth;
27646cc54096SNithin Dabilpuram 
27656cc54096SNithin Dabilpuram 	if (a_form->op == RTE_CRYPTO_AUTH_OP_VERIFY)
27666cc54096SNithin Dabilpuram 		sess->cpt_op |= CPT_OP_AUTH_VERIFY;
27676cc54096SNithin Dabilpuram 	else if (a_form->op == RTE_CRYPTO_AUTH_OP_GENERATE)
27686cc54096SNithin Dabilpuram 		sess->cpt_op |= CPT_OP_AUTH_GENERATE;
27696cc54096SNithin Dabilpuram 	else {
27706cc54096SNithin Dabilpuram 		CPT_LOG_DP_ERR("Unknown auth operation");
27716cc54096SNithin Dabilpuram 		return -1;
27726cc54096SNithin Dabilpuram 	}
27736cc54096SNithin Dabilpuram 
27746cc54096SNithin Dabilpuram 	switch (a_form->algo) {
27756cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_SHA1_HMAC:
27766cc54096SNithin Dabilpuram 		/* Fall through */
27776cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_SHA1:
27786cc54096SNithin Dabilpuram 		auth_type = SHA1_TYPE;
27796cc54096SNithin Dabilpuram 		break;
27806cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_SHA256_HMAC:
27816cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_SHA256:
27826cc54096SNithin Dabilpuram 		auth_type = SHA2_SHA256;
27836cc54096SNithin Dabilpuram 		break;
27846cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_SHA512_HMAC:
27856cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_SHA512:
27866cc54096SNithin Dabilpuram 		auth_type = SHA2_SHA512;
27876cc54096SNithin Dabilpuram 		break;
27886cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_AES_GMAC:
27896cc54096SNithin Dabilpuram 		auth_type = GMAC_TYPE;
27906cc54096SNithin Dabilpuram 		aes_gcm = 1;
27916cc54096SNithin Dabilpuram 		break;
27926cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_SHA224_HMAC:
27936cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_SHA224:
27946cc54096SNithin Dabilpuram 		auth_type = SHA2_SHA224;
27956cc54096SNithin Dabilpuram 		break;
27966cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_SHA384_HMAC:
27976cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_SHA384:
27986cc54096SNithin Dabilpuram 		auth_type = SHA2_SHA384;
27996cc54096SNithin Dabilpuram 		break;
28006cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_MD5_HMAC:
28016cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_MD5:
28026cc54096SNithin Dabilpuram 		auth_type = MD5_TYPE;
28036cc54096SNithin Dabilpuram 		break;
28046cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_KASUMI_F9:
28056cc54096SNithin Dabilpuram 		auth_type = KASUMI_F9_ECB;
28066cc54096SNithin Dabilpuram 		/*
28076cc54096SNithin Dabilpuram 		 * Indicate that direction needs to be taken out
28086cc54096SNithin Dabilpuram 		 * from end of src
28096cc54096SNithin Dabilpuram 		 */
28106cc54096SNithin Dabilpuram 		zsk_flag = K_F9;
28116cc54096SNithin Dabilpuram 		break;
28126cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_SNOW3G_UIA2:
28136cc54096SNithin Dabilpuram 		auth_type = SNOW3G_UIA2;
28146cc54096SNithin Dabilpuram 		zsk_flag = ZS_IA;
28156cc54096SNithin Dabilpuram 		break;
28166cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_ZUC_EIA3:
28176cc54096SNithin Dabilpuram 		auth_type = ZUC_EIA3;
28186cc54096SNithin Dabilpuram 		zsk_flag = ZS_IA;
28196cc54096SNithin Dabilpuram 		break;
28206cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_NULL:
28216cc54096SNithin Dabilpuram 		auth_type = 0;
28226cc54096SNithin Dabilpuram 		is_null = 1;
28236cc54096SNithin Dabilpuram 		break;
28246cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
28256cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_AES_CMAC:
28266cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_AES_CBC_MAC:
28276cc54096SNithin Dabilpuram 		CPT_LOG_DP_ERR("Crypto: Unsupported hash algo %u",
28286cc54096SNithin Dabilpuram 			       a_form->algo);
28298de5ede7SAnoob Joseph 		return -1;
28306cc54096SNithin Dabilpuram 	default:
28316cc54096SNithin Dabilpuram 		CPT_LOG_DP_ERR("Crypto: Undefined Hash algo %u specified",
28326cc54096SNithin Dabilpuram 			       a_form->algo);
28338de5ede7SAnoob Joseph 		return -1;
28346cc54096SNithin Dabilpuram 	}
28356cc54096SNithin Dabilpuram 
28366cc54096SNithin Dabilpuram 	sess->zsk_flag = zsk_flag;
28376cc54096SNithin Dabilpuram 	sess->aes_gcm = aes_gcm;
28386cc54096SNithin Dabilpuram 	sess->mac_len = a_form->digest_length;
28396cc54096SNithin Dabilpuram 	sess->is_null = is_null;
28406cc54096SNithin Dabilpuram 	if (zsk_flag) {
28416cc54096SNithin Dabilpuram 		sess->auth_iv_offset = a_form->iv.offset;
28426cc54096SNithin Dabilpuram 		sess->auth_iv_length = a_form->iv.length;
28436cc54096SNithin Dabilpuram 	}
2844e40175c5SArchana Muniganti 	if (unlikely(cpt_fc_auth_set_key(SESS_PRIV(sess), auth_type,
2845e40175c5SArchana Muniganti 			a_form->key.data, a_form->key.length,
2846e40175c5SArchana Muniganti 			a_form->digest_length)))
2847e40175c5SArchana Muniganti 		return -1;
28486cc54096SNithin Dabilpuram 
28496cc54096SNithin Dabilpuram 	return 0;
28506cc54096SNithin Dabilpuram }
28516cc54096SNithin Dabilpuram 
28526cc54096SNithin Dabilpuram static __rte_always_inline int
28536cc54096SNithin Dabilpuram fill_sess_gmac(struct rte_crypto_sym_xform *xform,
28546cc54096SNithin Dabilpuram 		 struct cpt_sess_misc *sess)
28556cc54096SNithin Dabilpuram {
28566cc54096SNithin Dabilpuram 	struct rte_crypto_auth_xform *a_form;
28576cc54096SNithin Dabilpuram 	cipher_type_t enc_type = 0; /* NULL Cipher type */
28586cc54096SNithin Dabilpuram 	auth_type_t auth_type = 0; /* NULL Auth type */
28598de5ede7SAnoob Joseph 	void *ctx = SESS_PRIV(sess);
28606cc54096SNithin Dabilpuram 
28616cc54096SNithin Dabilpuram 	a_form = &xform->auth;
28626cc54096SNithin Dabilpuram 
28636cc54096SNithin Dabilpuram 	if (a_form->op == RTE_CRYPTO_AUTH_OP_GENERATE)
28646cc54096SNithin Dabilpuram 		sess->cpt_op |= CPT_OP_ENCODE;
28656cc54096SNithin Dabilpuram 	else if (a_form->op == RTE_CRYPTO_AUTH_OP_VERIFY)
28666cc54096SNithin Dabilpuram 		sess->cpt_op |= CPT_OP_DECODE;
28676cc54096SNithin Dabilpuram 	else {
28686cc54096SNithin Dabilpuram 		CPT_LOG_DP_ERR("Unknown auth operation");
28696cc54096SNithin Dabilpuram 		return -1;
28706cc54096SNithin Dabilpuram 	}
28716cc54096SNithin Dabilpuram 
28726cc54096SNithin Dabilpuram 	switch (a_form->algo) {
28736cc54096SNithin Dabilpuram 	case RTE_CRYPTO_AUTH_AES_GMAC:
28746cc54096SNithin Dabilpuram 		enc_type = AES_GCM;
28756cc54096SNithin Dabilpuram 		auth_type = GMAC_TYPE;
28766cc54096SNithin Dabilpuram 		break;
28776cc54096SNithin Dabilpuram 	default:
28786cc54096SNithin Dabilpuram 		CPT_LOG_DP_ERR("Crypto: Undefined cipher algo %u specified",
28796cc54096SNithin Dabilpuram 			       a_form->algo);
28806cc54096SNithin Dabilpuram 		return -1;
28816cc54096SNithin Dabilpuram 	}
28826cc54096SNithin Dabilpuram 
28838de5ede7SAnoob Joseph 	sess->zsk_flag = 0;
28848de5ede7SAnoob Joseph 	sess->aes_gcm = 0;
28856cc54096SNithin Dabilpuram 	sess->is_gmac = 1;
28866cc54096SNithin Dabilpuram 	sess->iv_offset = a_form->iv.offset;
28876cc54096SNithin Dabilpuram 	sess->iv_length = a_form->iv.length;
28886cc54096SNithin Dabilpuram 	sess->mac_len = a_form->digest_length;
28896cc54096SNithin Dabilpuram 
2890e40175c5SArchana Muniganti 	if (unlikely(cpt_fc_ciph_set_key(ctx, enc_type, a_form->key.data,
2891e40175c5SArchana Muniganti 			a_form->key.length, NULL)))
2892e40175c5SArchana Muniganti 		return -1;
2893e40175c5SArchana Muniganti 
2894e40175c5SArchana Muniganti 	if (unlikely(cpt_fc_auth_set_key(ctx, auth_type, NULL, 0,
2895e40175c5SArchana Muniganti 			a_form->digest_length)))
2896e40175c5SArchana Muniganti 		return -1;
28976cc54096SNithin Dabilpuram 
28986cc54096SNithin Dabilpuram 	return 0;
28996cc54096SNithin Dabilpuram }
29006cc54096SNithin Dabilpuram 
2901b74652f3SRagothaman Jayaraman static __rte_always_inline void *
2902b74652f3SRagothaman Jayaraman alloc_op_meta(struct rte_mbuf *m_src,
2903b74652f3SRagothaman Jayaraman 	      buf_ptr_t *buf,
2904b74652f3SRagothaman Jayaraman 	      int32_t len,
2905b74652f3SRagothaman Jayaraman 	      struct rte_mempool *cpt_meta_pool)
2906b74652f3SRagothaman Jayaraman {
2907b74652f3SRagothaman Jayaraman 	uint8_t *mdata;
2908b74652f3SRagothaman Jayaraman 
2909b74652f3SRagothaman Jayaraman #ifndef CPT_ALWAYS_USE_SEPARATE_BUF
2910b74652f3SRagothaman Jayaraman 	if (likely(m_src && (m_src->nb_segs == 1))) {
2911b74652f3SRagothaman Jayaraman 		int32_t tailroom;
2912b74652f3SRagothaman Jayaraman 		phys_addr_t mphys;
2913b74652f3SRagothaman Jayaraman 
2914b74652f3SRagothaman Jayaraman 		/* Check if tailroom is sufficient to hold meta data */
2915b74652f3SRagothaman Jayaraman 		tailroom = rte_pktmbuf_tailroom(m_src);
2916b74652f3SRagothaman Jayaraman 		if (likely(tailroom > len + 8)) {
2917b74652f3SRagothaman Jayaraman 			mdata = (uint8_t *)m_src->buf_addr + m_src->buf_len;
29184be71727SThomas Monjalon 			mphys = m_src->buf_iova + m_src->buf_len;
2919b74652f3SRagothaman Jayaraman 			mdata -= len;
2920b74652f3SRagothaman Jayaraman 			mphys -= len;
2921b74652f3SRagothaman Jayaraman 			buf->vaddr = mdata;
2922b74652f3SRagothaman Jayaraman 			buf->dma_addr = mphys;
2923b74652f3SRagothaman Jayaraman 			buf->size = len;
2924b74652f3SRagothaman Jayaraman 			/* Indicate that this is a mbuf allocated mdata */
2925b74652f3SRagothaman Jayaraman 			mdata = (uint8_t *)((uint64_t)mdata | 1ull);
2926b74652f3SRagothaman Jayaraman 			return mdata;
2927b74652f3SRagothaman Jayaraman 		}
2928b74652f3SRagothaman Jayaraman 	}
2929b74652f3SRagothaman Jayaraman #else
2930b74652f3SRagothaman Jayaraman 	RTE_SET_USED(m_src);
2931b74652f3SRagothaman Jayaraman #endif
2932b74652f3SRagothaman Jayaraman 
2933b74652f3SRagothaman Jayaraman 	if (unlikely(rte_mempool_get(cpt_meta_pool, (void **)&mdata) < 0))
2934b74652f3SRagothaman Jayaraman 		return NULL;
2935b74652f3SRagothaman Jayaraman 
2936b74652f3SRagothaman Jayaraman 	buf->vaddr = mdata;
2937b74652f3SRagothaman Jayaraman 	buf->dma_addr = rte_mempool_virt2iova(mdata);
2938b74652f3SRagothaman Jayaraman 	buf->size = len;
2939b74652f3SRagothaman Jayaraman 
2940b74652f3SRagothaman Jayaraman 	return mdata;
2941b74652f3SRagothaman Jayaraman }
2942b74652f3SRagothaman Jayaraman 
2943b74652f3SRagothaman Jayaraman /**
2944b74652f3SRagothaman Jayaraman  * cpt_free_metabuf - free metabuf to mempool.
2945b74652f3SRagothaman Jayaraman  * @param instance: pointer to instance.
2946b74652f3SRagothaman Jayaraman  * @param objp: pointer to the metabuf.
2947b74652f3SRagothaman Jayaraman  */
2948b74652f3SRagothaman Jayaraman static __rte_always_inline void
2949b74652f3SRagothaman Jayaraman free_op_meta(void *mdata, struct rte_mempool *cpt_meta_pool)
2950b74652f3SRagothaman Jayaraman {
2951b74652f3SRagothaman Jayaraman 	bool nofree = ((uintptr_t)mdata & 1ull);
2952b74652f3SRagothaman Jayaraman 
2953b74652f3SRagothaman Jayaraman 	if (likely(nofree))
2954b74652f3SRagothaman Jayaraman 		return;
2955b74652f3SRagothaman Jayaraman 	rte_mempool_put(cpt_meta_pool, mdata);
2956b74652f3SRagothaman Jayaraman }
2957b74652f3SRagothaman Jayaraman 
2958b74652f3SRagothaman Jayaraman static __rte_always_inline uint32_t
2959b74652f3SRagothaman Jayaraman prepare_iov_from_pkt(struct rte_mbuf *pkt,
2960b74652f3SRagothaman Jayaraman 		     iov_ptr_t *iovec, uint32_t start_offset)
2961b74652f3SRagothaman Jayaraman {
2962b74652f3SRagothaman Jayaraman 	uint16_t index = 0;
2963b74652f3SRagothaman Jayaraman 	void *seg_data = NULL;
2964b74652f3SRagothaman Jayaraman 	phys_addr_t seg_phys;
2965b74652f3SRagothaman Jayaraman 	int32_t seg_size = 0;
2966b74652f3SRagothaman Jayaraman 
2967b74652f3SRagothaman Jayaraman 	if (!pkt) {
2968b74652f3SRagothaman Jayaraman 		iovec->buf_cnt = 0;
2969b74652f3SRagothaman Jayaraman 		return 0;
2970b74652f3SRagothaman Jayaraman 	}
2971b74652f3SRagothaman Jayaraman 
2972b74652f3SRagothaman Jayaraman 	if (!start_offset) {
2973b74652f3SRagothaman Jayaraman 		seg_data = rte_pktmbuf_mtod(pkt, void *);
2974ce627d63SThomas Monjalon 		seg_phys = rte_pktmbuf_iova(pkt);
2975b74652f3SRagothaman Jayaraman 		seg_size = pkt->data_len;
2976b74652f3SRagothaman Jayaraman 	} else {
2977b74652f3SRagothaman Jayaraman 		while (start_offset >= pkt->data_len) {
2978b74652f3SRagothaman Jayaraman 			start_offset -= pkt->data_len;
2979b74652f3SRagothaman Jayaraman 			pkt = pkt->next;
2980b74652f3SRagothaman Jayaraman 		}
2981b74652f3SRagothaman Jayaraman 
2982b74652f3SRagothaman Jayaraman 		seg_data = rte_pktmbuf_mtod_offset(pkt, void *, start_offset);
2983ce627d63SThomas Monjalon 		seg_phys = rte_pktmbuf_iova_offset(pkt, start_offset);
2984b74652f3SRagothaman Jayaraman 		seg_size = pkt->data_len - start_offset;
2985b74652f3SRagothaman Jayaraman 		if (!seg_size)
2986b74652f3SRagothaman Jayaraman 			return 1;
2987b74652f3SRagothaman Jayaraman 	}
2988b74652f3SRagothaman Jayaraman 
2989b74652f3SRagothaman Jayaraman 	/* first seg */
2990b74652f3SRagothaman Jayaraman 	iovec->bufs[index].vaddr = seg_data;
2991b74652f3SRagothaman Jayaraman 	iovec->bufs[index].dma_addr = seg_phys;
2992b74652f3SRagothaman Jayaraman 	iovec->bufs[index].size = seg_size;
2993b74652f3SRagothaman Jayaraman 	index++;
2994b74652f3SRagothaman Jayaraman 	pkt = pkt->next;
2995b74652f3SRagothaman Jayaraman 
2996b74652f3SRagothaman Jayaraman 	while (unlikely(pkt != NULL)) {
2997b74652f3SRagothaman Jayaraman 		seg_data = rte_pktmbuf_mtod(pkt, void *);
2998ce627d63SThomas Monjalon 		seg_phys = rte_pktmbuf_iova(pkt);
2999b74652f3SRagothaman Jayaraman 		seg_size = pkt->data_len;
3000b74652f3SRagothaman Jayaraman 		if (!seg_size)
3001b74652f3SRagothaman Jayaraman 			break;
3002b74652f3SRagothaman Jayaraman 
3003b74652f3SRagothaman Jayaraman 		iovec->bufs[index].vaddr = seg_data;
3004b74652f3SRagothaman Jayaraman 		iovec->bufs[index].dma_addr = seg_phys;
3005b74652f3SRagothaman Jayaraman 		iovec->bufs[index].size = seg_size;
3006b74652f3SRagothaman Jayaraman 
3007b74652f3SRagothaman Jayaraman 		index++;
3008b74652f3SRagothaman Jayaraman 
3009b74652f3SRagothaman Jayaraman 		pkt = pkt->next;
3010b74652f3SRagothaman Jayaraman 	}
3011b74652f3SRagothaman Jayaraman 
3012b74652f3SRagothaman Jayaraman 	iovec->buf_cnt = index;
3013b74652f3SRagothaman Jayaraman 	return 0;
3014b74652f3SRagothaman Jayaraman }
3015b74652f3SRagothaman Jayaraman 
3016b74652f3SRagothaman Jayaraman static __rte_always_inline uint32_t
3017b74652f3SRagothaman Jayaraman prepare_iov_from_pkt_inplace(struct rte_mbuf *pkt,
3018b74652f3SRagothaman Jayaraman 			     fc_params_t *param,
3019b74652f3SRagothaman Jayaraman 			     uint32_t *flags)
3020b74652f3SRagothaman Jayaraman {
3021b74652f3SRagothaman Jayaraman 	uint16_t index = 0;
3022b74652f3SRagothaman Jayaraman 	void *seg_data = NULL;
3023b74652f3SRagothaman Jayaraman 	phys_addr_t seg_phys;
3024b74652f3SRagothaman Jayaraman 	uint32_t seg_size = 0;
3025b74652f3SRagothaman Jayaraman 	iov_ptr_t *iovec;
3026b74652f3SRagothaman Jayaraman 
3027b74652f3SRagothaman Jayaraman 	seg_data = rte_pktmbuf_mtod(pkt, void *);
3028ce627d63SThomas Monjalon 	seg_phys = rte_pktmbuf_iova(pkt);
3029b74652f3SRagothaman Jayaraman 	seg_size = pkt->data_len;
3030b74652f3SRagothaman Jayaraman 
3031b74652f3SRagothaman Jayaraman 	/* first seg */
3032b74652f3SRagothaman Jayaraman 	if (likely(!pkt->next)) {
3033b74652f3SRagothaman Jayaraman 		uint32_t headroom, tailroom;
3034b74652f3SRagothaman Jayaraman 
3035b74652f3SRagothaman Jayaraman 		*flags |= SINGLE_BUF_INPLACE;
3036b74652f3SRagothaman Jayaraman 		headroom = rte_pktmbuf_headroom(pkt);
3037b74652f3SRagothaman Jayaraman 		tailroom = rte_pktmbuf_tailroom(pkt);
3038b74652f3SRagothaman Jayaraman 		if (likely((headroom >= 24) &&
3039b74652f3SRagothaman Jayaraman 		    (tailroom >= 8))) {
30407be78d02SJosh Soref 			/* In 83XX this is prerequisite for Direct mode */
3041b74652f3SRagothaman Jayaraman 			*flags |= SINGLE_BUF_HEADTAILROOM;
3042b74652f3SRagothaman Jayaraman 		}
3043b74652f3SRagothaman Jayaraman 		param->bufs[0].vaddr = seg_data;
3044b74652f3SRagothaman Jayaraman 		param->bufs[0].dma_addr = seg_phys;
3045b74652f3SRagothaman Jayaraman 		param->bufs[0].size = seg_size;
3046b74652f3SRagothaman Jayaraman 		return 0;
3047b74652f3SRagothaman Jayaraman 	}
3048b74652f3SRagothaman Jayaraman 	iovec = param->src_iov;
3049b74652f3SRagothaman Jayaraman 	iovec->bufs[index].vaddr = seg_data;
3050b74652f3SRagothaman Jayaraman 	iovec->bufs[index].dma_addr = seg_phys;
3051b74652f3SRagothaman Jayaraman 	iovec->bufs[index].size = seg_size;
3052b74652f3SRagothaman Jayaraman 	index++;
3053b74652f3SRagothaman Jayaraman 	pkt = pkt->next;
3054b74652f3SRagothaman Jayaraman 
3055b74652f3SRagothaman Jayaraman 	while (unlikely(pkt != NULL)) {
3056b74652f3SRagothaman Jayaraman 		seg_data = rte_pktmbuf_mtod(pkt, void *);
3057ce627d63SThomas Monjalon 		seg_phys = rte_pktmbuf_iova(pkt);
3058b74652f3SRagothaman Jayaraman 		seg_size = pkt->data_len;
3059b74652f3SRagothaman Jayaraman 
3060b74652f3SRagothaman Jayaraman 		if (!seg_size)
3061b74652f3SRagothaman Jayaraman 			break;
3062b74652f3SRagothaman Jayaraman 
3063b74652f3SRagothaman Jayaraman 		iovec->bufs[index].vaddr = seg_data;
3064b74652f3SRagothaman Jayaraman 		iovec->bufs[index].dma_addr = seg_phys;
3065b74652f3SRagothaman Jayaraman 		iovec->bufs[index].size = seg_size;
3066b74652f3SRagothaman Jayaraman 
3067b74652f3SRagothaman Jayaraman 		index++;
3068b74652f3SRagothaman Jayaraman 
3069b74652f3SRagothaman Jayaraman 		pkt = pkt->next;
3070b74652f3SRagothaman Jayaraman 	}
3071b74652f3SRagothaman Jayaraman 
3072b74652f3SRagothaman Jayaraman 	iovec->buf_cnt = index;
3073b74652f3SRagothaman Jayaraman 	return 0;
3074b74652f3SRagothaman Jayaraman }
3075b74652f3SRagothaman Jayaraman 
3076f39928e6SAnoob Joseph static __rte_always_inline int
3077b74652f3SRagothaman Jayaraman fill_fc_params(struct rte_crypto_op *cop,
3078b74652f3SRagothaman Jayaraman 	       struct cpt_sess_misc *sess_misc,
3079ec54bc9dSAnoob Joseph 	       struct cpt_qp_meta_info *m_info,
3080b74652f3SRagothaman Jayaraman 	       void **mdata_ptr,
3081f39928e6SAnoob Joseph 	       void **prep_req)
3082b74652f3SRagothaman Jayaraman {
3083b74652f3SRagothaman Jayaraman 	uint32_t space = 0;
3084b74652f3SRagothaman Jayaraman 	struct rte_crypto_sym_op *sym_op = cop->sym;
3085de5eb0a6STejasree Kondoj 	struct cpt_ctx *ctx = SESS_PRIV(sess_misc);
3086f39928e6SAnoob Joseph 	void *mdata = NULL;
3087b74652f3SRagothaman Jayaraman 	uintptr_t *op;
3088b74652f3SRagothaman Jayaraman 	uint32_t mc_hash_off;
3089b74652f3SRagothaman Jayaraman 	uint32_t flags = 0;
3090b74652f3SRagothaman Jayaraman 	uint64_t d_offs, d_lens;
3091b74652f3SRagothaman Jayaraman 	struct rte_mbuf *m_src, *m_dst;
3092b74652f3SRagothaman Jayaraman 	uint8_t cpt_op = sess_misc->cpt_op;
3093b74652f3SRagothaman Jayaraman #ifdef CPT_ALWAYS_USE_SG_MODE
3094b74652f3SRagothaman Jayaraman 	uint8_t inplace = 0;
3095b74652f3SRagothaman Jayaraman #else
3096b74652f3SRagothaman Jayaraman 	uint8_t inplace = 1;
3097b74652f3SRagothaman Jayaraman #endif
3098b74652f3SRagothaman Jayaraman 	fc_params_t fc_params;
3099b74652f3SRagothaman Jayaraman 	char src[SRC_IOV_SIZE];
3100b74652f3SRagothaman Jayaraman 	char dst[SRC_IOV_SIZE];
3101b74652f3SRagothaman Jayaraman 	uint32_t iv_buf[4];
3102f39928e6SAnoob Joseph 	int ret;
3103b74652f3SRagothaman Jayaraman 
3104b74652f3SRagothaman Jayaraman 	if (likely(sess_misc->iv_length)) {
3105b74652f3SRagothaman Jayaraman 		flags |= VALID_IV_BUF;
3106b74652f3SRagothaman Jayaraman 		fc_params.iv_buf = rte_crypto_op_ctod_offset(cop,
3107b74652f3SRagothaman Jayaraman 				   uint8_t *, sess_misc->iv_offset);
3108b74652f3SRagothaman Jayaraman 		if (sess_misc->aes_ctr &&
3109b74652f3SRagothaman Jayaraman 		    unlikely(sess_misc->iv_length != 16)) {
3110b74652f3SRagothaman Jayaraman 			memcpy((uint8_t *)iv_buf,
3111b74652f3SRagothaman Jayaraman 				rte_crypto_op_ctod_offset(cop,
3112b74652f3SRagothaman Jayaraman 				uint8_t *, sess_misc->iv_offset), 12);
3113b74652f3SRagothaman Jayaraman 			iv_buf[3] = rte_cpu_to_be_32(0x1);
3114b74652f3SRagothaman Jayaraman 			fc_params.iv_buf = iv_buf;
3115b74652f3SRagothaman Jayaraman 		}
3116b74652f3SRagothaman Jayaraman 	}
3117b74652f3SRagothaman Jayaraman 
31188de5ede7SAnoob Joseph 	if (sess_misc->zsk_flag) {
3119b74652f3SRagothaman Jayaraman 		fc_params.auth_iv_buf = rte_crypto_op_ctod_offset(cop,
3120b74652f3SRagothaman Jayaraman 					uint8_t *,
3121b74652f3SRagothaman Jayaraman 					sess_misc->auth_iv_offset);
31228de5ede7SAnoob Joseph 		if (sess_misc->zsk_flag != ZS_EA)
3123b74652f3SRagothaman Jayaraman 			inplace = 0;
3124b74652f3SRagothaman Jayaraman 	}
3125b74652f3SRagothaman Jayaraman 	m_src = sym_op->m_src;
3126b74652f3SRagothaman Jayaraman 	m_dst = sym_op->m_dst;
3127b74652f3SRagothaman Jayaraman 
3128cb7842f2STejasree Kondoj 	if (sess_misc->aes_gcm || sess_misc->chacha_poly) {
3129b74652f3SRagothaman Jayaraman 		uint8_t *salt;
3130b74652f3SRagothaman Jayaraman 		uint8_t *aad_data;
3131b74652f3SRagothaman Jayaraman 		uint16_t aad_len;
3132b74652f3SRagothaman Jayaraman 
3133b74652f3SRagothaman Jayaraman 		d_offs = sym_op->aead.data.offset;
3134b74652f3SRagothaman Jayaraman 		d_lens = sym_op->aead.data.length;
3135b74652f3SRagothaman Jayaraman 		mc_hash_off = sym_op->aead.data.offset +
3136b74652f3SRagothaman Jayaraman 			      sym_op->aead.data.length;
3137b74652f3SRagothaman Jayaraman 
3138b74652f3SRagothaman Jayaraman 		aad_data = sym_op->aead.aad.data;
3139b74652f3SRagothaman Jayaraman 		aad_len = sess_misc->aad_length;
3140b74652f3SRagothaman Jayaraman 		if (likely((aad_data + aad_len) ==
3141b74652f3SRagothaman Jayaraman 			   rte_pktmbuf_mtod_offset(m_src,
3142b74652f3SRagothaman Jayaraman 				uint8_t *,
3143b74652f3SRagothaman Jayaraman 				sym_op->aead.data.offset))) {
3144b74652f3SRagothaman Jayaraman 			d_offs = (d_offs - aad_len) | (d_offs << 16);
3145b74652f3SRagothaman Jayaraman 			d_lens = (d_lens + aad_len) | (d_lens << 32);
3146b74652f3SRagothaman Jayaraman 		} else {
3147b74652f3SRagothaman Jayaraman 			fc_params.aad_buf.vaddr = sym_op->aead.aad.data;
3148b74652f3SRagothaman Jayaraman 			fc_params.aad_buf.dma_addr = sym_op->aead.aad.phys_addr;
3149b74652f3SRagothaman Jayaraman 			fc_params.aad_buf.size = aad_len;
3150b74652f3SRagothaman Jayaraman 			flags |= VALID_AAD_BUF;
3151b74652f3SRagothaman Jayaraman 			inplace = 0;
3152b74652f3SRagothaman Jayaraman 			d_offs = d_offs << 16;
3153b74652f3SRagothaman Jayaraman 			d_lens = d_lens << 32;
3154b74652f3SRagothaman Jayaraman 		}
3155b74652f3SRagothaman Jayaraman 
3156b74652f3SRagothaman Jayaraman 		salt = fc_params.iv_buf;
3157b74652f3SRagothaman Jayaraman 		if (unlikely(*(uint32_t *)salt != sess_misc->salt)) {
3158b74652f3SRagothaman Jayaraman 			cpt_fc_salt_update(SESS_PRIV(sess_misc), salt);
3159b74652f3SRagothaman Jayaraman 			sess_misc->salt = *(uint32_t *)salt;
3160b74652f3SRagothaman Jayaraman 		}
3161b74652f3SRagothaman Jayaraman 		fc_params.iv_buf = salt + 4;
31628de5ede7SAnoob Joseph 		if (likely(sess_misc->mac_len)) {
3163b74652f3SRagothaman Jayaraman 			struct rte_mbuf *m = (cpt_op & CPT_OP_ENCODE) ? m_dst :
3164b74652f3SRagothaman Jayaraman 					     m_src;
3165b74652f3SRagothaman Jayaraman 
3166b74652f3SRagothaman Jayaraman 			if (!m)
3167b74652f3SRagothaman Jayaraman 				m = m_src;
3168b74652f3SRagothaman Jayaraman 
3169b74652f3SRagothaman Jayaraman 			/* hmac immediately following data is best case */
3170795651c8SStephen Hemminger 			if (unlikely(rte_pktmbuf_mtod_offset(m, uint8_t *, mc_hash_off) !=
3171b74652f3SRagothaman Jayaraman 				     (uint8_t *)sym_op->aead.digest.data)) {
3172b74652f3SRagothaman Jayaraman 				flags |= VALID_MAC_BUF;
3173b74652f3SRagothaman Jayaraman 				fc_params.mac_buf.size = sess_misc->mac_len;
3174b74652f3SRagothaman Jayaraman 				fc_params.mac_buf.vaddr =
3175b74652f3SRagothaman Jayaraman 				  sym_op->aead.digest.data;
3176b74652f3SRagothaman Jayaraman 				fc_params.mac_buf.dma_addr =
3177b74652f3SRagothaman Jayaraman 				 sym_op->aead.digest.phys_addr;
3178b74652f3SRagothaman Jayaraman 				inplace = 0;
3179b74652f3SRagothaman Jayaraman 			}
3180b74652f3SRagothaman Jayaraman 		}
3181b74652f3SRagothaman Jayaraman 	} else {
3182b74652f3SRagothaman Jayaraman 		d_offs = sym_op->cipher.data.offset;
3183b74652f3SRagothaman Jayaraman 		d_lens = sym_op->cipher.data.length;
3184b74652f3SRagothaman Jayaraman 		mc_hash_off = sym_op->cipher.data.offset +
3185b74652f3SRagothaman Jayaraman 			      sym_op->cipher.data.length;
3186b74652f3SRagothaman Jayaraman 		d_offs = (d_offs << 16) | sym_op->auth.data.offset;
3187b74652f3SRagothaman Jayaraman 		d_lens = (d_lens << 32) | sym_op->auth.data.length;
3188b74652f3SRagothaman Jayaraman 
3189b74652f3SRagothaman Jayaraman 		if (mc_hash_off < (sym_op->auth.data.offset +
3190b74652f3SRagothaman Jayaraman 				   sym_op->auth.data.length)){
3191b74652f3SRagothaman Jayaraman 			mc_hash_off = (sym_op->auth.data.offset +
3192b74652f3SRagothaman Jayaraman 				       sym_op->auth.data.length);
3193b74652f3SRagothaman Jayaraman 		}
3194b74652f3SRagothaman Jayaraman 		/* for gmac, salt should be updated like in gcm */
3195b74652f3SRagothaman Jayaraman 		if (unlikely(sess_misc->is_gmac)) {
3196b74652f3SRagothaman Jayaraman 			uint8_t *salt;
3197b74652f3SRagothaman Jayaraman 			salt = fc_params.iv_buf;
3198b74652f3SRagothaman Jayaraman 			if (unlikely(*(uint32_t *)salt != sess_misc->salt)) {
3199b74652f3SRagothaman Jayaraman 				cpt_fc_salt_update(SESS_PRIV(sess_misc), salt);
3200b74652f3SRagothaman Jayaraman 				sess_misc->salt = *(uint32_t *)salt;
3201b74652f3SRagothaman Jayaraman 			}
3202b74652f3SRagothaman Jayaraman 			fc_params.iv_buf = salt + 4;
3203b74652f3SRagothaman Jayaraman 		}
32048de5ede7SAnoob Joseph 		if (likely(sess_misc->mac_len)) {
3205b74652f3SRagothaman Jayaraman 			struct rte_mbuf *m;
3206b74652f3SRagothaman Jayaraman 
3207b74652f3SRagothaman Jayaraman 			m = (cpt_op & CPT_OP_ENCODE) ? m_dst : m_src;
3208b74652f3SRagothaman Jayaraman 			if (!m)
3209b74652f3SRagothaman Jayaraman 				m = m_src;
3210b74652f3SRagothaman Jayaraman 
3211b74652f3SRagothaman Jayaraman 			/* hmac immediately following data is best case */
3212de5eb0a6STejasree Kondoj 			if (!ctx->dec_auth && !ctx->auth_enc &&
3213795651c8SStephen Hemminger 				 (unlikely(rte_pktmbuf_mtod_offset(m, uint8_t *, mc_hash_off) !=
3214de5eb0a6STejasree Kondoj 					   (uint8_t *)sym_op->auth.digest.data))) {
3215b74652f3SRagothaman Jayaraman 				flags |= VALID_MAC_BUF;
3216b74652f3SRagothaman Jayaraman 				fc_params.mac_buf.size =
3217b74652f3SRagothaman Jayaraman 					sess_misc->mac_len;
3218b74652f3SRagothaman Jayaraman 				fc_params.mac_buf.vaddr =
3219b74652f3SRagothaman Jayaraman 					sym_op->auth.digest.data;
3220b74652f3SRagothaman Jayaraman 				fc_params.mac_buf.dma_addr =
3221b74652f3SRagothaman Jayaraman 				sym_op->auth.digest.phys_addr;
3222b74652f3SRagothaman Jayaraman 				inplace = 0;
3223b74652f3SRagothaman Jayaraman 			}
3224b74652f3SRagothaman Jayaraman 		}
3225b74652f3SRagothaman Jayaraman 	}
3226b74652f3SRagothaman Jayaraman 	fc_params.ctx_buf.vaddr = SESS_PRIV(sess_misc);
3227b74652f3SRagothaman Jayaraman 	fc_params.ctx_buf.dma_addr = sess_misc->ctx_dma_addr;
3228b74652f3SRagothaman Jayaraman 
3229de5eb0a6STejasree Kondoj 	if (!ctx->dec_auth &&
3230de5eb0a6STejasree Kondoj 		  unlikely(sess_misc->is_null ||
3231de5eb0a6STejasree Kondoj 		  sess_misc->cpt_op == CPT_OP_DECODE))
3232b74652f3SRagothaman Jayaraman 		inplace = 0;
3233b74652f3SRagothaman Jayaraman 
3234b74652f3SRagothaman Jayaraman 	if (likely(!m_dst && inplace)) {
3235b74652f3SRagothaman Jayaraman 		/* Case of single buffer without AAD buf or
3236b74652f3SRagothaman Jayaraman 		 * separate mac buf in place and
3237b74652f3SRagothaman Jayaraman 		 * not air crypto
3238b74652f3SRagothaman Jayaraman 		 */
3239b74652f3SRagothaman Jayaraman 		fc_params.dst_iov = fc_params.src_iov = (void *)src;
3240b74652f3SRagothaman Jayaraman 
3241b74652f3SRagothaman Jayaraman 		if (unlikely(prepare_iov_from_pkt_inplace(m_src,
3242b74652f3SRagothaman Jayaraman 							  &fc_params,
3243b74652f3SRagothaman Jayaraman 							  &flags))) {
3244b74652f3SRagothaman Jayaraman 			CPT_LOG_DP_ERR("Prepare inplace src iov failed");
3245f39928e6SAnoob Joseph 			ret = -EINVAL;
3246f39928e6SAnoob Joseph 			goto err_exit;
3247b74652f3SRagothaman Jayaraman 		}
3248b74652f3SRagothaman Jayaraman 
3249b74652f3SRagothaman Jayaraman 	} else {
3250b74652f3SRagothaman Jayaraman 		/* Out of place processing */
3251b74652f3SRagothaman Jayaraman 		fc_params.src_iov = (void *)src;
3252b74652f3SRagothaman Jayaraman 		fc_params.dst_iov = (void *)dst;
3253b74652f3SRagothaman Jayaraman 
3254b74652f3SRagothaman Jayaraman 		/* Store SG I/O in the api for reuse */
3255b74652f3SRagothaman Jayaraman 		if (prepare_iov_from_pkt(m_src, fc_params.src_iov, 0)) {
3256b74652f3SRagothaman Jayaraman 			CPT_LOG_DP_ERR("Prepare src iov failed");
3257f39928e6SAnoob Joseph 			ret = -EINVAL;
3258f39928e6SAnoob Joseph 			goto err_exit;
3259b74652f3SRagothaman Jayaraman 		}
3260b74652f3SRagothaman Jayaraman 
3261b74652f3SRagothaman Jayaraman 		if (unlikely(m_dst != NULL)) {
3262b74652f3SRagothaman Jayaraman 			uint32_t pkt_len;
3263b74652f3SRagothaman Jayaraman 
3264b74652f3SRagothaman Jayaraman 			/* Try to make room as much as src has */
3265b74652f3SRagothaman Jayaraman 			pkt_len = rte_pktmbuf_pkt_len(m_dst);
3266b74652f3SRagothaman Jayaraman 
3267b74652f3SRagothaman Jayaraman 			if (unlikely(pkt_len < rte_pktmbuf_pkt_len(m_src))) {
3268b74652f3SRagothaman Jayaraman 				pkt_len = rte_pktmbuf_pkt_len(m_src) - pkt_len;
3269b74652f3SRagothaman Jayaraman 				if (!rte_pktmbuf_append(m_dst, pkt_len)) {
3270b74652f3SRagothaman Jayaraman 					CPT_LOG_DP_ERR("Not enough space in "
3271b74652f3SRagothaman Jayaraman 						       "m_dst %p, need %u"
3272b74652f3SRagothaman Jayaraman 						       " more",
3273b74652f3SRagothaman Jayaraman 						       m_dst, pkt_len);
3274f39928e6SAnoob Joseph 					ret = -EINVAL;
3275f39928e6SAnoob Joseph 					goto err_exit;
3276b74652f3SRagothaman Jayaraman 				}
3277b74652f3SRagothaman Jayaraman 			}
3278b74652f3SRagothaman Jayaraman 
3279b74652f3SRagothaman Jayaraman 			if (prepare_iov_from_pkt(m_dst, fc_params.dst_iov, 0)) {
3280b74652f3SRagothaman Jayaraman 				CPT_LOG_DP_ERR("Prepare dst iov failed for "
3281b74652f3SRagothaman Jayaraman 					       "m_dst %p", m_dst);
3282f39928e6SAnoob Joseph 				ret = -EINVAL;
3283f39928e6SAnoob Joseph 				goto err_exit;
3284b74652f3SRagothaman Jayaraman 			}
3285b74652f3SRagothaman Jayaraman 		} else {
3286b74652f3SRagothaman Jayaraman 			fc_params.dst_iov = (void *)src;
3287b74652f3SRagothaman Jayaraman 		}
3288b74652f3SRagothaman Jayaraman 	}
3289b74652f3SRagothaman Jayaraman 
3290b74652f3SRagothaman Jayaraman 	if (likely(flags & SINGLE_BUF_HEADTAILROOM))
3291ec54bc9dSAnoob Joseph 		mdata = alloc_op_meta(m_src, &fc_params.meta_buf,
3292ec54bc9dSAnoob Joseph 				      m_info->lb_mlen, m_info->pool);
3293b74652f3SRagothaman Jayaraman 	else
3294ec54bc9dSAnoob Joseph 		mdata = alloc_op_meta(NULL, &fc_params.meta_buf,
3295ec54bc9dSAnoob Joseph 				      m_info->sg_mlen, m_info->pool);
3296b74652f3SRagothaman Jayaraman 
3297b74652f3SRagothaman Jayaraman 	if (unlikely(mdata == NULL)) {
3298b74652f3SRagothaman Jayaraman 		CPT_LOG_DP_ERR("Error allocating meta buffer for request");
3299f39928e6SAnoob Joseph 		ret = -ENOMEM;
3300f39928e6SAnoob Joseph 		goto err_exit;
3301b74652f3SRagothaman Jayaraman 	}
3302b74652f3SRagothaman Jayaraman 
3303b74652f3SRagothaman Jayaraman 	op = (uintptr_t *)((uintptr_t)mdata & (uintptr_t)~1ull);
3304b74652f3SRagothaman Jayaraman 	op[0] = (uintptr_t)mdata;
3305b74652f3SRagothaman Jayaraman 	op[1] = (uintptr_t)cop;
3306b74652f3SRagothaman Jayaraman 	op[2] = op[3] = 0; /* Used to indicate auth verify */
3307b74652f3SRagothaman Jayaraman 	space += 4 * sizeof(uint64_t);
3308b74652f3SRagothaman Jayaraman 
3309b74652f3SRagothaman Jayaraman 	fc_params.meta_buf.vaddr = (uint8_t *)op + space;
3310b74652f3SRagothaman Jayaraman 	fc_params.meta_buf.dma_addr += space;
3311b74652f3SRagothaman Jayaraman 	fc_params.meta_buf.size -= space;
3312b74652f3SRagothaman Jayaraman 
3313b74652f3SRagothaman Jayaraman 	/* Finally prepare the instruction */
3314b74652f3SRagothaman Jayaraman 	if (cpt_op & CPT_OP_ENCODE)
3315f39928e6SAnoob Joseph 		*prep_req = cpt_fc_enc_hmac_prep(flags, d_offs, d_lens,
3316f39928e6SAnoob Joseph 						 &fc_params, op);
3317177b41ceSRagothaman Jayaraman 	else
3318f39928e6SAnoob Joseph 		*prep_req = cpt_fc_dec_hmac_prep(flags, d_offs, d_lens,
3319f39928e6SAnoob Joseph 						 &fc_params, op);
3320b74652f3SRagothaman Jayaraman 
3321f39928e6SAnoob Joseph 	if (unlikely(*prep_req == NULL)) {
3322f39928e6SAnoob Joseph 		CPT_LOG_DP_ERR("Preparing request failed due to bad input arg");
3323f39928e6SAnoob Joseph 		ret = -EINVAL;
3324f39928e6SAnoob Joseph 		goto free_mdata_and_exit;
3325f39928e6SAnoob Joseph 	}
3326f39928e6SAnoob Joseph 
3327b74652f3SRagothaman Jayaraman 	*mdata_ptr = mdata;
3328f39928e6SAnoob Joseph 
3329f39928e6SAnoob Joseph 	return 0;
3330f39928e6SAnoob Joseph 
3331f39928e6SAnoob Joseph free_mdata_and_exit:
3332ec54bc9dSAnoob Joseph 	free_op_meta(mdata, m_info->pool);
3333f39928e6SAnoob Joseph err_exit:
3334f39928e6SAnoob Joseph 	return ret;
3335b74652f3SRagothaman Jayaraman }
3336b74652f3SRagothaman Jayaraman 
333789f1a8d6STejasree Kondoj static __rte_always_inline void
333889f1a8d6STejasree Kondoj compl_auth_verify(struct rte_crypto_op *op,
333989f1a8d6STejasree Kondoj 		      uint8_t *gen_mac,
334089f1a8d6STejasree Kondoj 		      uint64_t mac_len)
334189f1a8d6STejasree Kondoj {
334289f1a8d6STejasree Kondoj 	uint8_t *mac;
334389f1a8d6STejasree Kondoj 	struct rte_crypto_sym_op *sym_op = op->sym;
334489f1a8d6STejasree Kondoj 
334589f1a8d6STejasree Kondoj 	if (sym_op->auth.digest.data)
334689f1a8d6STejasree Kondoj 		mac = sym_op->auth.digest.data;
334789f1a8d6STejasree Kondoj 	else
334889f1a8d6STejasree Kondoj 		mac = rte_pktmbuf_mtod_offset(sym_op->m_src,
334989f1a8d6STejasree Kondoj 					      uint8_t *,
335089f1a8d6STejasree Kondoj 					      sym_op->auth.data.length +
335189f1a8d6STejasree Kondoj 					      sym_op->auth.data.offset);
335289f1a8d6STejasree Kondoj 	if (!mac) {
335389f1a8d6STejasree Kondoj 		op->status = RTE_CRYPTO_OP_STATUS_ERROR;
335489f1a8d6STejasree Kondoj 		return;
335589f1a8d6STejasree Kondoj 	}
335689f1a8d6STejasree Kondoj 
335789f1a8d6STejasree Kondoj 	if (memcmp(mac, gen_mac, mac_len))
335889f1a8d6STejasree Kondoj 		op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
335989f1a8d6STejasree Kondoj 	else
336089f1a8d6STejasree Kondoj 		op->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
336189f1a8d6STejasree Kondoj }
336289f1a8d6STejasree Kondoj 
3363351fbee2SSrisivasubramanian S static __rte_always_inline void
3364351fbee2SSrisivasubramanian S find_kasumif9_direction_and_length(uint8_t *src,
3365351fbee2SSrisivasubramanian S 				   uint32_t counter_num_bytes,
3366351fbee2SSrisivasubramanian S 				   uint32_t *addr_length_in_bits,
3367351fbee2SSrisivasubramanian S 				   uint8_t *addr_direction)
3368351fbee2SSrisivasubramanian S {
3369351fbee2SSrisivasubramanian S 	uint8_t found = 0;
3370f9494b67SAnkur Dwivedi 	uint32_t pos;
3371f9494b67SAnkur Dwivedi 	uint8_t last_byte;
3372351fbee2SSrisivasubramanian S 	while (!found && counter_num_bytes > 0) {
3373351fbee2SSrisivasubramanian S 		counter_num_bytes--;
3374351fbee2SSrisivasubramanian S 		if (src[counter_num_bytes] == 0x00)
3375351fbee2SSrisivasubramanian S 			continue;
3376f9494b67SAnkur Dwivedi 		pos = rte_bsf32(src[counter_num_bytes]);
3377f9494b67SAnkur Dwivedi 		if (pos == 7) {
3378f9494b67SAnkur Dwivedi 			if (likely(counter_num_bytes > 0)) {
3379f9494b67SAnkur Dwivedi 				last_byte = src[counter_num_bytes - 1];
3380f9494b67SAnkur Dwivedi 				*addr_direction  =  last_byte & 0x1;
3381f9494b67SAnkur Dwivedi 				*addr_length_in_bits = counter_num_bytes * 8
3382f9494b67SAnkur Dwivedi 							- 1;
3383f9494b67SAnkur Dwivedi 			}
3384351fbee2SSrisivasubramanian S 		} else {
3385f9494b67SAnkur Dwivedi 			last_byte = src[counter_num_bytes];
3386f9494b67SAnkur Dwivedi 			*addr_direction = (last_byte >> (pos + 1)) & 0x1;
3387f9494b67SAnkur Dwivedi 			*addr_length_in_bits = counter_num_bytes * 8
3388f9494b67SAnkur Dwivedi 						+ (8 - (pos + 2));
3389f9494b67SAnkur Dwivedi 		}
3390351fbee2SSrisivasubramanian S 		found = 1;
3391351fbee2SSrisivasubramanian S 	}
3392351fbee2SSrisivasubramanian S }
3393351fbee2SSrisivasubramanian S 
3394351fbee2SSrisivasubramanian S /*
3395351fbee2SSrisivasubramanian S  * This handles all auth only except AES_GMAC
3396351fbee2SSrisivasubramanian S  */
3397f39928e6SAnoob Joseph static __rte_always_inline int
3398351fbee2SSrisivasubramanian S fill_digest_params(struct rte_crypto_op *cop,
3399351fbee2SSrisivasubramanian S 		   struct cpt_sess_misc *sess,
3400ec54bc9dSAnoob Joseph 		   struct cpt_qp_meta_info *m_info,
3401351fbee2SSrisivasubramanian S 		   void **mdata_ptr,
3402f39928e6SAnoob Joseph 		   void **prep_req)
3403351fbee2SSrisivasubramanian S {
3404351fbee2SSrisivasubramanian S 	uint32_t space = 0;
3405351fbee2SSrisivasubramanian S 	struct rte_crypto_sym_op *sym_op = cop->sym;
3406351fbee2SSrisivasubramanian S 	void *mdata;
3407351fbee2SSrisivasubramanian S 	phys_addr_t mphys;
3408351fbee2SSrisivasubramanian S 	uint64_t *op;
3409351fbee2SSrisivasubramanian S 	uint32_t auth_range_off;
3410351fbee2SSrisivasubramanian S 	uint32_t flags = 0;
3411351fbee2SSrisivasubramanian S 	uint64_t d_offs = 0, d_lens;
3412351fbee2SSrisivasubramanian S 	struct rte_mbuf *m_src, *m_dst;
3413351fbee2SSrisivasubramanian S 	uint16_t auth_op = sess->cpt_op & CPT_OP_AUTH_MASK;
3414351fbee2SSrisivasubramanian S 	uint16_t mac_len = sess->mac_len;
3415351fbee2SSrisivasubramanian S 	fc_params_t params;
3416351fbee2SSrisivasubramanian S 	char src[SRC_IOV_SIZE];
3417351fbee2SSrisivasubramanian S 	uint8_t iv_buf[16];
3418f39928e6SAnoob Joseph 	int ret;
3419f39928e6SAnoob Joseph 
3420351fbee2SSrisivasubramanian S 	memset(&params, 0, sizeof(fc_params_t));
3421351fbee2SSrisivasubramanian S 
3422351fbee2SSrisivasubramanian S 	m_src = sym_op->m_src;
3423351fbee2SSrisivasubramanian S 
3424351fbee2SSrisivasubramanian S 	/* For just digest lets force mempool alloc */
3425ec54bc9dSAnoob Joseph 	mdata = alloc_op_meta(NULL, &params.meta_buf, m_info->sg_mlen,
3426ec54bc9dSAnoob Joseph 			      m_info->pool);
3427351fbee2SSrisivasubramanian S 	if (mdata == NULL) {
3428f39928e6SAnoob Joseph 		ret = -ENOMEM;
3429f39928e6SAnoob Joseph 		goto err_exit;
3430351fbee2SSrisivasubramanian S 	}
3431351fbee2SSrisivasubramanian S 
3432351fbee2SSrisivasubramanian S 	mphys = params.meta_buf.dma_addr;
3433351fbee2SSrisivasubramanian S 
3434351fbee2SSrisivasubramanian S 	op = mdata;
3435351fbee2SSrisivasubramanian S 	op[0] = (uintptr_t)mdata;
3436351fbee2SSrisivasubramanian S 	op[1] = (uintptr_t)cop;
3437351fbee2SSrisivasubramanian S 	op[2] = op[3] = 0; /* Used to indicate auth verify */
3438351fbee2SSrisivasubramanian S 	space += 4 * sizeof(uint64_t);
3439351fbee2SSrisivasubramanian S 
3440351fbee2SSrisivasubramanian S 	auth_range_off = sym_op->auth.data.offset;
3441351fbee2SSrisivasubramanian S 
3442351fbee2SSrisivasubramanian S 	flags = VALID_MAC_BUF;
3443351fbee2SSrisivasubramanian S 	params.src_iov = (void *)src;
34448de5ede7SAnoob Joseph 	if (unlikely(sess->zsk_flag)) {
3445351fbee2SSrisivasubramanian S 		/*
3446351fbee2SSrisivasubramanian S 		 * Since for Zuc, Kasumi, Snow3g offsets are in bits
3447351fbee2SSrisivasubramanian S 		 * we will send pass through even for auth only case,
3448351fbee2SSrisivasubramanian S 		 * let MC handle it
3449351fbee2SSrisivasubramanian S 		 */
3450351fbee2SSrisivasubramanian S 		d_offs = auth_range_off;
3451351fbee2SSrisivasubramanian S 		auth_range_off = 0;
3452351fbee2SSrisivasubramanian S 		params.auth_iv_buf = rte_crypto_op_ctod_offset(cop,
3453351fbee2SSrisivasubramanian S 					uint8_t *, sess->auth_iv_offset);
34548de5ede7SAnoob Joseph 		if (sess->zsk_flag == K_F9) {
3455351fbee2SSrisivasubramanian S 			uint32_t length_in_bits, num_bytes;
3456351fbee2SSrisivasubramanian S 			uint8_t *src, direction = 0;
3457351fbee2SSrisivasubramanian S 
3458351fbee2SSrisivasubramanian S 			memcpy(iv_buf, rte_pktmbuf_mtod(cop->sym->m_src,
3459351fbee2SSrisivasubramanian S 							uint8_t *), 8);
3460351fbee2SSrisivasubramanian S 			/*
3461351fbee2SSrisivasubramanian S 			 * This is kasumi f9, take direction from
3462351fbee2SSrisivasubramanian S 			 * source buffer
3463351fbee2SSrisivasubramanian S 			 */
3464351fbee2SSrisivasubramanian S 			length_in_bits = cop->sym->auth.data.length;
3465351fbee2SSrisivasubramanian S 			num_bytes = (length_in_bits >> 3);
3466351fbee2SSrisivasubramanian S 			src = rte_pktmbuf_mtod(cop->sym->m_src, uint8_t *);
3467351fbee2SSrisivasubramanian S 			find_kasumif9_direction_and_length(src,
34688de5ede7SAnoob Joseph 						num_bytes,
3469351fbee2SSrisivasubramanian S 						&length_in_bits,
3470351fbee2SSrisivasubramanian S 						&direction);
3471351fbee2SSrisivasubramanian S 			length_in_bits -= 64;
3472351fbee2SSrisivasubramanian S 			cop->sym->auth.data.offset += 64;
3473351fbee2SSrisivasubramanian S 			d_offs = cop->sym->auth.data.offset;
3474351fbee2SSrisivasubramanian S 			auth_range_off = d_offs / 8;
3475351fbee2SSrisivasubramanian S 			cop->sym->auth.data.length = length_in_bits;
3476351fbee2SSrisivasubramanian S 
3477351fbee2SSrisivasubramanian S 			/* Store it at end of auth iv */
3478351fbee2SSrisivasubramanian S 			iv_buf[8] = direction;
3479351fbee2SSrisivasubramanian S 			params.auth_iv_buf = iv_buf;
3480351fbee2SSrisivasubramanian S 		}
3481351fbee2SSrisivasubramanian S 	}
3482351fbee2SSrisivasubramanian S 
3483351fbee2SSrisivasubramanian S 	d_lens = sym_op->auth.data.length;
3484351fbee2SSrisivasubramanian S 
3485351fbee2SSrisivasubramanian S 	params.ctx_buf.vaddr = SESS_PRIV(sess);
3486351fbee2SSrisivasubramanian S 	params.ctx_buf.dma_addr = sess->ctx_dma_addr;
3487351fbee2SSrisivasubramanian S 
3488351fbee2SSrisivasubramanian S 	if (auth_op == CPT_OP_AUTH_GENERATE) {
3489351fbee2SSrisivasubramanian S 		if (sym_op->auth.digest.data) {
3490351fbee2SSrisivasubramanian S 			/*
3491351fbee2SSrisivasubramanian S 			 * Digest to be generated
3492351fbee2SSrisivasubramanian S 			 * in separate buffer
3493351fbee2SSrisivasubramanian S 			 */
3494351fbee2SSrisivasubramanian S 			params.mac_buf.size =
3495351fbee2SSrisivasubramanian S 				sess->mac_len;
3496351fbee2SSrisivasubramanian S 			params.mac_buf.vaddr =
3497351fbee2SSrisivasubramanian S 				sym_op->auth.digest.data;
3498351fbee2SSrisivasubramanian S 			params.mac_buf.dma_addr =
3499351fbee2SSrisivasubramanian S 				sym_op->auth.digest.phys_addr;
3500351fbee2SSrisivasubramanian S 		} else {
3501351fbee2SSrisivasubramanian S 			uint32_t off = sym_op->auth.data.offset +
3502351fbee2SSrisivasubramanian S 				sym_op->auth.data.length;
3503351fbee2SSrisivasubramanian S 			int32_t dlen, space;
3504351fbee2SSrisivasubramanian S 
3505351fbee2SSrisivasubramanian S 			m_dst = sym_op->m_dst ?
3506351fbee2SSrisivasubramanian S 				sym_op->m_dst : sym_op->m_src;
3507351fbee2SSrisivasubramanian S 			dlen = rte_pktmbuf_pkt_len(m_dst);
3508351fbee2SSrisivasubramanian S 
3509351fbee2SSrisivasubramanian S 			space = off + mac_len - dlen;
3510351fbee2SSrisivasubramanian S 			if (space > 0)
3511351fbee2SSrisivasubramanian S 				if (!rte_pktmbuf_append(m_dst, space)) {
3512351fbee2SSrisivasubramanian S 					CPT_LOG_DP_ERR("Failed to extend "
3513351fbee2SSrisivasubramanian S 						       "mbuf by %uB", space);
3514f39928e6SAnoob Joseph 					ret = -EINVAL;
3515f39928e6SAnoob Joseph 					goto free_mdata_and_exit;
3516351fbee2SSrisivasubramanian S 				}
3517351fbee2SSrisivasubramanian S 
3518351fbee2SSrisivasubramanian S 			params.mac_buf.vaddr =
3519351fbee2SSrisivasubramanian S 				rte_pktmbuf_mtod_offset(m_dst, void *, off);
3520351fbee2SSrisivasubramanian S 			params.mac_buf.dma_addr =
3521ce627d63SThomas Monjalon 				rte_pktmbuf_iova_offset(m_dst, off);
3522351fbee2SSrisivasubramanian S 			params.mac_buf.size = mac_len;
3523351fbee2SSrisivasubramanian S 		}
3524351fbee2SSrisivasubramanian S 	} else {
3525351fbee2SSrisivasubramanian S 		/* Need space for storing generated mac */
3526351fbee2SSrisivasubramanian S 		params.mac_buf.vaddr = (uint8_t *)mdata + space;
3527351fbee2SSrisivasubramanian S 		params.mac_buf.dma_addr = mphys + space;
3528351fbee2SSrisivasubramanian S 		params.mac_buf.size = mac_len;
3529351fbee2SSrisivasubramanian S 		space += RTE_ALIGN_CEIL(mac_len, 8);
3530351fbee2SSrisivasubramanian S 		op[2] = (uintptr_t)params.mac_buf.vaddr;
3531351fbee2SSrisivasubramanian S 		op[3] = mac_len;
3532351fbee2SSrisivasubramanian S 	}
3533351fbee2SSrisivasubramanian S 
3534351fbee2SSrisivasubramanian S 	params.meta_buf.vaddr = (uint8_t *)mdata + space;
3535351fbee2SSrisivasubramanian S 	params.meta_buf.dma_addr = mphys + space;
3536351fbee2SSrisivasubramanian S 	params.meta_buf.size -= space;
3537351fbee2SSrisivasubramanian S 
3538351fbee2SSrisivasubramanian S 	/* Out of place processing */
3539351fbee2SSrisivasubramanian S 	params.src_iov = (void *)src;
3540351fbee2SSrisivasubramanian S 
3541351fbee2SSrisivasubramanian S 	/*Store SG I/O in the api for reuse */
3542351fbee2SSrisivasubramanian S 	if (prepare_iov_from_pkt(m_src, params.src_iov, auth_range_off)) {
3543351fbee2SSrisivasubramanian S 		CPT_LOG_DP_ERR("Prepare src iov failed");
3544f39928e6SAnoob Joseph 		ret = -EINVAL;
3545f39928e6SAnoob Joseph 		goto free_mdata_and_exit;
3546351fbee2SSrisivasubramanian S 	}
3547351fbee2SSrisivasubramanian S 
3548f39928e6SAnoob Joseph 	*prep_req = cpt_fc_enc_hmac_prep(flags, d_offs, d_lens, &params, op);
3549f39928e6SAnoob Joseph 	if (unlikely(*prep_req == NULL)) {
3550f39928e6SAnoob Joseph 		ret = -EINVAL;
3551f39928e6SAnoob Joseph 		goto free_mdata_and_exit;
3552f39928e6SAnoob Joseph 	}
3553f39928e6SAnoob Joseph 
3554351fbee2SSrisivasubramanian S 	*mdata_ptr = mdata;
3555f39928e6SAnoob Joseph 
3556f39928e6SAnoob Joseph 	return 0;
3557f39928e6SAnoob Joseph 
3558f39928e6SAnoob Joseph free_mdata_and_exit:
3559ec54bc9dSAnoob Joseph 	free_op_meta(mdata, m_info->pool);
3560f39928e6SAnoob Joseph err_exit:
3561f39928e6SAnoob Joseph 	return ret;
3562351fbee2SSrisivasubramanian S }
3563351fbee2SSrisivasubramanian S 
356443d01767SNithin Dabilpuram #endif /*_CPT_UCODE_H_ */
3565