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->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_sq(struct mlx5_regex_qp *qp, uint16_t q_ind)
111 struct mlx5_regex_sq *sq = &qp->sqs[q_ind];
113 mlx5_devx_sq_destroy(&sq->sq_obj);
114 memset(sq, 0, sizeof(*sq));
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_sq(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_create_sq_attr attr = {
140 .cqn = qp->cq.cq_obj.cq->id,
141 .wq_attr = (struct mlx5_devx_wq_attr){
142 .uar_page = priv->uar->page_id,
144 .ts_format = mlx5_ts_format_conv(priv->sq_ts_format),
146 struct mlx5_devx_modify_sq_attr modify_attr = {
147 .state = MLX5_SQC_STATE_RDY,
149 struct mlx5_regex_sq *sq = &qp->sqs[q_ind];
153 sq->log_nb_desc = log_nb_desc;
157 ret = regex_get_pdn(priv->pd, &pd_num);
160 attr.wq_attr.pd = pd_num;
161 ret = mlx5_devx_sq_create(priv->ctx, &sq->sq_obj,
162 MLX5_REGEX_WQE_LOG_NUM(priv->has_umr, log_nb_desc),
163 &attr, SOCKET_ID_ANY);
165 DRV_LOG(ERR, "Can't create SQ object.");
169 ret = mlx5_devx_cmd_modify_sq(sq->sq_obj.sq, &modify_attr);
171 DRV_LOG(ERR, "Can't change SQ state to ready.");
172 regex_ctrl_destroy_sq(qp, q_ind);
182 DRV_LOG(ERR, "Cannot get pdn - no DV support.");
191 * Pointer to RegEx dev structure.
193 * The queue index to setup.
195 * The queue requested configuration.
198 * 0 on success, a negative errno value otherwise and rte_errno is set.
201 mlx5_regex_qp_setup(struct rte_regexdev *dev, uint16_t qp_ind,
202 const struct rte_regexdev_qp_conf *cfg)
204 struct mlx5_regex_priv *priv = dev->data->dev_private;
205 struct mlx5_regex_qp *qp;
207 int nb_sq_config = 0;
211 qp = &priv->qps[qp_ind];
212 qp->flags = cfg->qp_conf_flags;
213 log_desc = rte_log2_u32(cfg->nb_desc);
215 * UMR mode requires two WQEs(UMR and RegEx WQE) for one descriptor.
216 * For CQ, expand the CQE number multiple with 2.
217 * For SQ, the UMR and RegEx WQE for one descriptor consumes 4 WQEBBS,
218 * expand the WQE number multiple with 4.
220 qp->cq.log_nb_desc = log_desc + (!!priv->has_umr);
221 qp->nb_desc = 1 << log_desc;
222 if (qp->flags & RTE_REGEX_QUEUE_PAIR_CFG_OOS_F)
223 qp->nb_obj = regex_ctrl_get_nb_obj
224 (1 << MLX5_REGEX_WQE_LOG_NUM(priv->has_umr, log_desc));
227 qp->sqs = rte_malloc(NULL,
228 qp->nb_obj * sizeof(struct mlx5_regex_sq), 64);
230 DRV_LOG(ERR, "Can't allocate sq array memory.");
234 log_desc = rte_log2_u32(qp->nb_desc / qp->nb_obj);
235 ret = regex_ctrl_create_cq(priv, &qp->cq);
237 DRV_LOG(ERR, "Can't create cq.");
240 for (i = 0; i < qp->nb_obj; i++) {
241 ret = regex_ctrl_create_sq(priv, qp, i, log_desc);
243 DRV_LOG(ERR, "Can't create sq.");
249 /* Save pointer of global generation number to check memory event. */
250 qp->mr_ctrl.dev_gen_ptr = &priv->mr_scache.dev_gen;
251 ret = mlx5_mr_btree_init(&qp->mr_ctrl.cache_bh, MLX5_MR_BTREE_CACHE_N,
254 DRV_LOG(ERR, "Error setting up mr btree");
258 ret = mlx5_regexdev_setup_fastpath(priv, qp_ind);
260 DRV_LOG(ERR, "Error setting up fastpath");
266 mlx5_mr_btree_free(&qp->mr_ctrl.cache_bh);
268 for (i = 0; i < nb_sq_config; i++)
269 regex_ctrl_destroy_sq(qp, i);
270 regex_ctrl_destroy_cq(&qp->cq);