1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2020 Mellanox Technologies, Ltd
9 #include <rte_memory.h>
10 #include <rte_malloc.h>
11 #include <rte_regexdev.h>
12 #include <rte_regexdev_core.h>
13 #include <rte_regexdev_driver.h>
16 #include <mlx5_common.h>
17 #include <mlx5_glue.h>
18 #include <mlx5_devx_cmds.h>
20 #include <mlx5_common_os.h>
21 #include <mlx5_common_devx.h>
23 #include "mlx5_regex.h"
24 #include "mlx5_regex_utils.h"
25 #include "mlx5_rxp_csrs.h"
28 #define MLX5_REGEX_NUM_WQE_PER_PAGE (4096/64)
30 #define MLX5_REGEX_WQE_LOG_NUM(has_umr, log_desc) \
31 ((has_umr) ? ((log_desc) + 2) : (log_desc))
34 * Returns the number of qp obj to be created.
37 * The number of descriptors for the queue.
40 * The number of obj to be created.
43 regex_ctrl_get_nb_obj(uint16_t nb_desc)
45 return ((nb_desc / MLX5_REGEX_NUM_WQE_PER_PAGE) +
46 !!(nb_desc % MLX5_REGEX_NUM_WQE_PER_PAGE));
53 * Pointer to the CQ to be destroyed.
56 * 0 on success, a negative errno value otherwise and rte_errno is set.
59 regex_ctrl_destroy_cq(struct mlx5_regex_cq *cq)
61 mlx5_devx_cq_destroy(&cq->cq_obj);
62 memset(cq, 0, sizeof(*cq));
67 * create the CQ object.
70 * Pointer to the priv object.
72 * Pointer to the CQ to be created.
75 * 0 on success, a negative errno value otherwise and rte_errno is set.
78 regex_ctrl_create_cq(struct mlx5_regex_priv *priv, struct mlx5_regex_cq *cq)
80 struct mlx5_devx_cq_attr attr = {
81 .uar_page_id = priv->uar->page_id,
86 ret = mlx5_devx_cq_create(priv->cdev->ctx, &cq->cq_obj, cq->log_nb_desc,
87 &attr, SOCKET_ID_ANY);
89 DRV_LOG(ERR, "Can't create CQ object.");
90 memset(cq, 0, sizeof(*cq));
98 * Destroy the SQ object.
101 * Pointer to the QP element
103 * The index of the queue.
106 * 0 on success, a negative errno value otherwise and rte_errno is set.
109 regex_ctrl_destroy_hw_qp(struct mlx5_regex_qp *qp, uint16_t q_ind)
111 struct mlx5_regex_hw_qp *qp_obj = &qp->qps[q_ind];
113 mlx5_devx_qp_destroy(&qp_obj->qp_obj);
114 memset(qp, 0, sizeof(*qp));
119 * create the SQ object.
122 * Pointer to the priv object.
124 * Pointer to the QP element
126 * The index of the queue.
128 * Log 2 of the number of descriptors to be used.
131 * 0 on success, a negative errno value otherwise and rte_errno is set.
134 regex_ctrl_create_hw_qp(struct mlx5_regex_priv *priv, struct mlx5_regex_qp *qp,
135 uint16_t q_ind, uint16_t log_nb_desc)
137 #ifdef HAVE_IBV_FLOW_DV_SUPPORT
138 struct mlx5_devx_qp_attr attr = {
139 .cqn = qp->cq.cq_obj.cq->id,
140 .uar_index = priv->uar->page_id,
141 .pd = priv->cdev->pdn,
142 .ts_format = mlx5_ts_format_conv(priv->qp_ts_format),
145 struct mlx5_regex_hw_qp *qp_obj = &qp->qps[q_ind];
148 qp_obj->log_nb_desc = log_nb_desc;
153 attr.sq_size = RTE_BIT32(MLX5_REGEX_WQE_LOG_NUM(priv->has_umr,
155 attr.mmo = priv->mmo_regex_qp_cap;
156 ret = mlx5_devx_qp_create(priv->cdev->ctx, &qp_obj->qp_obj,
157 MLX5_REGEX_WQE_LOG_NUM(priv->has_umr, log_nb_desc),
158 &attr, SOCKET_ID_ANY);
160 DRV_LOG(ERR, "Can't create QP object.");
164 ret = mlx5_devx_qp2rts(&qp_obj->qp_obj, 0);
166 DRV_LOG(ERR, "Can't change QP state to RTS.");
167 regex_ctrl_destroy_hw_qp(qp, q_ind);
177 DRV_LOG(ERR, "Cannot get pdn - no DV support.");
186 * Pointer to RegEx dev structure.
188 * The queue index to setup.
190 * The queue requested configuration.
193 * 0 on success, a negative errno value otherwise and rte_errno is set.
196 mlx5_regex_qp_setup(struct rte_regexdev *dev, uint16_t qp_ind,
197 const struct rte_regexdev_qp_conf *cfg)
199 struct mlx5_regex_priv *priv = dev->data->dev_private;
200 struct mlx5_regex_qp *qp;
202 int nb_sq_config = 0;
206 qp = &priv->qps[qp_ind];
207 qp->flags = cfg->qp_conf_flags;
208 log_desc = rte_log2_u32(cfg->nb_desc);
210 * UMR mode requires two WQEs(UMR and RegEx WQE) for one descriptor.
211 * For CQ, expand the CQE number multiple with 2.
212 * For SQ, the UMR and RegEx WQE for one descriptor consumes 4 WQEBBS,
213 * expand the WQE number multiple with 4.
215 qp->cq.log_nb_desc = log_desc + (!!priv->has_umr);
216 qp->nb_desc = 1 << log_desc;
217 if (qp->flags & RTE_REGEX_QUEUE_PAIR_CFG_OOS_F)
218 qp->nb_obj = regex_ctrl_get_nb_obj
219 (1 << MLX5_REGEX_WQE_LOG_NUM(priv->has_umr, log_desc));
222 qp->qps = rte_malloc(NULL,
223 qp->nb_obj * sizeof(struct mlx5_regex_hw_qp), 64);
225 DRV_LOG(ERR, "Can't allocate qp array memory.");
229 log_desc = rte_log2_u32(qp->nb_desc / qp->nb_obj);
230 ret = regex_ctrl_create_cq(priv, &qp->cq);
232 DRV_LOG(ERR, "Can't create cq.");
235 for (i = 0; i < qp->nb_obj; i++) {
236 ret = regex_ctrl_create_hw_qp(priv, qp, i, log_desc);
238 DRV_LOG(ERR, "Can't create qp object.");
244 /* Save pointer of global generation number to check memory event. */
245 qp->mr_ctrl.dev_gen_ptr = &priv->mr_scache.dev_gen;
246 ret = mlx5_mr_btree_init(&qp->mr_ctrl.cache_bh, MLX5_MR_BTREE_CACHE_N,
249 DRV_LOG(ERR, "Error setting up mr btree");
253 ret = mlx5_regexdev_setup_fastpath(priv, qp_ind);
255 DRV_LOG(ERR, "Error setting up fastpath");
261 mlx5_mr_btree_free(&qp->mr_ctrl.cache_bh);
263 for (i = 0; i < nb_sq_config; i++)
264 regex_ctrl_destroy_hw_qp(qp, i);
265 regex_ctrl_destroy_cq(&qp->cq);