diff --git a/config/common_base b/config/common_base index 5ba283957..87469d385 100644 --- a/config/common_base +++ b/config/common_base @@ -739,6 +739,7 @@ CONFIG_RTE_LIBRTE_PMD_ZLIB=n # Compile RegEx device support # CONFIG_RTE_LIBRTE_REGEXDEV=y +CONFIG_RTE_MAX_REGEXDEV_DEVS=32 # # Compile generic event device library diff --git a/config/rte_config.h b/config/rte_config.h index 086acf74a..9bb915347 100644 --- a/config/rte_config.h +++ b/config/rte_config.h @@ -69,6 +69,9 @@ /* compressdev defines */ #define RTE_COMPRESS_MAX_DEVS 64 +/* regexdev defines */ +#define RTE_MAX_REGEXDEV_DEVS 32 + /* eventdev defines */ #define RTE_EVENT_MAX_DEVS 16 #define RTE_EVENT_MAX_QUEUES_PER_DEV 64 diff --git a/lib/librte_regexdev/Makefile b/lib/librte_regexdev/Makefile index e6e9d6b33..c123fcaf5 100644 --- a/lib/librte_regexdev/Makefile +++ b/lib/librte_regexdev/Makefile @@ -24,6 +24,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_REGEXDEV) := rte_regexdev.c # export include files SYMLINK-$(CONFIG_RTE_LIBRTE_REGEXDEV)-include += rte_regexdev.h SYMLINK-$(CONFIG_RTE_LIBRTE_REGEXDEV)-include += rte_regexdev_core.h +SYMLINK-$(CONFIG_RTE_LIBRTE_REGEXDEV)-include += rte_regexdev_driver.h # versioning export map EXPORT_MAP := rte_regexdev_version.map diff --git a/lib/librte_regexdev/meson.build b/lib/librte_regexdev/meson.build index f321b1fe3..c417b9caf 100644 --- a/lib/librte_regexdev/meson.build +++ b/lib/librte_regexdev/meson.build @@ -3,5 +3,6 @@ sources = files('rte_regexdev.c') headers = files('rte_regexdev.h', - 'rte_regexdev_core.h') + 'rte_regexdev_core.h', + 'rte_regexdev_driver.h') deps += ['mbuf'] diff --git a/lib/librte_regexdev/rte_regexdev.c b/lib/librte_regexdev/rte_regexdev.c index b18deeeb4..3f112ff2e 100644 --- a/lib/librte_regexdev/rte_regexdev.c +++ b/lib/librte_regexdev/rte_regexdev.c @@ -3,4 +3,141 @@ * Copyright 2020 Mellanox Technologies, Ltd */ +#include + +#include +#include +#include +#include + #include "rte_regexdev.h" +#include "rte_regexdev_core.h" +#include "rte_regexdev_driver.h" + +static const char *MZ_RTE_REGEXDEV_DATA = "rte_regexdev_data"; +static struct rte_regexdev regex_devices[RTE_MAX_REGEXDEV_DEVS]; +/* Shared memory between primary and secondary processes. */ +static struct { + struct rte_regexdev_data data[RTE_MAX_REGEXDEV_DEVS]; +} *rte_regexdev_shared_data; + +int rte_regexdev_logtype; + +static uint16_t +regexdev_find_free_dev(void) +{ + uint16_t i; + + for (i = 0; i < RTE_MAX_REGEXDEV_DEVS; i++) { + if (regex_devices[i].state == RTE_REGEXDEV_UNUSED) + return i; + } + return RTE_MAX_REGEXDEV_DEVS; +} + +static struct rte_regexdev* +regexdev_allocated(const char *name) +{ + uint16_t i; + + for (i = 0; i < RTE_MAX_REGEXDEV_DEVS; i++) { + if (regex_devices[i].state != RTE_REGEXDEV_UNUSED) + if (!strcmp(name, regex_devices[i].data->dev_name)) + return ®ex_devices[i]; + } + return NULL; +} + +static int +regexdev_shared_data_prepare(void) +{ + const unsigned int flags = 0; + const struct rte_memzone *mz; + + if (rte_regexdev_shared_data == NULL) { + /* Allocate port data and ownership shared memory. */ + mz = rte_memzone_reserve(MZ_RTE_REGEXDEV_DATA, + sizeof(*rte_regexdev_shared_data), + rte_socket_id(), flags); + if (mz == NULL) + return -ENOMEM; + + rte_regexdev_shared_data = mz->addr; + memset(rte_regexdev_shared_data->data, 0, + sizeof(rte_regexdev_shared_data->data)); + } + return 0; +} + +static int +regexdev_check_name(const char *name) +{ + size_t name_len; + + if (name == NULL) { + RTE_REGEXDEV_LOG(ERR, "Name can't be NULL\n"); + return -EINVAL; + } + name_len = strnlen(name, RTE_REGEXDEV_NAME_MAX_LEN); + if (name_len == 0) { + RTE_REGEXDEV_LOG(ERR, "Zero length RegEx device name\n"); + return -EINVAL; + } + if (name_len >= RTE_REGEXDEV_NAME_MAX_LEN) { + RTE_REGEXDEV_LOG(ERR, "RegEx device name is too long\n"); + return -EINVAL; + } + return (int)name_len; + +} + +struct rte_regexdev * +rte_regexdev_register(const char *name) +{ + uint16_t dev_id; + int name_len; + struct rte_regexdev *dev; + + name_len = regexdev_check_name(name); + if (name_len < 0) + return NULL; + dev = regexdev_allocated(name); + if (dev != NULL) { + RTE_REGEXDEV_LOG(ERR, "RegEx device already allocated\n"); + return NULL; + } + dev_id = regexdev_find_free_dev(); + if (dev_id == RTE_MAX_REGEXDEV_DEVS) { + RTE_REGEXDEV_LOG + (ERR, "Reached maximum number of RegEx devices\n"); + return NULL; + } + if (regexdev_shared_data_prepare() < 0) { + RTE_REGEXDEV_LOG(ERR, "Cannot allocate RegEx shared data\n"); + return NULL; + } + + dev = ®ex_devices[dev_id]; + dev->state = RTE_REGEXDEV_REGISTERED; + if (dev->data == NULL) + dev->data = &rte_regexdev_shared_data->data[dev_id]; + else + memset(dev->data, 1, sizeof(*dev->data)); + dev->data->dev_id = dev_id; + strlcpy(dev->data->dev_name, name, sizeof(dev->data->dev_name)); + return dev; +} + +void +rte_regexdev_unregister(struct rte_regexdev *dev) +{ + dev->state = RTE_REGEXDEV_UNUSED; +} + +struct rte_regexdev * +rte_regexdev_get_device_by_name(const char *name) +{ + if (regexdev_check_name(name) < 0) + return NULL; + return regexdev_allocated(name); +} diff --git a/lib/librte_regexdev/rte_regexdev.h b/lib/librte_regexdev/rte_regexdev.h index ec1dd4b03..5e7a653fe 100644 --- a/lib/librte_regexdev/rte_regexdev.h +++ b/lib/librte_regexdev/rte_regexdev.h @@ -205,6 +205,13 @@ extern "C" { #include #include +#define RTE_REGEXDEV_NAME_MAX_LEN RTE_DEV_NAME_MAX_LEN + +extern int rte_regexdev_logtype; + +#define RTE_REGEXDEV_LOG(level, ...) \ + rte_log(RTE_LOG_ ## level, rte_regexdev_logtype, "" __VA_ARGS__) + /** * @warning * @b EXPERIMENTAL: this API may change without prior notice. diff --git a/lib/librte_regexdev/rte_regexdev_core.h b/lib/librte_regexdev/rte_regexdev_core.h index c46438fff..617961753 100644 --- a/lib/librte_regexdev/rte_regexdev_core.h +++ b/lib/librte_regexdev/rte_regexdev_core.h @@ -127,6 +127,17 @@ struct rte_regexdev_ops { regexdev_dump_t dev_dump; }; +/** + * Possible states of a RegEx device. + */ +enum rte_regexdev_state { + RTE_REGEXDEV_UNUSED = 0, /**< Device is unused. */ + RTE_REGEXDEV_REGISTERED, + /**< Device is registered, but not ready to be used. */ + RTE_REGEXDEV_READY, + /**< Device is ready for use. This is set by the PMD. */ +}; + /** * @internal * The data part, with no function pointers, associated with each RegEx device. @@ -136,6 +147,8 @@ struct rte_regexdev_ops { */ struct rte_regexdev_data { void *dev_private; /**< PMD-specific private data. */ + char dev_name[RTE_REGEXDEV_NAME_MAX_LEN]; /**< Unique identifier name */ + uint16_t dev_id; /**< Device [external] identifier. */ } __rte_cache_aligned; /** @@ -154,6 +167,7 @@ struct rte_regexdev { const struct rte_regexdev_ops *dev_ops; /**< Functions exported by PMD */ struct rte_device *device; /**< Backing device */ + enum rte_regexdev_state state; /**< The device state. */ struct rte_regexdev_data *data; /**< Pointer to device data. */ } __rte_cache_aligned; diff --git a/lib/librte_regexdev/rte_regexdev_driver.h b/lib/librte_regexdev/rte_regexdev_driver.h new file mode 100644 index 000000000..64742016c --- /dev/null +++ b/lib/librte_regexdev/rte_regexdev_driver.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2020 Mellanox Technologies, Ltd + */ + +#ifndef _RTE_REGEXDEV_DRIVER_H_ +#define _RTE_REGEXDEV_DRIVER_H_ + +/** + * @file + * + * RTE RegEx Device PMD API + * + * APIs that are used by the RegEx drivers, to communicate with the + * RegEx lib. + */ + +#include "rte_regexdev.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @internal + * Register a RegEx device slot for a RegEx device and return the + * pointer to that slot. + * + * @param name + * RegEx device name. + * + * @return + * A pointer to the RegEx device slot case of success, + * NULL otherwise. + */ +struct rte_regexdev *rte_regexdev_register(const char *name); + +/** + * @internal + * Unregister the specified regexdev port. + * + * @param dev + * Device to be released. + */ +void rte_regexdev_unregister(struct rte_regexdev *dev); + +/** + * @internal + * Return the RegEx device based on the device name. + * + * @param name + * The device name. + */ +struct rte_regexdev *rte_regexdev_get_device_by_name(const char *name); + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_REGEXDEV_DRIVER_H_ */