From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM03-DM3-obe.outbound.protection.outlook.com (mail-dm3nam03on0085.outbound.protection.outlook.com [104.47.41.85]) by dpdk.org (Postfix) with ESMTP id CDFDC1B179 for ; Tue, 9 Oct 2018 11:09:33 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=CAVIUMNETWORKS.onmicrosoft.com; s=selector1-cavium-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=IsYR27jLpAv6X2dTpcGTPwqu+MnJLT5C0QRnMc7l6Gk=; b=glSafz0Rkzc6auKhJ76gGtClcAfuD5H4cLLdsuJ3wdj2zcVJZf8Obo7zkeKB36/K4EzBoCQzTrNFj7zNNxlR2vf0dgrjsEXh5O+iYhar9oh8Y64Ke9WkPKHy8UH0DAALoHpsX5FxNz9Jmy8OuAjMfMV+C/4dHLNWO1xrQv7wmH0= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Anoob.Joseph@cavium.com; Received: from ajoseph83.caveonetworks.com.com (115.113.156.2) by BN7PR07MB4897.namprd07.prod.outlook.com (2603:10b6:406:ef::26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1207.28; Tue, 9 Oct 2018 09:09:28 +0000 From: Anoob Joseph To: Akhil Goyal , Pablo de Lara , Thomas Monjalon Cc: Ragothaman Jayaraman , Jerin Jacob , Narayana Prasad , Ankur Dwivedi , Anoob Joseph , Murthy NSSR , Nithin Dabilpuram , Srisivasubramanian S , Tejasree Kondoj , dev@dpdk.org Date: Tue, 9 Oct 2018 14:37:46 +0530 Message-Id: <1539076076-19786-14-git-send-email-anoob.joseph@caviumnetworks.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1539076076-19786-1-git-send-email-anoob.joseph@caviumnetworks.com> References: <1538744363-30340-1-git-send-email-anoob.joseph@caviumnetworks.com> <1539076076-19786-1-git-send-email-anoob.joseph@caviumnetworks.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [115.113.156.2] X-ClientProxiedBy: PN1PR0101CA0004.INDPRD01.PROD.OUTLOOK.COM (2603:1096:c00:e::14) To BN7PR07MB4897.namprd07.prod.outlook.com (2603:10b6:406:ef::26) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 7f188e1e-f31f-4552-ad3f-08d62dc6ecc6 X-Microsoft-Antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989299)(4534185)(7168020)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(2017052603328)(7153060)(7193020); SRVR:BN7PR07MB4897; X-Microsoft-Exchange-Diagnostics: 1; BN7PR07MB4897; 3:1gBJrsoO1onVorFdMxJhlSDFedgpLO1wKuXmqjUU/ODfHu12KwTFtsNCrON1rrejN5GOO11IVwC5uWCnc/cvCQvxA8jy+FHgn4A9QS3OMpW/gW5KaMRxsmnxlz3vCBU59IeChGIUG5zHFH7OdTwpPKDEWAOfROz2ACwgjK6jS0LpqluNZnnTOlDsGsrMfxnojKb7v0OedJ577PqwT2shz7RstOpryTnwg9j+kN2uG5GlbW39mItLpcTgb4cdPGMd; 25:4tGSpeSwI0NXSzxtYZdPYRlEv4//yvcNwYUWtaIYoi5Esy9SD26FkFlaEVm0D5lhU1ceW52g0dMbX7Ys2HEFO5CmOarRh2NSDcyAvZGcWkFtEIVRu7HtnkWenY5Wym9nALg8WGWjmwkTvtiXYEZmSmQinnZuM11wnBKYqguYb3GCyxQswhTYzQCHPIjVfDH+TOYX9UJkoKmDQOexbadPwY5WDsDyXMsiJEltb4+D667FK5tkPUmDYhH/RteocJ+DMN6bx4eb5+JKM/Gv9k/Lp2oCUcnJgc66Cfk7GxxTotURWAFz3vEKKZZeV8WP2P/y+x809hPfGFvc2Z5Sh0k9zw==; 31:Sipm0GeGnbs3Q8lilSlU/Z586JWAIe8FlDS5fJRlGlQ+0vzWad/TNeuFcJHgUdtqtHeplNsA8PPlLWUh0JstiWqlXkmImf0wa7XSQSjuhwhOK69ymPqshY+weg56GCavfsia4qgSeEZWxIR8QXcwbHLesiEZsYWAzJWF4Ws/wvUsn8V/xrrzNi2ksEz7/elv4Aqr+8Jnc0uoSUMu2w6lN35Ja9lQ0NP9TMDkJB9fwWI= X-MS-TrafficTypeDiagnostic: BN7PR07MB4897: X-Microsoft-Exchange-Diagnostics: 1; BN7PR07MB4897; 20:SaoI4YxxEyxj4Lzn1UTxodtPTcUcUSbPAFHh6CQKK/Lrtc/Sse+8G7NFaHHIZ3h97CXFS+rY7xZZfzgnGt7MNBAdAsG3wTjeIpBfRH3Ehm8agKz7KdVd5LlF1Bm9jwocgCSm5eBZaW3ZLKxqfNy5wXSyrnrOYdDEx2lbzklfp851/uQeVad6/1WisU9OnrgaTOdSs+vw+qeRDKm4xue59DO2VFA+GXId1HGf6DIdTq9INnbLxjlfl0s62Ta+tLF/qJCAe7cCE0JZ3jx+ISFj3dgxb630qCW1ieIREiaLrxQNeK5/44edV7ExuX6xrRDBHwtu7tWsjIaTTlrmaAVv4qUenB9hsRyHYyeNU/Le2XLzIN/tlsYWlewbZSrsRjQLZ297dETTsZGqSzHaKGJyttxXkIpBp2gUZW/TYeDseBwoY6/I6Ym/2lh6ms90bOSKFyEtwGarcRFTA4rJORqDJSFdsn2sbizhb+uKES1d/lRDjbwfAjVy8NTpEi1fpv08VMk1oZzGyW/ZLfGqbX3QXk+gnE7hmKhF7O6sS5ZcNGNPY4ez9KBNfz7dJ89b5DFJfWEH0bS0JsZWWqAPMgFXJvVNkDKH+If0MkWjRYL9awA=; 4:ENplEGWb73lVlTn/2bfi18Ao6bjZpERmsMhuYpo6Q3XMqMy1NEarCm238OfcoTRD+AFQEFE3oGnxNuRDmvAridUDIIuCjq/9aLONI6giH0CjvfgxA+vre1Ck/wzmfxzPVT86G4bY59Hd/XxzlA2SSQjuezmNsOaQWE1LC0c5nZNxoeQTTTFc+ugrQkyMU2fP1j0X0kzRF0Zl1cuISMftJcTRxI6C0P4Ft+G76dBXvARLF7oKqaCrdZBA8cvbWCzjatW+lE3YQyTuVwK6hjDWZDzW564MrfNOs7tA0UE9VzOZ8dq4hjMdD+uJ/ydpOLD/ X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(163750095850); X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(3002001)(93006095)(10201501046)(3231355)(944501410)(52105095)(149066)(150057)(6041310)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(20161123564045)(20161123558120)(201708071742011)(7699051); SRVR:BN7PR07MB4897; BCL:0; PCL:0; RULEID:; SRVR:BN7PR07MB4897; X-Forefront-PRVS: 08200063E9 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(396003)(366004)(376002)(136003)(346002)(39860400002)(199004)(189003)(42882007)(47776003)(106356001)(6666003)(186003)(5660300001)(26005)(68736007)(16526019)(8936002)(25786009)(6116002)(2906002)(81156014)(50226002)(305945005)(81166006)(7736002)(3846002)(105586002)(478600001)(8676002)(54906003)(110136005)(48376002)(16586007)(14444005)(6486002)(6506007)(50466002)(316002)(53936002)(386003)(51416003)(52116002)(76176011)(11346002)(6512007)(44832011)(446003)(36756003)(55236004)(956004)(2616005)(4744004)(486006)(4326008)(66066001)(97736004)(72206003)(476003); DIR:OUT; SFP:1101; SCL:1; SRVR:BN7PR07MB4897; H:ajoseph83.caveonetworks.com.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; Received-SPF: None (protection.outlook.com: cavium.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BN7PR07MB4897; 23:YJPnr17GSGkBBV4JZmIDebV1w1igMb0bfDCzlmsDC?= =?us-ascii?Q?N6P8wbTFHRIRK8CXNfqr1gKoCb+l8Y8Jr2SDvDhP70OYMEbF7tNWfvsibYlR?= =?us-ascii?Q?C/4gA73aF1zFqKCvh8Om3rdTbzu0m8NkOm6mWxroE+emSOgKlhS6+BMsTY9H?= =?us-ascii?Q?fqS9gOUEYzlMZ/5o4M8R6Vh4+gU7RwBEmc6nX99oVC0GdQNakZUBJ3KXDStJ?= =?us-ascii?Q?9VICub3UHnlgCj/fu2k5O82VzomDF6ZTblnqrKTfZzNUA7rgHWRzgOsBfnI/?= =?us-ascii?Q?0bVGThuJInOPj3CAW8ResJBQ1b7bOJqSdlAbnZSqbdT7SIs7u0Gt6GRzMXbZ?= =?us-ascii?Q?T8uthnI6rJ1uX+W6hHVksRSaS4Fau8g5n5pcTz9WHBaoyN+rLPjUFY5S4X0J?= =?us-ascii?Q?c7zRNNu6c0jJ3sbM9RXRK7IAVaj2M0JY+RhXbb8waXFGY/pPLzoV4kw7ArPC?= =?us-ascii?Q?5VJCA/ONkpK6KuDs+B5qzVAMZ4o8uiOgg3vTCMYMed216yauGY8JlX4puOPf?= =?us-ascii?Q?6kkck+reRw/QzuPSHUG+sPqW0x8iyutQp4qTMwC998BDbFFVQBiwYfbKMKzH?= =?us-ascii?Q?geRHhdrRNcH9YMULR7T/H6HuMX7eV5dkim25L/cYY/8bp6oMXtIJxUM/qb2H?= =?us-ascii?Q?BsyVnFamQw1XpwZX+MtU17iDQV8NXSX3UERFbd5TUIFBIDac33xxm3mby6dH?= =?us-ascii?Q?oTs5yewoW+RxG+JsI56WTDU/H4Cg20rd33z8KQw34PuDKhwdjcMIjFE3bv+D?= =?us-ascii?Q?YMS0gTXvoxa3sX2vENjFyRXOaVwOyFdh80BmIpHxCxb3QR4Jgz1Udpq7lOTt?= =?us-ascii?Q?agEMN2glmtfANOk8rOCeY7Sq2hU+jSDU2m4+kqqg3s9X7erEBoafe6O3RMT9?= =?us-ascii?Q?q7Pf4lMjvpRuX6Yt0mnVLJOK4vbxlfaPn06jEwpmGqQpuDbbqhbs3NSvGsFC?= =?us-ascii?Q?uVFx8xvo384MqGRuTPqK9mSuLfC3Q4AiAh8HItyce1pI2tFDjzyyPJ+puFIc?= =?us-ascii?Q?7MfmcAsuK5MbUZUttbtAjNnuqL94BlNYYiiV3eHvXgyyLqdjrIF1/vcCQHFa?= =?us-ascii?Q?1eaV0PdalYqQ18VygRzir/5W4/TXI4t128R9eSU1A+RvE8iZpFVY8MNzYwv9?= =?us-ascii?Q?6+yMyWnQfprfJKussmr+Sn1xveOJObYMlha/EpiTVHea1AXicMHJsZOBh+4e?= =?us-ascii?Q?Edbfpv3YibetI5bdlRv+bxOAEaPyOFg/eoasmUGO825YWtZLz3v36aUzuZ9H?= =?us-ascii?Q?2B/r++dkf58xPelTLavaar3kXBckQbOwVlO+r5JkaKhwb5YUhrzWGWHLCarE?= =?us-ascii?B?Zz09?= X-Microsoft-Antispam-Message-Info: 7txW+vyj33Ur4sXI1H4RjsGf8Up6okWtbbTVDrefehfskN3DyiMIFwvl5bBdWy0zAApXl885QM8y/aGYb7/6oud/SaCOjdr1pIzGIvxxdzt/bbpYSbEPHxfSvU623nnbEsXn8IrRIhxvRCMg8oqpiQfNm9L4RKWAd8Yk5N7ZnxoARQkIFkiklQIohQn2BqJBNOCI8yfOpIMdVjow6zTMk48XKAHEKiVWb9ZODSrfitVwLPPu+LaXORDZSoX/SVFBrcVxf1RTv5w3aRfPFEaWDZdgitUDiv/SaczROZeL59j/+DOZdqHGgsApsoqZ21AWopNA0YQZxgTSCfBfetmZi+d2VIUJHYICjC3nfa5LhQA= X-Microsoft-Exchange-Diagnostics: 1; BN7PR07MB4897; 6:bb14tBE3JaYVy35cFiXcJCHsP5Q5ZJgvgwdq7sOZDCFZFZbEbJlHHPwBbm4a2cpMcz8S9CMcxOzhJ8tdbtYUGYFJebrbK1kqpuGAxXsNUYYbKdNI9Db9bIOBjBwInQOaIgVFYgTNDt11udLinkirGZ0fjx6XMJMnItv5uJScB5WS6utmjbyXmT176MPp0h25J8PyJoN68GeQhR1n9XBnLge4EoPEbOQXUY8618Mv0oUBhejRQfH6abLDCagaJOuG7fYEAx2didPHKp3UcdjaPuOEUl5mNJB4foRE8gRKi2O7EeHd94jTD7EuyOHMB7tqFV1FqA/wwlfrWRjHgGqN2804SxU+nuLdaog2y7BDOZ8/V6Ua1fQfuxZTMlt1WGUS3c0As1ocknaA3tu0P8QImPsJ3cld4OUrit9097TrRD/Ec6C41b2cQlYpgrtXEM0jjdVXiLRyxIUchiIdZ+kYjQ==; 5:H5TUs1pRSXREWAuJdgrBOnJ2IkiF9n+k8iwiCE022Um7gke9oND1V9i63zGurxGTNtL8ZfL25+XTdDp07iGjGrGZRBgMx7+FFQJwyxYDKBtv12xEPmf05DWWmjV0eOoQo3Ta5t8SrCNDnKEAySCSwrcIOECspeadot+xW96dNBc=; 7:xT0mZ28aLjwrnFE0zrS1CUlpNDaAR24Jz3SAizbvYULW2QT/6UOEdfM15HVreL7krmmBd6pU7tVydzW6waY1/5W7PivX396ETmzq1BTj7cL2HTL6fzx2V/ma+g/TR6T+x6rKPfdB+r6nNL305YWYICQdi66EFpVOjxgltn/p0p49LjvEWwyCk+uvMggJ+M/pYSi833H4hesd8aiyJqxa6/x43ibOY4Av8acPjCRkI4o9Khdx49LjqTRB1L3AAE4e SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: caviumnetworks.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 09 Oct 2018 09:09:28.5919 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 7f188e1e-f31f-4552-ad3f-08d62dc6ecc6 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 711e4ccf-2e9b-4bcf-a551-4094005b6194 X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN7PR07MB4897 Subject: [dpdk-dev] [PATCH v4 13/23] common/cpt: add microcode interface for encryption X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 09 Oct 2018 09:09:34 -0000 From: Ragothaman Jayaraman Adding microcode interface additions for supporting encryption. Signed-off-by: Ankur Dwivedi Signed-off-by: Anoob Joseph Signed-off-by: Murthy NSSR Signed-off-by: Nithin Dabilpuram Signed-off-by: Ragothaman Jayaraman Signed-off-by: Srisivasubramanian S Signed-off-by: Tejasree Kondoj --- drivers/common/cpt/cpt_ucode.h | 987 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 987 insertions(+) diff --git a/drivers/common/cpt/cpt_ucode.h b/drivers/common/cpt/cpt_ucode.h index 4bbb27a..f5247d5 100644 --- a/drivers/common/cpt/cpt_ucode.h +++ b/drivers/common/cpt/cpt_ucode.h @@ -5,6 +5,10 @@ #ifndef _CPT_UCODE_H_ #define _CPT_UCODE_H_ +#include + +#include "cpt_common.h" +#include "cpt_hw_types.h" #include "cpt_mcode_defines.h" /* @@ -64,6 +68,14 @@ gen_key_snow3g(uint8_t *ck, uint32_t *keyx) } } +static __rte_always_inline void +cpt_fc_salt_update(void *ctx, + uint8_t *salt) +{ + struct cpt_ctx *cpt_ctx = ctx; + memcpy(&cpt_ctx->fctx.enc.encr_iv, salt, 4); +} + static __rte_always_inline int cpt_fc_ciph_validate_key_aes(uint16_t key_len) { @@ -312,6 +324,550 @@ cpt_fc_ciph_set_key(void *ctx, cipher_type_t type, uint8_t *key, return 0; } +static __rte_always_inline uint32_t +fill_sg_comp(sg_comp_t *list, + uint32_t i, + phys_addr_t dma_addr, + uint32_t size) +{ + sg_comp_t *to = &list[i>>2]; + + to->u.s.len[i%4] = rte_cpu_to_be_16(size); + to->ptr[i%4] = rte_cpu_to_be_64(dma_addr); + i++; + return i; +} + +static __rte_always_inline uint32_t +fill_sg_comp_from_buf(sg_comp_t *list, + uint32_t i, + buf_ptr_t *from) +{ + sg_comp_t *to = &list[i>>2]; + + to->u.s.len[i%4] = rte_cpu_to_be_16(from->size); + to->ptr[i%4] = rte_cpu_to_be_64(from->dma_addr); + i++; + return i; +} + +static __rte_always_inline uint32_t +fill_sg_comp_from_buf_min(sg_comp_t *list, + uint32_t i, + buf_ptr_t *from, + uint32_t *psize) +{ + sg_comp_t *to = &list[i >> 2]; + uint32_t size = *psize; + uint32_t e_len; + + e_len = (size > from->size) ? from->size : size; + to->u.s.len[i % 4] = rte_cpu_to_be_16(e_len); + to->ptr[i % 4] = rte_cpu_to_be_64(from->dma_addr); + *psize -= e_len; + i++; + return i; +} + +/* + * This fills the MC expected SGIO list + * from IOV given by user. + */ +static __rte_always_inline uint32_t +fill_sg_comp_from_iov(sg_comp_t *list, + uint32_t i, + iov_ptr_t *from, uint32_t from_offset, + uint32_t *psize, buf_ptr_t *extra_buf, + uint32_t extra_offset) +{ + int32_t j; + uint32_t extra_len = extra_buf ? extra_buf->size : 0; + uint32_t size = *psize - extra_len; + buf_ptr_t *bufs; + + bufs = from->bufs; + for (j = 0; (j < from->buf_cnt) && size; j++) { + phys_addr_t e_dma_addr; + uint32_t e_len; + sg_comp_t *to = &list[i >> 2]; + + if (!bufs[j].size) + continue; + + if (unlikely(from_offset)) { + if (from_offset >= bufs[j].size) { + from_offset -= bufs[j].size; + continue; + } + e_dma_addr = bufs[j].dma_addr + from_offset; + e_len = (size > (bufs[j].size - from_offset)) ? + (bufs[j].size - from_offset) : size; + from_offset = 0; + } else { + e_dma_addr = bufs[j].dma_addr; + e_len = (size > bufs[j].size) ? + bufs[j].size : size; + } + + to->u.s.len[i % 4] = rte_cpu_to_be_16(e_len); + to->ptr[i % 4] = rte_cpu_to_be_64(e_dma_addr); + + if (extra_len && (e_len >= extra_offset)) { + /* Break the data at given offset */ + uint32_t next_len = e_len - extra_offset; + phys_addr_t next_dma = e_dma_addr + extra_offset; + + if (!extra_offset) { + i--; + } else { + e_len = extra_offset; + size -= e_len; + to->u.s.len[i % 4] = rte_cpu_to_be_16(e_len); + } + + /* Insert extra data ptr */ + if (extra_len) { + i++; + to = &list[i >> 2]; + to->u.s.len[i % 4] = + rte_cpu_to_be_16(extra_buf->size); + to->ptr[i % 4] = + rte_cpu_to_be_64(extra_buf->dma_addr); + + /* size already decremented by extra len */ + } + + /* insert the rest of the data */ + if (next_len) { + i++; + to = &list[i >> 2]; + to->u.s.len[i % 4] = rte_cpu_to_be_16(next_len); + to->ptr[i % 4] = rte_cpu_to_be_64(next_dma); + size -= next_len; + } + extra_len = 0; + + } else { + size -= e_len; + } + if (extra_offset) + extra_offset -= size; + i++; + } + + *psize = size; + return (uint32_t)i; +} + +static __rte_always_inline int +cpt_enc_hmac_prep(uint32_t flags, + uint64_t d_offs, + uint64_t d_lens, + fc_params_t *fc_params, + void *op, + void **prep_req) +{ + uint32_t iv_offset = 0; + int32_t inputlen, outputlen, enc_dlen, auth_dlen; + struct cpt_ctx *cpt_ctx; + uint32_t cipher_type, hash_type; + uint32_t mac_len, size; + uint8_t iv_len = 16; + struct cpt_request_info *req; + buf_ptr_t *meta_p, *aad_buf = NULL; + uint32_t encr_offset, auth_offset; + uint32_t encr_data_len, auth_data_len, aad_len = 0; + uint32_t passthrough_len = 0; + void *m_vaddr, *offset_vaddr; + uint64_t m_dma, offset_dma, ctx_dma; + vq_cmd_word0_t vq_cmd_w0; + vq_cmd_word3_t vq_cmd_w3; + void *c_vaddr; + uint64_t c_dma; + int32_t m_size; + opcode_info_t opcode; + + meta_p = &fc_params->meta_buf; + m_vaddr = meta_p->vaddr; + m_dma = meta_p->dma_addr; + m_size = meta_p->size; + + encr_offset = ENCR_OFFSET(d_offs); + auth_offset = AUTH_OFFSET(d_offs); + encr_data_len = ENCR_DLEN(d_lens); + auth_data_len = AUTH_DLEN(d_lens); + if (unlikely(flags & VALID_AAD_BUF)) { + /* + * We dont support both aad + * and auth data separately + */ + auth_data_len = 0; + auth_offset = 0; + aad_len = fc_params->aad_buf.size; + aad_buf = &fc_params->aad_buf; + } + cpt_ctx = fc_params->ctx_buf.vaddr; + cipher_type = cpt_ctx->enc_cipher; + hash_type = cpt_ctx->hash_type; + mac_len = cpt_ctx->mac_len; + + /* + * Save initial space that followed app data for completion code & + * alternate completion code to fall in same cache line as app data + */ + m_vaddr = (uint8_t *)m_vaddr + COMPLETION_CODE_SIZE; + m_dma += COMPLETION_CODE_SIZE; + size = (uint8_t *)RTE_PTR_ALIGN((uint8_t *)m_vaddr, 16) - + (uint8_t *)m_vaddr; + + c_vaddr = (uint8_t *)m_vaddr + size; + c_dma = m_dma + size; + size += sizeof(cpt_res_s_t); + + m_vaddr = (uint8_t *)m_vaddr + size; + m_dma += size; + m_size -= size; + + /* start cpt request info struct at 8 byte boundary */ + size = (uint8_t *)RTE_PTR_ALIGN(m_vaddr, 8) - + (uint8_t *)m_vaddr; + + req = (struct cpt_request_info *)((uint8_t *)m_vaddr + size); + + size += sizeof(struct cpt_request_info); + m_vaddr = (uint8_t *)m_vaddr + size; + m_dma += size; + m_size -= size; + + if (hash_type == GMAC_TYPE) + encr_data_len = 0; + + if (unlikely(!(flags & VALID_IV_BUF))) { + iv_len = 0; + iv_offset = ENCR_IV_OFFSET(d_offs); + } + + if (unlikely(flags & VALID_AAD_BUF)) { + /* + * When AAD is given, data above encr_offset is pass through + * Since AAD is given as separate pointer and not as offset, + * this is a special case as we need to fragment input data + * into passthrough + encr_data and then insert AAD in between. + */ + if (hash_type != GMAC_TYPE) { + passthrough_len = encr_offset; + auth_offset = passthrough_len + iv_len; + encr_offset = passthrough_len + aad_len + iv_len; + auth_data_len = aad_len + encr_data_len; + } else { + passthrough_len = 16 + aad_len; + auth_offset = passthrough_len + iv_len; + auth_data_len = aad_len; + } + } else { + encr_offset += iv_len; + auth_offset += iv_len; + } + + /* Encryption */ + opcode.s.major = CPT_MAJOR_OP_FC; + opcode.s.minor = 0; + + auth_dlen = auth_offset + auth_data_len; + enc_dlen = encr_data_len + encr_offset; + if (unlikely(encr_data_len & 0xf)) { + if ((cipher_type == DES3_CBC) || (cipher_type == DES3_ECB)) + enc_dlen = ROUNDUP8(encr_data_len) + encr_offset; + else if (likely((cipher_type == AES_CBC) || + (cipher_type == AES_ECB))) + enc_dlen = ROUNDUP16(encr_data_len) + encr_offset; + } + + if (unlikely(hash_type == GMAC_TYPE)) { + encr_offset = auth_dlen; + enc_dlen = 0; + } + + if (unlikely(auth_dlen > enc_dlen)) { + inputlen = auth_dlen; + outputlen = auth_dlen + mac_len; + } else { + inputlen = enc_dlen; + outputlen = enc_dlen + mac_len; + } + + /* GP op header */ + vq_cmd_w0.u64 = 0; + vq_cmd_w0.s.param1 = rte_cpu_to_be_16(encr_data_len); + vq_cmd_w0.s.param2 = rte_cpu_to_be_16(auth_data_len); + /* + * In 83XX since we have a limitation of + * IV & Offset control word not part of instruction + * and need to be part of Data Buffer, we check if + * head room is there and then only do the Direct mode processing + */ + if (likely((flags & SINGLE_BUF_INPLACE) && + (flags & SINGLE_BUF_HEADTAILROOM))) { + void *dm_vaddr = fc_params->bufs[0].vaddr; + uint64_t dm_dma_addr = fc_params->bufs[0].dma_addr; + /* + * This flag indicates that there is 24 bytes head room and + * 8 bytes tail room available, so that we get to do + * DIRECT MODE with limitation + */ + + offset_vaddr = (uint8_t *)dm_vaddr - OFF_CTRL_LEN - iv_len; + offset_dma = dm_dma_addr - OFF_CTRL_LEN - iv_len; + + /* DPTR */ + req->ist.ei1 = offset_dma; + /* RPTR should just exclude offset control word */ + req->ist.ei2 = dm_dma_addr - iv_len; + req->alternate_caddr = (uint64_t *)((uint8_t *)dm_vaddr + + outputlen - iv_len); + + vq_cmd_w0.s.dlen = rte_cpu_to_be_16(inputlen + OFF_CTRL_LEN); + + vq_cmd_w0.s.opcode = rte_cpu_to_be_16(opcode.flags); + + if (likely(iv_len)) { + uint64_t *dest = (uint64_t *)((uint8_t *)offset_vaddr + + OFF_CTRL_LEN); + uint64_t *src = fc_params->iv_buf; + dest[0] = src[0]; + dest[1] = src[1]; + } + + *(uint64_t *)offset_vaddr = + rte_cpu_to_be_64(((uint64_t)encr_offset << 16) | + ((uint64_t)iv_offset << 8) | + ((uint64_t)auth_offset)); + + } else { + uint32_t i, g_size_bytes, s_size_bytes; + uint64_t dptr_dma, rptr_dma; + sg_comp_t *gather_comp; + sg_comp_t *scatter_comp; + uint8_t *in_buffer; + + /* This falls under strict SG mode */ + offset_vaddr = m_vaddr; + offset_dma = m_dma; + size = OFF_CTRL_LEN + iv_len; + + m_vaddr = (uint8_t *)m_vaddr + size; + m_dma += size; + m_size -= size; + + opcode.s.major |= CPT_DMA_MODE; + + vq_cmd_w0.s.opcode = rte_cpu_to_be_16(opcode.flags); + + if (likely(iv_len)) { + uint64_t *dest = (uint64_t *)((uint8_t *)offset_vaddr + + OFF_CTRL_LEN); + uint64_t *src = fc_params->iv_buf; + dest[0] = src[0]; + dest[1] = src[1]; + } + + *(uint64_t *)offset_vaddr = + rte_cpu_to_be_64(((uint64_t)encr_offset << 16) | + ((uint64_t)iv_offset << 8) | + ((uint64_t)auth_offset)); + + /* DPTR has SG list */ + in_buffer = m_vaddr; + dptr_dma = m_dma; + + ((uint16_t *)in_buffer)[0] = 0; + ((uint16_t *)in_buffer)[1] = 0; + + /* TODO Add error check if space will be sufficient */ + gather_comp = (sg_comp_t *)((uint8_t *)m_vaddr + 8); + + /* + * Input Gather List + */ + + i = 0; + + /* Offset control word that includes iv */ + i = fill_sg_comp(gather_comp, i, offset_dma, + OFF_CTRL_LEN + iv_len); + + /* Add input data */ + size = inputlen - iv_len; + if (likely(size)) { + uint32_t aad_offset = aad_len ? passthrough_len : 0; + + if (unlikely(flags & SINGLE_BUF_INPLACE)) { + i = fill_sg_comp_from_buf_min(gather_comp, i, + fc_params->bufs, + &size); + } else { + i = fill_sg_comp_from_iov(gather_comp, i, + fc_params->src_iov, + 0, &size, + aad_buf, aad_offset); + } + + if (unlikely(size)) { + CPT_LOG_DP_ERR("Insufficient buffer space," + " size %d needed", size); + return ERR_BAD_INPUT_ARG; + } + } + ((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i); + g_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); + + /* + * Output Scatter list + */ + i = 0; + scatter_comp = + (sg_comp_t *)((uint8_t *)gather_comp + g_size_bytes); + + /* Add IV */ + if (likely(iv_len)) { + i = fill_sg_comp(scatter_comp, i, + offset_dma + OFF_CTRL_LEN, + iv_len); + } + + /* output data or output data + digest*/ + if (unlikely(flags & VALID_MAC_BUF)) { + size = outputlen - iv_len - mac_len; + if (size) { + uint32_t aad_offset = + aad_len ? passthrough_len : 0; + + if (unlikely(flags & SINGLE_BUF_INPLACE)) { + i = fill_sg_comp_from_buf_min( + scatter_comp, + i, + fc_params->bufs, + &size); + } else { + i = fill_sg_comp_from_iov(scatter_comp, + i, + fc_params->dst_iov, + 0, + &size, + aad_buf, + aad_offset); + } + if (size) + return ERR_BAD_INPUT_ARG; + } + /* mac_data */ + if (mac_len) { + i = fill_sg_comp_from_buf(scatter_comp, i, + &fc_params->mac_buf); + } + } else { + /* Output including mac */ + size = outputlen - iv_len; + if (likely(size)) { + uint32_t aad_offset = + aad_len ? passthrough_len : 0; + + if (unlikely(flags & SINGLE_BUF_INPLACE)) { + i = fill_sg_comp_from_buf_min( + scatter_comp, + i, + fc_params->bufs, + &size); + } else { + i = fill_sg_comp_from_iov(scatter_comp, + i, + fc_params->dst_iov, + 0, + &size, + aad_buf, + aad_offset); + } + if (unlikely(size)) { + CPT_LOG_DP_ERR("Insufficient buffer" + " space, size %d needed", + size); + return ERR_BAD_INPUT_ARG; + } + } + } + ((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i); + s_size_bytes = ((i + 3) / 4) * sizeof(sg_comp_t); + + size = g_size_bytes + s_size_bytes + SG_LIST_HDR_SIZE; + + /* This is DPTR len incase of SG mode */ + vq_cmd_w0.s.dlen = rte_cpu_to_be_16(size); + + m_vaddr = (uint8_t *)m_vaddr + size; + m_dma += size; + m_size -= size; + + /* cpt alternate completion address saved earlier */ + req->alternate_caddr = (uint64_t *)((uint8_t *)c_vaddr - 8); + *req->alternate_caddr = ~((uint64_t)COMPLETION_CODE_INIT); + rptr_dma = c_dma - 8; + + req->ist.ei1 = dptr_dma; + req->ist.ei2 = rptr_dma; + } + + /* First 16-bit swap then 64-bit swap */ + /* TODO: HACK: Reverse the vq_cmd and cpt_req bit field definitions + * to eliminate all the swapping + */ + vq_cmd_w0.u64 = rte_cpu_to_be_64(vq_cmd_w0.u64); + + ctx_dma = fc_params->ctx_buf.dma_addr + + offsetof(struct cpt_ctx, fctx); + /* vq command w3 */ + vq_cmd_w3.u64 = 0; + vq_cmd_w3.s.grp = 0; + vq_cmd_w3.s.cptr = ctx_dma; + + /* 16 byte aligned cpt res address */ + req->completion_addr = (uint64_t *)((uint8_t *)c_vaddr); + *req->completion_addr = COMPLETION_CODE_INIT; + req->comp_baddr = c_dma; + + /* Fill microcode part of instruction */ + req->ist.ei0 = vq_cmd_w0.u64; + req->ist.ei3 = vq_cmd_w3.u64; + + req->op = op; + + *prep_req = req; + return 0; +} + +static __rte_always_inline void *__hot +cpt_fc_enc_hmac_prep(uint32_t flags, uint64_t d_offs, uint64_t d_lens, + fc_params_t *fc_params, void *op, int *ret_val) +{ + struct cpt_ctx *ctx = fc_params->ctx_buf.vaddr; + uint8_t fc_type; + void *prep_req = NULL; + int ret; + + fc_type = ctx->fc_type; + + /* Common api for rest of the ops */ + if (likely(fc_type == FC_GEN)) { + ret = cpt_enc_hmac_prep(flags, d_offs, d_lens, + fc_params, op, &prep_req); + } else { + ret = ERR_EIO; + } + + if (unlikely(!prep_req)) + *ret_val = ret; + return prep_req; +} + static __rte_always_inline int cpt_fc_auth_set_key(void *ctx, auth_type_t type, uint8_t *key, uint16_t key_len, uint16_t mac_len) @@ -713,4 +1269,435 @@ fill_sess_gmac(struct rte_crypto_sym_xform *xform, return 0; } +static __rte_always_inline void * +alloc_op_meta(struct rte_mbuf *m_src, + buf_ptr_t *buf, + int32_t len, + struct rte_mempool *cpt_meta_pool) +{ + uint8_t *mdata; + +#ifndef CPT_ALWAYS_USE_SEPARATE_BUF + if (likely(m_src && (m_src->nb_segs == 1))) { + int32_t tailroom; + phys_addr_t mphys; + + /* Check if tailroom is sufficient to hold meta data */ + tailroom = rte_pktmbuf_tailroom(m_src); + if (likely(tailroom > len + 8)) { + mdata = (uint8_t *)m_src->buf_addr + m_src->buf_len; + mphys = m_src->buf_physaddr + m_src->buf_len; + mdata -= len; + mphys -= len; + buf->vaddr = mdata; + buf->dma_addr = mphys; + buf->size = len; + /* Indicate that this is a mbuf allocated mdata */ + mdata = (uint8_t *)((uint64_t)mdata | 1ull); + return mdata; + } + } +#else + RTE_SET_USED(m_src); +#endif + + if (unlikely(rte_mempool_get(cpt_meta_pool, (void **)&mdata) < 0)) + return NULL; + + buf->vaddr = mdata; + buf->dma_addr = rte_mempool_virt2iova(mdata); + buf->size = len; + + return mdata; +} + +/** + * cpt_free_metabuf - free metabuf to mempool. + * @param instance: pointer to instance. + * @param objp: pointer to the metabuf. + */ +static __rte_always_inline void +free_op_meta(void *mdata, struct rte_mempool *cpt_meta_pool) +{ + bool nofree = ((uintptr_t)mdata & 1ull); + + if (likely(nofree)) + return; + rte_mempool_put(cpt_meta_pool, mdata); +} + +static __rte_always_inline uint32_t +prepare_iov_from_pkt(struct rte_mbuf *pkt, + iov_ptr_t *iovec, uint32_t start_offset) +{ + uint16_t index = 0; + void *seg_data = NULL; + phys_addr_t seg_phys; + int32_t seg_size = 0; + + if (!pkt) { + iovec->buf_cnt = 0; + return 0; + } + + if (!start_offset) { + seg_data = rte_pktmbuf_mtod(pkt, void *); + seg_phys = rte_pktmbuf_mtophys(pkt); + seg_size = pkt->data_len; + } else { + while (start_offset >= pkt->data_len) { + start_offset -= pkt->data_len; + pkt = pkt->next; + } + + seg_data = rte_pktmbuf_mtod_offset(pkt, void *, start_offset); + seg_phys = rte_pktmbuf_mtophys_offset(pkt, start_offset); + seg_size = pkt->data_len - start_offset; + if (!seg_size) + return 1; + } + + /* first seg */ + iovec->bufs[index].vaddr = seg_data; + iovec->bufs[index].dma_addr = seg_phys; + iovec->bufs[index].size = seg_size; + index++; + pkt = pkt->next; + + while (unlikely(pkt != NULL)) { + seg_data = rte_pktmbuf_mtod(pkt, void *); + seg_phys = rte_pktmbuf_mtophys(pkt); + seg_size = pkt->data_len; + if (!seg_size) + break; + + iovec->bufs[index].vaddr = seg_data; + iovec->bufs[index].dma_addr = seg_phys; + iovec->bufs[index].size = seg_size; + + index++; + + pkt = pkt->next; + } + + iovec->buf_cnt = index; + return 0; +} + +static __rte_always_inline uint32_t +prepare_iov_from_pkt_inplace(struct rte_mbuf *pkt, + fc_params_t *param, + uint32_t *flags) +{ + uint16_t index = 0; + void *seg_data = NULL; + phys_addr_t seg_phys; + uint32_t seg_size = 0; + iov_ptr_t *iovec; + + seg_data = rte_pktmbuf_mtod(pkt, void *); + seg_phys = rte_pktmbuf_mtophys(pkt); + seg_size = pkt->data_len; + + /* first seg */ + if (likely(!pkt->next)) { + uint32_t headroom, tailroom; + + *flags |= SINGLE_BUF_INPLACE; + headroom = rte_pktmbuf_headroom(pkt); + tailroom = rte_pktmbuf_tailroom(pkt); + if (likely((headroom >= 24) && + (tailroom >= 8))) { + /* In 83XX this is prerequivisit for Direct mode */ + *flags |= SINGLE_BUF_HEADTAILROOM; + } + param->bufs[0].vaddr = seg_data; + param->bufs[0].dma_addr = seg_phys; + param->bufs[0].size = seg_size; + return 0; + } + iovec = param->src_iov; + iovec->bufs[index].vaddr = seg_data; + iovec->bufs[index].dma_addr = seg_phys; + iovec->bufs[index].size = seg_size; + index++; + pkt = pkt->next; + + while (unlikely(pkt != NULL)) { + seg_data = rte_pktmbuf_mtod(pkt, void *); + seg_phys = rte_pktmbuf_mtophys(pkt); + seg_size = pkt->data_len; + + if (!seg_size) + break; + + iovec->bufs[index].vaddr = seg_data; + iovec->bufs[index].dma_addr = seg_phys; + iovec->bufs[index].size = seg_size; + + index++; + + pkt = pkt->next; + } + + iovec->buf_cnt = index; + return 0; +} + +static __rte_always_inline void * +fill_fc_params(struct rte_crypto_op *cop, + struct cpt_sess_misc *sess_misc, + void **mdata_ptr, + int *op_ret) +{ + uint32_t space = 0; + struct rte_crypto_sym_op *sym_op = cop->sym; + void *mdata; + uintptr_t *op; + uint32_t mc_hash_off; + uint32_t flags = 0; + uint64_t d_offs, d_lens; + void *prep_req = NULL; + struct rte_mbuf *m_src, *m_dst; + uint8_t cpt_op = sess_misc->cpt_op; + uint8_t zsk_flag = sess_misc->zsk_flag; + uint8_t aes_gcm = sess_misc->aes_gcm; + uint16_t mac_len = sess_misc->mac_len; +#ifdef CPT_ALWAYS_USE_SG_MODE + uint8_t inplace = 0; +#else + uint8_t inplace = 1; +#endif + fc_params_t fc_params; + char src[SRC_IOV_SIZE]; + char dst[SRC_IOV_SIZE]; + uint32_t iv_buf[4]; + struct cptvf_meta_info *cpt_m_info = + (struct cptvf_meta_info *)(*mdata_ptr); + + if (likely(sess_misc->iv_length)) { + flags |= VALID_IV_BUF; + fc_params.iv_buf = rte_crypto_op_ctod_offset(cop, + uint8_t *, sess_misc->iv_offset); + if (sess_misc->aes_ctr && + unlikely(sess_misc->iv_length != 16)) { + memcpy((uint8_t *)iv_buf, + rte_crypto_op_ctod_offset(cop, + uint8_t *, sess_misc->iv_offset), 12); + iv_buf[3] = rte_cpu_to_be_32(0x1); + fc_params.iv_buf = iv_buf; + } + } + + if (zsk_flag) { + fc_params.auth_iv_buf = rte_crypto_op_ctod_offset(cop, + uint8_t *, + sess_misc->auth_iv_offset); + if (zsk_flag == K_F9) { + CPT_LOG_DP_ERR("Should not reach here for " + "kasumi F9\n"); + } + if (zsk_flag != ZS_EA) + inplace = 0; + } + m_src = sym_op->m_src; + m_dst = sym_op->m_dst; + + if (aes_gcm) { + uint8_t *salt; + uint8_t *aad_data; + uint16_t aad_len; + + d_offs = sym_op->aead.data.offset; + d_lens = sym_op->aead.data.length; + mc_hash_off = sym_op->aead.data.offset + + sym_op->aead.data.length; + + aad_data = sym_op->aead.aad.data; + aad_len = sess_misc->aad_length; + if (likely((aad_data + aad_len) == + rte_pktmbuf_mtod_offset(m_src, + uint8_t *, + sym_op->aead.data.offset))) { + d_offs = (d_offs - aad_len) | (d_offs << 16); + d_lens = (d_lens + aad_len) | (d_lens << 32); + } else { + fc_params.aad_buf.vaddr = sym_op->aead.aad.data; + fc_params.aad_buf.dma_addr = sym_op->aead.aad.phys_addr; + fc_params.aad_buf.size = aad_len; + flags |= VALID_AAD_BUF; + inplace = 0; + d_offs = d_offs << 16; + d_lens = d_lens << 32; + } + + salt = fc_params.iv_buf; + if (unlikely(*(uint32_t *)salt != sess_misc->salt)) { + cpt_fc_salt_update(SESS_PRIV(sess_misc), salt); + sess_misc->salt = *(uint32_t *)salt; + } + fc_params.iv_buf = salt + 4; + if (likely(mac_len)) { + struct rte_mbuf *m = (cpt_op & CPT_OP_ENCODE) ? m_dst : + m_src; + + if (!m) + m = m_src; + + /* hmac immediately following data is best case */ + if (unlikely(rte_pktmbuf_mtod(m, uint8_t *) + + mc_hash_off != + (uint8_t *)sym_op->aead.digest.data)) { + flags |= VALID_MAC_BUF; + fc_params.mac_buf.size = sess_misc->mac_len; + fc_params.mac_buf.vaddr = + sym_op->aead.digest.data; + fc_params.mac_buf.dma_addr = + sym_op->aead.digest.phys_addr; + inplace = 0; + } + } + } else { + d_offs = sym_op->cipher.data.offset; + d_lens = sym_op->cipher.data.length; + mc_hash_off = sym_op->cipher.data.offset + + sym_op->cipher.data.length; + d_offs = (d_offs << 16) | sym_op->auth.data.offset; + d_lens = (d_lens << 32) | sym_op->auth.data.length; + + if (mc_hash_off < (sym_op->auth.data.offset + + sym_op->auth.data.length)){ + mc_hash_off = (sym_op->auth.data.offset + + sym_op->auth.data.length); + } + /* for gmac, salt should be updated like in gcm */ + if (unlikely(sess_misc->is_gmac)) { + uint8_t *salt; + salt = fc_params.iv_buf; + if (unlikely(*(uint32_t *)salt != sess_misc->salt)) { + cpt_fc_salt_update(SESS_PRIV(sess_misc), salt); + sess_misc->salt = *(uint32_t *)salt; + } + fc_params.iv_buf = salt + 4; + } + if (likely(mac_len)) { + struct rte_mbuf *m; + + m = (cpt_op & CPT_OP_ENCODE) ? m_dst : m_src; + if (!m) + m = m_src; + + /* hmac immediately following data is best case */ + if (unlikely(rte_pktmbuf_mtod(m, uint8_t *) + + mc_hash_off != + (uint8_t *)sym_op->auth.digest.data)) { + flags |= VALID_MAC_BUF; + fc_params.mac_buf.size = + sess_misc->mac_len; + fc_params.mac_buf.vaddr = + sym_op->auth.digest.data; + fc_params.mac_buf.dma_addr = + sym_op->auth.digest.phys_addr; + inplace = 0; + } + } + } + fc_params.ctx_buf.vaddr = SESS_PRIV(sess_misc); + fc_params.ctx_buf.dma_addr = sess_misc->ctx_dma_addr; + + if (unlikely(sess_misc->is_null || sess_misc->cpt_op == CPT_OP_DECODE)) + inplace = 0; + + if (likely(!m_dst && inplace)) { + /* Case of single buffer without AAD buf or + * separate mac buf in place and + * not air crypto + */ + fc_params.dst_iov = fc_params.src_iov = (void *)src; + + if (unlikely(prepare_iov_from_pkt_inplace(m_src, + &fc_params, + &flags))) { + CPT_LOG_DP_ERR("Prepare inplace src iov failed"); + *op_ret = -1; + return NULL; + } + + } else { + /* Out of place processing */ + fc_params.src_iov = (void *)src; + fc_params.dst_iov = (void *)dst; + + /* Store SG I/O in the api for reuse */ + if (prepare_iov_from_pkt(m_src, fc_params.src_iov, 0)) { + CPT_LOG_DP_ERR("Prepare src iov failed"); + *op_ret = -1; + return NULL; + } + + if (unlikely(m_dst != NULL)) { + uint32_t pkt_len; + + /* Try to make room as much as src has */ + m_dst = sym_op->m_dst; + pkt_len = rte_pktmbuf_pkt_len(m_dst); + + if (unlikely(pkt_len < rte_pktmbuf_pkt_len(m_src))) { + pkt_len = rte_pktmbuf_pkt_len(m_src) - pkt_len; + if (!rte_pktmbuf_append(m_dst, pkt_len)) { + CPT_LOG_DP_ERR("Not enough space in " + "m_dst %p, need %u" + " more", + m_dst, pkt_len); + return NULL; + } + } + + if (prepare_iov_from_pkt(m_dst, fc_params.dst_iov, 0)) { + CPT_LOG_DP_ERR("Prepare dst iov failed for " + "m_dst %p", m_dst); + return NULL; + } + } else { + fc_params.dst_iov = (void *)src; + } + } + + if (likely(flags & SINGLE_BUF_HEADTAILROOM)) + mdata = alloc_op_meta(m_src, + &fc_params.meta_buf, + cpt_m_info->cptvf_op_sb_mlen, + cpt_m_info->cptvf_meta_pool); + else + mdata = alloc_op_meta(NULL, + &fc_params.meta_buf, + cpt_m_info->cptvf_op_mlen, + cpt_m_info->cptvf_meta_pool); + + if (unlikely(mdata == NULL)) { + CPT_LOG_DP_ERR("Error allocating meta buffer for request"); + return NULL; + } + + op = (uintptr_t *)((uintptr_t)mdata & (uintptr_t)~1ull); + op[0] = (uintptr_t)mdata; + op[1] = (uintptr_t)cop; + op[2] = op[3] = 0; /* Used to indicate auth verify */ + space += 4 * sizeof(uint64_t); + + fc_params.meta_buf.vaddr = (uint8_t *)op + space; + fc_params.meta_buf.dma_addr += space; + fc_params.meta_buf.size -= space; + + /* Finally prepare the instruction */ + if (cpt_op & CPT_OP_ENCODE) + prep_req = cpt_fc_enc_hmac_prep(flags, d_offs, d_lens, + &fc_params, op, op_ret); + + if (unlikely(!prep_req)) + free_op_meta(mdata, cpt_m_info->cptvf_meta_pool); + *mdata_ptr = mdata; + return prep_req; +} + #endif /*_CPT_UCODE_H_ */ -- 2.7.4