1*2d9fd380Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2*2d9fd380Sjfb8856606  * Copyright(C) 2019 Marvell International Ltd.
3*2d9fd380Sjfb8856606  * Copyright 2020 Mellanox Technologies, Ltd
4*2d9fd380Sjfb8856606  */
5*2d9fd380Sjfb8856606 
6*2d9fd380Sjfb8856606 #include <string.h>
7*2d9fd380Sjfb8856606 
8*2d9fd380Sjfb8856606 #include <rte_memory.h>
9*2d9fd380Sjfb8856606 #include <rte_memcpy.h>
10*2d9fd380Sjfb8856606 #include <rte_memzone.h>
11*2d9fd380Sjfb8856606 #include <rte_string_fns.h>
12*2d9fd380Sjfb8856606 
13*2d9fd380Sjfb8856606 #include "rte_regexdev.h"
14*2d9fd380Sjfb8856606 #include "rte_regexdev_core.h"
15*2d9fd380Sjfb8856606 #include "rte_regexdev_driver.h"
16*2d9fd380Sjfb8856606 
17*2d9fd380Sjfb8856606 static const char *MZ_RTE_REGEXDEV_DATA = "rte_regexdev_data";
18*2d9fd380Sjfb8856606 struct rte_regexdev rte_regex_devices[RTE_MAX_REGEXDEV_DEVS];
19*2d9fd380Sjfb8856606 /* Shared memory between primary and secondary processes. */
20*2d9fd380Sjfb8856606 static struct {
21*2d9fd380Sjfb8856606 	struct rte_regexdev_data data[RTE_MAX_REGEXDEV_DEVS];
22*2d9fd380Sjfb8856606 } *rte_regexdev_shared_data;
23*2d9fd380Sjfb8856606 
24*2d9fd380Sjfb8856606 int rte_regexdev_logtype;
25*2d9fd380Sjfb8856606 
26*2d9fd380Sjfb8856606 static uint16_t
regexdev_find_free_dev(void)27*2d9fd380Sjfb8856606 regexdev_find_free_dev(void)
28*2d9fd380Sjfb8856606 {
29*2d9fd380Sjfb8856606 	uint16_t i;
30*2d9fd380Sjfb8856606 
31*2d9fd380Sjfb8856606 	for (i = 0; i < RTE_MAX_REGEXDEV_DEVS; i++) {
32*2d9fd380Sjfb8856606 		if (rte_regex_devices[i].state == RTE_REGEXDEV_UNUSED)
33*2d9fd380Sjfb8856606 			return i;
34*2d9fd380Sjfb8856606 	}
35*2d9fd380Sjfb8856606 	return RTE_MAX_REGEXDEV_DEVS;
36*2d9fd380Sjfb8856606 }
37*2d9fd380Sjfb8856606 
38*2d9fd380Sjfb8856606 static struct rte_regexdev*
regexdev_allocated(const char * name)39*2d9fd380Sjfb8856606 regexdev_allocated(const char *name)
40*2d9fd380Sjfb8856606 {
41*2d9fd380Sjfb8856606 	uint16_t i;
42*2d9fd380Sjfb8856606 
43*2d9fd380Sjfb8856606 	for (i = 0; i < RTE_MAX_REGEXDEV_DEVS; i++) {
44*2d9fd380Sjfb8856606 		if (rte_regex_devices[i].state != RTE_REGEXDEV_UNUSED)
45*2d9fd380Sjfb8856606 			if (!strcmp(name, rte_regex_devices[i].data->dev_name))
46*2d9fd380Sjfb8856606 				return &rte_regex_devices[i];
47*2d9fd380Sjfb8856606 	}
48*2d9fd380Sjfb8856606 	return NULL;
49*2d9fd380Sjfb8856606 }
50*2d9fd380Sjfb8856606 
51*2d9fd380Sjfb8856606 static int
regexdev_shared_data_prepare(void)52*2d9fd380Sjfb8856606 regexdev_shared_data_prepare(void)
53*2d9fd380Sjfb8856606 {
54*2d9fd380Sjfb8856606 	const unsigned int flags = 0;
55*2d9fd380Sjfb8856606 	const struct rte_memzone *mz;
56*2d9fd380Sjfb8856606 
57*2d9fd380Sjfb8856606 	if (rte_regexdev_shared_data == NULL) {
58*2d9fd380Sjfb8856606 		/* Allocate port data and ownership shared memory. */
59*2d9fd380Sjfb8856606 		mz = rte_memzone_reserve(MZ_RTE_REGEXDEV_DATA,
60*2d9fd380Sjfb8856606 					 sizeof(*rte_regexdev_shared_data),
61*2d9fd380Sjfb8856606 					 rte_socket_id(), flags);
62*2d9fd380Sjfb8856606 		if (mz == NULL)
63*2d9fd380Sjfb8856606 			return -ENOMEM;
64*2d9fd380Sjfb8856606 
65*2d9fd380Sjfb8856606 		rte_regexdev_shared_data = mz->addr;
66*2d9fd380Sjfb8856606 		memset(rte_regexdev_shared_data->data, 0,
67*2d9fd380Sjfb8856606 		       sizeof(rte_regexdev_shared_data->data));
68*2d9fd380Sjfb8856606 	}
69*2d9fd380Sjfb8856606 	return 0;
70*2d9fd380Sjfb8856606 }
71*2d9fd380Sjfb8856606 
72*2d9fd380Sjfb8856606 static int
regexdev_check_name(const char * name)73*2d9fd380Sjfb8856606 regexdev_check_name(const char *name)
74*2d9fd380Sjfb8856606 {
75*2d9fd380Sjfb8856606 	size_t name_len;
76*2d9fd380Sjfb8856606 
77*2d9fd380Sjfb8856606 	if (name == NULL) {
78*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR, "Name can't be NULL\n");
79*2d9fd380Sjfb8856606 		return -EINVAL;
80*2d9fd380Sjfb8856606 	}
81*2d9fd380Sjfb8856606 	name_len = strnlen(name, RTE_REGEXDEV_NAME_MAX_LEN);
82*2d9fd380Sjfb8856606 	if (name_len == 0) {
83*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR, "Zero length RegEx device name\n");
84*2d9fd380Sjfb8856606 		return -EINVAL;
85*2d9fd380Sjfb8856606 	}
86*2d9fd380Sjfb8856606 	if (name_len >= RTE_REGEXDEV_NAME_MAX_LEN) {
87*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR, "RegEx device name is too long\n");
88*2d9fd380Sjfb8856606 		return -EINVAL;
89*2d9fd380Sjfb8856606 	}
90*2d9fd380Sjfb8856606 	return (int)name_len;
91*2d9fd380Sjfb8856606 
92*2d9fd380Sjfb8856606 }
93*2d9fd380Sjfb8856606 
94*2d9fd380Sjfb8856606 struct rte_regexdev *
rte_regexdev_register(const char * name)95*2d9fd380Sjfb8856606 rte_regexdev_register(const char *name)
96*2d9fd380Sjfb8856606 {
97*2d9fd380Sjfb8856606 	uint16_t dev_id;
98*2d9fd380Sjfb8856606 	int name_len;
99*2d9fd380Sjfb8856606 	struct rte_regexdev *dev;
100*2d9fd380Sjfb8856606 
101*2d9fd380Sjfb8856606 	name_len = regexdev_check_name(name);
102*2d9fd380Sjfb8856606 	if (name_len < 0)
103*2d9fd380Sjfb8856606 		return NULL;
104*2d9fd380Sjfb8856606 	dev = regexdev_allocated(name);
105*2d9fd380Sjfb8856606 	if (dev != NULL) {
106*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR, "RegEx device already allocated\n");
107*2d9fd380Sjfb8856606 		return NULL;
108*2d9fd380Sjfb8856606 	}
109*2d9fd380Sjfb8856606 	dev_id = regexdev_find_free_dev();
110*2d9fd380Sjfb8856606 	if (dev_id == RTE_MAX_REGEXDEV_DEVS) {
111*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG
112*2d9fd380Sjfb8856606 			(ERR, "Reached maximum number of RegEx devices\n");
113*2d9fd380Sjfb8856606 		return NULL;
114*2d9fd380Sjfb8856606 	}
115*2d9fd380Sjfb8856606 	if (regexdev_shared_data_prepare() < 0) {
116*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR, "Cannot allocate RegEx shared data\n");
117*2d9fd380Sjfb8856606 		return NULL;
118*2d9fd380Sjfb8856606 	}
119*2d9fd380Sjfb8856606 
120*2d9fd380Sjfb8856606 	dev = &rte_regex_devices[dev_id];
121*2d9fd380Sjfb8856606 	dev->state = RTE_REGEXDEV_REGISTERED;
122*2d9fd380Sjfb8856606 	if (dev->data == NULL)
123*2d9fd380Sjfb8856606 		dev->data = &rte_regexdev_shared_data->data[dev_id];
124*2d9fd380Sjfb8856606 	else
125*2d9fd380Sjfb8856606 		memset(dev->data, 1, sizeof(*dev->data));
126*2d9fd380Sjfb8856606 	dev->data->dev_id = dev_id;
127*2d9fd380Sjfb8856606 	strlcpy(dev->data->dev_name, name, sizeof(dev->data->dev_name));
128*2d9fd380Sjfb8856606 	return dev;
129*2d9fd380Sjfb8856606 }
130*2d9fd380Sjfb8856606 
131*2d9fd380Sjfb8856606 void
rte_regexdev_unregister(struct rte_regexdev * dev)132*2d9fd380Sjfb8856606 rte_regexdev_unregister(struct rte_regexdev *dev)
133*2d9fd380Sjfb8856606 {
134*2d9fd380Sjfb8856606 	dev->state = RTE_REGEXDEV_UNUSED;
135*2d9fd380Sjfb8856606 }
136*2d9fd380Sjfb8856606 
137*2d9fd380Sjfb8856606 struct rte_regexdev *
rte_regexdev_get_device_by_name(const char * name)138*2d9fd380Sjfb8856606 rte_regexdev_get_device_by_name(const char *name)
139*2d9fd380Sjfb8856606 {
140*2d9fd380Sjfb8856606 	if (regexdev_check_name(name) < 0)
141*2d9fd380Sjfb8856606 		return NULL;
142*2d9fd380Sjfb8856606 	return regexdev_allocated(name);
143*2d9fd380Sjfb8856606 }
144*2d9fd380Sjfb8856606 
145*2d9fd380Sjfb8856606 uint8_t
rte_regexdev_count(void)146*2d9fd380Sjfb8856606 rte_regexdev_count(void)
147*2d9fd380Sjfb8856606 {
148*2d9fd380Sjfb8856606 	int i;
149*2d9fd380Sjfb8856606 	int count = 0;
150*2d9fd380Sjfb8856606 
151*2d9fd380Sjfb8856606 	for (i = 0; i < RTE_MAX_REGEXDEV_DEVS; i++) {
152*2d9fd380Sjfb8856606 		if (rte_regex_devices[i].state != RTE_REGEXDEV_UNUSED)
153*2d9fd380Sjfb8856606 			count++;
154*2d9fd380Sjfb8856606 	}
155*2d9fd380Sjfb8856606 	return count;
156*2d9fd380Sjfb8856606 }
157*2d9fd380Sjfb8856606 
158*2d9fd380Sjfb8856606 int
rte_regexdev_get_dev_id(const char * name)159*2d9fd380Sjfb8856606 rte_regexdev_get_dev_id(const char *name)
160*2d9fd380Sjfb8856606 {
161*2d9fd380Sjfb8856606 	int i;
162*2d9fd380Sjfb8856606 	int id = -EINVAL;
163*2d9fd380Sjfb8856606 
164*2d9fd380Sjfb8856606 	if (name == NULL)
165*2d9fd380Sjfb8856606 		return -EINVAL;
166*2d9fd380Sjfb8856606 	for (i = 0; i < RTE_MAX_REGEXDEV_DEVS; i++) {
167*2d9fd380Sjfb8856606 		if (rte_regex_devices[i].state != RTE_REGEXDEV_UNUSED)
168*2d9fd380Sjfb8856606 			if (strcmp(name, rte_regex_devices[i].data->dev_name)) {
169*2d9fd380Sjfb8856606 				id = rte_regex_devices[i].data->dev_id;
170*2d9fd380Sjfb8856606 				break;
171*2d9fd380Sjfb8856606 			}
172*2d9fd380Sjfb8856606 	}
173*2d9fd380Sjfb8856606 	return id;
174*2d9fd380Sjfb8856606 }
175*2d9fd380Sjfb8856606 
176*2d9fd380Sjfb8856606 int
rte_regexdev_is_valid_dev(uint16_t dev_id)177*2d9fd380Sjfb8856606 rte_regexdev_is_valid_dev(uint16_t dev_id)
178*2d9fd380Sjfb8856606 {
179*2d9fd380Sjfb8856606 	if (dev_id >= RTE_MAX_REGEXDEV_DEVS ||
180*2d9fd380Sjfb8856606 	    rte_regex_devices[dev_id].state != RTE_REGEXDEV_READY)
181*2d9fd380Sjfb8856606 		return 0;
182*2d9fd380Sjfb8856606 	return 1;
183*2d9fd380Sjfb8856606 }
184*2d9fd380Sjfb8856606 
185*2d9fd380Sjfb8856606 static int
regexdev_info_get(uint8_t dev_id,struct rte_regexdev_info * dev_info)186*2d9fd380Sjfb8856606 regexdev_info_get(uint8_t dev_id, struct rte_regexdev_info *dev_info)
187*2d9fd380Sjfb8856606 {
188*2d9fd380Sjfb8856606 	struct rte_regexdev *dev;
189*2d9fd380Sjfb8856606 
190*2d9fd380Sjfb8856606 	RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
191*2d9fd380Sjfb8856606 	if (dev_info == NULL)
192*2d9fd380Sjfb8856606 		return -EINVAL;
193*2d9fd380Sjfb8856606 	dev = &rte_regex_devices[dev_id];
194*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_info_get, -ENOTSUP);
195*2d9fd380Sjfb8856606 	return (*dev->dev_ops->dev_info_get)(dev, dev_info);
196*2d9fd380Sjfb8856606 
197*2d9fd380Sjfb8856606 }
198*2d9fd380Sjfb8856606 
199*2d9fd380Sjfb8856606 int
rte_regexdev_info_get(uint8_t dev_id,struct rte_regexdev_info * dev_info)200*2d9fd380Sjfb8856606 rte_regexdev_info_get(uint8_t dev_id, struct rte_regexdev_info *dev_info)
201*2d9fd380Sjfb8856606 {
202*2d9fd380Sjfb8856606 	return regexdev_info_get(dev_id, dev_info);
203*2d9fd380Sjfb8856606 }
204*2d9fd380Sjfb8856606 
205*2d9fd380Sjfb8856606 int
rte_regexdev_configure(uint8_t dev_id,const struct rte_regexdev_config * cfg)206*2d9fd380Sjfb8856606 rte_regexdev_configure(uint8_t dev_id, const struct rte_regexdev_config *cfg)
207*2d9fd380Sjfb8856606 {
208*2d9fd380Sjfb8856606 	struct rte_regexdev *dev;
209*2d9fd380Sjfb8856606 	struct rte_regexdev_info dev_info;
210*2d9fd380Sjfb8856606 	int ret;
211*2d9fd380Sjfb8856606 
212*2d9fd380Sjfb8856606 	RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
213*2d9fd380Sjfb8856606 	if (cfg == NULL)
214*2d9fd380Sjfb8856606 		return -EINVAL;
215*2d9fd380Sjfb8856606 	dev = &rte_regex_devices[dev_id];
216*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
217*2d9fd380Sjfb8856606 	if (dev->data->dev_started) {
218*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG
219*2d9fd380Sjfb8856606 			(ERR, "Dev %u must be stopped to allow configuration\n",
220*2d9fd380Sjfb8856606 			 dev_id);
221*2d9fd380Sjfb8856606 		return -EBUSY;
222*2d9fd380Sjfb8856606 	}
223*2d9fd380Sjfb8856606 	ret = regexdev_info_get(dev_id, &dev_info);
224*2d9fd380Sjfb8856606 	if (ret < 0)
225*2d9fd380Sjfb8856606 		return ret;
226*2d9fd380Sjfb8856606 	if ((cfg->dev_cfg_flags & RTE_REGEXDEV_CFG_CROSS_BUFFER_SCAN_F) &&
227*2d9fd380Sjfb8856606 	    !(dev_info.regexdev_capa & RTE_REGEXDEV_SUPP_CROSS_BUFFER_F)) {
228*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR,
229*2d9fd380Sjfb8856606 				 "Dev %u doesn't support cross buffer scan\n",
230*2d9fd380Sjfb8856606 				 dev_id);
231*2d9fd380Sjfb8856606 		return -EINVAL;
232*2d9fd380Sjfb8856606 	}
233*2d9fd380Sjfb8856606 	if ((cfg->dev_cfg_flags & RTE_REGEXDEV_CFG_MATCH_AS_END_F) &&
234*2d9fd380Sjfb8856606 	    !(dev_info.regexdev_capa & RTE_REGEXDEV_SUPP_MATCH_AS_END_F)) {
235*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR,
236*2d9fd380Sjfb8856606 				 "Dev %u doesn't support match as end\n",
237*2d9fd380Sjfb8856606 				 dev_id);
238*2d9fd380Sjfb8856606 		return -EINVAL;
239*2d9fd380Sjfb8856606 	}
240*2d9fd380Sjfb8856606 	if ((cfg->dev_cfg_flags & RTE_REGEXDEV_CFG_MATCH_ALL_F) &&
241*2d9fd380Sjfb8856606 	    !(dev_info.regexdev_capa & RTE_REGEXDEV_SUPP_MATCH_ALL_F)) {
242*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR,
243*2d9fd380Sjfb8856606 				 "Dev %u doesn't support match all\n",
244*2d9fd380Sjfb8856606 				 dev_id);
245*2d9fd380Sjfb8856606 		return -EINVAL;
246*2d9fd380Sjfb8856606 	}
247*2d9fd380Sjfb8856606 	if (cfg->nb_groups == 0) {
248*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR, "Dev %u num of groups must be > 0\n",
249*2d9fd380Sjfb8856606 				 dev_id);
250*2d9fd380Sjfb8856606 		return -EINVAL;
251*2d9fd380Sjfb8856606 	}
252*2d9fd380Sjfb8856606 	if (cfg->nb_groups > dev_info.max_groups) {
253*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR, "Dev %u num of groups %d > %d\n",
254*2d9fd380Sjfb8856606 				 dev_id, cfg->nb_groups, dev_info.max_groups);
255*2d9fd380Sjfb8856606 		return -EINVAL;
256*2d9fd380Sjfb8856606 	}
257*2d9fd380Sjfb8856606 	if (cfg->nb_max_matches == 0) {
258*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR, "Dev %u num of matches must be > 0\n",
259*2d9fd380Sjfb8856606 				 dev_id);
260*2d9fd380Sjfb8856606 		return -EINVAL;
261*2d9fd380Sjfb8856606 	}
262*2d9fd380Sjfb8856606 	if (cfg->nb_max_matches > dev_info.max_matches) {
263*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR, "Dev %u num of matches %d > %d\n",
264*2d9fd380Sjfb8856606 				 dev_id, cfg->nb_max_matches,
265*2d9fd380Sjfb8856606 				 dev_info.max_matches);
266*2d9fd380Sjfb8856606 		return -EINVAL;
267*2d9fd380Sjfb8856606 	}
268*2d9fd380Sjfb8856606 	if (cfg->nb_queue_pairs == 0) {
269*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR, "Dev %u num of queues must be > 0\n",
270*2d9fd380Sjfb8856606 				 dev_id);
271*2d9fd380Sjfb8856606 		return -EINVAL;
272*2d9fd380Sjfb8856606 	}
273*2d9fd380Sjfb8856606 	if (cfg->nb_queue_pairs > dev_info.max_queue_pairs) {
274*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR, "Dev %u num of queues %d > %d\n",
275*2d9fd380Sjfb8856606 				 dev_id, cfg->nb_queue_pairs,
276*2d9fd380Sjfb8856606 				 dev_info.max_queue_pairs);
277*2d9fd380Sjfb8856606 		return -EINVAL;
278*2d9fd380Sjfb8856606 	}
279*2d9fd380Sjfb8856606 	if (cfg->nb_rules_per_group == 0) {
280*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR,
281*2d9fd380Sjfb8856606 				 "Dev %u num of rules per group must be > 0\n",
282*2d9fd380Sjfb8856606 				 dev_id);
283*2d9fd380Sjfb8856606 		return -EINVAL;
284*2d9fd380Sjfb8856606 	}
285*2d9fd380Sjfb8856606 	if (cfg->nb_rules_per_group > dev_info.max_rules_per_group) {
286*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR,
287*2d9fd380Sjfb8856606 				 "Dev %u num of rules per group %d > %d\n",
288*2d9fd380Sjfb8856606 				 dev_id, cfg->nb_rules_per_group,
289*2d9fd380Sjfb8856606 				 dev_info.max_rules_per_group);
290*2d9fd380Sjfb8856606 		return -EINVAL;
291*2d9fd380Sjfb8856606 	}
292*2d9fd380Sjfb8856606 	ret = (*dev->dev_ops->dev_configure)(dev, cfg);
293*2d9fd380Sjfb8856606 	if (ret == 0)
294*2d9fd380Sjfb8856606 		dev->data->dev_conf = *cfg;
295*2d9fd380Sjfb8856606 	return ret;
296*2d9fd380Sjfb8856606 }
297*2d9fd380Sjfb8856606 
298*2d9fd380Sjfb8856606 int
rte_regexdev_queue_pair_setup(uint8_t dev_id,uint16_t queue_pair_id,const struct rte_regexdev_qp_conf * qp_conf)299*2d9fd380Sjfb8856606 rte_regexdev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
300*2d9fd380Sjfb8856606 			   const struct rte_regexdev_qp_conf *qp_conf)
301*2d9fd380Sjfb8856606 {
302*2d9fd380Sjfb8856606 	struct rte_regexdev *dev;
303*2d9fd380Sjfb8856606 
304*2d9fd380Sjfb8856606 	RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
305*2d9fd380Sjfb8856606 	dev = &rte_regex_devices[dev_id];
306*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_qp_setup, -ENOTSUP);
307*2d9fd380Sjfb8856606 	if (dev->data->dev_started) {
308*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG
309*2d9fd380Sjfb8856606 			(ERR, "Dev %u must be stopped to allow configuration\n",
310*2d9fd380Sjfb8856606 			 dev_id);
311*2d9fd380Sjfb8856606 		return -EBUSY;
312*2d9fd380Sjfb8856606 	}
313*2d9fd380Sjfb8856606 	if (queue_pair_id >= dev->data->dev_conf.nb_queue_pairs) {
314*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR,
315*2d9fd380Sjfb8856606 				 "Dev %u invalid queue %d > %d\n",
316*2d9fd380Sjfb8856606 				 dev_id, queue_pair_id,
317*2d9fd380Sjfb8856606 				 dev->data->dev_conf.nb_queue_pairs);
318*2d9fd380Sjfb8856606 		return -EINVAL;
319*2d9fd380Sjfb8856606 	}
320*2d9fd380Sjfb8856606 	if (dev->data->dev_started) {
321*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG
322*2d9fd380Sjfb8856606 			(ERR, "Dev %u must be stopped to allow configuration\n",
323*2d9fd380Sjfb8856606 			 dev_id);
324*2d9fd380Sjfb8856606 		return -EBUSY;
325*2d9fd380Sjfb8856606 	}
326*2d9fd380Sjfb8856606 	return (*dev->dev_ops->dev_qp_setup)(dev, queue_pair_id, qp_conf);
327*2d9fd380Sjfb8856606 }
328*2d9fd380Sjfb8856606 
329*2d9fd380Sjfb8856606 int
rte_regexdev_start(uint8_t dev_id)330*2d9fd380Sjfb8856606 rte_regexdev_start(uint8_t dev_id)
331*2d9fd380Sjfb8856606 {
332*2d9fd380Sjfb8856606 	struct rte_regexdev *dev;
333*2d9fd380Sjfb8856606 	int ret;
334*2d9fd380Sjfb8856606 
335*2d9fd380Sjfb8856606 	RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
336*2d9fd380Sjfb8856606 	dev = &rte_regex_devices[dev_id];
337*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_start, -ENOTSUP);
338*2d9fd380Sjfb8856606 	ret = (*dev->dev_ops->dev_start)(dev);
339*2d9fd380Sjfb8856606 	if (ret == 0)
340*2d9fd380Sjfb8856606 		dev->data->dev_started = 1;
341*2d9fd380Sjfb8856606 	return ret;
342*2d9fd380Sjfb8856606 }
343*2d9fd380Sjfb8856606 
344*2d9fd380Sjfb8856606 int
rte_regexdev_stop(uint8_t dev_id)345*2d9fd380Sjfb8856606 rte_regexdev_stop(uint8_t dev_id)
346*2d9fd380Sjfb8856606 {
347*2d9fd380Sjfb8856606 	struct rte_regexdev *dev;
348*2d9fd380Sjfb8856606 
349*2d9fd380Sjfb8856606 	RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
350*2d9fd380Sjfb8856606 	dev = &rte_regex_devices[dev_id];
351*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_stop, -ENOTSUP);
352*2d9fd380Sjfb8856606 	(*dev->dev_ops->dev_stop)(dev);
353*2d9fd380Sjfb8856606 	dev->data->dev_started = 0;
354*2d9fd380Sjfb8856606 	return 0;
355*2d9fd380Sjfb8856606 }
356*2d9fd380Sjfb8856606 
357*2d9fd380Sjfb8856606 int
rte_regexdev_close(uint8_t dev_id)358*2d9fd380Sjfb8856606 rte_regexdev_close(uint8_t dev_id)
359*2d9fd380Sjfb8856606 {
360*2d9fd380Sjfb8856606 	struct rte_regexdev *dev;
361*2d9fd380Sjfb8856606 
362*2d9fd380Sjfb8856606 	RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
363*2d9fd380Sjfb8856606 	dev = &rte_regex_devices[dev_id];
364*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP);
365*2d9fd380Sjfb8856606 	(*dev->dev_ops->dev_close)(dev);
366*2d9fd380Sjfb8856606 	dev->data->dev_started = 0;
367*2d9fd380Sjfb8856606 	dev->state = RTE_REGEXDEV_UNUSED;
368*2d9fd380Sjfb8856606 	return 0;
369*2d9fd380Sjfb8856606 }
370*2d9fd380Sjfb8856606 
371*2d9fd380Sjfb8856606 int
rte_regexdev_attr_get(uint8_t dev_id,enum rte_regexdev_attr_id attr_id,void * attr_value)372*2d9fd380Sjfb8856606 rte_regexdev_attr_get(uint8_t dev_id, enum rte_regexdev_attr_id attr_id,
373*2d9fd380Sjfb8856606 		      void *attr_value)
374*2d9fd380Sjfb8856606 {
375*2d9fd380Sjfb8856606 	struct rte_regexdev *dev;
376*2d9fd380Sjfb8856606 
377*2d9fd380Sjfb8856606 	RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
378*2d9fd380Sjfb8856606 	dev = &rte_regex_devices[dev_id];
379*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_attr_get, -ENOTSUP);
380*2d9fd380Sjfb8856606 	if (attr_value == NULL) {
381*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR, "Dev %d attribute value can't be NULL\n",
382*2d9fd380Sjfb8856606 				 dev_id);
383*2d9fd380Sjfb8856606 		return -EINVAL;
384*2d9fd380Sjfb8856606 	}
385*2d9fd380Sjfb8856606 	return (*dev->dev_ops->dev_attr_get)(dev, attr_id, attr_value);
386*2d9fd380Sjfb8856606 }
387*2d9fd380Sjfb8856606 
388*2d9fd380Sjfb8856606 int
rte_regexdev_attr_set(uint8_t dev_id,enum rte_regexdev_attr_id attr_id,const void * attr_value)389*2d9fd380Sjfb8856606 rte_regexdev_attr_set(uint8_t dev_id, enum rte_regexdev_attr_id attr_id,
390*2d9fd380Sjfb8856606 		      const void *attr_value)
391*2d9fd380Sjfb8856606 {
392*2d9fd380Sjfb8856606 	struct rte_regexdev *dev;
393*2d9fd380Sjfb8856606 
394*2d9fd380Sjfb8856606 	RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
395*2d9fd380Sjfb8856606 	dev = &rte_regex_devices[dev_id];
396*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_attr_set, -ENOTSUP);
397*2d9fd380Sjfb8856606 	if (attr_value == NULL) {
398*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR, "Dev %d attribute value can't be NULL\n",
399*2d9fd380Sjfb8856606 				 dev_id);
400*2d9fd380Sjfb8856606 		return -EINVAL;
401*2d9fd380Sjfb8856606 	}
402*2d9fd380Sjfb8856606 	return (*dev->dev_ops->dev_attr_set)(dev, attr_id, attr_value);
403*2d9fd380Sjfb8856606 }
404*2d9fd380Sjfb8856606 
405*2d9fd380Sjfb8856606 int
rte_regexdev_rule_db_update(uint8_t dev_id,const struct rte_regexdev_rule * rules,uint32_t nb_rules)406*2d9fd380Sjfb8856606 rte_regexdev_rule_db_update(uint8_t dev_id,
407*2d9fd380Sjfb8856606 			    const struct rte_regexdev_rule *rules,
408*2d9fd380Sjfb8856606 			    uint32_t nb_rules)
409*2d9fd380Sjfb8856606 {
410*2d9fd380Sjfb8856606 	struct rte_regexdev *dev;
411*2d9fd380Sjfb8856606 
412*2d9fd380Sjfb8856606 	RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
413*2d9fd380Sjfb8856606 	dev = &rte_regex_devices[dev_id];
414*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_rule_db_update, -ENOTSUP);
415*2d9fd380Sjfb8856606 	if (rules == NULL) {
416*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR, "Dev %d rules can't be NULL\n",
417*2d9fd380Sjfb8856606 				 dev_id);
418*2d9fd380Sjfb8856606 		return -EINVAL;
419*2d9fd380Sjfb8856606 	}
420*2d9fd380Sjfb8856606 	return (*dev->dev_ops->dev_rule_db_update)(dev, rules, nb_rules);
421*2d9fd380Sjfb8856606 }
422*2d9fd380Sjfb8856606 
423*2d9fd380Sjfb8856606 int
rte_regexdev_rule_db_compile_activate(uint8_t dev_id)424*2d9fd380Sjfb8856606 rte_regexdev_rule_db_compile_activate(uint8_t dev_id)
425*2d9fd380Sjfb8856606 {
426*2d9fd380Sjfb8856606 	struct rte_regexdev *dev;
427*2d9fd380Sjfb8856606 
428*2d9fd380Sjfb8856606 	RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
429*2d9fd380Sjfb8856606 	dev = &rte_regex_devices[dev_id];
430*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_rule_db_compile_activate,
431*2d9fd380Sjfb8856606 				-ENOTSUP);
432*2d9fd380Sjfb8856606 	return (*dev->dev_ops->dev_rule_db_compile_activate)(dev);
433*2d9fd380Sjfb8856606 }
434*2d9fd380Sjfb8856606 
435*2d9fd380Sjfb8856606 int
rte_regexdev_rule_db_import(uint8_t dev_id,const char * rule_db,uint32_t rule_db_len)436*2d9fd380Sjfb8856606 rte_regexdev_rule_db_import(uint8_t dev_id, const char *rule_db,
437*2d9fd380Sjfb8856606 			    uint32_t rule_db_len)
438*2d9fd380Sjfb8856606 {
439*2d9fd380Sjfb8856606 	struct rte_regexdev *dev;
440*2d9fd380Sjfb8856606 
441*2d9fd380Sjfb8856606 	RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
442*2d9fd380Sjfb8856606 	dev = &rte_regex_devices[dev_id];
443*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_db_import,
444*2d9fd380Sjfb8856606 				-ENOTSUP);
445*2d9fd380Sjfb8856606 	if (rule_db == NULL) {
446*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR, "Dev %d rules can't be NULL\n",
447*2d9fd380Sjfb8856606 				 dev_id);
448*2d9fd380Sjfb8856606 		return -EINVAL;
449*2d9fd380Sjfb8856606 	}
450*2d9fd380Sjfb8856606 	return (*dev->dev_ops->dev_db_import)(dev, rule_db, rule_db_len);
451*2d9fd380Sjfb8856606 }
452*2d9fd380Sjfb8856606 
453*2d9fd380Sjfb8856606 int
rte_regexdev_rule_db_export(uint8_t dev_id,char * rule_db)454*2d9fd380Sjfb8856606 rte_regexdev_rule_db_export(uint8_t dev_id, char *rule_db)
455*2d9fd380Sjfb8856606 {
456*2d9fd380Sjfb8856606 	struct rte_regexdev *dev;
457*2d9fd380Sjfb8856606 
458*2d9fd380Sjfb8856606 	RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
459*2d9fd380Sjfb8856606 	dev = &rte_regex_devices[dev_id];
460*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_db_export,
461*2d9fd380Sjfb8856606 				-ENOTSUP);
462*2d9fd380Sjfb8856606 	return (*dev->dev_ops->dev_db_export)(dev, rule_db);
463*2d9fd380Sjfb8856606 }
464*2d9fd380Sjfb8856606 
465*2d9fd380Sjfb8856606 int
rte_regexdev_xstats_names_get(uint8_t dev_id,struct rte_regexdev_xstats_map * xstats_map)466*2d9fd380Sjfb8856606 rte_regexdev_xstats_names_get(uint8_t dev_id,
467*2d9fd380Sjfb8856606 			      struct rte_regexdev_xstats_map *xstats_map)
468*2d9fd380Sjfb8856606 {
469*2d9fd380Sjfb8856606 	struct rte_regexdev *dev;
470*2d9fd380Sjfb8856606 
471*2d9fd380Sjfb8856606 	RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
472*2d9fd380Sjfb8856606 	dev = &rte_regex_devices[dev_id];
473*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_xstats_names_get,
474*2d9fd380Sjfb8856606 				-ENOTSUP);
475*2d9fd380Sjfb8856606 	if (xstats_map == NULL) {
476*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR, "Dev %d xstats map can't be NULL\n",
477*2d9fd380Sjfb8856606 				 dev_id);
478*2d9fd380Sjfb8856606 		return -EINVAL;
479*2d9fd380Sjfb8856606 	}
480*2d9fd380Sjfb8856606 	return (*dev->dev_ops->dev_xstats_names_get)(dev, xstats_map);
481*2d9fd380Sjfb8856606 }
482*2d9fd380Sjfb8856606 
483*2d9fd380Sjfb8856606 int
rte_regexdev_xstats_get(uint8_t dev_id,const uint16_t * ids,uint64_t * values,uint16_t n)484*2d9fd380Sjfb8856606 rte_regexdev_xstats_get(uint8_t dev_id, const uint16_t *ids,
485*2d9fd380Sjfb8856606 			uint64_t *values, uint16_t n)
486*2d9fd380Sjfb8856606 {
487*2d9fd380Sjfb8856606 	struct rte_regexdev *dev;
488*2d9fd380Sjfb8856606 
489*2d9fd380Sjfb8856606 	RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
490*2d9fd380Sjfb8856606 	dev = &rte_regex_devices[dev_id];
491*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_xstats_get, -ENOTSUP);
492*2d9fd380Sjfb8856606 	if (ids == NULL) {
493*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR, "Dev %d ids can't be NULL\n", dev_id);
494*2d9fd380Sjfb8856606 		return -EINVAL;
495*2d9fd380Sjfb8856606 	}
496*2d9fd380Sjfb8856606 	if (values == NULL) {
497*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR, "Dev %d values can't be NULL\n", dev_id);
498*2d9fd380Sjfb8856606 		return -EINVAL;
499*2d9fd380Sjfb8856606 	}
500*2d9fd380Sjfb8856606 	return (*dev->dev_ops->dev_xstats_get)(dev, ids, values, n);
501*2d9fd380Sjfb8856606 }
502*2d9fd380Sjfb8856606 
503*2d9fd380Sjfb8856606 int
rte_regexdev_xstats_by_name_get(uint8_t dev_id,const char * name,uint16_t * id,uint64_t * value)504*2d9fd380Sjfb8856606 rte_regexdev_xstats_by_name_get(uint8_t dev_id, const char *name,
505*2d9fd380Sjfb8856606 				uint16_t *id, uint64_t *value)
506*2d9fd380Sjfb8856606 {
507*2d9fd380Sjfb8856606 	struct rte_regexdev *dev;
508*2d9fd380Sjfb8856606 
509*2d9fd380Sjfb8856606 	RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
510*2d9fd380Sjfb8856606 	dev = &rte_regex_devices[dev_id];
511*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_xstats_by_name_get,
512*2d9fd380Sjfb8856606 				-ENOTSUP);
513*2d9fd380Sjfb8856606 	if (name == NULL) {
514*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR, "Dev %d name can't be NULL\n", dev_id);
515*2d9fd380Sjfb8856606 		return -EINVAL;
516*2d9fd380Sjfb8856606 	}
517*2d9fd380Sjfb8856606 	if (id == NULL) {
518*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR, "Dev %d id can't be NULL\n", dev_id);
519*2d9fd380Sjfb8856606 		return -EINVAL;
520*2d9fd380Sjfb8856606 	}
521*2d9fd380Sjfb8856606 	if (value == NULL) {
522*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR, "Dev %d value can't be NULL\n", dev_id);
523*2d9fd380Sjfb8856606 		return -EINVAL;
524*2d9fd380Sjfb8856606 	}
525*2d9fd380Sjfb8856606 	return (*dev->dev_ops->dev_xstats_by_name_get)(dev, name, id, value);
526*2d9fd380Sjfb8856606 }
527*2d9fd380Sjfb8856606 
528*2d9fd380Sjfb8856606 int
rte_regexdev_xstats_reset(uint8_t dev_id,const uint16_t * ids,uint16_t nb_ids)529*2d9fd380Sjfb8856606 rte_regexdev_xstats_reset(uint8_t dev_id, const uint16_t *ids,
530*2d9fd380Sjfb8856606 			  uint16_t nb_ids)
531*2d9fd380Sjfb8856606 {
532*2d9fd380Sjfb8856606 	struct rte_regexdev *dev;
533*2d9fd380Sjfb8856606 
534*2d9fd380Sjfb8856606 	RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
535*2d9fd380Sjfb8856606 	dev = &rte_regex_devices[dev_id];
536*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_xstats_reset, -ENOTSUP);
537*2d9fd380Sjfb8856606 	if (ids == NULL) {
538*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR, "Dev %d ids can't be NULL\n", dev_id);
539*2d9fd380Sjfb8856606 		return -EINVAL;
540*2d9fd380Sjfb8856606 	}
541*2d9fd380Sjfb8856606 	return (*dev->dev_ops->dev_xstats_reset)(dev, ids, nb_ids);
542*2d9fd380Sjfb8856606 }
543*2d9fd380Sjfb8856606 
544*2d9fd380Sjfb8856606 int
rte_regexdev_selftest(uint8_t dev_id)545*2d9fd380Sjfb8856606 rte_regexdev_selftest(uint8_t dev_id)
546*2d9fd380Sjfb8856606 {
547*2d9fd380Sjfb8856606 	struct rte_regexdev *dev;
548*2d9fd380Sjfb8856606 
549*2d9fd380Sjfb8856606 	RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
550*2d9fd380Sjfb8856606 	dev = &rte_regex_devices[dev_id];
551*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_selftest, -ENOTSUP);
552*2d9fd380Sjfb8856606 	return (*dev->dev_ops->dev_selftest)(dev);
553*2d9fd380Sjfb8856606 }
554*2d9fd380Sjfb8856606 
555*2d9fd380Sjfb8856606 int
rte_regexdev_dump(uint8_t dev_id,FILE * f)556*2d9fd380Sjfb8856606 rte_regexdev_dump(uint8_t dev_id, FILE *f)
557*2d9fd380Sjfb8856606 {
558*2d9fd380Sjfb8856606 	struct rte_regexdev *dev;
559*2d9fd380Sjfb8856606 
560*2d9fd380Sjfb8856606 	RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
561*2d9fd380Sjfb8856606 	dev = &rte_regex_devices[dev_id];
562*2d9fd380Sjfb8856606 	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_dump, -ENOTSUP);
563*2d9fd380Sjfb8856606 	if (f == NULL) {
564*2d9fd380Sjfb8856606 		RTE_REGEXDEV_LOG(ERR, "Dev %d file can't be NULL\n", dev_id);
565*2d9fd380Sjfb8856606 		return -EINVAL;
566*2d9fd380Sjfb8856606 	}
567*2d9fd380Sjfb8856606 	return (*dev->dev_ops->dev_dump)(dev, f);
568*2d9fd380Sjfb8856606 }
569