/*-
* BSD LICENSE
*
- * Copyright(c) 2015 Intel Corporation. All rights reserved.
+ * Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#include <rte_atomic.h>
#include <rte_branch_prediction.h>
#include <rte_common.h>
-#include <rte_ring.h>
#include <rte_mempool.h>
#include <rte_malloc.h>
#include <rte_mbuf.h>
uint32_t active; /**< Callback is executing */
};
+#define RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG ("max_nb_queue_pairs")
+#define RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG ("max_nb_sessions")
+#define RTE_CRYPTODEV_VDEV_SOCKET_ID ("socket_id")
+
+static const char *cryptodev_vdev_valid_params[] = {
+ RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG,
+ RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG,
+ RTE_CRYPTODEV_VDEV_SOCKET_ID
+};
+
+static uint8_t
+number_of_sockets(void)
+{
+ int sockets = 0;
+ int i;
+ const struct rte_memseg *ms = rte_eal_get_physmem_layout();
+
+ for (i = 0; ((i < RTE_MAX_MEMSEG) && (ms[i].addr != NULL)); i++) {
+ if (sockets < ms[i].socket_id)
+ sockets = ms[i].socket_id;
+ }
+
+ /* Number of sockets = maximum socket_id + 1 */
+ return ++sockets;
+}
+
+/** Parse integer from integer argument */
+static int
+parse_integer_arg(const char *key __rte_unused,
+ const char *value, void *extra_args)
+{
+ int *i = (int *) extra_args;
+
+ *i = atoi(value);
+ if (*i < 0) {
+ CDEV_LOG_ERR("Argument has to be positive.");
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+rte_cryptodev_parse_vdev_init_params(struct rte_crypto_vdev_init_params *params,
+ const char *input_args)
+{
+ struct rte_kvargs *kvlist = NULL;
+ int ret = 0;
+
+ if (params == NULL)
+ return -EINVAL;
+
+ if (input_args) {
+ kvlist = rte_kvargs_parse(input_args,
+ cryptodev_vdev_valid_params);
+ if (kvlist == NULL)
+ return -1;
+
+ ret = rte_kvargs_process(kvlist,
+ RTE_CRYPTODEV_VDEV_MAX_NB_QP_ARG,
+ &parse_integer_arg,
+ ¶ms->max_nb_queue_pairs);
+ if (ret < 0)
+ goto free_kvlist;
+
+ ret = rte_kvargs_process(kvlist,
+ RTE_CRYPTODEV_VDEV_MAX_NB_SESS_ARG,
+ &parse_integer_arg,
+ ¶ms->max_nb_sessions);
+ if (ret < 0)
+ goto free_kvlist;
+
+ ret = rte_kvargs_process(kvlist, RTE_CRYPTODEV_VDEV_SOCKET_ID,
+ &parse_integer_arg,
+ ¶ms->socket_id);
+ if (ret < 0)
+ goto free_kvlist;
+
+ if (params->socket_id >= number_of_sockets()) {
+ CDEV_LOG_ERR("Invalid socket id specified to create "
+ "the virtual crypto device on");
+ goto free_kvlist;
+ }
+ }
+
+free_kvlist:
+ rte_kvargs_free(kvlist);
+ return ret;
+}
+
+const char *
+rte_cryptodev_get_feature_name(uint64_t flag)
+{
+ switch (flag) {
+ case RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO:
+ return "SYMMETRIC_CRYPTO";
+ case RTE_CRYPTODEV_FF_ASYMMETRIC_CRYPTO:
+ return "ASYMMETRIC_CRYPTO";
+ case RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING:
+ return "SYM_OPERATION_CHAINING";
+ case RTE_CRYPTODEV_FF_CPU_SSE:
+ return "CPU_SSE";
+ case RTE_CRYPTODEV_FF_CPU_AVX:
+ return "CPU_AVX";
+ case RTE_CRYPTODEV_FF_CPU_AVX2:
+ return "CPU_AVX2";
+ case RTE_CRYPTODEV_FF_CPU_AESNI:
+ return "CPU_AESNI";
+ case RTE_CRYPTODEV_FF_HW_ACCELERATED:
+ return "HW_ACCELERATED";
+
+ default:
+ return NULL;
+ }
+}
+
+
int
rte_cryptodev_create_vdev(const char *name, const char *args)
{
if (nb_qpairs > (dev_info.max_nb_queue_pairs)) {
CDEV_LOG_ERR("Invalid num queue_pairs (%u) for dev %u",
nb_qpairs, dev->data->dev_id);
- return (-EINVAL);
+ return -EINVAL;
}
if (dev->data->queue_pairs == NULL) { /* first time configuration */
{
struct rte_cryptodev *dev;
- /*
- * This function is only safe when called from the primary process
- * in a multi-process setup
- */
- RTE_PROC_PRIMARY_OR_ERR_RET(-E_RTE_SECONDARY);
-
if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
return -EINVAL;
{
struct rte_cryptodev *dev;
- /*
- * This function is only safe when called from the primary process
- * in a multi-process setup
- */
- RTE_PROC_PRIMARY_OR_ERR_RET(-E_RTE_SECONDARY);
-
if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
return -EINVAL;
}
static int
-rte_crypto_session_pool_create(struct rte_cryptodev *dev, unsigned nb_objs,
- unsigned obj_cache_size, int socket_id);
+rte_cryptodev_sym_session_pool_create(struct rte_cryptodev *dev,
+ unsigned nb_objs, unsigned obj_cache_size, int socket_id);
int
rte_cryptodev_configure(uint8_t dev_id, struct rte_cryptodev_config *config)
struct rte_cryptodev *dev;
int diag;
- /*
- * This function is only safe when called from the primary process
- * in a multi-process setup
- */
- RTE_PROC_PRIMARY_OR_ERR_RET(-E_RTE_SECONDARY);
-
if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
- return (-EINVAL);
+ return -EINVAL;
}
dev = &rte_crypto_devices[dev_id];
if (dev->data->dev_started) {
CDEV_LOG_ERR(
"device %d must be stopped to allow configuration", dev_id);
- return (-EBUSY);
+ return -EBUSY;
}
/* Setup new number of queue pairs and reconfigure device. */
}
/* Setup Session mempool for device */
- return rte_crypto_session_pool_create(dev, config->session_mp.nb_objs,
- config->session_mp.cache_size, config->socket_id);
+ return rte_cryptodev_sym_session_pool_create(dev,
+ config->session_mp.nb_objs,
+ config->session_mp.cache_size,
+ config->socket_id);
}
CDEV_LOG_DEBUG("Start dev_id=%" PRIu8, dev_id);
- /*
- * This function is only safe when called from the primary process
- * in a multi-process setup
- */
- RTE_PROC_PRIMARY_OR_ERR_RET(-E_RTE_SECONDARY);
-
if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
- return (-EINVAL);
+ return -EINVAL;
}
dev = &rte_crypto_devices[dev_id];
{
struct rte_cryptodev *dev;
- /*
- * This function is only safe when called from the primary process
- * in a multi-process setup
- */
- RTE_PROC_PRIMARY_OR_RET();
-
if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
return;
struct rte_cryptodev *dev;
int retval;
- /*
- * This function is only safe when called from the primary process
- * in a multi-process setup
- */
- RTE_PROC_PRIMARY_OR_ERR_RET(-EINVAL);
-
if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
return -1;
{
struct rte_cryptodev *dev;
- /*
- * This function is only safe when called from the primary process
- * in a multi-process setup
- */
- RTE_PROC_PRIMARY_OR_ERR_RET(-E_RTE_SECONDARY);
-
if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
- return (-EINVAL);
+ return -EINVAL;
}
dev = &rte_crypto_devices[dev_id];
if (queue_pair_id >= dev->data->nb_queue_pairs) {
CDEV_LOG_ERR("Invalid queue_pair_id=%d", queue_pair_id);
- return (-EINVAL);
+ return -EINVAL;
}
if (dev->data->dev_started) {
if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
CDEV_LOG_ERR("Invalid dev_id=%d", dev_id);
- return (-ENODEV);
+ return -ENODEV;
}
if (stats == NULL) {
struct rte_cryptodev_callback *user_cb;
if (!cb_fn)
- return (-EINVAL);
+ return -EINVAL;
if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
- return (-EINVAL);
+ return -EINVAL;
}
dev = &rte_crypto_devices[dev_id];
}
rte_spinlock_unlock(&rte_cryptodev_cb_lock);
- return ((user_cb == NULL) ? -ENOMEM : 0);
+ return (user_cb == NULL) ? -ENOMEM : 0;
}
int
struct rte_cryptodev_callback *cb, *next;
if (!cb_fn)
- return (-EINVAL);
+ return -EINVAL;
if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
- return (-EINVAL);
+ return -EINVAL;
}
dev = &rte_crypto_devices[dev_id];
static void
-rte_crypto_session_init(struct rte_mempool *mp,
+rte_cryptodev_sym_session_init(struct rte_mempool *mp,
void *opaque_arg,
void *_sess,
__rte_unused unsigned i)
{
- struct rte_cryptodev_session *sess = _sess;
+ struct rte_cryptodev_sym_session *sess = _sess;
struct rte_cryptodev *dev = opaque_arg;
memset(sess, 0, mp->elt_size);
sess->dev_id = dev->data->dev_id;
- sess->type = dev->dev_type;
+ sess->dev_type = dev->dev_type;
sess->mp = mp;
if (dev->dev_ops->session_initialize)
- (*dev->dev_ops->session_initialize)(mp, sess->_private);
+ (*dev->dev_ops->session_initialize)(mp, sess);
}
static int
-rte_crypto_session_pool_create(struct rte_cryptodev *dev, unsigned nb_objs,
- unsigned obj_cache_size, int socket_id)
+rte_cryptodev_sym_session_pool_create(struct rte_cryptodev *dev,
+ unsigned nb_objs, unsigned obj_cache_size, int socket_id)
{
char mp_name[RTE_CRYPTODEV_NAME_MAX_LEN];
unsigned priv_sess_size;
return -ENOMEM;
}
- unsigned elt_size = sizeof(struct rte_cryptodev_session) +
+ unsigned elt_size = sizeof(struct rte_cryptodev_sym_session) +
priv_sess_size;
dev->data->session_pool = rte_mempool_lookup(mp_name);
0, /* private data size */
NULL, /* obj initialization constructor */
NULL, /* obj initialization constructor arg */
- rte_crypto_session_init, /* obj constructor */
+ rte_cryptodev_sym_session_init,
+ /**< obj constructor*/
dev, /* obj constructor arg */
socket_id, /* socket id */
0); /* flags */
return 0;
}
-struct rte_cryptodev_session *
-rte_cryptodev_session_create(uint8_t dev_id, struct rte_crypto_xform *xform)
+struct rte_cryptodev_sym_session *
+rte_cryptodev_sym_session_create(uint8_t dev_id,
+ struct rte_crypto_sym_xform *xform)
{
struct rte_cryptodev *dev;
- struct rte_cryptodev_session *sess;
+ struct rte_cryptodev_sym_session *sess;
void *_sess;
if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
return NULL;
}
- sess = (struct rte_cryptodev_session *)_sess;
+ sess = (struct rte_cryptodev_sym_session *)_sess;
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->session_configure, NULL);
if (dev->dev_ops->session_configure(dev, xform, sess->_private) ==
return sess;
}
-struct rte_cryptodev_session *
-rte_cryptodev_session_free(uint8_t dev_id, struct rte_cryptodev_session *sess)
+struct rte_cryptodev_sym_session *
+rte_cryptodev_sym_session_free(uint8_t dev_id,
+ struct rte_cryptodev_sym_session *sess)
{
struct rte_cryptodev *dev;
dev = &rte_crypto_devices[dev_id];
/* Check the session belongs to this device type */
- if (sess->type != dev->dev_type)
+ if (sess->dev_type != dev->dev_type)
return sess;
/* Let device implementation clear session material */
return NULL;
}
+
+/** Initialise rte_crypto_op mempool element */
+static void
+rte_crypto_op_init(struct rte_mempool *mempool,
+ void *opaque_arg,
+ void *_op_data,
+ __rte_unused unsigned i)
+{
+ struct rte_crypto_op *op = _op_data;
+ enum rte_crypto_op_type type = *(enum rte_crypto_op_type *)opaque_arg;
+
+ memset(_op_data, 0, mempool->elt_size);
+
+ __rte_crypto_op_reset(op, type);
+
+ op->phys_addr = rte_mem_virt2phy(_op_data);
+ op->mempool = mempool;
+}
+
+
+struct rte_mempool *
+rte_crypto_op_pool_create(const char *name, enum rte_crypto_op_type type,
+ unsigned nb_elts, unsigned cache_size, uint16_t priv_size,
+ int socket_id)
+{
+ struct rte_crypto_op_pool_private *priv;
+
+ unsigned elt_size = sizeof(struct rte_crypto_op) +
+ sizeof(struct rte_crypto_sym_op) +
+ priv_size;
+
+ /* lookup mempool in case already allocated */
+ struct rte_mempool *mp = rte_mempool_lookup(name);
+
+ if (mp != NULL) {
+ priv = (struct rte_crypto_op_pool_private *)
+ rte_mempool_get_priv(mp);
+
+ if (mp->elt_size != elt_size ||
+ mp->cache_size < cache_size ||
+ mp->size < nb_elts ||
+ priv->priv_size < priv_size) {
+ mp = NULL;
+ CDEV_LOG_ERR("Mempool %s already exists but with "
+ "incompatible parameters", name);
+ return NULL;
+ }
+ return mp;
+ }
+
+ mp = rte_mempool_create(
+ name,
+ nb_elts,
+ elt_size,
+ cache_size,
+ sizeof(struct rte_crypto_op_pool_private),
+ NULL,
+ NULL,
+ rte_crypto_op_init,
+ &type,
+ socket_id,
+ 0);
+
+ if (mp == NULL) {
+ CDEV_LOG_ERR("Failed to create mempool %s", name);
+ return NULL;
+ }
+
+ priv = (struct rte_crypto_op_pool_private *)
+ rte_mempool_get_priv(mp);
+
+ priv->priv_size = priv_size;
+ priv->type = type;
+
+ return mp;
+}