1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2019 Marvell International Ltd.
3 * Copyright 2020 Mellanox Technologies, Ltd
8 #include <rte_memory.h>
9 #include <rte_memcpy.h>
10 #include <rte_memzone.h>
11 #include <rte_string_fns.h>
13 #include "rte_regexdev.h"
14 #include "rte_regexdev_core.h"
15 #include "rte_regexdev_driver.h"
17 static const char *MZ_RTE_REGEXDEV_DATA = "rte_regexdev_data";
18 struct rte_regexdev rte_regex_devices[RTE_MAX_REGEXDEV_DEVS];
19 /* Shared memory between primary and secondary processes. */
21 struct rte_regexdev_data data[RTE_MAX_REGEXDEV_DEVS];
22 } *rte_regexdev_shared_data;
24 int rte_regexdev_logtype;
27 regexdev_find_free_dev(void)
31 for (i = 0; i < RTE_MAX_REGEXDEV_DEVS; i++) {
32 if (rte_regex_devices[i].state == RTE_REGEXDEV_UNUSED)
35 return RTE_MAX_REGEXDEV_DEVS;
38 static struct rte_regexdev*
39 regexdev_allocated(const char *name)
43 for (i = 0; i < RTE_MAX_REGEXDEV_DEVS; i++) {
44 if (rte_regex_devices[i].state != RTE_REGEXDEV_UNUSED)
45 if (!strcmp(name, rte_regex_devices[i].data->dev_name))
46 return &rte_regex_devices[i];
52 regexdev_shared_data_prepare(void)
54 const unsigned int flags = 0;
55 const struct rte_memzone *mz;
57 if (rte_regexdev_shared_data == NULL) {
58 /* Allocate port data and ownership shared memory. */
59 mz = rte_memzone_reserve(MZ_RTE_REGEXDEV_DATA,
60 sizeof(*rte_regexdev_shared_data),
61 rte_socket_id(), flags);
65 rte_regexdev_shared_data = mz->addr;
66 memset(rte_regexdev_shared_data->data, 0,
67 sizeof(rte_regexdev_shared_data->data));
73 regexdev_check_name(const char *name)
78 RTE_REGEXDEV_LOG(ERR, "Name can't be NULL\n");
81 name_len = strnlen(name, RTE_REGEXDEV_NAME_MAX_LEN);
83 RTE_REGEXDEV_LOG(ERR, "Zero length RegEx device name\n");
86 if (name_len >= RTE_REGEXDEV_NAME_MAX_LEN) {
87 RTE_REGEXDEV_LOG(ERR, "RegEx device name is too long\n");
95 rte_regexdev_register(const char *name)
99 struct rte_regexdev *dev;
101 name_len = regexdev_check_name(name);
104 dev = regexdev_allocated(name);
106 RTE_REGEXDEV_LOG(ERR, "RegEx device already allocated\n");
109 dev_id = regexdev_find_free_dev();
110 if (dev_id == RTE_MAX_REGEXDEV_DEVS) {
112 (ERR, "Reached maximum number of RegEx devices\n");
115 if (regexdev_shared_data_prepare() < 0) {
116 RTE_REGEXDEV_LOG(ERR, "Cannot allocate RegEx shared data\n");
120 dev = &rte_regex_devices[dev_id];
121 dev->state = RTE_REGEXDEV_REGISTERED;
122 if (dev->data == NULL)
123 dev->data = &rte_regexdev_shared_data->data[dev_id];
125 memset(dev->data, 1, sizeof(*dev->data));
126 dev->data->dev_id = dev_id;
127 strlcpy(dev->data->dev_name, name, sizeof(dev->data->dev_name));
132 rte_regexdev_unregister(struct rte_regexdev *dev)
134 dev->state = RTE_REGEXDEV_UNUSED;
137 struct rte_regexdev *
138 rte_regexdev_get_device_by_name(const char *name)
140 if (regexdev_check_name(name) < 0)
142 return regexdev_allocated(name);
146 rte_regexdev_count(void)
151 for (i = 0; i < RTE_MAX_REGEXDEV_DEVS; i++) {
152 if (rte_regex_devices[i].state != RTE_REGEXDEV_UNUSED)
159 rte_regexdev_get_dev_id(const char *name)
166 for (i = 0; i < RTE_MAX_REGEXDEV_DEVS; i++) {
167 if (rte_regex_devices[i].state != RTE_REGEXDEV_UNUSED)
168 if (strcmp(name, rte_regex_devices[i].data->dev_name)) {
169 id = rte_regex_devices[i].data->dev_id;
177 rte_regexdev_is_valid_dev(uint16_t dev_id)
179 if (dev_id >= RTE_MAX_REGEXDEV_DEVS ||
180 rte_regex_devices[dev_id].state != RTE_REGEXDEV_READY)
186 regexdev_info_get(uint8_t dev_id, struct rte_regexdev_info *dev_info)
188 struct rte_regexdev *dev;
190 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
191 if (dev_info == NULL)
193 dev = &rte_regex_devices[dev_id];
194 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_info_get, -ENOTSUP);
195 return (*dev->dev_ops->dev_info_get)(dev, dev_info);
200 rte_regexdev_info_get(uint8_t dev_id, struct rte_regexdev_info *dev_info)
202 return regexdev_info_get(dev_id, dev_info);
206 rte_regexdev_configure(uint8_t dev_id, const struct rte_regexdev_config *cfg)
208 struct rte_regexdev *dev;
209 struct rte_regexdev_info dev_info;
212 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
215 dev = &rte_regex_devices[dev_id];
216 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
217 if (dev->data->dev_started) {
219 (ERR, "Dev %u must be stopped to allow configuration\n",
223 ret = regexdev_info_get(dev_id, &dev_info);
226 if ((cfg->dev_cfg_flags & RTE_REGEXDEV_CFG_CROSS_BUFFER_SCAN_F) &&
227 !(dev_info.regexdev_capa & RTE_REGEXDEV_SUPP_CROSS_BUFFER_F)) {
228 RTE_REGEXDEV_LOG(ERR,
229 "Dev %u doesn't support cross buffer scan\n",
233 if ((cfg->dev_cfg_flags & RTE_REGEXDEV_CFG_MATCH_AS_END_F) &&
234 !(dev_info.regexdev_capa & RTE_REGEXDEV_SUPP_MATCH_AS_END_F)) {
235 RTE_REGEXDEV_LOG(ERR,
236 "Dev %u doesn't support match as end\n",
240 if ((cfg->dev_cfg_flags & RTE_REGEXDEV_CFG_MATCH_ALL_F) &&
241 !(dev_info.regexdev_capa & RTE_REGEXDEV_SUPP_MATCH_ALL_F)) {
242 RTE_REGEXDEV_LOG(ERR,
243 "Dev %u doesn't support match all\n",
247 if (cfg->nb_groups == 0) {
248 RTE_REGEXDEV_LOG(ERR, "Dev %u num of groups must be > 0\n",
252 if (cfg->nb_groups > dev_info.max_groups) {
253 RTE_REGEXDEV_LOG(ERR, "Dev %u num of groups %d > %d\n",
254 dev_id, cfg->nb_groups, dev_info.max_groups);
257 if (cfg->nb_max_matches == 0) {
258 RTE_REGEXDEV_LOG(ERR, "Dev %u num of matches must be > 0\n",
262 if (cfg->nb_max_matches > dev_info.max_matches) {
263 RTE_REGEXDEV_LOG(ERR, "Dev %u num of matches %d > %d\n",
264 dev_id, cfg->nb_max_matches,
265 dev_info.max_matches);
268 if (cfg->nb_queue_pairs == 0) {
269 RTE_REGEXDEV_LOG(ERR, "Dev %u num of queues must be > 0\n",
273 if (cfg->nb_queue_pairs > dev_info.max_queue_pairs) {
274 RTE_REGEXDEV_LOG(ERR, "Dev %u num of queues %d > %d\n",
275 dev_id, cfg->nb_queue_pairs,
276 dev_info.max_queue_pairs);
279 if (cfg->nb_rules_per_group == 0) {
280 RTE_REGEXDEV_LOG(ERR,
281 "Dev %u num of rules per group must be > 0\n",
285 if (cfg->nb_rules_per_group > dev_info.max_rules_per_group) {
286 RTE_REGEXDEV_LOG(ERR,
287 "Dev %u num of rules per group %d > %d\n",
288 dev_id, cfg->nb_rules_per_group,
289 dev_info.max_rules_per_group);
292 ret = (*dev->dev_ops->dev_configure)(dev, cfg);
294 dev->data->dev_conf = *cfg;
299 rte_regexdev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
300 const struct rte_regexdev_qp_conf *qp_conf)
302 struct rte_regexdev *dev;
304 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
305 dev = &rte_regex_devices[dev_id];
306 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_qp_setup, -ENOTSUP);
307 if (dev->data->dev_started) {
309 (ERR, "Dev %u must be stopped to allow configuration\n",
313 if (queue_pair_id >= dev->data->dev_conf.nb_queue_pairs) {
314 RTE_REGEXDEV_LOG(ERR,
315 "Dev %u invalid queue %d > %d\n",
316 dev_id, queue_pair_id,
317 dev->data->dev_conf.nb_queue_pairs);
320 if (dev->data->dev_started) {
322 (ERR, "Dev %u must be stopped to allow configuration\n",
326 return (*dev->dev_ops->dev_qp_setup)(dev, queue_pair_id, qp_conf);
330 rte_regexdev_start(uint8_t dev_id)
332 struct rte_regexdev *dev;
335 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
336 dev = &rte_regex_devices[dev_id];
337 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_start, -ENOTSUP);
338 ret = (*dev->dev_ops->dev_start)(dev);
340 dev->data->dev_started = 1;
345 rte_regexdev_stop(uint8_t dev_id)
347 struct rte_regexdev *dev;
349 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
350 dev = &rte_regex_devices[dev_id];
351 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_stop, -ENOTSUP);
352 (*dev->dev_ops->dev_stop)(dev);
353 dev->data->dev_started = 0;
358 rte_regexdev_close(uint8_t dev_id)
360 struct rte_regexdev *dev;
362 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
363 dev = &rte_regex_devices[dev_id];
364 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP);
365 (*dev->dev_ops->dev_close)(dev);
366 dev->data->dev_started = 0;
367 dev->state = RTE_REGEXDEV_UNUSED;
372 rte_regexdev_attr_get(uint8_t dev_id, enum rte_regexdev_attr_id attr_id,
375 struct rte_regexdev *dev;
377 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
378 dev = &rte_regex_devices[dev_id];
379 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_attr_get, -ENOTSUP);
380 if (attr_value == NULL) {
381 RTE_REGEXDEV_LOG(ERR, "Dev %d attribute value can't be NULL\n",
385 return (*dev->dev_ops->dev_attr_get)(dev, attr_id, attr_value);
389 rte_regexdev_attr_set(uint8_t dev_id, enum rte_regexdev_attr_id attr_id,
390 const void *attr_value)
392 struct rte_regexdev *dev;
394 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
395 dev = &rte_regex_devices[dev_id];
396 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_attr_set, -ENOTSUP);
397 if (attr_value == NULL) {
398 RTE_REGEXDEV_LOG(ERR, "Dev %d attribute value can't be NULL\n",
402 return (*dev->dev_ops->dev_attr_set)(dev, attr_id, attr_value);
406 rte_regexdev_rule_db_update(uint8_t dev_id,
407 const struct rte_regexdev_rule *rules,
410 struct rte_regexdev *dev;
412 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
413 dev = &rte_regex_devices[dev_id];
414 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_rule_db_update, -ENOTSUP);
416 RTE_REGEXDEV_LOG(ERR, "Dev %d rules can't be NULL\n",
420 return (*dev->dev_ops->dev_rule_db_update)(dev, rules, nb_rules);
424 rte_regexdev_rule_db_compile_activate(uint8_t dev_id)
426 struct rte_regexdev *dev;
428 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
429 dev = &rte_regex_devices[dev_id];
430 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_rule_db_compile_activate,
432 return (*dev->dev_ops->dev_rule_db_compile_activate)(dev);
436 rte_regexdev_rule_db_import(uint8_t dev_id, const char *rule_db,
437 uint32_t rule_db_len)
439 struct rte_regexdev *dev;
441 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
442 dev = &rte_regex_devices[dev_id];
443 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_db_import,
445 if (rule_db == NULL) {
446 RTE_REGEXDEV_LOG(ERR, "Dev %d rules can't be NULL\n",
450 return (*dev->dev_ops->dev_db_import)(dev, rule_db, rule_db_len);
454 rte_regexdev_rule_db_export(uint8_t dev_id, char *rule_db)
456 struct rte_regexdev *dev;
458 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
459 dev = &rte_regex_devices[dev_id];
460 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_db_export,
462 return (*dev->dev_ops->dev_db_export)(dev, rule_db);
466 rte_regexdev_xstats_names_get(uint8_t dev_id,
467 struct rte_regexdev_xstats_map *xstats_map)
469 struct rte_regexdev *dev;
471 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
472 dev = &rte_regex_devices[dev_id];
473 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_xstats_names_get,
475 if (xstats_map == NULL) {
476 RTE_REGEXDEV_LOG(ERR, "Dev %d xstats map can't be NULL\n",
480 return (*dev->dev_ops->dev_xstats_names_get)(dev, xstats_map);
484 rte_regexdev_xstats_get(uint8_t dev_id, const uint16_t *ids,
485 uint64_t *values, uint16_t n)
487 struct rte_regexdev *dev;
489 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
490 dev = &rte_regex_devices[dev_id];
491 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_xstats_get, -ENOTSUP);
493 RTE_REGEXDEV_LOG(ERR, "Dev %d ids can't be NULL\n", dev_id);
496 if (values == NULL) {
497 RTE_REGEXDEV_LOG(ERR, "Dev %d values can't be NULL\n", dev_id);
500 return (*dev->dev_ops->dev_xstats_get)(dev, ids, values, n);
504 rte_regexdev_xstats_by_name_get(uint8_t dev_id, const char *name,
505 uint16_t *id, uint64_t *value)
507 struct rte_regexdev *dev;
509 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
510 dev = &rte_regex_devices[dev_id];
511 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_xstats_by_name_get,
514 RTE_REGEXDEV_LOG(ERR, "Dev %d name can't be NULL\n", dev_id);
518 RTE_REGEXDEV_LOG(ERR, "Dev %d id can't be NULL\n", dev_id);
522 RTE_REGEXDEV_LOG(ERR, "Dev %d value can't be NULL\n", dev_id);
525 return (*dev->dev_ops->dev_xstats_by_name_get)(dev, name, id, value);
529 rte_regexdev_xstats_reset(uint8_t dev_id, const uint16_t *ids,
532 struct rte_regexdev *dev;
534 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
535 dev = &rte_regex_devices[dev_id];
536 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_xstats_reset, -ENOTSUP);
538 RTE_REGEXDEV_LOG(ERR, "Dev %d ids can't be NULL\n", dev_id);
541 return (*dev->dev_ops->dev_xstats_reset)(dev, ids, nb_ids);
545 rte_regexdev_selftest(uint8_t dev_id)
547 struct rte_regexdev *dev;
549 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
550 dev = &rte_regex_devices[dev_id];
551 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_selftest, -ENOTSUP);
552 return (*dev->dev_ops->dev_selftest)(dev);
556 rte_regexdev_dump(uint8_t dev_id, FILE *f)
558 struct rte_regexdev *dev;
560 RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
561 dev = &rte_regex_devices[dev_id];
562 RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_dump, -ENOTSUP);
564 RTE_REGEXDEV_LOG(ERR, "Dev %d file can't be NULL\n", dev_id);
567 return (*dev->dev_ops->dev_dump)(dev, f);