xref: /dpdk/drivers/regex/mlx5/mlx5_regex_control.c (revision dd25bd201d18729b883acc4d4120a5e751807f5f)
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 /**
1159de7b160SMichael Baum  * Destroy the SQ object.
1169de7b160SMichael Baum  *
1179de7b160SMichael Baum  * @param qp
1189de7b160SMichael Baum  *   Pointer to the QP element
1199de7b160SMichael Baum  * @param q_ind
1209de7b160SMichael Baum  *   The index of the queue.
1219de7b160SMichael Baum  *
1229de7b160SMichael Baum  * @return
1239de7b160SMichael Baum  *   0 on success, a negative errno value otherwise and rte_errno is set.
1249de7b160SMichael Baum  */
1259de7b160SMichael Baum static int
1269de7b160SMichael Baum regex_ctrl_destroy_sq(struct mlx5_regex_qp *qp, uint16_t q_ind)
1279de7b160SMichael Baum {
1289de7b160SMichael Baum 	struct mlx5_regex_sq *sq = &qp->sqs[q_ind];
1299de7b160SMichael Baum 
1309de7b160SMichael Baum 	mlx5_devx_sq_destroy(&sq->sq_obj);
1319de7b160SMichael Baum 	memset(sq, 0, sizeof(*sq));
1329de7b160SMichael Baum 	return 0;
1339de7b160SMichael Baum }
1349de7b160SMichael Baum 
1359de7b160SMichael 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
1559de7b160SMichael Baum 	struct mlx5_devx_create_sq_attr attr = {
1569de7b160SMichael Baum 		.user_index = q_ind,
1579de7b160SMichael Baum 		.cqn = qp->cq.cq_obj.cq->id,
1589de7b160SMichael Baum 		.wq_attr = (struct mlx5_devx_wq_attr){
1599de7b160SMichael Baum 			.uar_page = priv->uar->page_id,
1609de7b160SMichael Baum 		},
161*dd25bd20SViacheslav Ovsiienko 		.ts_format = mlx5_ts_format_conv(priv->sq_ts_format),
1629de7b160SMichael Baum 	};
1639de7b160SMichael Baum 	struct mlx5_devx_modify_sq_attr modify_attr = {
1649de7b160SMichael Baum 		.state = MLX5_SQC_STATE_RDY,
1659de7b160SMichael Baum 	};
16692f2c6a3SOri Kam 	struct mlx5_regex_sq *sq = &qp->sqs[q_ind];
16792f2c6a3SOri Kam 	uint32_t pd_num = 0;
16892f2c6a3SOri Kam 	int ret;
16992f2c6a3SOri Kam 
17092f2c6a3SOri Kam 	sq->log_nb_desc = log_nb_desc;
1714d4e245aSYuval Avnery 	sq->ci = 0;
1724d4e245aSYuval Avnery 	sq->pi = 0;
1739de7b160SMichael Baum 	ret = regex_get_pdn(priv->pd, &pd_num);
1749de7b160SMichael Baum 	if (ret)
1759de7b160SMichael Baum 		return ret;
1769de7b160SMichael Baum 	attr.wq_attr.pd = pd_num;
1779de7b160SMichael Baum 	ret = mlx5_devx_sq_create(priv->ctx, &sq->sq_obj, log_nb_desc, &attr,
1789de7b160SMichael Baum 				  SOCKET_ID_ANY);
17992f2c6a3SOri Kam 	if (ret) {
1809de7b160SMichael Baum 		DRV_LOG(ERR, "Can't create SQ object.");
18192f2c6a3SOri Kam 		rte_errno = ENOMEM;
18292f2c6a3SOri Kam 		return -rte_errno;
1839de7b160SMichael Baum 	}
1849de7b160SMichael Baum 	ret = mlx5_devx_cmd_modify_sq(sq->sq_obj.sq, &modify_attr);
1859de7b160SMichael Baum 	if (ret) {
1869de7b160SMichael Baum 		DRV_LOG(ERR, "Can't change SQ state to ready.");
1879de7b160SMichael Baum 		regex_ctrl_destroy_sq(qp, q_ind);
1889de7b160SMichael Baum 		rte_errno = ENOMEM;
1899de7b160SMichael Baum 		return -rte_errno;
1909de7b160SMichael Baum 	}
1919de7b160SMichael Baum 	return 0;
19292f2c6a3SOri Kam #else
19392f2c6a3SOri Kam 	(void)priv;
19492f2c6a3SOri Kam 	(void)qp;
19592f2c6a3SOri Kam 	(void)q_ind;
19692f2c6a3SOri Kam 	(void)log_nb_desc;
19792f2c6a3SOri Kam 	DRV_LOG(ERR, "Cannot get pdn - no DV support.");
19892f2c6a3SOri Kam 	return -ENOTSUP;
19992f2c6a3SOri Kam #endif
20092f2c6a3SOri Kam }
20192f2c6a3SOri Kam 
20292f2c6a3SOri Kam /**
203fbc8c700SOri Kam  * Setup the qp.
204fbc8c700SOri Kam  *
205fbc8c700SOri Kam  * @param dev
206fbc8c700SOri Kam  *   Pointer to RegEx dev structure.
207fbc8c700SOri Kam  * @param qp_ind
208fbc8c700SOri Kam  *   The queue index to setup.
209fbc8c700SOri Kam  * @param cfg
210fbc8c700SOri Kam  *   The queue requested configuration.
211fbc8c700SOri Kam  *
212fbc8c700SOri Kam  * @return
213fbc8c700SOri Kam  *   0 on success, a negative errno value otherwise and rte_errno is set.
214fbc8c700SOri Kam  */
215fbc8c700SOri Kam int
216fbc8c700SOri Kam mlx5_regex_qp_setup(struct rte_regexdev *dev, uint16_t qp_ind,
217fbc8c700SOri Kam 		    const struct rte_regexdev_qp_conf *cfg)
218fbc8c700SOri Kam {
219fbc8c700SOri Kam 	struct mlx5_regex_priv *priv = dev->data->dev_private;
220fbc8c700SOri Kam 	struct mlx5_regex_qp *qp;
22192f2c6a3SOri Kam 	int i;
222a165ee1eSMichael Baum 	int nb_sq_config = 0;
223fbc8c700SOri Kam 	int ret;
22492f2c6a3SOri Kam 	uint16_t log_desc;
225fbc8c700SOri Kam 
226fbc8c700SOri Kam 	qp = &priv->qps[qp_ind];
227fbc8c700SOri Kam 	qp->flags = cfg->qp_conf_flags;
228fbc8c700SOri Kam 	qp->cq.log_nb_desc = rte_log2_u32(cfg->nb_desc);
229fbc8c700SOri Kam 	qp->nb_desc = 1 << qp->cq.log_nb_desc;
230fbc8c700SOri Kam 	if (qp->flags & RTE_REGEX_QUEUE_PAIR_CFG_OOS_F)
231fbc8c700SOri Kam 		qp->nb_obj = regex_ctrl_get_nb_obj(qp->nb_desc);
232fbc8c700SOri Kam 	else
233fbc8c700SOri Kam 		qp->nb_obj = 1;
234fbc8c700SOri Kam 	qp->sqs = rte_malloc(NULL,
235fbc8c700SOri Kam 			     qp->nb_obj * sizeof(struct mlx5_regex_sq), 64);
236fbc8c700SOri Kam 	if (!qp->sqs) {
237fbc8c700SOri Kam 		DRV_LOG(ERR, "Can't allocate sq array memory.");
238fbc8c700SOri Kam 		rte_errno = ENOMEM;
239fbc8c700SOri Kam 		return -rte_errno;
240fbc8c700SOri Kam 	}
24192f2c6a3SOri Kam 	log_desc = rte_log2_u32(qp->nb_desc / qp->nb_obj);
242fbc8c700SOri Kam 	ret = regex_ctrl_create_cq(priv, &qp->cq);
243fbc8c700SOri Kam 	if (ret) {
244fbc8c700SOri Kam 		DRV_LOG(ERR, "Can't create cq.");
24554fa1f6aSYuval Avnery 		goto err_cq;
246fbc8c700SOri Kam 	}
24792f2c6a3SOri Kam 	for (i = 0; i < qp->nb_obj; i++) {
24892f2c6a3SOri Kam 		ret = regex_ctrl_create_sq(priv, qp, i, log_desc);
24992f2c6a3SOri Kam 		if (ret) {
25092f2c6a3SOri Kam 			DRV_LOG(ERR, "Can't create sq.");
251a165ee1eSMichael Baum 			goto err_btree;
25292f2c6a3SOri Kam 		}
253a165ee1eSMichael Baum 		nb_sq_config++;
25492f2c6a3SOri Kam 	}
2555f41b66dSYuval Avnery 
256cda883bbSYuval Avnery 	ret = mlx5_mr_btree_init(&qp->mr_ctrl.cache_bh, MLX5_MR_BTREE_CACHE_N,
257cda883bbSYuval Avnery 				 rte_socket_id());
258cda883bbSYuval Avnery 	if (ret) {
259cda883bbSYuval Avnery 		DRV_LOG(ERR, "Error setting up mr btree");
260cda883bbSYuval Avnery 		goto err_btree;
261cda883bbSYuval Avnery 	}
262cda883bbSYuval Avnery 
26354fa1f6aSYuval Avnery 	ret = mlx5_regexdev_setup_fastpath(priv, qp_ind);
26454fa1f6aSYuval Avnery 	if (ret) {
265cda883bbSYuval Avnery 		DRV_LOG(ERR, "Error setting up fastpath");
26654fa1f6aSYuval Avnery 		goto err_fp;
26754fa1f6aSYuval Avnery 	}
268fbc8c700SOri Kam 	return 0;
269fbc8c700SOri Kam 
27054fa1f6aSYuval Avnery err_fp:
271cda883bbSYuval Avnery 	mlx5_mr_btree_free(&qp->mr_ctrl.cache_bh);
272cda883bbSYuval Avnery err_btree:
273a165ee1eSMichael Baum 	for (i = 0; i < nb_sq_config; i++)
2749de7b160SMichael Baum 		regex_ctrl_destroy_sq(qp, i);
2753ddf5706SMichael Baum 	regex_ctrl_destroy_cq(&qp->cq);
27654fa1f6aSYuval Avnery err_cq:
27754fa1f6aSYuval Avnery 	rte_free(qp->sqs);
27854fa1f6aSYuval Avnery 	return ret;
279fbc8c700SOri Kam }
280