#include <rte_branch_prediction.h>
#include <rte_common.h>
+#include <cryptodev_pmd.h>
#include <rte_errno.h>
+#include <rte_mempool.h>
#include <rte_memzone.h>
+#include <rte_string_fns.h>
#include "otx_cryptodev_hw_access.h"
#include "otx_cryptodev_mbox.h"
#include "cpt_pmd_logs.h"
+#include "cpt_pmd_ops_helper.h"
#include "cpt_hw_types.h"
+#define METABUF_POOL_CACHE_SIZE 512
+
/*
* VF HAL functions
* Access its own BAR0/4 registers by passing VF number as 0.
/* CPT VF device initialization */
otx_cpt_vfvq_init(cptvf);
- /* Send msg to PF to assign currnet Q to required group */
+ /* Send msg to PF to assign current Q to required group */
cptvf->vfgrp = group;
err = otx_cpt_send_vf_grp_msg(cptvf, group);
if (err) {
/* Bar0 base address */
cptvf->reg_base = reg_base;
- strncpy(cptvf->dev_name, name, 32);
+
+ /* Save device name */
+ strlcpy(cptvf->dev_name, name, (sizeof(cptvf->dev_name)));
cptvf->pdev = pdev;
return -1;
}
+ /* Gets device type */
+ if (otx_cpt_get_dev_type(cptvf)) {
+ CPT_LOG_ERR("Failed to get device type");
+ return -1;
+ }
+
return 0;
}
return 0;
}
+static int
+otx_cpt_metabuf_mempool_create(const struct rte_cryptodev *dev,
+ struct cpt_instance *instance, uint8_t qp_id,
+ unsigned int nb_elements)
+{
+ char mempool_name[RTE_MEMPOOL_NAMESIZE];
+ struct cpt_qp_meta_info *meta_info;
+ struct rte_mempool *pool;
+ int max_mlen = 0;
+ int sg_mlen = 0;
+ int lb_mlen = 0;
+ int mb_pool_sz;
+ int ret;
+
+ /*
+ * Calculate metabuf length required. The 'crypto_octeontx' device
+ * would be either SYMMETRIC or ASYMMETRIC.
+ */
+
+ if (dev->feature_flags & RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO) {
+
+ /* Get meta len for scatter gather mode */
+ sg_mlen = cpt_pmd_ops_helper_get_mlen_sg_mode();
+
+ /* Extra 32B saved for future considerations */
+ sg_mlen += 4 * sizeof(uint64_t);
+
+ /* Get meta len for linear buffer (direct) mode */
+ lb_mlen = cpt_pmd_ops_helper_get_mlen_direct_mode();
+
+ /* Extra 32B saved for future considerations */
+ lb_mlen += 4 * sizeof(uint64_t);
+
+ /* Check max requirement for meta buffer */
+ max_mlen = RTE_MAX(lb_mlen, sg_mlen);
+ } else {
+
+ /* Asymmetric device */
+
+ /* Get meta len for asymmetric operations */
+ max_mlen = cpt_pmd_ops_helper_asym_get_mlen();
+ }
+
+ /* Allocate mempool */
+
+ snprintf(mempool_name, RTE_MEMPOOL_NAMESIZE, "otx_cpt_mb_%u:%u",
+ dev->data->dev_id, qp_id);
+
+ mb_pool_sz = RTE_MAX(nb_elements, (METABUF_POOL_CACHE_SIZE * rte_lcore_count()));
+
+ pool = rte_mempool_create_empty(mempool_name, mb_pool_sz, max_mlen,
+ METABUF_POOL_CACHE_SIZE, 0,
+ rte_socket_id(), 0);
+
+ if (pool == NULL) {
+ CPT_LOG_ERR("Could not create mempool for metabuf");
+ return rte_errno;
+ }
+
+ ret = rte_mempool_set_ops_byname(pool, RTE_MBUF_DEFAULT_MEMPOOL_OPS,
+ NULL);
+ if (ret) {
+ CPT_LOG_ERR("Could not set mempool ops");
+ goto mempool_free;
+ }
+
+ ret = rte_mempool_populate_default(pool);
+ if (ret <= 0) {
+ CPT_LOG_ERR("Could not populate metabuf pool");
+ goto mempool_free;
+ }
+
+ meta_info = &instance->meta_info;
+
+ meta_info->pool = pool;
+ meta_info->lb_mlen = lb_mlen;
+ meta_info->sg_mlen = sg_mlen;
+
+ return 0;
+
+mempool_free:
+ rte_mempool_free(pool);
+ return ret;
+}
+
+static void
+otx_cpt_metabuf_mempool_destroy(struct cpt_instance *instance)
+{
+ struct cpt_qp_meta_info *meta_info = &instance->meta_info;
+
+ rte_mempool_free(meta_info->pool);
+
+ meta_info->pool = NULL;
+ meta_info->lb_mlen = 0;
+ meta_info->sg_mlen = 0;
+}
+
int
-otx_cpt_get_resource(void *dev, uint8_t group, struct cpt_instance **instance)
+otx_cpt_get_resource(const struct rte_cryptodev *dev, uint8_t group,
+ struct cpt_instance **instance, uint16_t qp_id)
{
int ret = -ENOENT, len, qlen, i;
int chunk_len, chunks, chunk_size;
- struct cpt_vf *cptvf = (struct cpt_vf *)dev;
+ struct cpt_vf *cptvf = dev->data->dev_private;
struct cpt_instance *cpt_instance;
struct command_chunk *chunk_head = NULL, *chunk_prev = NULL;
struct command_chunk *chunk = NULL;
memset(&cptvf->pqueue, 0, sizeof(cptvf->pqueue));
/* Chunks are of fixed size buffers */
+
+ qlen = DEFAULT_CMD_QLEN;
chunks = DEFAULT_CMD_QCHUNKS;
chunk_len = DEFAULT_CMD_QCHUNK_SIZE;
-
- qlen = chunks * chunk_len;
/* Chunk size includes 8 bytes of next chunk ptr */
chunk_size = chunk_len * CPT_INST_SIZE + CPT_NEXT_CHUNK_PTR_SIZE;
len = chunks * RTE_ALIGN(sizeof(struct command_chunk), 8);
/* For pending queue */
- len += qlen * RTE_ALIGN(sizeof(struct rid), 8);
+ len += qlen * RTE_ALIGN(sizeof(cptvf->pqueue.rid_queue[0]), 8);
/* So that instruction queues start as pg size aligned */
len = RTE_ALIGN(len, pg_sz);
RTE_CACHE_LINE_SIZE);
if (!rz) {
ret = rte_errno;
- goto cleanup;
+ goto exit;
}
mem = rz->addr;
- dma_addr = rz->phys_addr;
+ dma_addr = rz->iova;
alloc_len = len;
memset(mem, 0, len);
cpt_instance->rsvd = (uintptr_t)rz;
+ ret = otx_cpt_metabuf_mempool_create(dev, cpt_instance, qp_id, qlen);
+ if (ret) {
+ CPT_LOG_ERR("Could not create mempool for metabuf");
+ goto memzone_free;
+ }
+
/* Pending queue setup */
- cptvf->pqueue.rid_queue = (struct rid *)mem;
- cptvf->pqueue.enq_tail = 0;
- cptvf->pqueue.deq_head = 0;
- cptvf->pqueue.pending_count = 0;
+ cptvf->pqueue.rid_queue = (void **)mem;
- mem += qlen * RTE_ALIGN(sizeof(struct rid), 8);
- len -= qlen * RTE_ALIGN(sizeof(struct rid), 8);
- dma_addr += qlen * RTE_ALIGN(sizeof(struct rid), 8);
+ mem += qlen * RTE_ALIGN(sizeof(cptvf->pqueue.rid_queue[0]), 8);
+ len -= qlen * RTE_ALIGN(sizeof(cptvf->pqueue.rid_queue[0]), 8);
+ dma_addr += qlen * RTE_ALIGN(sizeof(cptvf->pqueue.rid_queue[0]), 8);
/* Alignment wastage */
used_len = alloc_len - len;
CPT_LOG_ERR("Failed to initialize CPT VQ of device %s",
cptvf->dev_name);
ret = -EBUSY;
- goto cleanup;
+ goto mempool_destroy;
}
*instance = cpt_instance;
CPT_LOG_DP_DEBUG("Crypto device (%s) initialized", cptvf->dev_name);
return 0;
-cleanup:
+
+mempool_destroy:
+ otx_cpt_metabuf_mempool_destroy(cpt_instance);
+memzone_free:
rte_memzone_free(rz);
+exit:
*instance = NULL;
return ret;
}
CPT_LOG_DP_DEBUG("Releasing cpt device %s", cptvf->dev_name);
+ otx_cpt_metabuf_mempool_destroy(instance);
+
rz = (struct rte_memzone *)instance->rsvd;
rte_memzone_free(rz);
return 0;
return -EFAULT;
}
- if ((cptvf->vftype != SE_TYPE) && (cptvf->vftype != AE_TYPE)) {
- CPT_LOG_ERR("Fatal error, unexpected vf type %u, for CPT VF "
- "device %s", cptvf->vftype, cptvf->dev_name);
- return -ENOENT;
- }
-
return 0;
}