1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2019 Marvell International Ltd.
3 * Copyright 2020 Mellanox Technologies, Ltd
8 #include <rte_memzone.h>
9 #include <rte_string_fns.h>
11 #include "rte_regexdev.h"
12 #include "rte_regexdev_core.h"
13 #include "rte_regexdev_driver.h"
15 static const char *MZ_RTE_REGEXDEV_DATA = "rte_regexdev_data";
16 struct rte_regexdev rte_regex_devices[RTE_MAX_REGEXDEV_DEVS];
17 /* Shared memory between primary and secondary processes. */
19 struct rte_regexdev_data data[RTE_MAX_REGEXDEV_DEVS];
20 } *rte_regexdev_shared_data;
22 int rte_regexdev_logtype;
25 regexdev_find_free_dev(void)
29 for (i = 0; i < RTE_MAX_REGEXDEV_DEVS; i++) {
30 if (rte_regex_devices[i].state == RTE_REGEXDEV_UNUSED)
33 return RTE_MAX_REGEXDEV_DEVS;
36 static struct rte_regexdev*
37 regexdev_allocated(const char *name)
41 for (i = 0; i < RTE_MAX_REGEXDEV_DEVS; i++) {
42 if (rte_regex_devices[i].state != RTE_REGEXDEV_UNUSED)
43 if (!strcmp(name, rte_regex_devices[i].data->dev_name))
44 return &rte_regex_devices[i];
50 regexdev_shared_data_prepare(void)
52 const unsigned int flags = 0;
53 const struct rte_memzone *mz;
55 if (rte_regexdev_shared_data == NULL) {
56 /* Allocate port data and ownership shared memory. */
57 mz = rte_memzone_reserve(MZ_RTE_REGEXDEV_DATA,
58 sizeof(*rte_regexdev_shared_data),
59 rte_socket_id(), flags);
63 rte_regexdev_shared_data = mz->addr;
64 memset(rte_regexdev_shared_data->data, 0,
65 sizeof(rte_regexdev_shared_data->data));
71 regexdev_check_name(const char *name)
76 RTE_REGEXDEV_LOG(ERR, "Name can't be NULL\n");
79 name_len = strnlen(name, RTE_REGEXDEV_NAME_MAX_LEN);
81 RTE_REGEXDEV_LOG(ERR, "Zero length RegEx device name\n");
84 if (name_len >= RTE_REGEXDEV_NAME_MAX_LEN) {
85 RTE_REGEXDEV_LOG(ERR, "RegEx device name is too long\n");
93 rte_regexdev_register(const char *name)
97 struct rte_regexdev *dev;
99 name_len = regexdev_check_name(name);
102 dev = regexdev_allocated(name);
104 RTE_REGEXDEV_LOG(ERR, "RegEx device already allocated\n");
107 dev_id = regexdev_find_free_dev();
108 if (dev_id == RTE_MAX_REGEXDEV_DEVS) {
110 (ERR, "Reached maximum number of RegEx devices\n");
113 if (regexdev_shared_data_prepare() < 0) {
114 RTE_REGEXDEV_LOG(ERR, "Cannot allocate RegEx shared data\n");
118 dev = &rte_regex_devices[dev_id];
119 dev->state = RTE_REGEXDEV_REGISTERED;
120 if (dev->data == NULL)
121 dev->data = &rte_regexdev_shared_data->data[dev_id];
123 memset(dev->data, 1, sizeof(*dev->data));
124 dev->data->dev_id = dev_id;
125 strlcpy(dev->data->dev_name, name, sizeof(dev->data->dev_name));
130 rte_regexdev_unregister(struct rte_regexdev *dev)
132 dev->state = RTE_REGEXDEV_UNUSED;
135 struct rte_regexdev *
136 rte_regexdev_get_device_by_name(const char *name)
138 if (regexdev_check_name(name) < 0)
140 return regexdev_allocated(name);
144 rte_regexdev_count(void)
149 for (i = 0; i < RTE_MAX_REGEXDEV_DEVS; i++) {
150 if (rte_regex_devices[i].state != RTE_REGEXDEV_UNUSED)
157 rte_regexdev_get_dev_id(const char *name)
164 for (i = 0; i < RTE_MAX_REGEXDEV_DEVS; i++) {
165 if (rte_regex_devices[i].state != RTE_REGEXDEV_UNUSED)
166 if (strcmp(name, rte_regex_devices[i].data->dev_name)) {
167 id = rte_regex_devices[i].data->dev_id;
175 rte_regexdev_is_valid_dev(uint16_t dev_id)
177 if (dev_id >= RTE_MAX_REGEXDEV_DEVS ||
178 rte_regex_devices[dev_id].state != RTE_REGEXDEV_READY)
184 regexdev_info_get(uint8_t dev_id, struct rte_regexdev_info *dev_info)
186 struct rte_regexdev *dev;
188 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
189 if (dev_info == NULL)
191 dev = &rte_regex_devices[dev_id];
192 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_info_get, -ENOTSUP);
193 return (*dev->dev_ops->dev_info_get)(dev, dev_info);
198 rte_regexdev_info_get(uint8_t dev_id, struct rte_regexdev_info *dev_info)
200 return regexdev_info_get(dev_id, dev_info);
204 rte_regexdev_configure(uint8_t dev_id, const struct rte_regexdev_config *cfg)
206 struct rte_regexdev *dev;
207 struct rte_regexdev_info dev_info;
210 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
213 dev = &rte_regex_devices[dev_id];
214 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
215 if (dev->data->dev_started) {
217 (ERR, "Dev %u must be stopped to allow configuration\n",
221 ret = regexdev_info_get(dev_id, &dev_info);
224 if ((cfg->dev_cfg_flags & RTE_REGEXDEV_CFG_CROSS_BUFFER_SCAN_F) &&
225 !(dev_info.regexdev_capa & RTE_REGEXDEV_SUPP_CROSS_BUFFER_F)) {
226 RTE_REGEXDEV_LOG(ERR,
227 "Dev %u doesn't support cross buffer scan\n",
231 if ((cfg->dev_cfg_flags & RTE_REGEXDEV_CFG_MATCH_AS_END_F) &&
232 !(dev_info.regexdev_capa & RTE_REGEXDEV_SUPP_MATCH_AS_END_F)) {
233 RTE_REGEXDEV_LOG(ERR,
234 "Dev %u doesn't support match as end\n",
238 if ((cfg->dev_cfg_flags & RTE_REGEXDEV_CFG_MATCH_ALL_F) &&
239 !(dev_info.regexdev_capa & RTE_REGEXDEV_SUPP_MATCH_ALL_F)) {
240 RTE_REGEXDEV_LOG(ERR,
241 "Dev %u doesn't support match all\n",
245 if (cfg->nb_groups == 0) {
246 RTE_REGEXDEV_LOG(ERR, "Dev %u num of groups must be > 0\n",
250 if (cfg->nb_groups > dev_info.max_groups) {
251 RTE_REGEXDEV_LOG(ERR, "Dev %u num of groups %d > %d\n",
252 dev_id, cfg->nb_groups, dev_info.max_groups);
255 if (cfg->nb_max_matches == 0) {
256 RTE_REGEXDEV_LOG(ERR, "Dev %u num of matches must be > 0\n",
260 if (cfg->nb_max_matches > dev_info.max_matches) {
261 RTE_REGEXDEV_LOG(ERR, "Dev %u num of matches %d > %d\n",
262 dev_id, cfg->nb_max_matches,
263 dev_info.max_matches);
266 if (cfg->nb_queue_pairs == 0) {
267 RTE_REGEXDEV_LOG(ERR, "Dev %u num of queues must be > 0\n",
271 if (cfg->nb_queue_pairs > dev_info.max_queue_pairs) {
272 RTE_REGEXDEV_LOG(ERR, "Dev %u num of queues %d > %d\n",
273 dev_id, cfg->nb_queue_pairs,
274 dev_info.max_queue_pairs);
277 if (cfg->nb_rules_per_group == 0) {
278 RTE_REGEXDEV_LOG(ERR,
279 "Dev %u num of rules per group must be > 0\n",
283 if (cfg->nb_rules_per_group > dev_info.max_rules_per_group) {
284 RTE_REGEXDEV_LOG(ERR,
285 "Dev %u num of rules per group %d > %d\n",
286 dev_id, cfg->nb_rules_per_group,
287 dev_info.max_rules_per_group);
290 ret = (*dev->dev_ops->dev_configure)(dev, cfg);
292 dev->data->dev_conf = *cfg;
297 rte_regexdev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
298 const struct rte_regexdev_qp_conf *qp_conf)
300 struct rte_regexdev *dev;
302 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
303 dev = &rte_regex_devices[dev_id];
304 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_qp_setup, -ENOTSUP);
305 if (dev->data->dev_started) {
307 (ERR, "Dev %u must be stopped to allow configuration\n",
311 if (queue_pair_id >= dev->data->dev_conf.nb_queue_pairs) {
312 RTE_REGEXDEV_LOG(ERR,
313 "Dev %u invalid queue %d > %d\n",
314 dev_id, queue_pair_id,
315 dev->data->dev_conf.nb_queue_pairs);
318 if (dev->data->dev_started) {
320 (ERR, "Dev %u must be stopped to allow configuration\n",
324 return (*dev->dev_ops->dev_qp_setup)(dev, queue_pair_id, qp_conf);
328 rte_regexdev_start(uint8_t dev_id)
330 struct rte_regexdev *dev;
333 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
334 dev = &rte_regex_devices[dev_id];
335 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_start, -ENOTSUP);
336 ret = (*dev->dev_ops->dev_start)(dev);
338 dev->data->dev_started = 1;
343 rte_regexdev_stop(uint8_t dev_id)
345 struct rte_regexdev *dev;
347 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
348 dev = &rte_regex_devices[dev_id];
349 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_stop, -ENOTSUP);
350 (*dev->dev_ops->dev_stop)(dev);
351 dev->data->dev_started = 0;
356 rte_regexdev_close(uint8_t dev_id)
358 struct rte_regexdev *dev;
360 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
361 dev = &rte_regex_devices[dev_id];
362 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP);
363 (*dev->dev_ops->dev_close)(dev);
364 dev->data->dev_started = 0;
365 dev->state = RTE_REGEXDEV_UNUSED;
370 rte_regexdev_attr_get(uint8_t dev_id, enum rte_regexdev_attr_id attr_id,
373 struct rte_regexdev *dev;
375 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
376 dev = &rte_regex_devices[dev_id];
377 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_attr_get, -ENOTSUP);
378 if (attr_value == NULL) {
379 RTE_REGEXDEV_LOG(ERR, "Dev %d attribute value can't be NULL\n",
383 return (*dev->dev_ops->dev_attr_get)(dev, attr_id, attr_value);
387 rte_regexdev_attr_set(uint8_t dev_id, enum rte_regexdev_attr_id attr_id,
388 const void *attr_value)
390 struct rte_regexdev *dev;
392 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
393 dev = &rte_regex_devices[dev_id];
394 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_attr_set, -ENOTSUP);
395 if (attr_value == NULL) {
396 RTE_REGEXDEV_LOG(ERR, "Dev %d attribute value can't be NULL\n",
400 return (*dev->dev_ops->dev_attr_set)(dev, attr_id, attr_value);
404 rte_regexdev_rule_db_update(uint8_t dev_id,
405 const struct rte_regexdev_rule *rules,
408 struct rte_regexdev *dev;
410 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
411 dev = &rte_regex_devices[dev_id];
412 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_rule_db_update, -ENOTSUP);
414 RTE_REGEXDEV_LOG(ERR, "Dev %d rules can't be NULL\n",
418 return (*dev->dev_ops->dev_rule_db_update)(dev, rules, nb_rules);
422 rte_regexdev_rule_db_compile_activate(uint8_t dev_id)
424 struct rte_regexdev *dev;
426 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
427 dev = &rte_regex_devices[dev_id];
428 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_rule_db_compile_activate,
430 return (*dev->dev_ops->dev_rule_db_compile_activate)(dev);
434 rte_regexdev_rule_db_import(uint8_t dev_id, const char *rule_db,
435 uint32_t rule_db_len)
437 struct rte_regexdev *dev;
439 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
440 dev = &rte_regex_devices[dev_id];
441 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_db_import,
443 if (rule_db == NULL) {
444 RTE_REGEXDEV_LOG(ERR, "Dev %d rules can't be NULL\n",
448 return (*dev->dev_ops->dev_db_import)(dev, rule_db, rule_db_len);
452 rte_regexdev_rule_db_export(uint8_t dev_id, char *rule_db)
454 struct rte_regexdev *dev;
456 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
457 dev = &rte_regex_devices[dev_id];
458 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_db_export,
460 return (*dev->dev_ops->dev_db_export)(dev, rule_db);
464 rte_regexdev_xstats_names_get(uint8_t dev_id,
465 struct rte_regexdev_xstats_map *xstats_map)
467 struct rte_regexdev *dev;
469 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
470 dev = &rte_regex_devices[dev_id];
471 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_xstats_names_get,
473 if (xstats_map == NULL) {
474 RTE_REGEXDEV_LOG(ERR, "Dev %d xstats map can't be NULL\n",
478 return (*dev->dev_ops->dev_xstats_names_get)(dev, xstats_map);
482 rte_regexdev_xstats_get(uint8_t dev_id, const uint16_t *ids,
483 uint64_t *values, uint16_t n)
485 struct rte_regexdev *dev;
487 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
488 dev = &rte_regex_devices[dev_id];
489 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_xstats_get, -ENOTSUP);
491 RTE_REGEXDEV_LOG(ERR, "Dev %d ids can't be NULL\n", dev_id);
494 if (values == NULL) {
495 RTE_REGEXDEV_LOG(ERR, "Dev %d values can't be NULL\n", dev_id);
498 return (*dev->dev_ops->dev_xstats_get)(dev, ids, values, n);
502 rte_regexdev_xstats_by_name_get(uint8_t dev_id, const char *name,
503 uint16_t *id, uint64_t *value)
505 struct rte_regexdev *dev;
507 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
508 dev = &rte_regex_devices[dev_id];
509 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_xstats_by_name_get,
512 RTE_REGEXDEV_LOG(ERR, "Dev %d name can't be NULL\n", dev_id);
516 RTE_REGEXDEV_LOG(ERR, "Dev %d id can't be NULL\n", dev_id);
520 RTE_REGEXDEV_LOG(ERR, "Dev %d value can't be NULL\n", dev_id);
523 return (*dev->dev_ops->dev_xstats_by_name_get)(dev, name, id, value);
527 rte_regexdev_xstats_reset(uint8_t dev_id, const uint16_t *ids,
530 struct rte_regexdev *dev;
532 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
533 dev = &rte_regex_devices[dev_id];
534 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_xstats_reset, -ENOTSUP);
536 RTE_REGEXDEV_LOG(ERR, "Dev %d ids can't be NULL\n", dev_id);
539 return (*dev->dev_ops->dev_xstats_reset)(dev, ids, nb_ids);
543 rte_regexdev_selftest(uint8_t dev_id)
545 struct rte_regexdev *dev;
547 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
548 dev = &rte_regex_devices[dev_id];
549 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_selftest, -ENOTSUP);
550 return (*dev->dev_ops->dev_selftest)(dev);
554 rte_regexdev_dump(uint8_t dev_id, FILE *f)
556 struct rte_regexdev *dev;
558 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
559 dev = &rte_regex_devices[dev_id];
560 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_dump, -ENOTSUP);
562 RTE_REGEXDEV_LOG(ERR, "Dev %d file can't be NULL\n", dev_id);
565 return (*dev->dev_ops->dev_dump)(dev, f);