1*d81734caSHemant Agrawal /* SPDX-License-Identifier: BSD-3-Clause 2c3e85bdcSAkhil Goyal * 3c3e85bdcSAkhil Goyal * Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved. 4*d81734caSHemant Agrawal * Copyright 2017 NXP 5c3e85bdcSAkhil Goyal * 6c3e85bdcSAkhil Goyal */ 7c3e85bdcSAkhil Goyal 8c3e85bdcSAkhil Goyal #include <fcntl.h> 9c3e85bdcSAkhil Goyal #include <unistd.h> 10c3e85bdcSAkhil Goyal #include <sched.h> 11c3e85bdcSAkhil Goyal #include <net/if.h> 12c3e85bdcSAkhil Goyal 13c3e85bdcSAkhil Goyal #include <rte_byteorder.h> 14c3e85bdcSAkhil Goyal #include <rte_common.h> 15c3e85bdcSAkhil Goyal #include <rte_cryptodev_pmd.h> 16c3e85bdcSAkhil Goyal #include <rte_crypto.h> 17c3e85bdcSAkhil Goyal #include <rte_cryptodev.h> 18c3e85bdcSAkhil Goyal #include <rte_cycles.h> 19c3e85bdcSAkhil Goyal #include <rte_dev.h> 20c3e85bdcSAkhil Goyal #include <rte_kvargs.h> 21c3e85bdcSAkhil Goyal #include <rte_malloc.h> 22c3e85bdcSAkhil Goyal #include <rte_mbuf.h> 23c3e85bdcSAkhil Goyal #include <rte_memcpy.h> 24c3e85bdcSAkhil Goyal #include <rte_string_fns.h> 25c3e85bdcSAkhil Goyal 26c3e85bdcSAkhil Goyal #include <fsl_usd.h> 27c3e85bdcSAkhil Goyal #include <fsl_qman.h> 28c3e85bdcSAkhil Goyal #include <of.h> 29c3e85bdcSAkhil Goyal 30c3e85bdcSAkhil Goyal /* RTA header files */ 31c3e85bdcSAkhil Goyal #include <hw/desc/common.h> 32c3e85bdcSAkhil Goyal #include <hw/desc/algo.h> 33c3e85bdcSAkhil Goyal #include <hw/desc/ipsec.h> 34c3e85bdcSAkhil Goyal 35c3e85bdcSAkhil Goyal #include <rte_dpaa_bus.h> 36c3e85bdcSAkhil Goyal #include <dpaa_sec.h> 37c3e85bdcSAkhil Goyal #include <dpaa_sec_log.h> 38c3e85bdcSAkhil Goyal 39c3e85bdcSAkhil Goyal enum rta_sec_era rta_sec_era; 40c3e85bdcSAkhil Goyal 41c3e85bdcSAkhil Goyal static uint8_t cryptodev_driver_id; 42c3e85bdcSAkhil Goyal 43c3e85bdcSAkhil Goyal static __thread struct rte_crypto_op **dpaa_sec_ops; 44c3e85bdcSAkhil Goyal static __thread int dpaa_sec_op_nb; 45c3e85bdcSAkhil Goyal 46c3e85bdcSAkhil Goyal static inline void 47c3e85bdcSAkhil Goyal dpaa_sec_op_ending(struct dpaa_sec_op_ctx *ctx) 48c3e85bdcSAkhil Goyal { 49c3e85bdcSAkhil Goyal if (!ctx->fd_status) { 50c3e85bdcSAkhil Goyal ctx->op->status = RTE_CRYPTO_OP_STATUS_SUCCESS; 51c3e85bdcSAkhil Goyal } else { 52c3e85bdcSAkhil Goyal PMD_RX_LOG(ERR, "SEC return err: 0x%x", ctx->fd_status); 53c3e85bdcSAkhil Goyal ctx->op->status = RTE_CRYPTO_OP_STATUS_ERROR; 54c3e85bdcSAkhil Goyal } 55c3e85bdcSAkhil Goyal 56c3e85bdcSAkhil Goyal /* report op status to sym->op and then free the ctx memeory */ 57c3e85bdcSAkhil Goyal rte_mempool_put(ctx->ctx_pool, (void *)ctx); 58c3e85bdcSAkhil Goyal } 59c3e85bdcSAkhil Goyal 60c3e85bdcSAkhil Goyal static inline struct dpaa_sec_op_ctx * 61c3e85bdcSAkhil Goyal dpaa_sec_alloc_ctx(dpaa_sec_session *ses) 62c3e85bdcSAkhil Goyal { 63c3e85bdcSAkhil Goyal struct dpaa_sec_op_ctx *ctx; 64c3e85bdcSAkhil Goyal int retval; 65c3e85bdcSAkhil Goyal 66c3e85bdcSAkhil Goyal retval = rte_mempool_get(ses->ctx_pool, (void **)(&ctx)); 67c3e85bdcSAkhil Goyal if (!ctx || retval) { 68c3e85bdcSAkhil Goyal PMD_TX_LOG(ERR, "Alloc sec descriptor failed!"); 69c3e85bdcSAkhil Goyal return NULL; 70c3e85bdcSAkhil Goyal } 71c3e85bdcSAkhil Goyal /* 72c3e85bdcSAkhil Goyal * Clear SG memory. There are 16 SG entries of 16 Bytes each. 73c3e85bdcSAkhil Goyal * one call to dcbz_64() clear 64 bytes, hence calling it 4 times 74c3e85bdcSAkhil Goyal * to clear all the SG entries. dpaa_sec_alloc_ctx() is called for 75c3e85bdcSAkhil Goyal * each packet, memset is costlier than dcbz_64(). 76c3e85bdcSAkhil Goyal */ 77c3e85bdcSAkhil Goyal dcbz_64(&ctx->job.sg[SG_CACHELINE_0]); 78c3e85bdcSAkhil Goyal dcbz_64(&ctx->job.sg[SG_CACHELINE_1]); 79c3e85bdcSAkhil Goyal dcbz_64(&ctx->job.sg[SG_CACHELINE_2]); 80c3e85bdcSAkhil Goyal dcbz_64(&ctx->job.sg[SG_CACHELINE_3]); 81c3e85bdcSAkhil Goyal 82c3e85bdcSAkhil Goyal ctx->ctx_pool = ses->ctx_pool; 83c3e85bdcSAkhil Goyal 84c3e85bdcSAkhil Goyal return ctx; 85c3e85bdcSAkhil Goyal } 86c3e85bdcSAkhil Goyal 87c4509373SSantosh Shukla static inline rte_iova_t 88c3e85bdcSAkhil Goyal dpaa_mem_vtop(void *vaddr) 89c3e85bdcSAkhil Goyal { 90c3e85bdcSAkhil Goyal const struct rte_memseg *memseg = rte_eal_get_physmem_layout(); 91c3e85bdcSAkhil Goyal uint64_t vaddr_64, paddr; 92c3e85bdcSAkhil Goyal int i; 93c3e85bdcSAkhil Goyal 94c3e85bdcSAkhil Goyal vaddr_64 = (uint64_t)vaddr; 95c3e85bdcSAkhil Goyal for (i = 0; i < RTE_MAX_MEMSEG && memseg[i].addr_64 != 0; i++) { 96c3e85bdcSAkhil Goyal if (vaddr_64 >= memseg[i].addr_64 && 97c3e85bdcSAkhil Goyal vaddr_64 < memseg[i].addr_64 + memseg[i].len) { 98c3e85bdcSAkhil Goyal paddr = memseg[i].phys_addr + 99c3e85bdcSAkhil Goyal (vaddr_64 - memseg[i].addr_64); 100c3e85bdcSAkhil Goyal 101c4509373SSantosh Shukla return (rte_iova_t)paddr; 102c3e85bdcSAkhil Goyal } 103c3e85bdcSAkhil Goyal } 104c4509373SSantosh Shukla return (rte_iova_t)(NULL); 105c3e85bdcSAkhil Goyal } 106c3e85bdcSAkhil Goyal 107c3e85bdcSAkhil Goyal static inline void * 108c4509373SSantosh Shukla dpaa_mem_ptov(rte_iova_t paddr) 109c3e85bdcSAkhil Goyal { 110c3e85bdcSAkhil Goyal const struct rte_memseg *memseg = rte_eal_get_physmem_layout(); 111c3e85bdcSAkhil Goyal int i; 112c3e85bdcSAkhil Goyal 113c3e85bdcSAkhil Goyal for (i = 0; i < RTE_MAX_MEMSEG && memseg[i].addr_64 != 0; i++) { 114c3e85bdcSAkhil Goyal if (paddr >= memseg[i].phys_addr && 115c3e85bdcSAkhil Goyal (char *)paddr < (char *)memseg[i].phys_addr + memseg[i].len) 116c3e85bdcSAkhil Goyal return (void *)(memseg[i].addr_64 + 117c3e85bdcSAkhil Goyal (paddr - memseg[i].phys_addr)); 118c3e85bdcSAkhil Goyal } 119c3e85bdcSAkhil Goyal return NULL; 120c3e85bdcSAkhil Goyal } 121c3e85bdcSAkhil Goyal 122c3e85bdcSAkhil Goyal static void 123c3e85bdcSAkhil Goyal ern_sec_fq_handler(struct qman_portal *qm __rte_unused, 124c3e85bdcSAkhil Goyal struct qman_fq *fq, 125c3e85bdcSAkhil Goyal const struct qm_mr_entry *msg) 126c3e85bdcSAkhil Goyal { 127c3e85bdcSAkhil Goyal RTE_LOG_DP(ERR, PMD, "sec fq %d error, RC = %x, seqnum = %x\n", 128c3e85bdcSAkhil Goyal fq->fqid, msg->ern.rc, msg->ern.seqnum); 129c3e85bdcSAkhil Goyal } 130c3e85bdcSAkhil Goyal 131c3e85bdcSAkhil Goyal /* initialize the queue with dest chan as caam chan so that 132c3e85bdcSAkhil Goyal * all the packets in this queue could be dispatched into caam 133c3e85bdcSAkhil Goyal */ 134c3e85bdcSAkhil Goyal static int 135c4509373SSantosh Shukla dpaa_sec_init_rx(struct qman_fq *fq_in, rte_iova_t hwdesc, 136c3e85bdcSAkhil Goyal uint32_t fqid_out) 137c3e85bdcSAkhil Goyal { 138c3e85bdcSAkhil Goyal struct qm_mcc_initfq fq_opts; 139c3e85bdcSAkhil Goyal uint32_t flags; 140c3e85bdcSAkhil Goyal int ret = -1; 141c3e85bdcSAkhil Goyal 142c3e85bdcSAkhil Goyal /* Clear FQ options */ 143c3e85bdcSAkhil Goyal memset(&fq_opts, 0x00, sizeof(struct qm_mcc_initfq)); 144c3e85bdcSAkhil Goyal 145c3e85bdcSAkhil Goyal flags = QMAN_FQ_FLAG_LOCKED | QMAN_FQ_FLAG_DYNAMIC_FQID | 146c3e85bdcSAkhil Goyal QMAN_FQ_FLAG_TO_DCPORTAL; 147c3e85bdcSAkhil Goyal 148c3e85bdcSAkhil Goyal ret = qman_create_fq(0, flags, fq_in); 149c3e85bdcSAkhil Goyal if (unlikely(ret != 0)) { 150c3e85bdcSAkhil Goyal PMD_INIT_LOG(ERR, "qman_create_fq failed"); 151c3e85bdcSAkhil Goyal return ret; 152c3e85bdcSAkhil Goyal } 153c3e85bdcSAkhil Goyal 154c3e85bdcSAkhil Goyal flags = QMAN_INITFQ_FLAG_SCHED; 155c3e85bdcSAkhil Goyal fq_opts.we_mask = QM_INITFQ_WE_DESTWQ | QM_INITFQ_WE_CONTEXTA | 156c3e85bdcSAkhil Goyal QM_INITFQ_WE_CONTEXTB; 157c3e85bdcSAkhil Goyal 158c3e85bdcSAkhil Goyal qm_fqd_context_a_set64(&fq_opts.fqd, hwdesc); 159c3e85bdcSAkhil Goyal fq_opts.fqd.context_b = fqid_out; 160c3e85bdcSAkhil Goyal fq_opts.fqd.dest.channel = qm_channel_caam; 161c3e85bdcSAkhil Goyal fq_opts.fqd.dest.wq = 0; 162c3e85bdcSAkhil Goyal 163c3e85bdcSAkhil Goyal fq_in->cb.ern = ern_sec_fq_handler; 164c3e85bdcSAkhil Goyal 165c3e85bdcSAkhil Goyal ret = qman_init_fq(fq_in, flags, &fq_opts); 166c3e85bdcSAkhil Goyal if (unlikely(ret != 0)) 167c3e85bdcSAkhil Goyal PMD_INIT_LOG(ERR, "qman_init_fq failed"); 168c3e85bdcSAkhil Goyal 169c3e85bdcSAkhil Goyal return ret; 170c3e85bdcSAkhil Goyal } 171c3e85bdcSAkhil Goyal 172c3e85bdcSAkhil Goyal /* something is put into in_fq and caam put the crypto result into out_fq */ 173c3e85bdcSAkhil Goyal static enum qman_cb_dqrr_result 174c3e85bdcSAkhil Goyal dqrr_out_fq_cb_rx(struct qman_portal *qm __always_unused, 175c3e85bdcSAkhil Goyal struct qman_fq *fq __always_unused, 176c3e85bdcSAkhil Goyal const struct qm_dqrr_entry *dqrr) 177c3e85bdcSAkhil Goyal { 178c3e85bdcSAkhil Goyal const struct qm_fd *fd; 179c3e85bdcSAkhil Goyal struct dpaa_sec_job *job; 180c3e85bdcSAkhil Goyal struct dpaa_sec_op_ctx *ctx; 181c3e85bdcSAkhil Goyal 182c3e85bdcSAkhil Goyal if (dpaa_sec_op_nb >= DPAA_SEC_BURST) 183c3e85bdcSAkhil Goyal return qman_cb_dqrr_defer; 184c3e85bdcSAkhil Goyal 185c3e85bdcSAkhil Goyal if (!(dqrr->stat & QM_DQRR_STAT_FD_VALID)) 186c3e85bdcSAkhil Goyal return qman_cb_dqrr_consume; 187c3e85bdcSAkhil Goyal 188c3e85bdcSAkhil Goyal fd = &dqrr->fd; 189c3e85bdcSAkhil Goyal /* sg is embedded in an op ctx, 190c3e85bdcSAkhil Goyal * sg[0] is for output 191c3e85bdcSAkhil Goyal * sg[1] for input 192c3e85bdcSAkhil Goyal */ 193c3e85bdcSAkhil Goyal job = dpaa_mem_ptov(qm_fd_addr_get64(fd)); 194c3e85bdcSAkhil Goyal ctx = container_of(job, struct dpaa_sec_op_ctx, job); 195c3e85bdcSAkhil Goyal ctx->fd_status = fd->status; 196c3e85bdcSAkhil Goyal dpaa_sec_ops[dpaa_sec_op_nb++] = ctx->op; 197c3e85bdcSAkhil Goyal dpaa_sec_op_ending(ctx); 198c3e85bdcSAkhil Goyal 199c3e85bdcSAkhil Goyal return qman_cb_dqrr_consume; 200c3e85bdcSAkhil Goyal } 201c3e85bdcSAkhil Goyal 202c3e85bdcSAkhil Goyal /* caam result is put into this queue */ 203c3e85bdcSAkhil Goyal static int 204c3e85bdcSAkhil Goyal dpaa_sec_init_tx(struct qman_fq *fq) 205c3e85bdcSAkhil Goyal { 206c3e85bdcSAkhil Goyal int ret; 207c3e85bdcSAkhil Goyal struct qm_mcc_initfq opts; 208c3e85bdcSAkhil Goyal uint32_t flags; 209c3e85bdcSAkhil Goyal 210c3e85bdcSAkhil Goyal flags = QMAN_FQ_FLAG_NO_ENQUEUE | QMAN_FQ_FLAG_LOCKED | 211c3e85bdcSAkhil Goyal QMAN_FQ_FLAG_DYNAMIC_FQID; 212c3e85bdcSAkhil Goyal 213c3e85bdcSAkhil Goyal ret = qman_create_fq(0, flags, fq); 214c3e85bdcSAkhil Goyal if (unlikely(ret)) { 215c3e85bdcSAkhil Goyal PMD_INIT_LOG(ERR, "qman_create_fq failed"); 216c3e85bdcSAkhil Goyal return ret; 217c3e85bdcSAkhil Goyal } 218c3e85bdcSAkhil Goyal 219c3e85bdcSAkhil Goyal memset(&opts, 0, sizeof(opts)); 220c3e85bdcSAkhil Goyal opts.we_mask = QM_INITFQ_WE_DESTWQ | QM_INITFQ_WE_FQCTRL | 221c3e85bdcSAkhil Goyal QM_INITFQ_WE_CONTEXTA | QM_INITFQ_WE_CONTEXTB; 222c3e85bdcSAkhil Goyal 223c3e85bdcSAkhil Goyal /* opts.fqd.dest.channel = dpaa_sec_pool_chan; */ 224c3e85bdcSAkhil Goyal 225c3e85bdcSAkhil Goyal fq->cb.dqrr = dqrr_out_fq_cb_rx; 226c3e85bdcSAkhil Goyal fq->cb.ern = ern_sec_fq_handler; 227c3e85bdcSAkhil Goyal 228c3e85bdcSAkhil Goyal ret = qman_init_fq(fq, 0, &opts); 229c3e85bdcSAkhil Goyal if (unlikely(ret)) { 230c3e85bdcSAkhil Goyal PMD_INIT_LOG(ERR, "unable to init caam source fq!"); 231c3e85bdcSAkhil Goyal return ret; 232c3e85bdcSAkhil Goyal } 233c3e85bdcSAkhil Goyal 234c3e85bdcSAkhil Goyal return ret; 235c3e85bdcSAkhil Goyal } 236c3e85bdcSAkhil Goyal 237c3e85bdcSAkhil Goyal static inline int is_cipher_only(dpaa_sec_session *ses) 238c3e85bdcSAkhil Goyal { 239c3e85bdcSAkhil Goyal return ((ses->cipher_alg != RTE_CRYPTO_CIPHER_NULL) && 240c3e85bdcSAkhil Goyal (ses->auth_alg == RTE_CRYPTO_AUTH_NULL)); 241c3e85bdcSAkhil Goyal } 242c3e85bdcSAkhil Goyal 243c3e85bdcSAkhil Goyal static inline int is_auth_only(dpaa_sec_session *ses) 244c3e85bdcSAkhil Goyal { 245c3e85bdcSAkhil Goyal return ((ses->cipher_alg == RTE_CRYPTO_CIPHER_NULL) && 246c3e85bdcSAkhil Goyal (ses->auth_alg != RTE_CRYPTO_AUTH_NULL)); 247c3e85bdcSAkhil Goyal } 248c3e85bdcSAkhil Goyal 249c3e85bdcSAkhil Goyal static inline int is_aead(dpaa_sec_session *ses) 250c3e85bdcSAkhil Goyal { 251c3e85bdcSAkhil Goyal return ((ses->cipher_alg == 0) && 252c3e85bdcSAkhil Goyal (ses->auth_alg == 0) && 253c3e85bdcSAkhil Goyal (ses->aead_alg != 0)); 254c3e85bdcSAkhil Goyal } 255c3e85bdcSAkhil Goyal 256c3e85bdcSAkhil Goyal static inline int is_auth_cipher(dpaa_sec_session *ses) 257c3e85bdcSAkhil Goyal { 258c3e85bdcSAkhil Goyal return ((ses->cipher_alg != RTE_CRYPTO_CIPHER_NULL) && 259c3e85bdcSAkhil Goyal (ses->auth_alg != RTE_CRYPTO_AUTH_NULL)); 260c3e85bdcSAkhil Goyal } 261c3e85bdcSAkhil Goyal 262c3e85bdcSAkhil Goyal static inline int is_encode(dpaa_sec_session *ses) 263c3e85bdcSAkhil Goyal { 264c3e85bdcSAkhil Goyal return ses->dir == DIR_ENC; 265c3e85bdcSAkhil Goyal } 266c3e85bdcSAkhil Goyal 267c3e85bdcSAkhil Goyal static inline int is_decode(dpaa_sec_session *ses) 268c3e85bdcSAkhil Goyal { 269c3e85bdcSAkhil Goyal return ses->dir == DIR_DEC; 270c3e85bdcSAkhil Goyal } 271c3e85bdcSAkhil Goyal 272c3e85bdcSAkhil Goyal static inline void 273c3e85bdcSAkhil Goyal caam_auth_alg(dpaa_sec_session *ses, struct alginfo *alginfo_a) 274c3e85bdcSAkhil Goyal { 275c3e85bdcSAkhil Goyal switch (ses->auth_alg) { 276c3e85bdcSAkhil Goyal case RTE_CRYPTO_AUTH_NULL: 277c3e85bdcSAkhil Goyal ses->digest_length = 0; 278c3e85bdcSAkhil Goyal break; 279c3e85bdcSAkhil Goyal case RTE_CRYPTO_AUTH_MD5_HMAC: 280c3e85bdcSAkhil Goyal alginfo_a->algtype = OP_ALG_ALGSEL_MD5; 281c3e85bdcSAkhil Goyal alginfo_a->algmode = OP_ALG_AAI_HMAC; 282c3e85bdcSAkhil Goyal break; 283c3e85bdcSAkhil Goyal case RTE_CRYPTO_AUTH_SHA1_HMAC: 284c3e85bdcSAkhil Goyal alginfo_a->algtype = OP_ALG_ALGSEL_SHA1; 285c3e85bdcSAkhil Goyal alginfo_a->algmode = OP_ALG_AAI_HMAC; 286c3e85bdcSAkhil Goyal break; 287c3e85bdcSAkhil Goyal case RTE_CRYPTO_AUTH_SHA224_HMAC: 288c3e85bdcSAkhil Goyal alginfo_a->algtype = OP_ALG_ALGSEL_SHA224; 289c3e85bdcSAkhil Goyal alginfo_a->algmode = OP_ALG_AAI_HMAC; 290c3e85bdcSAkhil Goyal break; 291c3e85bdcSAkhil Goyal case RTE_CRYPTO_AUTH_SHA256_HMAC: 292c3e85bdcSAkhil Goyal alginfo_a->algtype = OP_ALG_ALGSEL_SHA256; 293c3e85bdcSAkhil Goyal alginfo_a->algmode = OP_ALG_AAI_HMAC; 294c3e85bdcSAkhil Goyal break; 295c3e85bdcSAkhil Goyal case RTE_CRYPTO_AUTH_SHA384_HMAC: 296c3e85bdcSAkhil Goyal alginfo_a->algtype = OP_ALG_ALGSEL_SHA384; 297c3e85bdcSAkhil Goyal alginfo_a->algmode = OP_ALG_AAI_HMAC; 298c3e85bdcSAkhil Goyal break; 299c3e85bdcSAkhil Goyal case RTE_CRYPTO_AUTH_SHA512_HMAC: 300c3e85bdcSAkhil Goyal alginfo_a->algtype = OP_ALG_ALGSEL_SHA512; 301c3e85bdcSAkhil Goyal alginfo_a->algmode = OP_ALG_AAI_HMAC; 302c3e85bdcSAkhil Goyal break; 303c3e85bdcSAkhil Goyal default: 304c3e85bdcSAkhil Goyal PMD_INIT_LOG(ERR, "unsupported auth alg %u", ses->auth_alg); 305c3e85bdcSAkhil Goyal } 306c3e85bdcSAkhil Goyal } 307c3e85bdcSAkhil Goyal 308c3e85bdcSAkhil Goyal static inline void 309c3e85bdcSAkhil Goyal caam_cipher_alg(dpaa_sec_session *ses, struct alginfo *alginfo_c) 310c3e85bdcSAkhil Goyal { 311c3e85bdcSAkhil Goyal switch (ses->cipher_alg) { 312c3e85bdcSAkhil Goyal case RTE_CRYPTO_CIPHER_NULL: 313c3e85bdcSAkhil Goyal break; 314c3e85bdcSAkhil Goyal case RTE_CRYPTO_CIPHER_AES_CBC: 315c3e85bdcSAkhil Goyal alginfo_c->algtype = OP_ALG_ALGSEL_AES; 316c3e85bdcSAkhil Goyal alginfo_c->algmode = OP_ALG_AAI_CBC; 317c3e85bdcSAkhil Goyal break; 318c3e85bdcSAkhil Goyal case RTE_CRYPTO_CIPHER_3DES_CBC: 319c3e85bdcSAkhil Goyal alginfo_c->algtype = OP_ALG_ALGSEL_3DES; 320c3e85bdcSAkhil Goyal alginfo_c->algmode = OP_ALG_AAI_CBC; 321c3e85bdcSAkhil Goyal break; 322c3e85bdcSAkhil Goyal case RTE_CRYPTO_CIPHER_AES_CTR: 323c3e85bdcSAkhil Goyal alginfo_c->algtype = OP_ALG_ALGSEL_AES; 324c3e85bdcSAkhil Goyal alginfo_c->algmode = OP_ALG_AAI_CTR; 325c3e85bdcSAkhil Goyal break; 326c3e85bdcSAkhil Goyal default: 327c3e85bdcSAkhil Goyal PMD_INIT_LOG(ERR, "unsupported cipher alg %d", ses->cipher_alg); 328c3e85bdcSAkhil Goyal } 329c3e85bdcSAkhil Goyal } 330c3e85bdcSAkhil Goyal 331c3e85bdcSAkhil Goyal static inline void 332c3e85bdcSAkhil Goyal caam_aead_alg(dpaa_sec_session *ses, struct alginfo *alginfo) 333c3e85bdcSAkhil Goyal { 334c3e85bdcSAkhil Goyal switch (ses->aead_alg) { 335c3e85bdcSAkhil Goyal case RTE_CRYPTO_AEAD_AES_GCM: 336c3e85bdcSAkhil Goyal alginfo->algtype = OP_ALG_ALGSEL_AES; 337c3e85bdcSAkhil Goyal alginfo->algmode = OP_ALG_AAI_GCM; 338c3e85bdcSAkhil Goyal break; 339c3e85bdcSAkhil Goyal default: 340c3e85bdcSAkhil Goyal PMD_INIT_LOG(ERR, "unsupported AEAD alg %d", ses->aead_alg); 341c3e85bdcSAkhil Goyal } 342c3e85bdcSAkhil Goyal } 343c3e85bdcSAkhil Goyal 344c3e85bdcSAkhil Goyal 345c3e85bdcSAkhil Goyal /* prepare command block of the session */ 346c3e85bdcSAkhil Goyal static int 347c3e85bdcSAkhil Goyal dpaa_sec_prep_cdb(dpaa_sec_session *ses) 348c3e85bdcSAkhil Goyal { 349c3e85bdcSAkhil Goyal struct alginfo alginfo_c = {0}, alginfo_a = {0}, alginfo = {0}; 350c3e85bdcSAkhil Goyal uint32_t shared_desc_len = 0; 351c3e85bdcSAkhil Goyal struct sec_cdb *cdb = &ses->qp->cdb; 352c3e85bdcSAkhil Goyal int err; 353c3e85bdcSAkhil Goyal #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN 354c3e85bdcSAkhil Goyal int swap = false; 355c3e85bdcSAkhil Goyal #else 356c3e85bdcSAkhil Goyal int swap = true; 357c3e85bdcSAkhil Goyal #endif 358c3e85bdcSAkhil Goyal 359c3e85bdcSAkhil Goyal memset(cdb, 0, sizeof(struct sec_cdb)); 360c3e85bdcSAkhil Goyal 361c3e85bdcSAkhil Goyal if (is_cipher_only(ses)) { 362c3e85bdcSAkhil Goyal caam_cipher_alg(ses, &alginfo_c); 363c3e85bdcSAkhil Goyal if (alginfo_c.algtype == (unsigned int)DPAA_SEC_ALG_UNSUPPORT) { 364c3e85bdcSAkhil Goyal PMD_TX_LOG(ERR, "not supported cipher alg\n"); 365c3e85bdcSAkhil Goyal return -ENOTSUP; 366c3e85bdcSAkhil Goyal } 367c3e85bdcSAkhil Goyal 368c3e85bdcSAkhil Goyal alginfo_c.key = (uint64_t)ses->cipher_key.data; 369c3e85bdcSAkhil Goyal alginfo_c.keylen = ses->cipher_key.length; 370c3e85bdcSAkhil Goyal alginfo_c.key_enc_flags = 0; 371c3e85bdcSAkhil Goyal alginfo_c.key_type = RTA_DATA_IMM; 372c3e85bdcSAkhil Goyal 373c3e85bdcSAkhil Goyal shared_desc_len = cnstr_shdsc_blkcipher( 374c3e85bdcSAkhil Goyal cdb->sh_desc, true, 375c3e85bdcSAkhil Goyal swap, &alginfo_c, 376c3e85bdcSAkhil Goyal NULL, 377c3e85bdcSAkhil Goyal ses->iv.length, 378c3e85bdcSAkhil Goyal ses->dir); 379c3e85bdcSAkhil Goyal } else if (is_auth_only(ses)) { 380c3e85bdcSAkhil Goyal caam_auth_alg(ses, &alginfo_a); 381c3e85bdcSAkhil Goyal if (alginfo_a.algtype == (unsigned int)DPAA_SEC_ALG_UNSUPPORT) { 382c3e85bdcSAkhil Goyal PMD_TX_LOG(ERR, "not supported auth alg\n"); 383c3e85bdcSAkhil Goyal return -ENOTSUP; 384c3e85bdcSAkhil Goyal } 385c3e85bdcSAkhil Goyal 386c3e85bdcSAkhil Goyal alginfo_a.key = (uint64_t)ses->auth_key.data; 387c3e85bdcSAkhil Goyal alginfo_a.keylen = ses->auth_key.length; 388c3e85bdcSAkhil Goyal alginfo_a.key_enc_flags = 0; 389c3e85bdcSAkhil Goyal alginfo_a.key_type = RTA_DATA_IMM; 390c3e85bdcSAkhil Goyal 391c3e85bdcSAkhil Goyal shared_desc_len = cnstr_shdsc_hmac(cdb->sh_desc, true, 392c3e85bdcSAkhil Goyal swap, &alginfo_a, 393c3e85bdcSAkhil Goyal !ses->dir, 394c3e85bdcSAkhil Goyal ses->digest_length); 395c3e85bdcSAkhil Goyal } else if (is_aead(ses)) { 396c3e85bdcSAkhil Goyal caam_aead_alg(ses, &alginfo); 397c3e85bdcSAkhil Goyal if (alginfo.algtype == (unsigned int)DPAA_SEC_ALG_UNSUPPORT) { 398c3e85bdcSAkhil Goyal PMD_TX_LOG(ERR, "not supported aead alg\n"); 399c3e85bdcSAkhil Goyal return -ENOTSUP; 400c3e85bdcSAkhil Goyal } 401c3e85bdcSAkhil Goyal alginfo.key = (uint64_t)ses->aead_key.data; 402c3e85bdcSAkhil Goyal alginfo.keylen = ses->aead_key.length; 403c3e85bdcSAkhil Goyal alginfo.key_enc_flags = 0; 404c3e85bdcSAkhil Goyal alginfo.key_type = RTA_DATA_IMM; 405c3e85bdcSAkhil Goyal 406c3e85bdcSAkhil Goyal if (ses->dir == DIR_ENC) 407c3e85bdcSAkhil Goyal shared_desc_len = cnstr_shdsc_gcm_encap( 408c3e85bdcSAkhil Goyal cdb->sh_desc, true, swap, 409c3e85bdcSAkhil Goyal &alginfo, 410c3e85bdcSAkhil Goyal ses->iv.length, 411c3e85bdcSAkhil Goyal ses->digest_length); 412c3e85bdcSAkhil Goyal else 413c3e85bdcSAkhil Goyal shared_desc_len = cnstr_shdsc_gcm_decap( 414c3e85bdcSAkhil Goyal cdb->sh_desc, true, swap, 415c3e85bdcSAkhil Goyal &alginfo, 416c3e85bdcSAkhil Goyal ses->iv.length, 417c3e85bdcSAkhil Goyal ses->digest_length); 418c3e85bdcSAkhil Goyal } else { 419c3e85bdcSAkhil Goyal caam_cipher_alg(ses, &alginfo_c); 420c3e85bdcSAkhil Goyal if (alginfo_c.algtype == (unsigned int)DPAA_SEC_ALG_UNSUPPORT) { 421c3e85bdcSAkhil Goyal PMD_TX_LOG(ERR, "not supported cipher alg\n"); 422c3e85bdcSAkhil Goyal return -ENOTSUP; 423c3e85bdcSAkhil Goyal } 424c3e85bdcSAkhil Goyal 425c3e85bdcSAkhil Goyal alginfo_c.key = (uint64_t)ses->cipher_key.data; 426c3e85bdcSAkhil Goyal alginfo_c.keylen = ses->cipher_key.length; 427c3e85bdcSAkhil Goyal alginfo_c.key_enc_flags = 0; 428c3e85bdcSAkhil Goyal alginfo_c.key_type = RTA_DATA_IMM; 429c3e85bdcSAkhil Goyal 430c3e85bdcSAkhil Goyal caam_auth_alg(ses, &alginfo_a); 431c3e85bdcSAkhil Goyal if (alginfo_a.algtype == (unsigned int)DPAA_SEC_ALG_UNSUPPORT) { 432c3e85bdcSAkhil Goyal PMD_TX_LOG(ERR, "not supported auth alg\n"); 433c3e85bdcSAkhil Goyal return -ENOTSUP; 434c3e85bdcSAkhil Goyal } 435c3e85bdcSAkhil Goyal 436c3e85bdcSAkhil Goyal alginfo_a.key = (uint64_t)ses->auth_key.data; 437c3e85bdcSAkhil Goyal alginfo_a.keylen = ses->auth_key.length; 438c3e85bdcSAkhil Goyal alginfo_a.key_enc_flags = 0; 439c3e85bdcSAkhil Goyal alginfo_a.key_type = RTA_DATA_IMM; 440c3e85bdcSAkhil Goyal 441c3e85bdcSAkhil Goyal cdb->sh_desc[0] = alginfo_c.keylen; 442c3e85bdcSAkhil Goyal cdb->sh_desc[1] = alginfo_a.keylen; 443c3e85bdcSAkhil Goyal err = rta_inline_query(IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN, 444c3e85bdcSAkhil Goyal MIN_JOB_DESC_SIZE, 445c3e85bdcSAkhil Goyal (unsigned int *)cdb->sh_desc, 446c3e85bdcSAkhil Goyal &cdb->sh_desc[2], 2); 447c3e85bdcSAkhil Goyal 448c3e85bdcSAkhil Goyal if (err < 0) { 449c3e85bdcSAkhil Goyal PMD_TX_LOG(ERR, "Crypto: Incorrect key lengths"); 450c3e85bdcSAkhil Goyal return err; 451c3e85bdcSAkhil Goyal } 452c3e85bdcSAkhil Goyal if (cdb->sh_desc[2] & 1) 453c3e85bdcSAkhil Goyal alginfo_c.key_type = RTA_DATA_IMM; 454c3e85bdcSAkhil Goyal else { 455c3e85bdcSAkhil Goyal alginfo_c.key = (uint64_t)dpaa_mem_vtop( 456c3e85bdcSAkhil Goyal (void *)alginfo_c.key); 457c3e85bdcSAkhil Goyal alginfo_c.key_type = RTA_DATA_PTR; 458c3e85bdcSAkhil Goyal } 459c3e85bdcSAkhil Goyal if (cdb->sh_desc[2] & (1<<1)) 460c3e85bdcSAkhil Goyal alginfo_a.key_type = RTA_DATA_IMM; 461c3e85bdcSAkhil Goyal else { 462c3e85bdcSAkhil Goyal alginfo_a.key = (uint64_t)dpaa_mem_vtop( 463c3e85bdcSAkhil Goyal (void *)alginfo_a.key); 464c3e85bdcSAkhil Goyal alginfo_a.key_type = RTA_DATA_PTR; 465c3e85bdcSAkhil Goyal } 466c3e85bdcSAkhil Goyal cdb->sh_desc[0] = 0; 467c3e85bdcSAkhil Goyal cdb->sh_desc[1] = 0; 468c3e85bdcSAkhil Goyal cdb->sh_desc[2] = 0; 469c3e85bdcSAkhil Goyal 470c3e85bdcSAkhil Goyal /* Auth_only_len is set as 0 here and it will be overwritten 471c3e85bdcSAkhil Goyal * in fd for each packet. 472c3e85bdcSAkhil Goyal */ 473c3e85bdcSAkhil Goyal shared_desc_len = cnstr_shdsc_authenc(cdb->sh_desc, 474c3e85bdcSAkhil Goyal true, swap, &alginfo_c, &alginfo_a, 475c3e85bdcSAkhil Goyal ses->iv.length, 0, 476c3e85bdcSAkhil Goyal ses->digest_length, ses->dir); 477c3e85bdcSAkhil Goyal } 478c3e85bdcSAkhil Goyal cdb->sh_hdr.hi.field.idlen = shared_desc_len; 479c3e85bdcSAkhil Goyal cdb->sh_hdr.hi.word = rte_cpu_to_be_32(cdb->sh_hdr.hi.word); 480c3e85bdcSAkhil Goyal cdb->sh_hdr.lo.word = rte_cpu_to_be_32(cdb->sh_hdr.lo.word); 481c3e85bdcSAkhil Goyal 482c3e85bdcSAkhil Goyal return 0; 483c3e85bdcSAkhil Goyal } 484c3e85bdcSAkhil Goyal 485c3e85bdcSAkhil Goyal static inline unsigned int 486c3e85bdcSAkhil Goyal dpaa_volatile_deq(struct qman_fq *fq, unsigned int len, bool exact) 487c3e85bdcSAkhil Goyal { 488c3e85bdcSAkhil Goyal unsigned int pkts = 0; 489c3e85bdcSAkhil Goyal int ret; 490c3e85bdcSAkhil Goyal struct qm_mcr_queryfq_np np; 491c3e85bdcSAkhil Goyal enum qman_fq_state state; 492c3e85bdcSAkhil Goyal uint32_t flags; 493c3e85bdcSAkhil Goyal uint32_t vdqcr; 494c3e85bdcSAkhil Goyal 495c3e85bdcSAkhil Goyal qman_query_fq_np(fq, &np); 496c3e85bdcSAkhil Goyal if (np.frm_cnt) { 497c3e85bdcSAkhil Goyal vdqcr = QM_VDQCR_NUMFRAMES_SET(len); 498c3e85bdcSAkhil Goyal if (exact) 499c3e85bdcSAkhil Goyal vdqcr |= QM_VDQCR_EXACT; 500c3e85bdcSAkhil Goyal ret = qman_volatile_dequeue(fq, 0, vdqcr); 501c3e85bdcSAkhil Goyal if (ret) 502c3e85bdcSAkhil Goyal return 0; 503c3e85bdcSAkhil Goyal do { 504c3e85bdcSAkhil Goyal pkts += qman_poll_dqrr(len); 505c3e85bdcSAkhil Goyal qman_fq_state(fq, &state, &flags); 506c3e85bdcSAkhil Goyal } while (flags & QMAN_FQ_STATE_VDQCR); 507c3e85bdcSAkhil Goyal } 508c3e85bdcSAkhil Goyal return pkts; 509c3e85bdcSAkhil Goyal } 510c3e85bdcSAkhil Goyal 511c3e85bdcSAkhil Goyal /* qp is lockless, should be accessed by only one thread */ 512c3e85bdcSAkhil Goyal static int 513c3e85bdcSAkhil Goyal dpaa_sec_deq(struct dpaa_sec_qp *qp, struct rte_crypto_op **ops, int nb_ops) 514c3e85bdcSAkhil Goyal { 515c3e85bdcSAkhil Goyal struct qman_fq *fq; 516c3e85bdcSAkhil Goyal 517c3e85bdcSAkhil Goyal fq = &qp->outq; 518c3e85bdcSAkhil Goyal dpaa_sec_op_nb = 0; 519c3e85bdcSAkhil Goyal dpaa_sec_ops = ops; 520c3e85bdcSAkhil Goyal 521c3e85bdcSAkhil Goyal if (unlikely(nb_ops > DPAA_SEC_BURST)) 522c3e85bdcSAkhil Goyal nb_ops = DPAA_SEC_BURST; 523c3e85bdcSAkhil Goyal 524c3e85bdcSAkhil Goyal return dpaa_volatile_deq(fq, nb_ops, 1); 525c3e85bdcSAkhil Goyal } 526c3e85bdcSAkhil Goyal 527c3e85bdcSAkhil Goyal /** 528c3e85bdcSAkhil Goyal * packet looks like: 529c3e85bdcSAkhil Goyal * |<----data_len------->| 530c3e85bdcSAkhil Goyal * |ip_header|ah_header|icv|payload| 531c3e85bdcSAkhil Goyal * ^ 532c3e85bdcSAkhil Goyal * | 533c3e85bdcSAkhil Goyal * mbuf->pkt.data 534c3e85bdcSAkhil Goyal */ 535c3e85bdcSAkhil Goyal static inline struct dpaa_sec_job * 536c3e85bdcSAkhil Goyal build_auth_only(struct rte_crypto_op *op, dpaa_sec_session *ses) 537c3e85bdcSAkhil Goyal { 538c3e85bdcSAkhil Goyal struct rte_crypto_sym_op *sym = op->sym; 539c3e85bdcSAkhil Goyal struct rte_mbuf *mbuf = sym->m_src; 540c3e85bdcSAkhil Goyal struct dpaa_sec_job *cf; 541c3e85bdcSAkhil Goyal struct dpaa_sec_op_ctx *ctx; 542c3e85bdcSAkhil Goyal struct qm_sg_entry *sg; 543c4509373SSantosh Shukla rte_iova_t start_addr; 544c3e85bdcSAkhil Goyal uint8_t *old_digest; 545c3e85bdcSAkhil Goyal 546c3e85bdcSAkhil Goyal ctx = dpaa_sec_alloc_ctx(ses); 547c3e85bdcSAkhil Goyal if (!ctx) 548c3e85bdcSAkhil Goyal return NULL; 549c3e85bdcSAkhil Goyal 550c3e85bdcSAkhil Goyal cf = &ctx->job; 551c3e85bdcSAkhil Goyal ctx->op = op; 552c3e85bdcSAkhil Goyal old_digest = ctx->digest; 553c3e85bdcSAkhil Goyal 554bfa9a8a4SThomas Monjalon start_addr = rte_pktmbuf_iova(mbuf); 555c3e85bdcSAkhil Goyal /* output */ 556c3e85bdcSAkhil Goyal sg = &cf->sg[0]; 557c3e85bdcSAkhil Goyal qm_sg_entry_set64(sg, sym->auth.digest.phys_addr); 558c3e85bdcSAkhil Goyal sg->length = ses->digest_length; 559c3e85bdcSAkhil Goyal cpu_to_hw_sg(sg); 560c3e85bdcSAkhil Goyal 561c3e85bdcSAkhil Goyal /* input */ 562c3e85bdcSAkhil Goyal sg = &cf->sg[1]; 563c3e85bdcSAkhil Goyal if (is_decode(ses)) { 564c3e85bdcSAkhil Goyal /* need to extend the input to a compound frame */ 565c3e85bdcSAkhil Goyal sg->extension = 1; 566c3e85bdcSAkhil Goyal qm_sg_entry_set64(sg, dpaa_mem_vtop(&cf->sg[2])); 567c3e85bdcSAkhil Goyal sg->length = sym->auth.data.length + ses->digest_length; 568c3e85bdcSAkhil Goyal sg->final = 1; 569c3e85bdcSAkhil Goyal cpu_to_hw_sg(sg); 570c3e85bdcSAkhil Goyal 571c3e85bdcSAkhil Goyal sg = &cf->sg[2]; 572c3e85bdcSAkhil Goyal /* hash result or digest, save digest first */ 573c3e85bdcSAkhil Goyal rte_memcpy(old_digest, sym->auth.digest.data, 574c3e85bdcSAkhil Goyal ses->digest_length); 575c3e85bdcSAkhil Goyal qm_sg_entry_set64(sg, start_addr + sym->auth.data.offset); 576c3e85bdcSAkhil Goyal sg->length = sym->auth.data.length; 577c3e85bdcSAkhil Goyal cpu_to_hw_sg(sg); 578c3e85bdcSAkhil Goyal 579c3e85bdcSAkhil Goyal /* let's check digest by hw */ 580c3e85bdcSAkhil Goyal start_addr = dpaa_mem_vtop(old_digest); 581c3e85bdcSAkhil Goyal sg++; 582c3e85bdcSAkhil Goyal qm_sg_entry_set64(sg, start_addr); 583c3e85bdcSAkhil Goyal sg->length = ses->digest_length; 584c3e85bdcSAkhil Goyal sg->final = 1; 585c3e85bdcSAkhil Goyal cpu_to_hw_sg(sg); 586c3e85bdcSAkhil Goyal } else { 587c3e85bdcSAkhil Goyal qm_sg_entry_set64(sg, start_addr + sym->auth.data.offset); 588c3e85bdcSAkhil Goyal sg->length = sym->auth.data.length; 589c3e85bdcSAkhil Goyal sg->final = 1; 590c3e85bdcSAkhil Goyal cpu_to_hw_sg(sg); 591c3e85bdcSAkhil Goyal } 592c3e85bdcSAkhil Goyal 593c3e85bdcSAkhil Goyal return cf; 594c3e85bdcSAkhil Goyal } 595c3e85bdcSAkhil Goyal 596c3e85bdcSAkhil Goyal static inline struct dpaa_sec_job * 597c3e85bdcSAkhil Goyal build_cipher_only(struct rte_crypto_op *op, dpaa_sec_session *ses) 598c3e85bdcSAkhil Goyal { 599c3e85bdcSAkhil Goyal struct rte_crypto_sym_op *sym = op->sym; 600c3e85bdcSAkhil Goyal struct dpaa_sec_job *cf; 601c3e85bdcSAkhil Goyal struct dpaa_sec_op_ctx *ctx; 602c3e85bdcSAkhil Goyal struct qm_sg_entry *sg; 603c4509373SSantosh Shukla rte_iova_t src_start_addr, dst_start_addr; 604c3e85bdcSAkhil Goyal uint8_t *IV_ptr = rte_crypto_op_ctod_offset(op, uint8_t *, 605c3e85bdcSAkhil Goyal ses->iv.offset); 606c3e85bdcSAkhil Goyal 607c3e85bdcSAkhil Goyal ctx = dpaa_sec_alloc_ctx(ses); 608c3e85bdcSAkhil Goyal if (!ctx) 609c3e85bdcSAkhil Goyal return NULL; 610c3e85bdcSAkhil Goyal 611c3e85bdcSAkhil Goyal cf = &ctx->job; 612c3e85bdcSAkhil Goyal ctx->op = op; 613a389434eSAlok Makhariya 614bfa9a8a4SThomas Monjalon src_start_addr = rte_pktmbuf_iova(sym->m_src); 615a389434eSAlok Makhariya 616a389434eSAlok Makhariya if (sym->m_dst) 617bfa9a8a4SThomas Monjalon dst_start_addr = rte_pktmbuf_iova(sym->m_dst); 618a389434eSAlok Makhariya else 619a389434eSAlok Makhariya dst_start_addr = src_start_addr; 620c3e85bdcSAkhil Goyal 621c3e85bdcSAkhil Goyal /* output */ 622c3e85bdcSAkhil Goyal sg = &cf->sg[0]; 623a389434eSAlok Makhariya qm_sg_entry_set64(sg, dst_start_addr + sym->cipher.data.offset); 624c3e85bdcSAkhil Goyal sg->length = sym->cipher.data.length + ses->iv.length; 625c3e85bdcSAkhil Goyal cpu_to_hw_sg(sg); 626c3e85bdcSAkhil Goyal 627c3e85bdcSAkhil Goyal /* input */ 628c3e85bdcSAkhil Goyal sg = &cf->sg[1]; 629c3e85bdcSAkhil Goyal 630c3e85bdcSAkhil Goyal /* need to extend the input to a compound frame */ 631c3e85bdcSAkhil Goyal sg->extension = 1; 632c3e85bdcSAkhil Goyal sg->final = 1; 633c3e85bdcSAkhil Goyal sg->length = sym->cipher.data.length + ses->iv.length; 634c3e85bdcSAkhil Goyal qm_sg_entry_set64(sg, dpaa_mem_vtop(&cf->sg[2])); 635c3e85bdcSAkhil Goyal cpu_to_hw_sg(sg); 636c3e85bdcSAkhil Goyal 637c3e85bdcSAkhil Goyal sg = &cf->sg[2]; 638c3e85bdcSAkhil Goyal qm_sg_entry_set64(sg, dpaa_mem_vtop(IV_ptr)); 639c3e85bdcSAkhil Goyal sg->length = ses->iv.length; 640c3e85bdcSAkhil Goyal cpu_to_hw_sg(sg); 641c3e85bdcSAkhil Goyal 642c3e85bdcSAkhil Goyal sg++; 643a389434eSAlok Makhariya qm_sg_entry_set64(sg, src_start_addr + sym->cipher.data.offset); 644c3e85bdcSAkhil Goyal sg->length = sym->cipher.data.length; 645c3e85bdcSAkhil Goyal sg->final = 1; 646c3e85bdcSAkhil Goyal cpu_to_hw_sg(sg); 647c3e85bdcSAkhil Goyal 648c3e85bdcSAkhil Goyal return cf; 649c3e85bdcSAkhil Goyal } 650c3e85bdcSAkhil Goyal 651c3e85bdcSAkhil Goyal static inline struct dpaa_sec_job * 652c3e85bdcSAkhil Goyal build_cipher_auth_gcm(struct rte_crypto_op *op, dpaa_sec_session *ses) 653c3e85bdcSAkhil Goyal { 654c3e85bdcSAkhil Goyal struct rte_crypto_sym_op *sym = op->sym; 655c3e85bdcSAkhil Goyal struct dpaa_sec_job *cf; 656c3e85bdcSAkhil Goyal struct dpaa_sec_op_ctx *ctx; 657c3e85bdcSAkhil Goyal struct qm_sg_entry *sg; 658c3e85bdcSAkhil Goyal uint32_t length = 0; 659c4509373SSantosh Shukla rte_iova_t src_start_addr, dst_start_addr; 660c3e85bdcSAkhil Goyal uint8_t *IV_ptr = rte_crypto_op_ctod_offset(op, uint8_t *, 661c3e85bdcSAkhil Goyal ses->iv.offset); 662c3e85bdcSAkhil Goyal 663116ff44aSHemant Agrawal src_start_addr = sym->m_src->buf_iova + sym->m_src->data_off; 664a389434eSAlok Makhariya 665a389434eSAlok Makhariya if (sym->m_dst) 666116ff44aSHemant Agrawal dst_start_addr = sym->m_dst->buf_iova + sym->m_dst->data_off; 667a389434eSAlok Makhariya else 668a389434eSAlok Makhariya dst_start_addr = src_start_addr; 669c3e85bdcSAkhil Goyal 670c3e85bdcSAkhil Goyal ctx = dpaa_sec_alloc_ctx(ses); 671c3e85bdcSAkhil Goyal if (!ctx) 672c3e85bdcSAkhil Goyal return NULL; 673c3e85bdcSAkhil Goyal 674c3e85bdcSAkhil Goyal cf = &ctx->job; 675c3e85bdcSAkhil Goyal ctx->op = op; 676c3e85bdcSAkhil Goyal 677c3e85bdcSAkhil Goyal /* input */ 678c3e85bdcSAkhil Goyal rte_prefetch0(cf->sg); 679c3e85bdcSAkhil Goyal sg = &cf->sg[2]; 680c3e85bdcSAkhil Goyal qm_sg_entry_set64(&cf->sg[1], dpaa_mem_vtop(sg)); 681c3e85bdcSAkhil Goyal if (is_encode(ses)) { 682c3e85bdcSAkhil Goyal qm_sg_entry_set64(sg, dpaa_mem_vtop(IV_ptr)); 683c3e85bdcSAkhil Goyal sg->length = ses->iv.length; 684c3e85bdcSAkhil Goyal length += sg->length; 685c3e85bdcSAkhil Goyal cpu_to_hw_sg(sg); 686c3e85bdcSAkhil Goyal 687c3e85bdcSAkhil Goyal sg++; 688c3e85bdcSAkhil Goyal if (ses->auth_only_len) { 689c3e85bdcSAkhil Goyal qm_sg_entry_set64(sg, 690c3e85bdcSAkhil Goyal dpaa_mem_vtop(sym->aead.aad.data)); 691c3e85bdcSAkhil Goyal sg->length = ses->auth_only_len; 692c3e85bdcSAkhil Goyal length += sg->length; 693c3e85bdcSAkhil Goyal cpu_to_hw_sg(sg); 694c3e85bdcSAkhil Goyal sg++; 695c3e85bdcSAkhil Goyal } 696a389434eSAlok Makhariya qm_sg_entry_set64(sg, src_start_addr + sym->aead.data.offset); 697c3e85bdcSAkhil Goyal sg->length = sym->aead.data.length; 698c3e85bdcSAkhil Goyal length += sg->length; 699c3e85bdcSAkhil Goyal sg->final = 1; 700c3e85bdcSAkhil Goyal cpu_to_hw_sg(sg); 701c3e85bdcSAkhil Goyal } else { 702c3e85bdcSAkhil Goyal qm_sg_entry_set64(sg, dpaa_mem_vtop(IV_ptr)); 703c3e85bdcSAkhil Goyal sg->length = ses->iv.length; 704c3e85bdcSAkhil Goyal length += sg->length; 705c3e85bdcSAkhil Goyal cpu_to_hw_sg(sg); 706c3e85bdcSAkhil Goyal 707c3e85bdcSAkhil Goyal sg++; 708c3e85bdcSAkhil Goyal if (ses->auth_only_len) { 709c3e85bdcSAkhil Goyal qm_sg_entry_set64(sg, 710c3e85bdcSAkhil Goyal dpaa_mem_vtop(sym->aead.aad.data)); 711c3e85bdcSAkhil Goyal sg->length = ses->auth_only_len; 712c3e85bdcSAkhil Goyal length += sg->length; 713c3e85bdcSAkhil Goyal cpu_to_hw_sg(sg); 714c3e85bdcSAkhil Goyal sg++; 715c3e85bdcSAkhil Goyal } 716a389434eSAlok Makhariya qm_sg_entry_set64(sg, src_start_addr + sym->aead.data.offset); 717c3e85bdcSAkhil Goyal sg->length = sym->aead.data.length; 718c3e85bdcSAkhil Goyal length += sg->length; 719c3e85bdcSAkhil Goyal cpu_to_hw_sg(sg); 720c3e85bdcSAkhil Goyal 721c3e85bdcSAkhil Goyal memcpy(ctx->digest, sym->aead.digest.data, 722c3e85bdcSAkhil Goyal ses->digest_length); 723c3e85bdcSAkhil Goyal sg++; 724c3e85bdcSAkhil Goyal 725c3e85bdcSAkhil Goyal qm_sg_entry_set64(sg, dpaa_mem_vtop(ctx->digest)); 726c3e85bdcSAkhil Goyal sg->length = ses->digest_length; 727c3e85bdcSAkhil Goyal length += sg->length; 728c3e85bdcSAkhil Goyal sg->final = 1; 729c3e85bdcSAkhil Goyal cpu_to_hw_sg(sg); 730c3e85bdcSAkhil Goyal } 731c3e85bdcSAkhil Goyal /* input compound frame */ 732c3e85bdcSAkhil Goyal cf->sg[1].length = length; 733c3e85bdcSAkhil Goyal cf->sg[1].extension = 1; 734c3e85bdcSAkhil Goyal cf->sg[1].final = 1; 735c3e85bdcSAkhil Goyal cpu_to_hw_sg(&cf->sg[1]); 736c3e85bdcSAkhil Goyal 737c3e85bdcSAkhil Goyal /* output */ 738c3e85bdcSAkhil Goyal sg++; 739c3e85bdcSAkhil Goyal qm_sg_entry_set64(&cf->sg[0], dpaa_mem_vtop(sg)); 740c3e85bdcSAkhil Goyal qm_sg_entry_set64(sg, 741a389434eSAlok Makhariya dst_start_addr + sym->aead.data.offset - ses->auth_only_len); 742c3e85bdcSAkhil Goyal sg->length = sym->aead.data.length + ses->auth_only_len; 743c3e85bdcSAkhil Goyal length = sg->length; 744c3e85bdcSAkhil Goyal if (is_encode(ses)) { 745c3e85bdcSAkhil Goyal cpu_to_hw_sg(sg); 746c3e85bdcSAkhil Goyal /* set auth output */ 747c3e85bdcSAkhil Goyal sg++; 748c3e85bdcSAkhil Goyal qm_sg_entry_set64(sg, sym->aead.digest.phys_addr); 749c3e85bdcSAkhil Goyal sg->length = ses->digest_length; 750c3e85bdcSAkhil Goyal length += sg->length; 751c3e85bdcSAkhil Goyal } 752c3e85bdcSAkhil Goyal sg->final = 1; 753c3e85bdcSAkhil Goyal cpu_to_hw_sg(sg); 754c3e85bdcSAkhil Goyal 755c3e85bdcSAkhil Goyal /* output compound frame */ 756c3e85bdcSAkhil Goyal cf->sg[0].length = length; 757c3e85bdcSAkhil Goyal cf->sg[0].extension = 1; 758c3e85bdcSAkhil Goyal cpu_to_hw_sg(&cf->sg[0]); 759c3e85bdcSAkhil Goyal 760c3e85bdcSAkhil Goyal return cf; 761c3e85bdcSAkhil Goyal } 762c3e85bdcSAkhil Goyal 763c3e85bdcSAkhil Goyal static inline struct dpaa_sec_job * 764c3e85bdcSAkhil Goyal build_cipher_auth(struct rte_crypto_op *op, dpaa_sec_session *ses) 765c3e85bdcSAkhil Goyal { 766c3e85bdcSAkhil Goyal struct rte_crypto_sym_op *sym = op->sym; 767c3e85bdcSAkhil Goyal struct dpaa_sec_job *cf; 768c3e85bdcSAkhil Goyal struct dpaa_sec_op_ctx *ctx; 769c3e85bdcSAkhil Goyal struct qm_sg_entry *sg; 770c4509373SSantosh Shukla rte_iova_t src_start_addr, dst_start_addr; 771c3e85bdcSAkhil Goyal uint32_t length = 0; 772c3e85bdcSAkhil Goyal uint8_t *IV_ptr = rte_crypto_op_ctod_offset(op, uint8_t *, 773c3e85bdcSAkhil Goyal ses->iv.offset); 774c3e85bdcSAkhil Goyal 775455da545SSantosh Shukla src_start_addr = sym->m_src->buf_iova + sym->m_src->data_off; 776a389434eSAlok Makhariya if (sym->m_dst) 777455da545SSantosh Shukla dst_start_addr = sym->m_dst->buf_iova + sym->m_dst->data_off; 778a389434eSAlok Makhariya else 779a389434eSAlok Makhariya dst_start_addr = src_start_addr; 780c3e85bdcSAkhil Goyal 781c3e85bdcSAkhil Goyal ctx = dpaa_sec_alloc_ctx(ses); 782c3e85bdcSAkhil Goyal if (!ctx) 783c3e85bdcSAkhil Goyal return NULL; 784c3e85bdcSAkhil Goyal 785c3e85bdcSAkhil Goyal cf = &ctx->job; 786c3e85bdcSAkhil Goyal ctx->op = op; 787c3e85bdcSAkhil Goyal 788c3e85bdcSAkhil Goyal /* input */ 789c3e85bdcSAkhil Goyal rte_prefetch0(cf->sg); 790c3e85bdcSAkhil Goyal sg = &cf->sg[2]; 791c3e85bdcSAkhil Goyal qm_sg_entry_set64(&cf->sg[1], dpaa_mem_vtop(sg)); 792c3e85bdcSAkhil Goyal if (is_encode(ses)) { 793c3e85bdcSAkhil Goyal qm_sg_entry_set64(sg, dpaa_mem_vtop(IV_ptr)); 794c3e85bdcSAkhil Goyal sg->length = ses->iv.length; 795c3e85bdcSAkhil Goyal length += sg->length; 796c3e85bdcSAkhil Goyal cpu_to_hw_sg(sg); 797c3e85bdcSAkhil Goyal 798c3e85bdcSAkhil Goyal sg++; 799a389434eSAlok Makhariya qm_sg_entry_set64(sg, src_start_addr + sym->auth.data.offset); 800c3e85bdcSAkhil Goyal sg->length = sym->auth.data.length; 801c3e85bdcSAkhil Goyal length += sg->length; 802c3e85bdcSAkhil Goyal sg->final = 1; 803c3e85bdcSAkhil Goyal cpu_to_hw_sg(sg); 804c3e85bdcSAkhil Goyal } else { 805c3e85bdcSAkhil Goyal qm_sg_entry_set64(sg, dpaa_mem_vtop(IV_ptr)); 806c3e85bdcSAkhil Goyal sg->length = ses->iv.length; 807c3e85bdcSAkhil Goyal length += sg->length; 808c3e85bdcSAkhil Goyal cpu_to_hw_sg(sg); 809c3e85bdcSAkhil Goyal 810c3e85bdcSAkhil Goyal sg++; 811c3e85bdcSAkhil Goyal 812a389434eSAlok Makhariya qm_sg_entry_set64(sg, src_start_addr + sym->auth.data.offset); 813c3e85bdcSAkhil Goyal sg->length = sym->auth.data.length; 814c3e85bdcSAkhil Goyal length += sg->length; 815c3e85bdcSAkhil Goyal cpu_to_hw_sg(sg); 816c3e85bdcSAkhil Goyal 817c3e85bdcSAkhil Goyal memcpy(ctx->digest, sym->auth.digest.data, 818c3e85bdcSAkhil Goyal ses->digest_length); 819c3e85bdcSAkhil Goyal sg++; 820c3e85bdcSAkhil Goyal 821c3e85bdcSAkhil Goyal qm_sg_entry_set64(sg, dpaa_mem_vtop(ctx->digest)); 822c3e85bdcSAkhil Goyal sg->length = ses->digest_length; 823c3e85bdcSAkhil Goyal length += sg->length; 824c3e85bdcSAkhil Goyal sg->final = 1; 825c3e85bdcSAkhil Goyal cpu_to_hw_sg(sg); 826c3e85bdcSAkhil Goyal } 827c3e85bdcSAkhil Goyal /* input compound frame */ 828c3e85bdcSAkhil Goyal cf->sg[1].length = length; 829c3e85bdcSAkhil Goyal cf->sg[1].extension = 1; 830c3e85bdcSAkhil Goyal cf->sg[1].final = 1; 831c3e85bdcSAkhil Goyal cpu_to_hw_sg(&cf->sg[1]); 832c3e85bdcSAkhil Goyal 833c3e85bdcSAkhil Goyal /* output */ 834c3e85bdcSAkhil Goyal sg++; 835c3e85bdcSAkhil Goyal qm_sg_entry_set64(&cf->sg[0], dpaa_mem_vtop(sg)); 836a389434eSAlok Makhariya qm_sg_entry_set64(sg, dst_start_addr + sym->cipher.data.offset); 837c3e85bdcSAkhil Goyal sg->length = sym->cipher.data.length; 838c3e85bdcSAkhil Goyal length = sg->length; 839c3e85bdcSAkhil Goyal if (is_encode(ses)) { 840c3e85bdcSAkhil Goyal cpu_to_hw_sg(sg); 841c3e85bdcSAkhil Goyal /* set auth output */ 842c3e85bdcSAkhil Goyal sg++; 843c3e85bdcSAkhil Goyal qm_sg_entry_set64(sg, sym->auth.digest.phys_addr); 844c3e85bdcSAkhil Goyal sg->length = ses->digest_length; 845c3e85bdcSAkhil Goyal length += sg->length; 846c3e85bdcSAkhil Goyal } 847c3e85bdcSAkhil Goyal sg->final = 1; 848c3e85bdcSAkhil Goyal cpu_to_hw_sg(sg); 849c3e85bdcSAkhil Goyal 850c3e85bdcSAkhil Goyal /* output compound frame */ 851c3e85bdcSAkhil Goyal cf->sg[0].length = length; 852c3e85bdcSAkhil Goyal cf->sg[0].extension = 1; 853c3e85bdcSAkhil Goyal cpu_to_hw_sg(&cf->sg[0]); 854c3e85bdcSAkhil Goyal 855c3e85bdcSAkhil Goyal return cf; 856c3e85bdcSAkhil Goyal } 857c3e85bdcSAkhil Goyal 858c3e85bdcSAkhil Goyal static int 859c3e85bdcSAkhil Goyal dpaa_sec_enqueue_op(struct rte_crypto_op *op, struct dpaa_sec_qp *qp) 860c3e85bdcSAkhil Goyal { 861c3e85bdcSAkhil Goyal struct dpaa_sec_job *cf; 862c3e85bdcSAkhil Goyal dpaa_sec_session *ses; 863c3e85bdcSAkhil Goyal struct qm_fd fd; 864c3e85bdcSAkhil Goyal int ret; 865c3e85bdcSAkhil Goyal uint32_t auth_only_len = op->sym->auth.data.length - 866c3e85bdcSAkhil Goyal op->sym->cipher.data.length; 867c3e85bdcSAkhil Goyal 868c3e85bdcSAkhil Goyal ses = (dpaa_sec_session *)get_session_private_data(op->sym->session, 869c3e85bdcSAkhil Goyal cryptodev_driver_id); 870c3e85bdcSAkhil Goyal 871c3e85bdcSAkhil Goyal if (unlikely(!qp->ses || qp->ses != ses)) { 872c3e85bdcSAkhil Goyal qp->ses = ses; 873c3e85bdcSAkhil Goyal ses->qp = qp; 874c3e85bdcSAkhil Goyal ret = dpaa_sec_prep_cdb(ses); 875c3e85bdcSAkhil Goyal if (ret) 876c3e85bdcSAkhil Goyal return ret; 877c3e85bdcSAkhil Goyal } 878c3e85bdcSAkhil Goyal 879cf6f70eeSAlok Makhariya /* 880cf6f70eeSAlok Makhariya * Segmented buffer is not supported. 881cf6f70eeSAlok Makhariya */ 882cf6f70eeSAlok Makhariya if (!rte_pktmbuf_is_contiguous(op->sym->m_src)) { 883cf6f70eeSAlok Makhariya op->status = RTE_CRYPTO_OP_STATUS_ERROR; 884cf6f70eeSAlok Makhariya return -ENOTSUP; 885cf6f70eeSAlok Makhariya } 886c3e85bdcSAkhil Goyal if (is_auth_only(ses)) { 887c3e85bdcSAkhil Goyal cf = build_auth_only(op, ses); 888c3e85bdcSAkhil Goyal } else if (is_cipher_only(ses)) { 889c3e85bdcSAkhil Goyal cf = build_cipher_only(op, ses); 890c3e85bdcSAkhil Goyal } else if (is_aead(ses)) { 891c3e85bdcSAkhil Goyal cf = build_cipher_auth_gcm(op, ses); 892c3e85bdcSAkhil Goyal auth_only_len = ses->auth_only_len; 893c3e85bdcSAkhil Goyal } else if (is_auth_cipher(ses)) { 894c3e85bdcSAkhil Goyal cf = build_cipher_auth(op, ses); 895c3e85bdcSAkhil Goyal } else { 896c3e85bdcSAkhil Goyal PMD_TX_LOG(ERR, "not supported sec op"); 897c3e85bdcSAkhil Goyal return -ENOTSUP; 898c3e85bdcSAkhil Goyal } 899c3e85bdcSAkhil Goyal if (unlikely(!cf)) 900c3e85bdcSAkhil Goyal return -ENOMEM; 901c3e85bdcSAkhil Goyal 902c3e85bdcSAkhil Goyal memset(&fd, 0, sizeof(struct qm_fd)); 903c3e85bdcSAkhil Goyal qm_fd_addr_set64(&fd, dpaa_mem_vtop(cf->sg)); 904c3e85bdcSAkhil Goyal fd._format1 = qm_fd_compound; 905c3e85bdcSAkhil Goyal fd.length29 = 2 * sizeof(struct qm_sg_entry); 906c3e85bdcSAkhil Goyal /* Auth_only_len is set as 0 in descriptor and it is overwritten 907c3e85bdcSAkhil Goyal * here in the fd.cmd which will update the DPOVRD reg. 908c3e85bdcSAkhil Goyal */ 909c3e85bdcSAkhil Goyal if (auth_only_len) 910c3e85bdcSAkhil Goyal fd.cmd = 0x80000000 | auth_only_len; 911c3e85bdcSAkhil Goyal do { 912c3e85bdcSAkhil Goyal ret = qman_enqueue(&qp->inq, &fd, 0); 913c3e85bdcSAkhil Goyal } while (ret != 0); 914c3e85bdcSAkhil Goyal 915c3e85bdcSAkhil Goyal return 0; 916c3e85bdcSAkhil Goyal } 917c3e85bdcSAkhil Goyal 918c3e85bdcSAkhil Goyal static uint16_t 919c3e85bdcSAkhil Goyal dpaa_sec_enqueue_burst(void *qp, struct rte_crypto_op **ops, 920c3e85bdcSAkhil Goyal uint16_t nb_ops) 921c3e85bdcSAkhil Goyal { 922c3e85bdcSAkhil Goyal /* Function to transmit the frames to given device and queuepair */ 923c3e85bdcSAkhil Goyal uint32_t loop; 924c3e85bdcSAkhil Goyal int32_t ret; 925c3e85bdcSAkhil Goyal struct dpaa_sec_qp *dpaa_qp = (struct dpaa_sec_qp *)qp; 926c3e85bdcSAkhil Goyal uint16_t num_tx = 0; 927c3e85bdcSAkhil Goyal 928c3e85bdcSAkhil Goyal if (unlikely(nb_ops == 0)) 929c3e85bdcSAkhil Goyal return 0; 930c3e85bdcSAkhil Goyal 931c3e85bdcSAkhil Goyal /*Prepare each packet which is to be sent*/ 932c3e85bdcSAkhil Goyal for (loop = 0; loop < nb_ops; loop++) { 933c3e85bdcSAkhil Goyal if (ops[loop]->sess_type != RTE_CRYPTO_OP_WITH_SESSION) { 934c3e85bdcSAkhil Goyal PMD_TX_LOG(ERR, "sessionless crypto op not supported"); 935c3e85bdcSAkhil Goyal return 0; 936c3e85bdcSAkhil Goyal } 937c3e85bdcSAkhil Goyal ret = dpaa_sec_enqueue_op(ops[loop], dpaa_qp); 938c3e85bdcSAkhil Goyal if (!ret) 939c3e85bdcSAkhil Goyal num_tx++; 940c3e85bdcSAkhil Goyal } 941c3e85bdcSAkhil Goyal dpaa_qp->tx_pkts += num_tx; 942c3e85bdcSAkhil Goyal dpaa_qp->tx_errs += nb_ops - num_tx; 943c3e85bdcSAkhil Goyal 944c3e85bdcSAkhil Goyal return num_tx; 945c3e85bdcSAkhil Goyal } 946c3e85bdcSAkhil Goyal 947c3e85bdcSAkhil Goyal static uint16_t 948c3e85bdcSAkhil Goyal dpaa_sec_dequeue_burst(void *qp, struct rte_crypto_op **ops, 949c3e85bdcSAkhil Goyal uint16_t nb_ops) 950c3e85bdcSAkhil Goyal { 951c3e85bdcSAkhil Goyal uint16_t num_rx; 952c3e85bdcSAkhil Goyal struct dpaa_sec_qp *dpaa_qp = (struct dpaa_sec_qp *)qp; 953c3e85bdcSAkhil Goyal 954c3e85bdcSAkhil Goyal num_rx = dpaa_sec_deq(dpaa_qp, ops, nb_ops); 955c3e85bdcSAkhil Goyal 956c3e85bdcSAkhil Goyal dpaa_qp->rx_pkts += num_rx; 957c3e85bdcSAkhil Goyal dpaa_qp->rx_errs += nb_ops - num_rx; 958c3e85bdcSAkhil Goyal 959c3e85bdcSAkhil Goyal PMD_RX_LOG(DEBUG, "SEC Received %d Packets\n", num_rx); 960c3e85bdcSAkhil Goyal 961c3e85bdcSAkhil Goyal return num_rx; 962c3e85bdcSAkhil Goyal } 963c3e85bdcSAkhil Goyal 964c3e85bdcSAkhil Goyal /** Release queue pair */ 965c3e85bdcSAkhil Goyal static int 966c3e85bdcSAkhil Goyal dpaa_sec_queue_pair_release(struct rte_cryptodev *dev, 967c3e85bdcSAkhil Goyal uint16_t qp_id) 968c3e85bdcSAkhil Goyal { 969c3e85bdcSAkhil Goyal struct dpaa_sec_dev_private *internals; 970c3e85bdcSAkhil Goyal struct dpaa_sec_qp *qp = NULL; 971c3e85bdcSAkhil Goyal 972c3e85bdcSAkhil Goyal PMD_INIT_FUNC_TRACE(); 973c3e85bdcSAkhil Goyal 974c3e85bdcSAkhil Goyal PMD_INIT_LOG(DEBUG, "dev =%p, queue =%d", dev, qp_id); 975c3e85bdcSAkhil Goyal 976c3e85bdcSAkhil Goyal internals = dev->data->dev_private; 977c3e85bdcSAkhil Goyal if (qp_id >= internals->max_nb_queue_pairs) { 978c3e85bdcSAkhil Goyal PMD_INIT_LOG(ERR, "Max supported qpid %d", 979c3e85bdcSAkhil Goyal internals->max_nb_queue_pairs); 980c3e85bdcSAkhil Goyal return -EINVAL; 981c3e85bdcSAkhil Goyal } 982c3e85bdcSAkhil Goyal 983c3e85bdcSAkhil Goyal qp = &internals->qps[qp_id]; 984c3e85bdcSAkhil Goyal qp->internals = NULL; 985c3e85bdcSAkhil Goyal dev->data->queue_pairs[qp_id] = NULL; 986c3e85bdcSAkhil Goyal 987c3e85bdcSAkhil Goyal return 0; 988c3e85bdcSAkhil Goyal } 989c3e85bdcSAkhil Goyal 990c3e85bdcSAkhil Goyal /** Setup a queue pair */ 991c3e85bdcSAkhil Goyal static int 992c3e85bdcSAkhil Goyal dpaa_sec_queue_pair_setup(struct rte_cryptodev *dev, uint16_t qp_id, 993c3e85bdcSAkhil Goyal __rte_unused const struct rte_cryptodev_qp_conf *qp_conf, 994c3e85bdcSAkhil Goyal __rte_unused int socket_id, 995c3e85bdcSAkhil Goyal __rte_unused struct rte_mempool *session_pool) 996c3e85bdcSAkhil Goyal { 997c3e85bdcSAkhil Goyal struct dpaa_sec_dev_private *internals; 998c3e85bdcSAkhil Goyal struct dpaa_sec_qp *qp = NULL; 999c3e85bdcSAkhil Goyal 1000c3e85bdcSAkhil Goyal PMD_INIT_LOG(DEBUG, "dev =%p, queue =%d, conf =%p", 1001c3e85bdcSAkhil Goyal dev, qp_id, qp_conf); 1002c3e85bdcSAkhil Goyal 1003c3e85bdcSAkhil Goyal internals = dev->data->dev_private; 1004c3e85bdcSAkhil Goyal if (qp_id >= internals->max_nb_queue_pairs) { 1005c3e85bdcSAkhil Goyal PMD_INIT_LOG(ERR, "Max supported qpid %d", 1006c3e85bdcSAkhil Goyal internals->max_nb_queue_pairs); 1007c3e85bdcSAkhil Goyal return -EINVAL; 1008c3e85bdcSAkhil Goyal } 1009c3e85bdcSAkhil Goyal 1010c3e85bdcSAkhil Goyal qp = &internals->qps[qp_id]; 1011c3e85bdcSAkhil Goyal qp->internals = internals; 1012c3e85bdcSAkhil Goyal dev->data->queue_pairs[qp_id] = qp; 1013c3e85bdcSAkhil Goyal 1014c3e85bdcSAkhil Goyal return 0; 1015c3e85bdcSAkhil Goyal } 1016c3e85bdcSAkhil Goyal 1017c3e85bdcSAkhil Goyal /** Start queue pair */ 1018c3e85bdcSAkhil Goyal static int 1019c3e85bdcSAkhil Goyal dpaa_sec_queue_pair_start(__rte_unused struct rte_cryptodev *dev, 1020c3e85bdcSAkhil Goyal __rte_unused uint16_t queue_pair_id) 1021c3e85bdcSAkhil Goyal { 1022c3e85bdcSAkhil Goyal PMD_INIT_FUNC_TRACE(); 1023c3e85bdcSAkhil Goyal 1024c3e85bdcSAkhil Goyal return 0; 1025c3e85bdcSAkhil Goyal } 1026c3e85bdcSAkhil Goyal 1027c3e85bdcSAkhil Goyal /** Stop queue pair */ 1028c3e85bdcSAkhil Goyal static int 1029c3e85bdcSAkhil Goyal dpaa_sec_queue_pair_stop(__rte_unused struct rte_cryptodev *dev, 1030c3e85bdcSAkhil Goyal __rte_unused uint16_t queue_pair_id) 1031c3e85bdcSAkhil Goyal { 1032c3e85bdcSAkhil Goyal PMD_INIT_FUNC_TRACE(); 1033c3e85bdcSAkhil Goyal 1034c3e85bdcSAkhil Goyal return 0; 1035c3e85bdcSAkhil Goyal } 1036c3e85bdcSAkhil Goyal 1037c3e85bdcSAkhil Goyal /** Return the number of allocated queue pairs */ 1038c3e85bdcSAkhil Goyal static uint32_t 1039c3e85bdcSAkhil Goyal dpaa_sec_queue_pair_count(struct rte_cryptodev *dev) 1040c3e85bdcSAkhil Goyal { 1041c3e85bdcSAkhil Goyal PMD_INIT_FUNC_TRACE(); 1042c3e85bdcSAkhil Goyal 1043c3e85bdcSAkhil Goyal return dev->data->nb_queue_pairs; 1044c3e85bdcSAkhil Goyal } 1045c3e85bdcSAkhil Goyal 1046c3e85bdcSAkhil Goyal /** Returns the size of session structure */ 1047c3e85bdcSAkhil Goyal static unsigned int 1048c3e85bdcSAkhil Goyal dpaa_sec_session_get_size(struct rte_cryptodev *dev __rte_unused) 1049c3e85bdcSAkhil Goyal { 1050c3e85bdcSAkhil Goyal PMD_INIT_FUNC_TRACE(); 1051c3e85bdcSAkhil Goyal 1052c3e85bdcSAkhil Goyal return sizeof(dpaa_sec_session); 1053c3e85bdcSAkhil Goyal } 1054c3e85bdcSAkhil Goyal 1055c3e85bdcSAkhil Goyal static int 1056c3e85bdcSAkhil Goyal dpaa_sec_cipher_init(struct rte_cryptodev *dev __rte_unused, 1057c3e85bdcSAkhil Goyal struct rte_crypto_sym_xform *xform, 1058c3e85bdcSAkhil Goyal dpaa_sec_session *session) 1059c3e85bdcSAkhil Goyal { 1060c3e85bdcSAkhil Goyal session->cipher_alg = xform->cipher.algo; 1061c3e85bdcSAkhil Goyal session->iv.length = xform->cipher.iv.length; 1062c3e85bdcSAkhil Goyal session->iv.offset = xform->cipher.iv.offset; 1063c3e85bdcSAkhil Goyal session->cipher_key.data = rte_zmalloc(NULL, xform->cipher.key.length, 1064c3e85bdcSAkhil Goyal RTE_CACHE_LINE_SIZE); 1065c3e85bdcSAkhil Goyal if (session->cipher_key.data == NULL && xform->cipher.key.length > 0) { 1066c3e85bdcSAkhil Goyal PMD_INIT_LOG(ERR, "No Memory for cipher key\n"); 1067c3e85bdcSAkhil Goyal return -ENOMEM; 1068c3e85bdcSAkhil Goyal } 1069c3e85bdcSAkhil Goyal session->cipher_key.length = xform->cipher.key.length; 1070c3e85bdcSAkhil Goyal 1071c3e85bdcSAkhil Goyal memcpy(session->cipher_key.data, xform->cipher.key.data, 1072c3e85bdcSAkhil Goyal xform->cipher.key.length); 1073c3e85bdcSAkhil Goyal session->dir = (xform->cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) ? 1074c3e85bdcSAkhil Goyal DIR_ENC : DIR_DEC; 1075c3e85bdcSAkhil Goyal 1076c3e85bdcSAkhil Goyal return 0; 1077c3e85bdcSAkhil Goyal } 1078c3e85bdcSAkhil Goyal 1079c3e85bdcSAkhil Goyal static int 1080c3e85bdcSAkhil Goyal dpaa_sec_auth_init(struct rte_cryptodev *dev __rte_unused, 1081c3e85bdcSAkhil Goyal struct rte_crypto_sym_xform *xform, 1082c3e85bdcSAkhil Goyal dpaa_sec_session *session) 1083c3e85bdcSAkhil Goyal { 1084c3e85bdcSAkhil Goyal session->auth_alg = xform->auth.algo; 1085c3e85bdcSAkhil Goyal session->auth_key.data = rte_zmalloc(NULL, xform->auth.key.length, 1086c3e85bdcSAkhil Goyal RTE_CACHE_LINE_SIZE); 1087c3e85bdcSAkhil Goyal if (session->auth_key.data == NULL && xform->auth.key.length > 0) { 1088c3e85bdcSAkhil Goyal PMD_INIT_LOG(ERR, "No Memory for auth key\n"); 1089c3e85bdcSAkhil Goyal return -ENOMEM; 1090c3e85bdcSAkhil Goyal } 1091c3e85bdcSAkhil Goyal session->auth_key.length = xform->auth.key.length; 1092c3e85bdcSAkhil Goyal session->digest_length = xform->auth.digest_length; 1093c3e85bdcSAkhil Goyal 1094c3e85bdcSAkhil Goyal memcpy(session->auth_key.data, xform->auth.key.data, 1095c3e85bdcSAkhil Goyal xform->auth.key.length); 1096c3e85bdcSAkhil Goyal session->dir = (xform->auth.op == RTE_CRYPTO_AUTH_OP_GENERATE) ? 1097c3e85bdcSAkhil Goyal DIR_ENC : DIR_DEC; 1098c3e85bdcSAkhil Goyal 1099c3e85bdcSAkhil Goyal return 0; 1100c3e85bdcSAkhil Goyal } 1101c3e85bdcSAkhil Goyal 1102c3e85bdcSAkhil Goyal static int 1103c3e85bdcSAkhil Goyal dpaa_sec_aead_init(struct rte_cryptodev *dev __rte_unused, 1104c3e85bdcSAkhil Goyal struct rte_crypto_sym_xform *xform, 1105c3e85bdcSAkhil Goyal dpaa_sec_session *session) 1106c3e85bdcSAkhil Goyal { 1107c3e85bdcSAkhil Goyal session->aead_alg = xform->aead.algo; 1108c3e85bdcSAkhil Goyal session->iv.length = xform->aead.iv.length; 1109c3e85bdcSAkhil Goyal session->iv.offset = xform->aead.iv.offset; 1110c3e85bdcSAkhil Goyal session->auth_only_len = xform->aead.aad_length; 1111c3e85bdcSAkhil Goyal session->aead_key.data = rte_zmalloc(NULL, xform->aead.key.length, 1112c3e85bdcSAkhil Goyal RTE_CACHE_LINE_SIZE); 1113c3e85bdcSAkhil Goyal if (session->aead_key.data == NULL && xform->aead.key.length > 0) { 1114c3e85bdcSAkhil Goyal PMD_INIT_LOG(ERR, "No Memory for aead key\n"); 1115c3e85bdcSAkhil Goyal return -ENOMEM; 1116c3e85bdcSAkhil Goyal } 1117c3e85bdcSAkhil Goyal session->aead_key.length = xform->aead.key.length; 1118c3e85bdcSAkhil Goyal session->digest_length = xform->aead.digest_length; 1119c3e85bdcSAkhil Goyal 1120c3e85bdcSAkhil Goyal memcpy(session->aead_key.data, xform->aead.key.data, 1121c3e85bdcSAkhil Goyal xform->aead.key.length); 1122c3e85bdcSAkhil Goyal session->dir = (xform->aead.op == RTE_CRYPTO_AEAD_OP_ENCRYPT) ? 1123c3e85bdcSAkhil Goyal DIR_ENC : DIR_DEC; 1124c3e85bdcSAkhil Goyal 1125c3e85bdcSAkhil Goyal return 0; 1126c3e85bdcSAkhil Goyal } 1127c3e85bdcSAkhil Goyal 1128c3e85bdcSAkhil Goyal static int 1129c3e85bdcSAkhil Goyal dpaa_sec_qp_attach_sess(struct rte_cryptodev *dev, uint16_t qp_id, void *ses) 1130c3e85bdcSAkhil Goyal { 1131c3e85bdcSAkhil Goyal dpaa_sec_session *sess = ses; 1132c3e85bdcSAkhil Goyal struct dpaa_sec_qp *qp; 1133c3e85bdcSAkhil Goyal 1134c3e85bdcSAkhil Goyal PMD_INIT_FUNC_TRACE(); 1135c3e85bdcSAkhil Goyal 1136c3e85bdcSAkhil Goyal qp = dev->data->queue_pairs[qp_id]; 1137c3e85bdcSAkhil Goyal if (qp->ses != NULL) { 1138c3e85bdcSAkhil Goyal PMD_INIT_LOG(ERR, "qp in-use by another session\n"); 1139c3e85bdcSAkhil Goyal return -EBUSY; 1140c3e85bdcSAkhil Goyal } 1141c3e85bdcSAkhil Goyal 1142c3e85bdcSAkhil Goyal qp->ses = sess; 1143c3e85bdcSAkhil Goyal sess->qp = qp; 1144c3e85bdcSAkhil Goyal 1145c3e85bdcSAkhil Goyal return dpaa_sec_prep_cdb(sess); 1146c3e85bdcSAkhil Goyal } 1147c3e85bdcSAkhil Goyal 1148c3e85bdcSAkhil Goyal static int 1149c3e85bdcSAkhil Goyal dpaa_sec_qp_detach_sess(struct rte_cryptodev *dev, uint16_t qp_id, void *ses) 1150c3e85bdcSAkhil Goyal { 1151c3e85bdcSAkhil Goyal dpaa_sec_session *sess = ses; 1152c3e85bdcSAkhil Goyal struct dpaa_sec_qp *qp; 1153c3e85bdcSAkhil Goyal 1154c3e85bdcSAkhil Goyal PMD_INIT_FUNC_TRACE(); 1155c3e85bdcSAkhil Goyal 1156c3e85bdcSAkhil Goyal qp = dev->data->queue_pairs[qp_id]; 1157c3e85bdcSAkhil Goyal if (qp->ses != NULL) { 1158c3e85bdcSAkhil Goyal qp->ses = NULL; 1159c3e85bdcSAkhil Goyal sess->qp = NULL; 1160c3e85bdcSAkhil Goyal return 0; 1161c3e85bdcSAkhil Goyal } 1162c3e85bdcSAkhil Goyal 1163c3e85bdcSAkhil Goyal PMD_DRV_LOG(ERR, "No session attached to qp"); 1164c3e85bdcSAkhil Goyal return -EINVAL; 1165c3e85bdcSAkhil Goyal } 1166c3e85bdcSAkhil Goyal 1167c3e85bdcSAkhil Goyal static int 1168c3e85bdcSAkhil Goyal dpaa_sec_set_session_parameters(struct rte_cryptodev *dev, 1169c3e85bdcSAkhil Goyal struct rte_crypto_sym_xform *xform, void *sess) 1170c3e85bdcSAkhil Goyal { 1171c3e85bdcSAkhil Goyal struct dpaa_sec_dev_private *internals = dev->data->dev_private; 1172c3e85bdcSAkhil Goyal dpaa_sec_session *session = sess; 1173c3e85bdcSAkhil Goyal 1174c3e85bdcSAkhil Goyal PMD_INIT_FUNC_TRACE(); 1175c3e85bdcSAkhil Goyal 1176c3e85bdcSAkhil Goyal if (unlikely(sess == NULL)) { 1177c3e85bdcSAkhil Goyal RTE_LOG(ERR, PMD, "invalid session struct\n"); 1178c3e85bdcSAkhil Goyal return -EINVAL; 1179c3e85bdcSAkhil Goyal } 1180c3e85bdcSAkhil Goyal 1181c3e85bdcSAkhil Goyal /* Default IV length = 0 */ 1182c3e85bdcSAkhil Goyal session->iv.length = 0; 1183c3e85bdcSAkhil Goyal 1184c3e85bdcSAkhil Goyal /* Cipher Only */ 1185c3e85bdcSAkhil Goyal if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER && xform->next == NULL) { 1186c3e85bdcSAkhil Goyal session->auth_alg = RTE_CRYPTO_AUTH_NULL; 1187c3e85bdcSAkhil Goyal dpaa_sec_cipher_init(dev, xform, session); 1188c3e85bdcSAkhil Goyal 1189c3e85bdcSAkhil Goyal /* Authentication Only */ 1190c3e85bdcSAkhil Goyal } else if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH && 1191c3e85bdcSAkhil Goyal xform->next == NULL) { 1192c3e85bdcSAkhil Goyal session->cipher_alg = RTE_CRYPTO_CIPHER_NULL; 1193c3e85bdcSAkhil Goyal dpaa_sec_auth_init(dev, xform, session); 1194c3e85bdcSAkhil Goyal 1195c3e85bdcSAkhil Goyal /* Cipher then Authenticate */ 1196c3e85bdcSAkhil Goyal } else if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER && 1197c3e85bdcSAkhil Goyal xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH) { 1198c3e85bdcSAkhil Goyal if (xform->cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) { 1199c3e85bdcSAkhil Goyal dpaa_sec_cipher_init(dev, xform, session); 1200c3e85bdcSAkhil Goyal dpaa_sec_auth_init(dev, xform->next, session); 1201c3e85bdcSAkhil Goyal } else { 1202c3e85bdcSAkhil Goyal PMD_DRV_LOG(ERR, "Not supported: Auth then Cipher"); 1203c3e85bdcSAkhil Goyal return -EINVAL; 1204c3e85bdcSAkhil Goyal } 1205c3e85bdcSAkhil Goyal 1206c3e85bdcSAkhil Goyal /* Authenticate then Cipher */ 1207c3e85bdcSAkhil Goyal } else if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH && 1208c3e85bdcSAkhil Goyal xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER) { 1209c3e85bdcSAkhil Goyal if (xform->next->cipher.op == RTE_CRYPTO_CIPHER_OP_DECRYPT) { 1210c3e85bdcSAkhil Goyal dpaa_sec_auth_init(dev, xform, session); 1211c3e85bdcSAkhil Goyal dpaa_sec_cipher_init(dev, xform->next, session); 1212c3e85bdcSAkhil Goyal } else { 1213c3e85bdcSAkhil Goyal PMD_DRV_LOG(ERR, "Not supported: Auth then Cipher"); 1214c3e85bdcSAkhil Goyal return -EINVAL; 1215c3e85bdcSAkhil Goyal } 1216c3e85bdcSAkhil Goyal 1217c3e85bdcSAkhil Goyal /* AEAD operation for AES-GCM kind of Algorithms */ 1218c3e85bdcSAkhil Goyal } else if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD && 1219c3e85bdcSAkhil Goyal xform->next == NULL) { 1220c3e85bdcSAkhil Goyal dpaa_sec_aead_init(dev, xform, session); 1221c3e85bdcSAkhil Goyal 1222c3e85bdcSAkhil Goyal } else { 1223c3e85bdcSAkhil Goyal PMD_DRV_LOG(ERR, "Invalid crypto type"); 1224c3e85bdcSAkhil Goyal return -EINVAL; 1225c3e85bdcSAkhil Goyal } 1226c3e85bdcSAkhil Goyal session->ctx_pool = internals->ctx_pool; 1227c3e85bdcSAkhil Goyal 1228c3e85bdcSAkhil Goyal return 0; 1229c3e85bdcSAkhil Goyal } 1230c3e85bdcSAkhil Goyal 1231c3e85bdcSAkhil Goyal static int 1232c3e85bdcSAkhil Goyal dpaa_sec_session_configure(struct rte_cryptodev *dev, 1233c3e85bdcSAkhil Goyal struct rte_crypto_sym_xform *xform, 1234c3e85bdcSAkhil Goyal struct rte_cryptodev_sym_session *sess, 1235c3e85bdcSAkhil Goyal struct rte_mempool *mempool) 1236c3e85bdcSAkhil Goyal { 1237c3e85bdcSAkhil Goyal void *sess_private_data; 1238c3e85bdcSAkhil Goyal int ret; 1239c3e85bdcSAkhil Goyal 1240c3e85bdcSAkhil Goyal PMD_INIT_FUNC_TRACE(); 1241c3e85bdcSAkhil Goyal 1242c3e85bdcSAkhil Goyal if (rte_mempool_get(mempool, &sess_private_data)) { 1243c3e85bdcSAkhil Goyal CDEV_LOG_ERR( 1244c3e85bdcSAkhil Goyal "Couldn't get object from session mempool"); 1245c3e85bdcSAkhil Goyal return -ENOMEM; 1246c3e85bdcSAkhil Goyal } 1247c3e85bdcSAkhil Goyal 1248c3e85bdcSAkhil Goyal ret = dpaa_sec_set_session_parameters(dev, xform, sess_private_data); 1249c3e85bdcSAkhil Goyal if (ret != 0) { 1250c3e85bdcSAkhil Goyal PMD_DRV_LOG(ERR, "DPAA PMD: failed to configure " 1251c3e85bdcSAkhil Goyal "session parameters"); 1252c3e85bdcSAkhil Goyal 1253c3e85bdcSAkhil Goyal /* Return session to mempool */ 1254c3e85bdcSAkhil Goyal rte_mempool_put(mempool, sess_private_data); 1255c3e85bdcSAkhil Goyal return ret; 1256c3e85bdcSAkhil Goyal } 1257c3e85bdcSAkhil Goyal 1258c3e85bdcSAkhil Goyal set_session_private_data(sess, dev->driver_id, 1259c3e85bdcSAkhil Goyal sess_private_data); 1260c3e85bdcSAkhil Goyal 1261c3e85bdcSAkhil Goyal return 0; 1262c3e85bdcSAkhil Goyal } 1263c3e85bdcSAkhil Goyal 1264c3e85bdcSAkhil Goyal /** Clear the memory of session so it doesn't leave key material behind */ 1265c3e85bdcSAkhil Goyal static void 1266c3e85bdcSAkhil Goyal dpaa_sec_session_clear(struct rte_cryptodev *dev, 1267c3e85bdcSAkhil Goyal struct rte_cryptodev_sym_session *sess) 1268c3e85bdcSAkhil Goyal { 1269c3e85bdcSAkhil Goyal PMD_INIT_FUNC_TRACE(); 1270c3e85bdcSAkhil Goyal uint8_t index = dev->driver_id; 1271c3e85bdcSAkhil Goyal void *sess_priv = get_session_private_data(sess, index); 1272c3e85bdcSAkhil Goyal dpaa_sec_session *s = (dpaa_sec_session *)sess_priv; 1273c3e85bdcSAkhil Goyal 1274c3e85bdcSAkhil Goyal if (sess_priv) { 1275c3e85bdcSAkhil Goyal rte_free(s->cipher_key.data); 1276c3e85bdcSAkhil Goyal rte_free(s->auth_key.data); 1277c3e85bdcSAkhil Goyal memset(s, 0, sizeof(dpaa_sec_session)); 1278c3e85bdcSAkhil Goyal struct rte_mempool *sess_mp = rte_mempool_from_obj(sess_priv); 1279c3e85bdcSAkhil Goyal set_session_private_data(sess, index, NULL); 1280c3e85bdcSAkhil Goyal rte_mempool_put(sess_mp, sess_priv); 1281c3e85bdcSAkhil Goyal } 1282c3e85bdcSAkhil Goyal } 1283c3e85bdcSAkhil Goyal 1284c3e85bdcSAkhil Goyal static int 1285c3e85bdcSAkhil Goyal dpaa_sec_dev_configure(struct rte_cryptodev *dev __rte_unused, 1286c3e85bdcSAkhil Goyal struct rte_cryptodev_config *config __rte_unused) 1287c3e85bdcSAkhil Goyal { 1288c3e85bdcSAkhil Goyal PMD_INIT_FUNC_TRACE(); 1289c3e85bdcSAkhil Goyal 1290c3e85bdcSAkhil Goyal return 0; 1291c3e85bdcSAkhil Goyal } 1292c3e85bdcSAkhil Goyal 1293c3e85bdcSAkhil Goyal static int 1294c3e85bdcSAkhil Goyal dpaa_sec_dev_start(struct rte_cryptodev *dev __rte_unused) 1295c3e85bdcSAkhil Goyal { 1296c3e85bdcSAkhil Goyal PMD_INIT_FUNC_TRACE(); 1297c3e85bdcSAkhil Goyal return 0; 1298c3e85bdcSAkhil Goyal } 1299c3e85bdcSAkhil Goyal 1300c3e85bdcSAkhil Goyal static void 1301c3e85bdcSAkhil Goyal dpaa_sec_dev_stop(struct rte_cryptodev *dev __rte_unused) 1302c3e85bdcSAkhil Goyal { 1303c3e85bdcSAkhil Goyal PMD_INIT_FUNC_TRACE(); 1304c3e85bdcSAkhil Goyal } 1305c3e85bdcSAkhil Goyal 1306c3e85bdcSAkhil Goyal static int 1307c3e85bdcSAkhil Goyal dpaa_sec_dev_close(struct rte_cryptodev *dev __rte_unused) 1308c3e85bdcSAkhil Goyal { 1309c3e85bdcSAkhil Goyal PMD_INIT_FUNC_TRACE(); 1310c3e85bdcSAkhil Goyal return 0; 1311c3e85bdcSAkhil Goyal } 1312c3e85bdcSAkhil Goyal 1313c3e85bdcSAkhil Goyal static void 1314c3e85bdcSAkhil Goyal dpaa_sec_dev_infos_get(struct rte_cryptodev *dev, 1315c3e85bdcSAkhil Goyal struct rte_cryptodev_info *info) 1316c3e85bdcSAkhil Goyal { 1317c3e85bdcSAkhil Goyal struct dpaa_sec_dev_private *internals = dev->data->dev_private; 1318c3e85bdcSAkhil Goyal 1319c3e85bdcSAkhil Goyal PMD_INIT_FUNC_TRACE(); 1320c3e85bdcSAkhil Goyal if (info != NULL) { 1321c3e85bdcSAkhil Goyal info->max_nb_queue_pairs = internals->max_nb_queue_pairs; 1322c3e85bdcSAkhil Goyal info->feature_flags = dev->feature_flags; 1323c3e85bdcSAkhil Goyal info->capabilities = dpaa_sec_capabilities; 1324c3e85bdcSAkhil Goyal info->sym.max_nb_sessions = internals->max_nb_sessions; 1325c3e85bdcSAkhil Goyal info->sym.max_nb_sessions_per_qp = 1326c3e85bdcSAkhil Goyal RTE_DPAA_SEC_PMD_MAX_NB_SESSIONS / RTE_MAX_NB_SEC_QPS; 1327c3e85bdcSAkhil Goyal info->driver_id = cryptodev_driver_id; 1328c3e85bdcSAkhil Goyal } 1329c3e85bdcSAkhil Goyal } 1330c3e85bdcSAkhil Goyal 1331c3e85bdcSAkhil Goyal static struct rte_cryptodev_ops crypto_ops = { 1332c3e85bdcSAkhil Goyal .dev_configure = dpaa_sec_dev_configure, 1333c3e85bdcSAkhil Goyal .dev_start = dpaa_sec_dev_start, 1334c3e85bdcSAkhil Goyal .dev_stop = dpaa_sec_dev_stop, 1335c3e85bdcSAkhil Goyal .dev_close = dpaa_sec_dev_close, 1336c3e85bdcSAkhil Goyal .dev_infos_get = dpaa_sec_dev_infos_get, 1337c3e85bdcSAkhil Goyal .queue_pair_setup = dpaa_sec_queue_pair_setup, 1338c3e85bdcSAkhil Goyal .queue_pair_release = dpaa_sec_queue_pair_release, 1339c3e85bdcSAkhil Goyal .queue_pair_start = dpaa_sec_queue_pair_start, 1340c3e85bdcSAkhil Goyal .queue_pair_stop = dpaa_sec_queue_pair_stop, 1341c3e85bdcSAkhil Goyal .queue_pair_count = dpaa_sec_queue_pair_count, 1342c3e85bdcSAkhil Goyal .session_get_size = dpaa_sec_session_get_size, 1343c3e85bdcSAkhil Goyal .session_configure = dpaa_sec_session_configure, 1344c3e85bdcSAkhil Goyal .session_clear = dpaa_sec_session_clear, 1345c3e85bdcSAkhil Goyal .qp_attach_session = dpaa_sec_qp_attach_sess, 1346c3e85bdcSAkhil Goyal .qp_detach_session = dpaa_sec_qp_detach_sess, 1347c3e85bdcSAkhil Goyal }; 1348c3e85bdcSAkhil Goyal 1349c3e85bdcSAkhil Goyal static int 1350c3e85bdcSAkhil Goyal dpaa_sec_uninit(struct rte_cryptodev *dev) 1351c3e85bdcSAkhil Goyal { 1352c3e85bdcSAkhil Goyal struct dpaa_sec_dev_private *internals = dev->data->dev_private; 1353c3e85bdcSAkhil Goyal 1354c3e85bdcSAkhil Goyal if (dev == NULL) 1355c3e85bdcSAkhil Goyal return -ENODEV; 1356c3e85bdcSAkhil Goyal 1357c3e85bdcSAkhil Goyal rte_mempool_free(internals->ctx_pool); 1358c3e85bdcSAkhil Goyal rte_free(internals); 1359c3e85bdcSAkhil Goyal 1360c3e85bdcSAkhil Goyal PMD_INIT_LOG(INFO, "Closing DPAA_SEC device %s on numa socket %u\n", 1361c3e85bdcSAkhil Goyal dev->data->name, rte_socket_id()); 1362c3e85bdcSAkhil Goyal 1363c3e85bdcSAkhil Goyal return 0; 1364c3e85bdcSAkhil Goyal } 1365c3e85bdcSAkhil Goyal 1366c3e85bdcSAkhil Goyal static int 1367c3e85bdcSAkhil Goyal dpaa_sec_dev_init(struct rte_cryptodev *cryptodev) 1368c3e85bdcSAkhil Goyal { 1369c3e85bdcSAkhil Goyal struct dpaa_sec_dev_private *internals; 1370c3e85bdcSAkhil Goyal struct dpaa_sec_qp *qp; 1371c3e85bdcSAkhil Goyal uint32_t i; 1372c3e85bdcSAkhil Goyal int ret; 1373c3e85bdcSAkhil Goyal char str[20]; 1374c3e85bdcSAkhil Goyal 1375c3e85bdcSAkhil Goyal PMD_INIT_FUNC_TRACE(); 1376c3e85bdcSAkhil Goyal 1377c3e85bdcSAkhil Goyal cryptodev->driver_id = cryptodev_driver_id; 1378c3e85bdcSAkhil Goyal cryptodev->dev_ops = &crypto_ops; 1379c3e85bdcSAkhil Goyal 1380c3e85bdcSAkhil Goyal cryptodev->enqueue_burst = dpaa_sec_enqueue_burst; 1381c3e85bdcSAkhil Goyal cryptodev->dequeue_burst = dpaa_sec_dequeue_burst; 1382c3e85bdcSAkhil Goyal cryptodev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO | 1383c3e85bdcSAkhil Goyal RTE_CRYPTODEV_FF_HW_ACCELERATED | 1384c3e85bdcSAkhil Goyal RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING; 1385c3e85bdcSAkhil Goyal 1386c3e85bdcSAkhil Goyal internals = cryptodev->data->dev_private; 1387c3e85bdcSAkhil Goyal internals->max_nb_queue_pairs = RTE_MAX_NB_SEC_QPS; 1388c3e85bdcSAkhil Goyal internals->max_nb_sessions = RTE_DPAA_SEC_PMD_MAX_NB_SESSIONS; 1389c3e85bdcSAkhil Goyal 1390c3e85bdcSAkhil Goyal for (i = 0; i < internals->max_nb_queue_pairs; i++) { 1391c3e85bdcSAkhil Goyal /* init qman fq for queue pair */ 1392c3e85bdcSAkhil Goyal qp = &internals->qps[i]; 1393c3e85bdcSAkhil Goyal ret = dpaa_sec_init_tx(&qp->outq); 1394c3e85bdcSAkhil Goyal if (ret) { 1395c3e85bdcSAkhil Goyal PMD_INIT_LOG(ERR, "config tx of queue pair %d", i); 1396c3e85bdcSAkhil Goyal goto init_error; 1397c3e85bdcSAkhil Goyal } 1398c3e85bdcSAkhil Goyal ret = dpaa_sec_init_rx(&qp->inq, dpaa_mem_vtop(&qp->cdb), 1399c3e85bdcSAkhil Goyal qman_fq_fqid(&qp->outq)); 1400c3e85bdcSAkhil Goyal if (ret) { 1401c3e85bdcSAkhil Goyal PMD_INIT_LOG(ERR, "config rx of queue pair %d", i); 1402c3e85bdcSAkhil Goyal goto init_error; 1403c3e85bdcSAkhil Goyal } 1404c3e85bdcSAkhil Goyal } 1405c3e85bdcSAkhil Goyal 1406c3e85bdcSAkhil Goyal sprintf(str, "ctx_pool_%d", cryptodev->data->dev_id); 1407c3e85bdcSAkhil Goyal internals->ctx_pool = rte_mempool_create((const char *)str, 1408c3e85bdcSAkhil Goyal CTX_POOL_NUM_BUFS, 1409c3e85bdcSAkhil Goyal CTX_POOL_BUF_SIZE, 1410c3e85bdcSAkhil Goyal CTX_POOL_CACHE_SIZE, 0, 1411c3e85bdcSAkhil Goyal NULL, NULL, NULL, NULL, 1412c3e85bdcSAkhil Goyal SOCKET_ID_ANY, 0); 1413c3e85bdcSAkhil Goyal if (!internals->ctx_pool) { 1414c3e85bdcSAkhil Goyal RTE_LOG(ERR, PMD, "%s create failed\n", str); 1415c3e85bdcSAkhil Goyal goto init_error; 1416c3e85bdcSAkhil Goyal } 1417c3e85bdcSAkhil Goyal 1418c3e85bdcSAkhil Goyal PMD_INIT_LOG(DEBUG, "driver %s: created\n", cryptodev->data->name); 1419c3e85bdcSAkhil Goyal return 0; 1420c3e85bdcSAkhil Goyal 1421c3e85bdcSAkhil Goyal init_error: 1422c3e85bdcSAkhil Goyal PMD_INIT_LOG(ERR, "driver %s: create failed\n", cryptodev->data->name); 1423c3e85bdcSAkhil Goyal 1424c3e85bdcSAkhil Goyal dpaa_sec_uninit(cryptodev); 1425c3e85bdcSAkhil Goyal return -EFAULT; 1426c3e85bdcSAkhil Goyal } 1427c3e85bdcSAkhil Goyal 1428c3e85bdcSAkhil Goyal static int 1429c3e85bdcSAkhil Goyal cryptodev_dpaa_sec_probe(struct rte_dpaa_driver *dpaa_drv, 1430c3e85bdcSAkhil Goyal struct rte_dpaa_device *dpaa_dev) 1431c3e85bdcSAkhil Goyal { 1432c3e85bdcSAkhil Goyal struct rte_cryptodev *cryptodev; 1433c3e85bdcSAkhil Goyal char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN]; 1434c3e85bdcSAkhil Goyal 1435c3e85bdcSAkhil Goyal int retval; 1436c3e85bdcSAkhil Goyal 1437c3e85bdcSAkhil Goyal sprintf(cryptodev_name, "dpaa_sec-%d", dpaa_dev->id.dev_id); 1438c3e85bdcSAkhil Goyal 1439c3e85bdcSAkhil Goyal cryptodev = rte_cryptodev_pmd_allocate(cryptodev_name, rte_socket_id()); 1440c3e85bdcSAkhil Goyal if (cryptodev == NULL) 1441c3e85bdcSAkhil Goyal return -ENOMEM; 1442c3e85bdcSAkhil Goyal 1443c3e85bdcSAkhil Goyal if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 1444c3e85bdcSAkhil Goyal cryptodev->data->dev_private = rte_zmalloc_socket( 1445c3e85bdcSAkhil Goyal "cryptodev private structure", 1446c3e85bdcSAkhil Goyal sizeof(struct dpaa_sec_dev_private), 1447c3e85bdcSAkhil Goyal RTE_CACHE_LINE_SIZE, 1448c3e85bdcSAkhil Goyal rte_socket_id()); 1449c3e85bdcSAkhil Goyal 1450c3e85bdcSAkhil Goyal if (cryptodev->data->dev_private == NULL) 1451c3e85bdcSAkhil Goyal rte_panic("Cannot allocate memzone for private " 1452c3e85bdcSAkhil Goyal "device data"); 1453c3e85bdcSAkhil Goyal } 1454c3e85bdcSAkhil Goyal 1455c3e85bdcSAkhil Goyal dpaa_dev->crypto_dev = cryptodev; 1456c3e85bdcSAkhil Goyal cryptodev->device = &dpaa_dev->device; 1457c3e85bdcSAkhil Goyal cryptodev->device->driver = &dpaa_drv->driver; 1458c3e85bdcSAkhil Goyal 1459c3e85bdcSAkhil Goyal /* init user callbacks */ 1460c3e85bdcSAkhil Goyal TAILQ_INIT(&(cryptodev->link_intr_cbs)); 1461c3e85bdcSAkhil Goyal 1462c3e85bdcSAkhil Goyal /* if sec device version is not configured */ 1463c3e85bdcSAkhil Goyal if (!rta_get_sec_era()) { 1464c3e85bdcSAkhil Goyal const struct device_node *caam_node; 1465c3e85bdcSAkhil Goyal 1466c3e85bdcSAkhil Goyal for_each_compatible_node(caam_node, NULL, "fsl,sec-v4.0") { 1467c3e85bdcSAkhil Goyal const uint32_t *prop = of_get_property(caam_node, 1468c3e85bdcSAkhil Goyal "fsl,sec-era", 1469c3e85bdcSAkhil Goyal NULL); 1470c3e85bdcSAkhil Goyal if (prop) { 1471c3e85bdcSAkhil Goyal rta_set_sec_era( 1472c3e85bdcSAkhil Goyal INTL_SEC_ERA(rte_cpu_to_be_32(*prop))); 1473c3e85bdcSAkhil Goyal break; 1474c3e85bdcSAkhil Goyal } 1475c3e85bdcSAkhil Goyal } 1476c3e85bdcSAkhil Goyal } 1477c3e85bdcSAkhil Goyal 1478c3e85bdcSAkhil Goyal /* Invoke PMD device initialization function */ 1479c3e85bdcSAkhil Goyal retval = dpaa_sec_dev_init(cryptodev); 1480c3e85bdcSAkhil Goyal if (retval == 0) 1481c3e85bdcSAkhil Goyal return 0; 1482c3e85bdcSAkhil Goyal 1483c3e85bdcSAkhil Goyal /* In case of error, cleanup is done */ 1484c3e85bdcSAkhil Goyal if (rte_eal_process_type() == RTE_PROC_PRIMARY) 1485c3e85bdcSAkhil Goyal rte_free(cryptodev->data->dev_private); 1486c3e85bdcSAkhil Goyal 1487c3e85bdcSAkhil Goyal rte_cryptodev_pmd_release_device(cryptodev); 1488c3e85bdcSAkhil Goyal 1489c3e85bdcSAkhil Goyal return -ENXIO; 1490c3e85bdcSAkhil Goyal } 1491c3e85bdcSAkhil Goyal 1492c3e85bdcSAkhil Goyal static int 1493c3e85bdcSAkhil Goyal cryptodev_dpaa_sec_remove(struct rte_dpaa_device *dpaa_dev) 1494c3e85bdcSAkhil Goyal { 1495c3e85bdcSAkhil Goyal struct rte_cryptodev *cryptodev; 1496c3e85bdcSAkhil Goyal int ret; 1497c3e85bdcSAkhil Goyal 1498c3e85bdcSAkhil Goyal cryptodev = dpaa_dev->crypto_dev; 1499c3e85bdcSAkhil Goyal if (cryptodev == NULL) 1500c3e85bdcSAkhil Goyal return -ENODEV; 1501c3e85bdcSAkhil Goyal 1502c3e85bdcSAkhil Goyal ret = dpaa_sec_uninit(cryptodev); 1503c3e85bdcSAkhil Goyal if (ret) 1504c3e85bdcSAkhil Goyal return ret; 1505c3e85bdcSAkhil Goyal 1506f2f020d2SDeclan Doherty return rte_cryptodev_pmd_destroy(cryptodev); 1507c3e85bdcSAkhil Goyal } 1508c3e85bdcSAkhil Goyal 1509c3e85bdcSAkhil Goyal static struct rte_dpaa_driver rte_dpaa_sec_driver = { 1510c3e85bdcSAkhil Goyal .drv_type = FSL_DPAA_CRYPTO, 1511c3e85bdcSAkhil Goyal .driver = { 1512c3e85bdcSAkhil Goyal .name = "DPAA SEC PMD" 1513c3e85bdcSAkhil Goyal }, 1514c3e85bdcSAkhil Goyal .probe = cryptodev_dpaa_sec_probe, 1515c3e85bdcSAkhil Goyal .remove = cryptodev_dpaa_sec_remove, 1516c3e85bdcSAkhil Goyal }; 1517c3e85bdcSAkhil Goyal 1518c3e85bdcSAkhil Goyal static struct cryptodev_driver dpaa_sec_crypto_drv; 1519c3e85bdcSAkhil Goyal 1520c3e85bdcSAkhil Goyal RTE_PMD_REGISTER_DPAA(CRYPTODEV_NAME_DPAA_SEC_PMD, rte_dpaa_sec_driver); 1521c3e85bdcSAkhil Goyal RTE_PMD_REGISTER_CRYPTO_DRIVER(dpaa_sec_crypto_drv, rte_dpaa_sec_driver, 1522c3e85bdcSAkhil Goyal cryptodev_driver_id); 1523