xref: /dpdk/drivers/regex/mlx5/mlx5_regex_control.c (revision 9de7b16015a92742cac0ea42327eb0c5b638ae0a)
1fbc8c700SOri Kam /* SPDX-License-Identifier: BSD-3-Clause
2fbc8c700SOri Kam  * Copyright 2020 Mellanox Technologies, Ltd
3fbc8c700SOri Kam  */
4fbc8c700SOri Kam 
5fbc8c700SOri Kam #include <errno.h>
6fbc8c700SOri Kam 
7fbc8c700SOri Kam #include <rte_log.h>
8fbc8c700SOri Kam #include <rte_errno.h>
93ddf5706SMichael Baum #include <rte_memory.h>
10fbc8c700SOri Kam #include <rte_malloc.h>
11fbc8c700SOri Kam #include <rte_regexdev.h>
12fbc8c700SOri Kam #include <rte_regexdev_core.h>
13fbc8c700SOri Kam #include <rte_regexdev_driver.h>
14cda883bbSYuval Avnery #include <rte_dev.h>
15fbc8c700SOri Kam 
16fbc8c700SOri Kam #include <mlx5_common.h>
17fbc8c700SOri Kam #include <mlx5_glue.h>
18fbc8c700SOri Kam #include <mlx5_devx_cmds.h>
19fbc8c700SOri Kam #include <mlx5_prm.h>
20fbc8c700SOri Kam #include <mlx5_common_os.h>
213ddf5706SMichael Baum #include <mlx5_common_devx.h>
22fbc8c700SOri Kam 
23fbc8c700SOri Kam #include "mlx5_regex.h"
24fbc8c700SOri Kam #include "mlx5_regex_utils.h"
25fbc8c700SOri Kam #include "mlx5_rxp_csrs.h"
26fbc8c700SOri Kam #include "mlx5_rxp.h"
27fbc8c700SOri Kam 
28fbc8c700SOri Kam #define MLX5_REGEX_NUM_WQE_PER_PAGE (4096/64)
29fbc8c700SOri Kam 
30fbc8c700SOri Kam /**
31fbc8c700SOri Kam  * Returns the number of qp obj to be created.
32fbc8c700SOri Kam  *
33fbc8c700SOri Kam  * @param nb_desc
34fbc8c700SOri Kam  *   The number of descriptors for the queue.
35fbc8c700SOri Kam  *
36fbc8c700SOri Kam  * @return
37fbc8c700SOri Kam  *   The number of obj to be created.
38fbc8c700SOri Kam  */
39fbc8c700SOri Kam static uint16_t
40fbc8c700SOri Kam regex_ctrl_get_nb_obj(uint16_t nb_desc)
41fbc8c700SOri Kam {
42fbc8c700SOri Kam 	return ((nb_desc / MLX5_REGEX_NUM_WQE_PER_PAGE) +
43fbc8c700SOri Kam 		!!(nb_desc % MLX5_REGEX_NUM_WQE_PER_PAGE));
44fbc8c700SOri Kam }
45fbc8c700SOri Kam 
46fbc8c700SOri Kam /**
47fbc8c700SOri Kam  * destroy CQ.
48fbc8c700SOri Kam  *
49fbc8c700SOri Kam  * @param cp
50fbc8c700SOri Kam  *   Pointer to the CQ to be destroyed.
51fbc8c700SOri Kam  *
52fbc8c700SOri Kam  * @return
53fbc8c700SOri Kam  *   0 on success, a negative errno value otherwise and rte_errno is set.
54fbc8c700SOri Kam  */
55fbc8c700SOri Kam static int
563ddf5706SMichael Baum regex_ctrl_destroy_cq(struct mlx5_regex_cq *cq)
57fbc8c700SOri Kam {
583ddf5706SMichael Baum 	mlx5_devx_cq_destroy(&cq->cq_obj);
593ddf5706SMichael Baum 	memset(cq, 0, sizeof(*cq));
60fbc8c700SOri Kam 	return 0;
61fbc8c700SOri Kam }
62fbc8c700SOri Kam 
63fbc8c700SOri Kam /**
64fbc8c700SOri Kam  * create the CQ object.
65fbc8c700SOri Kam  *
66fbc8c700SOri Kam  * @param priv
67fbc8c700SOri Kam  *   Pointer to the priv object.
68fbc8c700SOri Kam  * @param cp
69fbc8c700SOri Kam  *   Pointer to the CQ to be created.
70fbc8c700SOri Kam  *
71fbc8c700SOri Kam  * @return
72fbc8c700SOri Kam  *   0 on success, a negative errno value otherwise and rte_errno is set.
73fbc8c700SOri Kam  */
74fbc8c700SOri Kam static int
75fbc8c700SOri Kam regex_ctrl_create_cq(struct mlx5_regex_priv *priv, struct mlx5_regex_cq *cq)
76fbc8c700SOri Kam {
77fbc8c700SOri Kam 	struct mlx5_devx_cq_attr attr = {
783ddf5706SMichael Baum 		.uar_page_id = priv->uar->page_id,
79fbc8c700SOri Kam 	};
803ddf5706SMichael Baum 	int ret;
81fbc8c700SOri Kam 
820db041e7SYuval Avnery 	cq->ci = 0;
833ddf5706SMichael Baum 	ret = mlx5_devx_cq_create(priv->ctx, &cq->cq_obj, cq->log_nb_desc,
843ddf5706SMichael Baum 				  &attr, SOCKET_ID_ANY);
853ddf5706SMichael Baum 	if (ret) {
863ddf5706SMichael Baum 		DRV_LOG(ERR, "Can't create CQ object.");
873ddf5706SMichael Baum 		memset(cq, 0, sizeof(*cq));
88fbc8c700SOri Kam 		rte_errno = ENOMEM;
893ddf5706SMichael Baum 		return -rte_errno;
90fbc8c700SOri Kam 	}
91fbc8c700SOri Kam 	return 0;
92fbc8c700SOri Kam }
93fbc8c700SOri Kam 
9492f2c6a3SOri Kam #ifdef HAVE_IBV_FLOW_DV_SUPPORT
9592f2c6a3SOri Kam static int
9692f2c6a3SOri Kam regex_get_pdn(void *pd, uint32_t *pdn)
9792f2c6a3SOri Kam {
9892f2c6a3SOri Kam 	struct mlx5dv_obj obj;
9992f2c6a3SOri Kam 	struct mlx5dv_pd pd_info;
10092f2c6a3SOri Kam 	int ret = 0;
10192f2c6a3SOri Kam 
10292f2c6a3SOri Kam 	obj.pd.in = pd;
10392f2c6a3SOri Kam 	obj.pd.out = &pd_info;
10492f2c6a3SOri Kam 	ret = mlx5_glue->dv_init_obj(&obj, MLX5DV_OBJ_PD);
10592f2c6a3SOri Kam 	if (ret) {
10692f2c6a3SOri Kam 		DRV_LOG(DEBUG, "Fail to get PD object info");
10792f2c6a3SOri Kam 		return ret;
10892f2c6a3SOri Kam 	}
10992f2c6a3SOri Kam 	*pdn = pd_info.pdn;
11092f2c6a3SOri Kam 	return 0;
11192f2c6a3SOri Kam }
11292f2c6a3SOri Kam #endif
11392f2c6a3SOri Kam 
11492f2c6a3SOri Kam /**
115*9de7b160SMichael Baum  * Destroy the SQ object.
116*9de7b160SMichael Baum  *
117*9de7b160SMichael Baum  * @param qp
118*9de7b160SMichael Baum  *   Pointer to the QP element
119*9de7b160SMichael Baum  * @param q_ind
120*9de7b160SMichael Baum  *   The index of the queue.
121*9de7b160SMichael Baum  *
122*9de7b160SMichael Baum  * @return
123*9de7b160SMichael Baum  *   0 on success, a negative errno value otherwise and rte_errno is set.
124*9de7b160SMichael Baum  */
125*9de7b160SMichael Baum static int
126*9de7b160SMichael Baum regex_ctrl_destroy_sq(struct mlx5_regex_qp *qp, uint16_t q_ind)
127*9de7b160SMichael Baum {
128*9de7b160SMichael Baum 	struct mlx5_regex_sq *sq = &qp->sqs[q_ind];
129*9de7b160SMichael Baum 
130*9de7b160SMichael Baum 	mlx5_devx_sq_destroy(&sq->sq_obj);
131*9de7b160SMichael Baum 	memset(sq, 0, sizeof(*sq));
132*9de7b160SMichael Baum 	return 0;
133*9de7b160SMichael Baum }
134*9de7b160SMichael Baum 
135*9de7b160SMichael Baum /**
13692f2c6a3SOri Kam  * create the SQ object.
13792f2c6a3SOri Kam  *
13892f2c6a3SOri Kam  * @param priv
13992f2c6a3SOri Kam  *   Pointer to the priv object.
14092f2c6a3SOri Kam  * @param qp
14192f2c6a3SOri Kam  *   Pointer to the QP element
14292f2c6a3SOri Kam  * @param q_ind
14392f2c6a3SOri Kam  *   The index of the queue.
14492f2c6a3SOri Kam  * @param log_nb_desc
14592f2c6a3SOri Kam  *   Log 2 of the number of descriptors to be used.
14692f2c6a3SOri Kam  *
14792f2c6a3SOri Kam  * @return
14892f2c6a3SOri Kam  *   0 on success, a negative errno value otherwise and rte_errno is set.
14992f2c6a3SOri Kam  */
15092f2c6a3SOri Kam static int
15192f2c6a3SOri Kam regex_ctrl_create_sq(struct mlx5_regex_priv *priv, struct mlx5_regex_qp *qp,
15292f2c6a3SOri Kam 		     uint16_t q_ind, uint16_t log_nb_desc)
15392f2c6a3SOri Kam {
15492f2c6a3SOri Kam #ifdef HAVE_IBV_FLOW_DV_SUPPORT
155*9de7b160SMichael Baum 	struct mlx5_devx_create_sq_attr attr = {
156*9de7b160SMichael Baum 		.user_index = q_ind,
157*9de7b160SMichael Baum 		.cqn = qp->cq.cq_obj.cq->id,
158*9de7b160SMichael Baum 		.wq_attr = (struct mlx5_devx_wq_attr){
159*9de7b160SMichael Baum 			.uar_page = priv->uar->page_id,
160*9de7b160SMichael Baum 		},
161*9de7b160SMichael Baum 	};
162*9de7b160SMichael Baum 	struct mlx5_devx_modify_sq_attr modify_attr = {
163*9de7b160SMichael Baum 		.state = MLX5_SQC_STATE_RDY,
164*9de7b160SMichael Baum 	};
16592f2c6a3SOri Kam 	struct mlx5_regex_sq *sq = &qp->sqs[q_ind];
16692f2c6a3SOri Kam 	uint32_t pd_num = 0;
16792f2c6a3SOri Kam 	int ret;
16892f2c6a3SOri Kam 
16992f2c6a3SOri Kam 	sq->log_nb_desc = log_nb_desc;
1704d4e245aSYuval Avnery 	sq->ci = 0;
1714d4e245aSYuval Avnery 	sq->pi = 0;
172*9de7b160SMichael Baum 	ret = regex_get_pdn(priv->pd, &pd_num);
173*9de7b160SMichael Baum 	if (ret)
174*9de7b160SMichael Baum 		return ret;
175*9de7b160SMichael Baum 	attr.wq_attr.pd = pd_num;
176*9de7b160SMichael Baum 	ret = mlx5_devx_sq_create(priv->ctx, &sq->sq_obj, log_nb_desc, &attr,
177*9de7b160SMichael Baum 				  SOCKET_ID_ANY);
17892f2c6a3SOri Kam 	if (ret) {
179*9de7b160SMichael Baum 		DRV_LOG(ERR, "Can't create SQ object.");
18092f2c6a3SOri Kam 		rte_errno = ENOMEM;
18192f2c6a3SOri Kam 		return -rte_errno;
182*9de7b160SMichael Baum 	}
183*9de7b160SMichael Baum 	ret = mlx5_devx_cmd_modify_sq(sq->sq_obj.sq, &modify_attr);
184*9de7b160SMichael Baum 	if (ret) {
185*9de7b160SMichael Baum 		DRV_LOG(ERR, "Can't change SQ state to ready.");
186*9de7b160SMichael Baum 		regex_ctrl_destroy_sq(qp, q_ind);
187*9de7b160SMichael Baum 		rte_errno = ENOMEM;
188*9de7b160SMichael Baum 		return -rte_errno;
189*9de7b160SMichael Baum 	}
190*9de7b160SMichael Baum 	return 0;
19192f2c6a3SOri Kam #else
19292f2c6a3SOri Kam 	(void)priv;
19392f2c6a3SOri Kam 	(void)qp;
19492f2c6a3SOri Kam 	(void)q_ind;
19592f2c6a3SOri Kam 	(void)log_nb_desc;
19692f2c6a3SOri Kam 	DRV_LOG(ERR, "Cannot get pdn - no DV support.");
19792f2c6a3SOri Kam 	return -ENOTSUP;
19892f2c6a3SOri Kam #endif
19992f2c6a3SOri Kam }
20092f2c6a3SOri Kam 
20192f2c6a3SOri Kam /**
202fbc8c700SOri Kam  * Setup the qp.
203fbc8c700SOri Kam  *
204fbc8c700SOri Kam  * @param dev
205fbc8c700SOri Kam  *   Pointer to RegEx dev structure.
206fbc8c700SOri Kam  * @param qp_ind
207fbc8c700SOri Kam  *   The queue index to setup.
208fbc8c700SOri Kam  * @param cfg
209fbc8c700SOri Kam  *   The queue requested configuration.
210fbc8c700SOri Kam  *
211fbc8c700SOri Kam  * @return
212fbc8c700SOri Kam  *   0 on success, a negative errno value otherwise and rte_errno is set.
213fbc8c700SOri Kam  */
214fbc8c700SOri Kam int
215fbc8c700SOri Kam mlx5_regex_qp_setup(struct rte_regexdev *dev, uint16_t qp_ind,
216fbc8c700SOri Kam 		    const struct rte_regexdev_qp_conf *cfg)
217fbc8c700SOri Kam {
218fbc8c700SOri Kam 	struct mlx5_regex_priv *priv = dev->data->dev_private;
219fbc8c700SOri Kam 	struct mlx5_regex_qp *qp;
22092f2c6a3SOri Kam 	int i;
221a165ee1eSMichael Baum 	int nb_sq_config = 0;
222fbc8c700SOri Kam 	int ret;
22392f2c6a3SOri Kam 	uint16_t log_desc;
224fbc8c700SOri Kam 
225fbc8c700SOri Kam 	qp = &priv->qps[qp_ind];
226fbc8c700SOri Kam 	qp->flags = cfg->qp_conf_flags;
227fbc8c700SOri Kam 	qp->cq.log_nb_desc = rte_log2_u32(cfg->nb_desc);
228fbc8c700SOri Kam 	qp->nb_desc = 1 << qp->cq.log_nb_desc;
229fbc8c700SOri Kam 	if (qp->flags & RTE_REGEX_QUEUE_PAIR_CFG_OOS_F)
230fbc8c700SOri Kam 		qp->nb_obj = regex_ctrl_get_nb_obj(qp->nb_desc);
231fbc8c700SOri Kam 	else
232fbc8c700SOri Kam 		qp->nb_obj = 1;
233fbc8c700SOri Kam 	qp->sqs = rte_malloc(NULL,
234fbc8c700SOri Kam 			     qp->nb_obj * sizeof(struct mlx5_regex_sq), 64);
235fbc8c700SOri Kam 	if (!qp->sqs) {
236fbc8c700SOri Kam 		DRV_LOG(ERR, "Can't allocate sq array memory.");
237fbc8c700SOri Kam 		rte_errno = ENOMEM;
238fbc8c700SOri Kam 		return -rte_errno;
239fbc8c700SOri Kam 	}
24092f2c6a3SOri Kam 	log_desc = rte_log2_u32(qp->nb_desc / qp->nb_obj);
241fbc8c700SOri Kam 	ret = regex_ctrl_create_cq(priv, &qp->cq);
242fbc8c700SOri Kam 	if (ret) {
243fbc8c700SOri Kam 		DRV_LOG(ERR, "Can't create cq.");
24454fa1f6aSYuval Avnery 		goto err_cq;
245fbc8c700SOri Kam 	}
24692f2c6a3SOri Kam 	for (i = 0; i < qp->nb_obj; i++) {
24792f2c6a3SOri Kam 		ret = regex_ctrl_create_sq(priv, qp, i, log_desc);
24892f2c6a3SOri Kam 		if (ret) {
24992f2c6a3SOri Kam 			DRV_LOG(ERR, "Can't create sq.");
250a165ee1eSMichael Baum 			goto err_btree;
25192f2c6a3SOri Kam 		}
252a165ee1eSMichael Baum 		nb_sq_config++;
25392f2c6a3SOri Kam 	}
2545f41b66dSYuval Avnery 
255cda883bbSYuval Avnery 	ret = mlx5_mr_btree_init(&qp->mr_ctrl.cache_bh, MLX5_MR_BTREE_CACHE_N,
256cda883bbSYuval Avnery 				 rte_socket_id());
257cda883bbSYuval Avnery 	if (ret) {
258cda883bbSYuval Avnery 		DRV_LOG(ERR, "Error setting up mr btree");
259cda883bbSYuval Avnery 		goto err_btree;
260cda883bbSYuval Avnery 	}
261cda883bbSYuval Avnery 
26254fa1f6aSYuval Avnery 	ret = mlx5_regexdev_setup_fastpath(priv, qp_ind);
26354fa1f6aSYuval Avnery 	if (ret) {
264cda883bbSYuval Avnery 		DRV_LOG(ERR, "Error setting up fastpath");
26554fa1f6aSYuval Avnery 		goto err_fp;
26654fa1f6aSYuval Avnery 	}
267fbc8c700SOri Kam 	return 0;
268fbc8c700SOri Kam 
26954fa1f6aSYuval Avnery err_fp:
270cda883bbSYuval Avnery 	mlx5_mr_btree_free(&qp->mr_ctrl.cache_bh);
271cda883bbSYuval Avnery err_btree:
272a165ee1eSMichael Baum 	for (i = 0; i < nb_sq_config; i++)
273*9de7b160SMichael Baum 		regex_ctrl_destroy_sq(qp, i);
2743ddf5706SMichael Baum 	regex_ctrl_destroy_cq(&qp->cq);
27554fa1f6aSYuval Avnery err_cq:
27654fa1f6aSYuval Avnery 	rte_free(qp->sqs);
27754fa1f6aSYuval Avnery 	return ret;
278fbc8c700SOri Kam }
279