#define MLX5_CRYPTO_DRIVER_NAME crypto_mlx5
#define MLX5_CRYPTO_LOG_NAME pmd.crypto.mlx5
-#define MLX5_CRYPTO_MAX_QPS 1024
+#define MLX5_CRYPTO_MAX_QPS 128
#define MLX5_CRYPTO_MAX_SEGS 56
#define MLX5_CRYPTO_FEATURE_FLAGS \
return 1;
}
-static __rte_always_inline void
-mlx5_crypto_uar_write(uint64_t val, struct mlx5_crypto_priv *priv)
-{
-#ifdef RTE_ARCH_64
- *priv->uar_addr = val;
-#else /* !RTE_ARCH_64 */
- rte_spinlock_lock(&priv->uar32_sl);
- *(volatile uint32_t *)priv->uar_addr = val;
- rte_io_wmb();
- *((volatile uint32_t *)priv->uar_addr + 1) = val >> 32;
- rte_spinlock_unlock(&priv->uar32_sl);
-#endif
-}
-
static uint16_t
mlx5_crypto_enqueue_burst(void *queue_pair, struct rte_crypto_op **ops,
uint16_t nb_ops)
qp->pi++;
} while (--remain);
qp->stats.enqueued_count += nb_ops;
- rte_io_wmb();
- qp->qp_obj.db_rec[MLX5_SND_DBR] = rte_cpu_to_be_32(qp->db_pi);
- rte_wmb();
- mlx5_crypto_uar_write(*(volatile uint64_t *)qp->wqe, qp->priv);
- rte_wmb();
+ mlx5_doorbell_ring(&priv->uar.bf_db, *(volatile uint64_t *)qp->wqe,
+ qp->db_pi, &qp->qp_obj.db_rec[MLX5_SND_DBR],
+ !priv->uar.dbnc);
return nb_ops;
}
ucseg->if_cf_toe_cq_res = RTE_BE32(1u << MLX5_UMRC_IF_OFFSET);
ucseg->mkey_mask = RTE_BE64(1u << 0); /* Mkey length bit. */
ucseg->ko_to_bs = rte_cpu_to_be_32
- ((RTE_ALIGN(priv->max_segs_num, 4u) <<
+ ((MLX5_CRYPTO_KLM_SEGS_NUM(priv->umr_wqe_size) <<
MLX5_UMRC_KO_OFFSET) | (4 << MLX5_UMRC_TO_BS_OFFSET));
bsf->keytag = priv->keytag;
/* Init RDMA WRITE WQE. */
.umr_en = 1,
.crypto_en = 1,
.set_remote_rw = 1,
- .klm_num = RTE_ALIGN(priv->max_segs_num, 4),
+ .klm_num = MLX5_CRYPTO_KLM_SEGS_NUM(priv->umr_wqe_size),
};
for (umr = (struct mlx5_umr_wqe *)qp->qp_obj.umem_buf, i = 0;
uint16_t log_nb_desc = rte_log2_u32(qp_conf->nb_descriptors);
uint32_t ret;
uint32_t alloc_size = sizeof(*qp);
+ uint32_t log_wqbb_n;
struct mlx5_devx_cq_attr cq_attr = {
- .uar_page_id = mlx5_os_get_devx_uar_page_id(priv->uar),
+ .uar_page_id = mlx5_os_get_devx_uar_page_id(priv->uar.obj),
};
if (dev->data->queue_pairs[qp_id] != NULL)
DRV_LOG(ERR, "Failed to create CQ.");
goto error;
}
+ log_wqbb_n = rte_log2_u32(RTE_BIT32(log_nb_desc) *
+ (priv->wqe_set_size / MLX5_SEND_WQE_BB));
attr.pd = priv->cdev->pdn;
- attr.uar_index = mlx5_os_get_devx_uar_page_id(priv->uar);
+ attr.uar_index = mlx5_os_get_devx_uar_page_id(priv->uar.obj);
attr.cqn = qp->cq_obj.cq->id;
- attr.rq_size = 0;
- attr.sq_size = RTE_BIT32(log_nb_desc);
+ attr.num_of_receive_wqes = 0;
+ attr.num_of_send_wqbbs = RTE_BIT32(log_wqbb_n);
attr.ts_format =
mlx5_ts_format_conv(priv->cdev->config.hca_attr.qp_ts_format);
- ret = mlx5_devx_qp_create(priv->cdev->ctx, &qp->qp_obj, log_nb_desc,
- &attr, socket_id);
+ ret = mlx5_devx_qp_create(priv->cdev->ctx, &qp->qp_obj,
+ attr.num_of_send_wqbbs * MLX5_WQE_SIZE,
+ &attr, socket_id);
if (ret) {
DRV_LOG(ERR, "Failed to create QP.");
goto error;
}
- if (mlx5_mr_ctrl_init(&qp->mr_ctrl, priv->cdev,
+ if (mlx5_mr_ctrl_init(&qp->mr_ctrl, &priv->cdev->mr_scache.dev_gen,
priv->dev_config.socket_id) != 0) {
DRV_LOG(ERR, "Cannot allocate MR Btree for qp %u.",
(uint32_t)qp_id);
.sym_configure_raw_dp_ctx = NULL,
};
-static void
-mlx5_crypto_uar_release(struct mlx5_crypto_priv *priv)
-{
- if (priv->uar != NULL) {
- mlx5_glue->devx_free_uar(priv->uar);
- priv->uar = NULL;
- }
-}
-
-static int
-mlx5_crypto_uar_prepare(struct mlx5_crypto_priv *priv)
-{
- priv->uar = mlx5_devx_alloc_uar(priv->cdev->ctx, -1);
- if (priv->uar)
- priv->uar_addr = mlx5_os_get_devx_uar_reg_addr(priv->uar);
- if (priv->uar == NULL || priv->uar_addr == NULL) {
- rte_errno = errno;
- DRV_LOG(ERR, "Failed to allocate UAR.");
- return -1;
- }
- return 0;
-}
-
-
static int
mlx5_crypto_args_check_handler(const char *key, const char *val, void *opaque)
{
int ret;
int i;
- if (strcmp(key, "class") == 0)
- return 0;
if (strcmp(key, "wcs_file") == 0) {
file = fopen(val, "rb");
if (file == NULL) {
return -errno;
}
if (strcmp(key, "max_segs_num") == 0) {
- if (!tmp || tmp > MLX5_CRYPTO_MAX_SEGS) {
- DRV_LOG(WARNING, "Invalid max_segs_num: %d, should"
- " be less than %d.",
- (uint32_t)tmp, MLX5_CRYPTO_MAX_SEGS);
+ if (!tmp) {
+ DRV_LOG(ERR, "max_segs_num must be greater than 0.");
rte_errno = EINVAL;
return -rte_errno;
}
attr->credential_pointer = (uint32_t)tmp;
} else if (strcmp(key, "keytag") == 0) {
devarg_prms->keytag = tmp;
- } else {
- DRV_LOG(WARNING, "Invalid key %s.", key);
}
return 0;
}
static int
-mlx5_crypto_parse_devargs(struct rte_devargs *devargs,
+mlx5_crypto_parse_devargs(struct mlx5_kvargs_ctrl *mkvlist,
struct mlx5_crypto_devarg_params *devarg_prms)
{
struct mlx5_devx_crypto_login_attr *attr = &devarg_prms->login_attr;
- struct rte_kvargs *kvlist;
+ const char **params = (const char *[]){
+ "credential_id",
+ "import_kek_id",
+ "keytag",
+ "max_segs_num",
+ "wcs_file",
+ NULL,
+ };
/* Default values. */
attr->credential_pointer = 0;
attr->session_import_kek_ptr = 0;
devarg_prms->keytag = 0;
devarg_prms->max_segs_num = 8;
- if (devargs == NULL) {
+ if (mkvlist == NULL) {
DRV_LOG(ERR,
- "No login devargs in order to enable crypto operations in the device.");
- rte_errno = EINVAL;
- return -1;
- }
- kvlist = rte_kvargs_parse(devargs->args, NULL);
- if (kvlist == NULL) {
- DRV_LOG(ERR, "Failed to parse devargs.");
+ "No login devargs in order to enable crypto operations in the device.");
rte_errno = EINVAL;
return -1;
}
- if (rte_kvargs_process(kvlist, NULL, mlx5_crypto_args_check_handler,
- devarg_prms) != 0) {
+ if (mlx5_kvargs_process(mkvlist, params, mlx5_crypto_args_check_handler,
+ devarg_prms) != 0) {
DRV_LOG(ERR, "Devargs handler function Failed.");
- rte_kvargs_free(kvlist);
rte_errno = EINVAL;
return -1;
}
- rte_kvargs_free(kvlist);
if (devarg_prms->login_devarg == false) {
DRV_LOG(ERR,
- "No login credential devarg in order to enable crypto operations "
- "in the device.");
+ "No login credential devarg in order to enable crypto operations in the device.");
rte_errno = EINVAL;
return -1;
}
return 0;
}
+/*
+ * Calculate UMR WQE size and RDMA Write WQE size with the
+ * following limitations:
+ * - Each WQE size is multiple of 64.
+ * - The summarize of both UMR WQE and RDMA_W WQE is a power of 2.
+ * - The number of entries in the UMR WQE's KLM list is multiple of 4.
+ */
+static void
+mlx5_crypto_get_wqe_sizes(uint32_t segs_num, uint32_t *umr_size,
+ uint32_t *rdmaw_size)
+{
+ uint32_t diff, wqe_set_size;
+
+ *umr_size = MLX5_CRYPTO_UMR_WQE_STATIC_SIZE +
+ RTE_ALIGN(segs_num, 4) *
+ sizeof(struct mlx5_wqe_dseg);
+ /* Make sure UMR WQE size is multiple of WQBB. */
+ *umr_size = RTE_ALIGN(*umr_size, MLX5_SEND_WQE_BB);
+ *rdmaw_size = sizeof(struct mlx5_rdma_write_wqe) +
+ sizeof(struct mlx5_wqe_dseg) *
+ (segs_num <= 2 ? 2 : 2 +
+ RTE_ALIGN(segs_num - 2, 4));
+ /* Make sure RDMA_WRITE WQE size is multiple of WQBB. */
+ *rdmaw_size = RTE_ALIGN(*rdmaw_size, MLX5_SEND_WQE_BB);
+ wqe_set_size = *rdmaw_size + *umr_size;
+ diff = rte_align32pow2(wqe_set_size) - wqe_set_size;
+ /* Make sure wqe_set size is power of 2. */
+ if (diff)
+ *umr_size += diff;
+}
+
+static uint8_t
+mlx5_crypto_max_segs_num(uint16_t max_wqe_size)
+{
+ int klms_sizes = max_wqe_size - MLX5_CRYPTO_UMR_WQE_STATIC_SIZE;
+ uint32_t max_segs_cap = RTE_ALIGN_FLOOR(klms_sizes, MLX5_SEND_WQE_BB) /
+ sizeof(struct mlx5_wqe_dseg);
+
+ MLX5_ASSERT(klms_sizes >= MLX5_SEND_WQE_BB);
+ while (max_segs_cap) {
+ uint32_t umr_wqe_size, rdmw_wqe_size;
+
+ mlx5_crypto_get_wqe_sizes(max_segs_cap, &umr_wqe_size,
+ &rdmw_wqe_size);
+ if (umr_wqe_size <= max_wqe_size &&
+ rdmw_wqe_size <= max_wqe_size)
+ break;
+ max_segs_cap -= 4;
+ }
+ return max_segs_cap;
+}
+
+static int
+mlx5_crypto_configure_wqe_size(struct mlx5_crypto_priv *priv,
+ uint16_t max_wqe_size, uint32_t max_segs_num)
+{
+ uint32_t rdmw_wqe_size, umr_wqe_size;
+
+ mlx5_crypto_get_wqe_sizes(max_segs_num, &umr_wqe_size,
+ &rdmw_wqe_size);
+ priv->wqe_set_size = rdmw_wqe_size + umr_wqe_size;
+ if (umr_wqe_size > max_wqe_size ||
+ rdmw_wqe_size > max_wqe_size) {
+ DRV_LOG(ERR, "Invalid max_segs_num: %u. should be %u or lower.",
+ max_segs_num,
+ mlx5_crypto_max_segs_num(max_wqe_size));
+ rte_errno = EINVAL;
+ return -EINVAL;
+ }
+ priv->umr_wqe_size = (uint16_t)umr_wqe_size;
+ priv->umr_wqe_stride = priv->umr_wqe_size / MLX5_SEND_WQE_BB;
+ priv->max_rdmar_ds = rdmw_wqe_size / sizeof(struct mlx5_wqe_dseg);
+ return 0;
+}
+
static int
-mlx5_crypto_dev_probe(struct mlx5_common_device *cdev)
+mlx5_crypto_dev_probe(struct mlx5_common_device *cdev,
+ struct mlx5_kvargs_ctrl *mkvlist)
{
struct rte_cryptodev *crypto_dev;
struct mlx5_devx_obj *login;
RTE_CRYPTODEV_PMD_DEFAULT_MAX_NB_QUEUE_PAIRS,
};
const char *ibdev_name = mlx5_os_get_ctx_device_name(cdev->ctx);
- uint16_t rdmw_wqe_size;
int ret;
if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
rte_errno = ENOTSUP;
return -ENOTSUP;
}
- ret = mlx5_crypto_parse_devargs(cdev->dev->devargs, &devarg_prms);
+ ret = mlx5_crypto_parse_devargs(mkvlist, &devarg_prms);
if (ret) {
DRV_LOG(ERR, "Failed to parse devargs.");
return -rte_errno;
}
- login = mlx5_devx_cmd_create_crypto_login_obj(cdev->ctx,
- &devarg_prms.login_attr);
- if (login == NULL) {
- DRV_LOG(ERR, "Failed to configure login.");
- return -rte_errno;
- }
crypto_dev = rte_cryptodev_pmd_create(ibdev_name, cdev->dev,
&init_params);
if (crypto_dev == NULL) {
crypto_dev->driver_id = mlx5_crypto_driver_id;
priv = crypto_dev->data->dev_private;
priv->cdev = cdev;
- priv->login_obj = login;
priv->crypto_dev = crypto_dev;
- if (mlx5_crypto_uar_prepare(priv) != 0) {
+ if (mlx5_devx_uar_prepare(cdev, &priv->uar) != 0) {
rte_cryptodev_pmd_destroy(priv->crypto_dev);
return -1;
}
+ login = mlx5_devx_cmd_create_crypto_login_obj(cdev->ctx,
+ &devarg_prms.login_attr);
+ if (login == NULL) {
+ DRV_LOG(ERR, "Failed to configure login.");
+ mlx5_devx_uar_release(&priv->uar);
+ rte_cryptodev_pmd_destroy(priv->crypto_dev);
+ return -rte_errno;
+ }
+ priv->login_obj = login;
priv->keytag = rte_cpu_to_be_64(devarg_prms.keytag);
- priv->max_segs_num = devarg_prms.max_segs_num;
- priv->umr_wqe_size = sizeof(struct mlx5_wqe_umr_bsf_seg) +
- sizeof(struct mlx5_wqe_cseg) +
- sizeof(struct mlx5_wqe_umr_cseg) +
- sizeof(struct mlx5_wqe_mkey_cseg) +
- RTE_ALIGN(priv->max_segs_num, 4) *
- sizeof(struct mlx5_wqe_dseg);
- rdmw_wqe_size = sizeof(struct mlx5_rdma_write_wqe) +
- sizeof(struct mlx5_wqe_dseg) *
- (priv->max_segs_num <= 2 ? 2 : 2 +
- RTE_ALIGN(priv->max_segs_num - 2, 4));
- priv->wqe_set_size = priv->umr_wqe_size + rdmw_wqe_size;
- priv->umr_wqe_stride = priv->umr_wqe_size / MLX5_SEND_WQE_BB;
- priv->max_rdmar_ds = rdmw_wqe_size / sizeof(struct mlx5_wqe_dseg);
+ ret = mlx5_crypto_configure_wqe_size(priv,
+ cdev->config.hca_attr.max_wqe_sz_sq, devarg_prms.max_segs_num);
+ if (ret) {
+ mlx5_devx_uar_release(&priv->uar);
+ rte_cryptodev_pmd_destroy(priv->crypto_dev);
+ return -1;
+ }
+ DRV_LOG(INFO, "Max number of segments: %u.",
+ (unsigned int)RTE_MIN(
+ MLX5_CRYPTO_KLM_SEGS_NUM(priv->umr_wqe_size),
+ (uint16_t)(priv->max_rdmar_ds - 2)));
pthread_mutex_lock(&priv_list_lock);
TAILQ_INSERT_TAIL(&mlx5_crypto_priv_list, priv, next);
pthread_mutex_unlock(&priv_list_lock);
TAILQ_REMOVE(&mlx5_crypto_priv_list, priv, next);
pthread_mutex_unlock(&priv_list_lock);
if (priv) {
- mlx5_crypto_uar_release(priv);
- rte_cryptodev_pmd_destroy(priv->crypto_dev);
claim_zero(mlx5_devx_cmd_destroy(priv->login_obj));
+ mlx5_devx_uar_release(&priv->uar);
+ rte_cryptodev_pmd_destroy(priv->crypto_dev);
}
return 0;
}
RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
PCI_DEVICE_ID_MELLANOX_CONNECTX6)
},
+ {
+ RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
+ PCI_DEVICE_ID_MELLANOX_CONNECTX6DX)
+ },
+ {
+ RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
+ PCI_DEVICE_ID_MELLANOX_CONNECTX6DXBF)
+ },
{
.vendor_id = 0
}