xref: /dpdk/drivers/regex/mlx5/mlx5_regex_control.c (revision fbc8c7003b93a7555887a4195678aca9ee69f4ae)
1*fbc8c700SOri Kam /* SPDX-License-Identifier: BSD-3-Clause
2*fbc8c700SOri Kam  * Copyright 2020 Mellanox Technologies, Ltd
3*fbc8c700SOri Kam  */
4*fbc8c700SOri Kam 
5*fbc8c700SOri Kam #include <errno.h>
6*fbc8c700SOri Kam 
7*fbc8c700SOri Kam #include <rte_log.h>
8*fbc8c700SOri Kam #include <rte_errno.h>
9*fbc8c700SOri Kam #include <rte_malloc.h>
10*fbc8c700SOri Kam #include <rte_regexdev.h>
11*fbc8c700SOri Kam #include <rte_regexdev_core.h>
12*fbc8c700SOri Kam #include <rte_regexdev_driver.h>
13*fbc8c700SOri Kam 
14*fbc8c700SOri Kam #include <mlx5_common.h>
15*fbc8c700SOri Kam #include <mlx5_glue.h>
16*fbc8c700SOri Kam #include <mlx5_devx_cmds.h>
17*fbc8c700SOri Kam #include <mlx5_prm.h>
18*fbc8c700SOri Kam #include <mlx5_common_os.h>
19*fbc8c700SOri Kam 
20*fbc8c700SOri Kam #include "mlx5_regex.h"
21*fbc8c700SOri Kam #include "mlx5_regex_utils.h"
22*fbc8c700SOri Kam #include "mlx5_rxp_csrs.h"
23*fbc8c700SOri Kam #include "mlx5_rxp.h"
24*fbc8c700SOri Kam 
25*fbc8c700SOri Kam #define MLX5_REGEX_NUM_WQE_PER_PAGE (4096/64)
26*fbc8c700SOri Kam 
27*fbc8c700SOri Kam /**
28*fbc8c700SOri Kam  * Returns the number of qp obj to be created.
29*fbc8c700SOri Kam  *
30*fbc8c700SOri Kam  * @param nb_desc
31*fbc8c700SOri Kam  *   The number of descriptors for the queue.
32*fbc8c700SOri Kam  *
33*fbc8c700SOri Kam  * @return
34*fbc8c700SOri Kam  *   The number of obj to be created.
35*fbc8c700SOri Kam  */
36*fbc8c700SOri Kam static uint16_t
37*fbc8c700SOri Kam regex_ctrl_get_nb_obj(uint16_t nb_desc)
38*fbc8c700SOri Kam {
39*fbc8c700SOri Kam 	return ((nb_desc / MLX5_REGEX_NUM_WQE_PER_PAGE) +
40*fbc8c700SOri Kam 		!!(nb_desc % MLX5_REGEX_NUM_WQE_PER_PAGE));
41*fbc8c700SOri Kam }
42*fbc8c700SOri Kam 
43*fbc8c700SOri Kam /**
44*fbc8c700SOri Kam  * destroy CQ.
45*fbc8c700SOri Kam  *
46*fbc8c700SOri Kam  * @param priv
47*fbc8c700SOri Kam  *   Pointer to the priv object.
48*fbc8c700SOri Kam  * @param cp
49*fbc8c700SOri Kam  *   Pointer to the CQ to be destroyed.
50*fbc8c700SOri Kam  *
51*fbc8c700SOri Kam  * @return
52*fbc8c700SOri Kam  *   0 on success, a negative errno value otherwise and rte_errno is set.
53*fbc8c700SOri Kam  */
54*fbc8c700SOri Kam static int
55*fbc8c700SOri Kam regex_ctrl_destroy_cq(struct mlx5_regex_priv *priv, struct mlx5_regex_cq *cq)
56*fbc8c700SOri Kam {
57*fbc8c700SOri Kam 	if (cq->cqe_umem) {
58*fbc8c700SOri Kam 		mlx5_glue->devx_umem_dereg(cq->cqe_umem);
59*fbc8c700SOri Kam 		cq->cqe_umem = NULL;
60*fbc8c700SOri Kam 	}
61*fbc8c700SOri Kam 	if (cq->cqe) {
62*fbc8c700SOri Kam 		rte_free((void *)(uintptr_t)cq->cqe);
63*fbc8c700SOri Kam 		cq->cqe = NULL;
64*fbc8c700SOri Kam 	}
65*fbc8c700SOri Kam 	if (cq->dbr_offset) {
66*fbc8c700SOri Kam 		mlx5_release_dbr(&priv->dbrpgs, cq->dbr_umem, cq->dbr_offset);
67*fbc8c700SOri Kam 		cq->dbr_offset = -1;
68*fbc8c700SOri Kam 	}
69*fbc8c700SOri Kam 	if (cq->obj) {
70*fbc8c700SOri Kam 		mlx5_devx_cmd_destroy(cq->obj);
71*fbc8c700SOri Kam 		cq->obj = NULL;
72*fbc8c700SOri Kam 	}
73*fbc8c700SOri Kam 	return 0;
74*fbc8c700SOri Kam }
75*fbc8c700SOri Kam 
76*fbc8c700SOri Kam /**
77*fbc8c700SOri Kam  * create the CQ object.
78*fbc8c700SOri Kam  *
79*fbc8c700SOri Kam  * @param priv
80*fbc8c700SOri Kam  *   Pointer to the priv object.
81*fbc8c700SOri Kam  * @param cp
82*fbc8c700SOri Kam  *   Pointer to the CQ to be created.
83*fbc8c700SOri Kam  *
84*fbc8c700SOri Kam  * @return
85*fbc8c700SOri Kam  *   0 on success, a negative errno value otherwise and rte_errno is set.
86*fbc8c700SOri Kam  */
87*fbc8c700SOri Kam static int
88*fbc8c700SOri Kam regex_ctrl_create_cq(struct mlx5_regex_priv *priv, struct mlx5_regex_cq *cq)
89*fbc8c700SOri Kam {
90*fbc8c700SOri Kam 	struct mlx5_devx_cq_attr attr = {
91*fbc8c700SOri Kam 		.q_umem_valid = 1,
92*fbc8c700SOri Kam 		.db_umem_valid = 1,
93*fbc8c700SOri Kam 		.eqn = priv->eqn,
94*fbc8c700SOri Kam 	};
95*fbc8c700SOri Kam 	struct mlx5_devx_dbr_page *dbr_page = NULL;
96*fbc8c700SOri Kam 	void *buf = NULL;
97*fbc8c700SOri Kam 	size_t pgsize = sysconf(_SC_PAGESIZE);
98*fbc8c700SOri Kam 	uint32_t cq_size = 1 << cq->log_nb_desc;
99*fbc8c700SOri Kam 	uint32_t i;
100*fbc8c700SOri Kam 
101*fbc8c700SOri Kam 	cq->dbr_offset = mlx5_get_dbr(priv->ctx, &priv->dbrpgs, &dbr_page);
102*fbc8c700SOri Kam 	if (cq->dbr_offset < 0) {
103*fbc8c700SOri Kam 		DRV_LOG(ERR, "Can't allocate cq door bell record.");
104*fbc8c700SOri Kam 		rte_errno  = ENOMEM;
105*fbc8c700SOri Kam 		goto error;
106*fbc8c700SOri Kam 	}
107*fbc8c700SOri Kam 	cq->dbr_umem = mlx5_os_get_umem_id(dbr_page->umem);
108*fbc8c700SOri Kam 	buf = rte_calloc(NULL, 1, sizeof(struct mlx5_cqe) * cq_size, 4096);
109*fbc8c700SOri Kam 	if (!buf) {
110*fbc8c700SOri Kam 		DRV_LOG(ERR, "Can't allocate cqe buffer.");
111*fbc8c700SOri Kam 		rte_errno  = ENOMEM;
112*fbc8c700SOri Kam 		goto error;
113*fbc8c700SOri Kam 	}
114*fbc8c700SOri Kam 	cq->cqe = buf;
115*fbc8c700SOri Kam 	for (i = 0; i < cq_size; i++)
116*fbc8c700SOri Kam 		cq->cqe[i].op_own = 0xff;
117*fbc8c700SOri Kam 	cq->cqe_umem = mlx5_glue->devx_umem_reg(priv->ctx, buf,
118*fbc8c700SOri Kam 						sizeof(struct mlx5_cqe) *
119*fbc8c700SOri Kam 						cq_size, 7);
120*fbc8c700SOri Kam 	if (!cq->cqe_umem) {
121*fbc8c700SOri Kam 		DRV_LOG(ERR, "Can't register cqe mem.");
122*fbc8c700SOri Kam 		rte_errno  = ENOMEM;
123*fbc8c700SOri Kam 		goto error;
124*fbc8c700SOri Kam 	}
125*fbc8c700SOri Kam 	attr.db_umem_offset = cq->dbr_offset;
126*fbc8c700SOri Kam 	attr.db_umem_id = cq->dbr_umem;
127*fbc8c700SOri Kam 	attr.q_umem_id = mlx5_os_get_umem_id(cq->cqe_umem);
128*fbc8c700SOri Kam 	attr.log_cq_size = cq->log_nb_desc;
129*fbc8c700SOri Kam 	attr.uar_page_id = priv->uar->page_id;
130*fbc8c700SOri Kam 	attr.log_page_size = rte_log2_u32(pgsize);
131*fbc8c700SOri Kam 	cq->obj = mlx5_devx_cmd_create_cq(priv->ctx, &attr);
132*fbc8c700SOri Kam 	if (!cq->obj) {
133*fbc8c700SOri Kam 		DRV_LOG(ERR, "Can't create cq object.");
134*fbc8c700SOri Kam 		rte_errno  = ENOMEM;
135*fbc8c700SOri Kam 		goto error;
136*fbc8c700SOri Kam 	}
137*fbc8c700SOri Kam 	return 0;
138*fbc8c700SOri Kam error:
139*fbc8c700SOri Kam 	if (cq->cqe_umem)
140*fbc8c700SOri Kam 		mlx5_glue->devx_umem_dereg(cq->cqe_umem);
141*fbc8c700SOri Kam 	if (buf)
142*fbc8c700SOri Kam 		rte_free(buf);
143*fbc8c700SOri Kam 	if (cq->dbr_offset)
144*fbc8c700SOri Kam 		mlx5_release_dbr(&priv->dbrpgs, cq->dbr_umem, cq->dbr_offset);
145*fbc8c700SOri Kam 	return -rte_errno;
146*fbc8c700SOri Kam }
147*fbc8c700SOri Kam 
148*fbc8c700SOri Kam /**
149*fbc8c700SOri Kam  * Setup the qp.
150*fbc8c700SOri Kam  *
151*fbc8c700SOri Kam  * @param dev
152*fbc8c700SOri Kam  *   Pointer to RegEx dev structure.
153*fbc8c700SOri Kam  * @param qp_ind
154*fbc8c700SOri Kam  *   The queue index to setup.
155*fbc8c700SOri Kam  * @param cfg
156*fbc8c700SOri Kam  *   The queue requested configuration.
157*fbc8c700SOri Kam  *
158*fbc8c700SOri Kam  * @return
159*fbc8c700SOri Kam  *   0 on success, a negative errno value otherwise and rte_errno is set.
160*fbc8c700SOri Kam  */
161*fbc8c700SOri Kam int
162*fbc8c700SOri Kam mlx5_regex_qp_setup(struct rte_regexdev *dev, uint16_t qp_ind,
163*fbc8c700SOri Kam 		    const struct rte_regexdev_qp_conf *cfg)
164*fbc8c700SOri Kam {
165*fbc8c700SOri Kam 	struct mlx5_regex_priv *priv = dev->data->dev_private;
166*fbc8c700SOri Kam 	struct mlx5_regex_qp *qp;
167*fbc8c700SOri Kam 	int ret;
168*fbc8c700SOri Kam 
169*fbc8c700SOri Kam 	qp = &priv->qps[qp_ind];
170*fbc8c700SOri Kam 	qp->flags = cfg->qp_conf_flags;
171*fbc8c700SOri Kam 	qp->cq.log_nb_desc = rte_log2_u32(cfg->nb_desc);
172*fbc8c700SOri Kam 	qp->nb_desc = 1 << qp->cq.log_nb_desc;
173*fbc8c700SOri Kam 	if (qp->flags & RTE_REGEX_QUEUE_PAIR_CFG_OOS_F)
174*fbc8c700SOri Kam 		qp->nb_obj = regex_ctrl_get_nb_obj(qp->nb_desc);
175*fbc8c700SOri Kam 	else
176*fbc8c700SOri Kam 		qp->nb_obj = 1;
177*fbc8c700SOri Kam 	qp->sqs = rte_malloc(NULL,
178*fbc8c700SOri Kam 			     qp->nb_obj * sizeof(struct mlx5_regex_sq), 64);
179*fbc8c700SOri Kam 	if (!qp->sqs) {
180*fbc8c700SOri Kam 		DRV_LOG(ERR, "Can't allocate sq array memory.");
181*fbc8c700SOri Kam 		rte_errno  = ENOMEM;
182*fbc8c700SOri Kam 		return -rte_errno;
183*fbc8c700SOri Kam 	}
184*fbc8c700SOri Kam 	ret = regex_ctrl_create_cq(priv, &qp->cq);
185*fbc8c700SOri Kam 	if (ret) {
186*fbc8c700SOri Kam 		DRV_LOG(ERR, "Can't create cq.");
187*fbc8c700SOri Kam 		goto error;
188*fbc8c700SOri Kam 	}
189*fbc8c700SOri Kam 	return 0;
190*fbc8c700SOri Kam 
191*fbc8c700SOri Kam error:
192*fbc8c700SOri Kam 	regex_ctrl_destroy_cq(priv, &qp->cq);
193*fbc8c700SOri Kam 	return -rte_errno;
194*fbc8c700SOri Kam 
195*fbc8c700SOri Kam }
196