Hi,
> +int
> +rte_regexdev_configure(uint8_t dev_id, const struct rte_regexdev_config
> +*cfg) {
> + struct rte_regexdev *dev;
> + struct rte_regexdev_info dev_info;
> + int ret;
> +
> + RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
> + if (cfg == NULL)
> + return -EINVAL;
> + dev = &rte_regex_devices[dev_id];
> + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -
> ENOTSUP);
> + if (dev->data->dev_started) {
> + RTE_REGEXDEV_LOG
> + (ERR, "Dev %u must be stopped to allow
> configuration\n",
> + dev_id);
> + return -EBUSY;
> + }
> + ret = regexdev_info_get(dev_id, &dev_info);
> + if (ret < 0)
> + return ret;
> + if ((cfg->dev_cfg_flags &
> RTE_REGEXDEV_CFG_CROSS_BUFFER_SCAN_F) &&
> + !(dev_info.regexdev_capa &
> RTE_REGEXDEV_SUPP_CROSS_BUFFER_F)) {
> + RTE_REGEXDEV_LOG(ERR,
> + "Dev %u doesn't support cross buffer
> scan\n",
> + dev_id);
> + return -EINVAL;
> + }
> + if ((cfg->dev_cfg_flags & RTE_REGEXDEV_CFG_MATCH_AS_END_F)
> &&
> + !(dev_info.regexdev_capa &
> RTE_REGEXDEV_SUPP_MATCH_AS_END_F)) {
> + RTE_REGEXDEV_LOG(ERR,
> + "Dev %u doesn't support match as end\n",
> + dev_id);
> + return -EINVAL;
> + }
> + if ((cfg->dev_cfg_flags & RTE_REGEXDEV_CFG_MATCH_ALL_F) &&
> + !(dev_info.regexdev_capa &
> RTE_REGEXDEV_SUPP_MATCH_ALL_F)) {
> + RTE_REGEXDEV_LOG(ERR,
> + "Dev %u doesn't support match all\n",
> + dev_id);
> + return -EINVAL;
> + }
> + if (cfg->nb_groups == 0) {
> + RTE_REGEXDEV_LOG(ERR, "Dev %u num of groups must be >
> 0\n",
> + dev_id);
> + return -EINVAL;
> + }
> + if (cfg->nb_groups >= dev_info.max_groups) {
> + RTE_REGEXDEV_LOG(ERR, "Dev %u num of groups %d >
> %d\n",
> + dev_id, cfg->nb_groups,
> dev_info.max_groups);
> + return -EINVAL;
> + }
The comparison should be > and not >=
> + if (cfg->nb_max_matches == 0) {
> + RTE_REGEXDEV_LOG(ERR, "Dev %u num of matches must be
> > 0\n",
> + dev_id);
> + return -EINVAL;
> + }
> + if (cfg->nb_max_matches >= dev_info.max_matches) {
> + RTE_REGEXDEV_LOG(ERR, "Dev %u num of matches %d >
> %d\n",
> + dev_id, cfg->nb_max_matches,
> + dev_info.max_matches);
> + return -EINVAL;
> + }
The comparison should be > and not >=
> + if (cfg->nb_queue_pairs == 0) {
> + RTE_REGEXDEV_LOG(ERR, "Dev %u num of queues must be
> > 0\n",
> + dev_id);
> + return -EINVAL;
> + }
> + if (cfg->nb_queue_pairs >= dev_info.max_queue_pairs) {
> + RTE_REGEXDEV_LOG(ERR, "Dev %u num of queues %d >
> %d\n",
> + dev_id, cfg->nb_queue_pairs,
> + dev_info.max_queue_pairs);
> + return -EINVAL;
> + }
The comparison should be > and not >=
> + if (cfg->nb_rules_per_group == 0) {
> + RTE_REGEXDEV_LOG(ERR,
> + "Dev %u num of rules per group must be >
> 0\n",
> + dev_id);
> + return -EINVAL;
> + }
> + if (cfg->nb_rules_per_group >= dev_info.max_rules_per_group) {
> + RTE_REGEXDEV_LOG(ERR,
> + "Dev %u num of rules per group %d > %d\n",
> + dev_id, cfg->nb_rules_per_group,
> + dev_info.max_rules_per_group);
> + return -EINVAL;
> + }
The comparison should be > and not >=
> + ret = (*dev->dev_ops->dev_configure)(dev, cfg);
> + if (ret == 0)
> + dev->data->dev_conf = *cfg;
> + return ret;
> +}
In general I think that the validation of the cfg values should be done by the PMD
Hi Guy,
> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Guy Kaneti
> Sent: Tuesday, April 21, 2020 2:36 PM
> To: Ori Kam <orika@mellanox.com>; Jerin Jacob Kollanukkaran
> <jerinj@marvell.com>; xiang.w.wang@intel.com
> Cc: dev@dpdk.org; Pavan Nikhilesh Bhagavatula
> <pbhagavatula@marvell.com>; Shahaf Shuler <shahafs@mellanox.com>;
> hemant.agrawal@nxp.com; Opher Reviv <opher@mellanox.com>; Alex
> Rosenbaum <alexr@mellanox.com>; Dovrat Zifroni <dovrat@marvell.com>;
> Prasun Kapoor <pkapoor@marvell.com>; nipun.gupta@nxp.com;
> bruce.richardson@intel.com; yang.a.hong@intel.com; harry.chang@intel.com;
> gu.jian1@zte.com.cn; shanjiangh@chinatelecom.cn;
> zhangy.yun@chinatelecom.cn; lixingfu@huachentel.com; wushuai@inspur.com;
> yuyingxia@yxlink.com; fanchenggang@sunyainfo.com;
> davidfgao@tencent.com; liuzhong1@chinaunicom.cn;
> zhaoyong11@huawei.com; oc@yunify.com; jim@netgate.com;
> hongjun.ni@intel.com; j.bromhead@titan-ic.com; deri@ntop.org;
> fc@napatech.com; arthur.su@lionic.com; Thomas Monjalon
> <thomas@monjalon.net>
> Subject: Re: [dpdk-dev] [PATCH v2 4/4] regexdev: implement regex rte level
> functions
>
> Hi,
>
> > +int
> > +rte_regexdev_configure(uint8_t dev_id, const struct rte_regexdev_config
> > +*cfg) {
> > + struct rte_regexdev *dev;
> > + struct rte_regexdev_info dev_info;
> > + int ret;
> > +
> > + RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
> > + if (cfg == NULL)
> > + return -EINVAL;
> > + dev = &rte_regex_devices[dev_id];
> > + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -
> > ENOTSUP);
> > + if (dev->data->dev_started) {
> > + RTE_REGEXDEV_LOG
> > + (ERR, "Dev %u must be stopped to allow
> > configuration\n",
> > + dev_id);
> > + return -EBUSY;
> > + }
> > + ret = regexdev_info_get(dev_id, &dev_info);
> > + if (ret < 0)
> > + return ret;
> > + if ((cfg->dev_cfg_flags &
> > RTE_REGEXDEV_CFG_CROSS_BUFFER_SCAN_F) &&
> > + !(dev_info.regexdev_capa &
> > RTE_REGEXDEV_SUPP_CROSS_BUFFER_F)) {
> > + RTE_REGEXDEV_LOG(ERR,
> > + "Dev %u doesn't support cross buffer
> > scan\n",
> > + dev_id);
> > + return -EINVAL;
> > + }
> > + if ((cfg->dev_cfg_flags & RTE_REGEXDEV_CFG_MATCH_AS_END_F)
> > &&
> > + !(dev_info.regexdev_capa &
> > RTE_REGEXDEV_SUPP_MATCH_AS_END_F)) {
> > + RTE_REGEXDEV_LOG(ERR,
> > + "Dev %u doesn't support match as end\n",
> > + dev_id);
> > + return -EINVAL;
> > + }
> > + if ((cfg->dev_cfg_flags & RTE_REGEXDEV_CFG_MATCH_ALL_F) &&
> > + !(dev_info.regexdev_capa &
> > RTE_REGEXDEV_SUPP_MATCH_ALL_F)) {
> > + RTE_REGEXDEV_LOG(ERR,
> > + "Dev %u doesn't support match all\n",
> > + dev_id);
> > + return -EINVAL;
> > + }
> > + if (cfg->nb_groups == 0) {
> > + RTE_REGEXDEV_LOG(ERR, "Dev %u num of groups must be >
> > 0\n",
> > + dev_id);
> > + return -EINVAL;
> > + }
> > + if (cfg->nb_groups >= dev_info.max_groups) {
> > + RTE_REGEXDEV_LOG(ERR, "Dev %u num of groups %d >
> > %d\n",
> > + dev_id, cfg->nb_groups,
> > dev_info.max_groups);
> > + return -EINVAL;
> > + }
>
> The comparison should be > and not >=
>
Yes, you are correct will fix.
> > + if (cfg->nb_max_matches == 0) {
> > + RTE_REGEXDEV_LOG(ERR, "Dev %u num of matches must be
> > > 0\n",
> > + dev_id);
> > + return -EINVAL;
> > + }
> > + if (cfg->nb_max_matches >= dev_info.max_matches) {
> > + RTE_REGEXDEV_LOG(ERR, "Dev %u num of matches %d >
> > %d\n",
> > + dev_id, cfg->nb_max_matches,
> > + dev_info.max_matches);
> > + return -EINVAL;
> > + }
>
> The comparison should be > and not >=
>
Yes, will fix.
> > + if (cfg->nb_queue_pairs == 0) {
> > + RTE_REGEXDEV_LOG(ERR, "Dev %u num of queues must be
> > > 0\n",
> > + dev_id);
> > + return -EINVAL;
> > + }
> > + if (cfg->nb_queue_pairs >= dev_info.max_queue_pairs) {
> > + RTE_REGEXDEV_LOG(ERR, "Dev %u num of queues %d >
> > %d\n",
> > + dev_id, cfg->nb_queue_pairs,
> > + dev_info.max_queue_pairs);
> > + return -EINVAL;
> > + }
>
> The comparison should be > and not >=
>
Will fix.
> > + if (cfg->nb_rules_per_group == 0) {
> > + RTE_REGEXDEV_LOG(ERR,
> > + "Dev %u num of rules per group must be >
> > 0\n",
> > + dev_id);
> > + return -EINVAL;
> > + }
> > + if (cfg->nb_rules_per_group >= dev_info.max_rules_per_group) {
> > + RTE_REGEXDEV_LOG(ERR,
> > + "Dev %u num of rules per group %d > %d\n",
> > + dev_id, cfg->nb_rules_per_group,
> > + dev_info.max_rules_per_group);
> > + return -EINVAL;
> > + }
>
> The comparison should be > and not >=
>
Will fix.
> > + ret = (*dev->dev_ops->dev_configure)(dev, cfg);
> > + if (ret == 0)
> > + dev->data->dev_conf = *cfg;
> > + return ret;
> > +}
>
> In general I think that the validation of the cfg values should be done by the
> PMD
This was done in the first version.
after comments from the community, I changed it.
As much as I like the idea that PMD should handle everything by itself.
there is no point of code duplication, all PMD will require to do those test,
and there is no advantage of doing it inside the PMD.
Also it is common practice in DPDK to assume that the input was tested in the above
layer. (you can see ethdev)
@@ -829,6 +829,7 @@ CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV=y
# Compile RexEx device support
#
CONFIG_RTE_LIBRTE_REGEXDEV=y
+CONFIG_RTE_LIBRTE_REGEXDEV_DEBUG=n
CONFIG_RTE_MAX_REGEXDEV_DEVS=32
#
@@ -15,7 +15,7 @@
#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];
+struct rte_regexdev rte_regex_devices[RTE_MAX_REGEXDEV_DEVS];
/* Shared memory between primary and secondary processes. */
static struct {
struct rte_regexdev_data data[RTE_MAX_REGEXDEV_DEVS];
@@ -29,7 +29,7 @@
uint16_t i;
for (i = 0; i < RTE_MAX_REGEXDEV_DEVS; i++) {
- if (regex_devices[i].state == RTE_REGEXDEV_UNUSED)
+ if (rte_regex_devices[i].state == RTE_REGEXDEV_UNUSED)
return i;
}
return RTE_MAX_REGEXDEV_DEVS;
@@ -41,9 +41,9 @@
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];
+ if (rte_regex_devices[i].state != RTE_REGEXDEV_UNUSED)
+ if (!strcmp(name, rte_regex_devices[i].data->dev_name))
+ return &rte_regex_devices[i];
}
return NULL;
}
@@ -101,7 +101,7 @@ struct rte_regexdev *
return NULL;
}
- dev = ®ex_devices[dev_id];
+ dev = &rte_regex_devices[dev_id];
dev->state = RTE_REGEXDEV_REGISTERED;
if (dev->data == NULL)
dev->data = &rte_regexdev_shared_data->data[dev_id];
@@ -117,3 +117,433 @@ struct rte_regexdev *
{
dev->state = RTE_REGEXDEV_UNUSED;
}
+
+uint8_t
+rte_regexdev_count(void)
+{
+ int i;
+ int count = 0;
+
+ for (i = 0; i < RTE_MAX_REGEXDEV_DEVS; i++) {
+ if (rte_regex_devices[i].state != RTE_REGEXDEV_UNUSED)
+ count++;
+ }
+ return count;
+}
+
+int
+rte_regexdev_get_dev_id(const char *name)
+{
+ int i;
+ int id = -EINVAL;
+
+ if (name == NULL)
+ return -EINVAL;
+ for (i = 0; i < RTE_MAX_REGEXDEV_DEVS; i++) {
+ if (rte_regex_devices[i].state != RTE_REGEXDEV_UNUSED)
+ if (strcmp(name, rte_regex_devices[i].data->dev_name)) {
+ id = rte_regex_devices[i].data->dev_id;
+ break;
+ }
+ }
+ return id;
+}
+
+int
+rte_regexdev_is_valid_dev(uint16_t dev_id)
+{
+ if (dev_id >= RTE_MAX_REGEXDEV_DEVS ||
+ rte_regex_devices[dev_id].state != RTE_REGEXDEV_READY)
+ return 0;
+ return 1;
+}
+
+static int
+regexdev_info_get(uint8_t dev_id, struct rte_regexdev_info *dev_info)
+{
+ struct rte_regexdev *dev;
+
+ RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
+ if (dev_info == NULL)
+ return -EINVAL;
+ dev = &rte_regex_devices[dev_id];
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_info_get, -ENOTSUP);
+ return (*dev->dev_ops->dev_info_get)(dev, dev_info);
+
+}
+
+int
+rte_regexdev_info_get(uint8_t dev_id, struct rte_regexdev_info *dev_info)
+{
+ return regexdev_info_get(dev_id, dev_info);
+}
+
+int
+rte_regexdev_configure(uint8_t dev_id, const struct rte_regexdev_config *cfg)
+{
+ struct rte_regexdev *dev;
+ struct rte_regexdev_info dev_info;
+ int ret;
+
+ RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
+ if (cfg == NULL)
+ return -EINVAL;
+ dev = &rte_regex_devices[dev_id];
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
+ if (dev->data->dev_started) {
+ RTE_REGEXDEV_LOG
+ (ERR, "Dev %u must be stopped to allow configuration\n",
+ dev_id);
+ return -EBUSY;
+ }
+ ret = regexdev_info_get(dev_id, &dev_info);
+ if (ret < 0)
+ return ret;
+ if ((cfg->dev_cfg_flags & RTE_REGEXDEV_CFG_CROSS_BUFFER_SCAN_F) &&
+ !(dev_info.regexdev_capa & RTE_REGEXDEV_SUPP_CROSS_BUFFER_F)) {
+ RTE_REGEXDEV_LOG(ERR,
+ "Dev %u doesn't support cross buffer scan\n",
+ dev_id);
+ return -EINVAL;
+ }
+ if ((cfg->dev_cfg_flags & RTE_REGEXDEV_CFG_MATCH_AS_END_F) &&
+ !(dev_info.regexdev_capa & RTE_REGEXDEV_SUPP_MATCH_AS_END_F)) {
+ RTE_REGEXDEV_LOG(ERR,
+ "Dev %u doesn't support match as end\n",
+ dev_id);
+ return -EINVAL;
+ }
+ if ((cfg->dev_cfg_flags & RTE_REGEXDEV_CFG_MATCH_ALL_F) &&
+ !(dev_info.regexdev_capa & RTE_REGEXDEV_SUPP_MATCH_ALL_F)) {
+ RTE_REGEXDEV_LOG(ERR,
+ "Dev %u doesn't support match all\n",
+ dev_id);
+ return -EINVAL;
+ }
+ if (cfg->nb_groups == 0) {
+ RTE_REGEXDEV_LOG(ERR, "Dev %u num of groups must be > 0\n",
+ dev_id);
+ return -EINVAL;
+ }
+ if (cfg->nb_groups >= dev_info.max_groups) {
+ RTE_REGEXDEV_LOG(ERR, "Dev %u num of groups %d > %d\n",
+ dev_id, cfg->nb_groups, dev_info.max_groups);
+ return -EINVAL;
+ }
+ if (cfg->nb_max_matches == 0) {
+ RTE_REGEXDEV_LOG(ERR, "Dev %u num of matches must be > 0\n",
+ dev_id);
+ return -EINVAL;
+ }
+ if (cfg->nb_max_matches >= dev_info.max_matches) {
+ RTE_REGEXDEV_LOG(ERR, "Dev %u num of matches %d > %d\n",
+ dev_id, cfg->nb_max_matches,
+ dev_info.max_matches);
+ return -EINVAL;
+ }
+ if (cfg->nb_queue_pairs == 0) {
+ RTE_REGEXDEV_LOG(ERR, "Dev %u num of queues must be > 0\n",
+ dev_id);
+ return -EINVAL;
+ }
+ if (cfg->nb_queue_pairs >= dev_info.max_queue_pairs) {
+ RTE_REGEXDEV_LOG(ERR, "Dev %u num of queues %d > %d\n",
+ dev_id, cfg->nb_queue_pairs,
+ dev_info.max_queue_pairs);
+ return -EINVAL;
+ }
+ if (cfg->nb_rules_per_group == 0) {
+ RTE_REGEXDEV_LOG(ERR,
+ "Dev %u num of rules per group must be > 0\n",
+ dev_id);
+ return -EINVAL;
+ }
+ if (cfg->nb_rules_per_group >= dev_info.max_rules_per_group) {
+ RTE_REGEXDEV_LOG(ERR,
+ "Dev %u num of rules per group %d > %d\n",
+ dev_id, cfg->nb_rules_per_group,
+ dev_info.max_rules_per_group);
+ return -EINVAL;
+ }
+ ret = (*dev->dev_ops->dev_configure)(dev, cfg);
+ if (ret == 0)
+ dev->data->dev_conf = *cfg;
+ return ret;
+}
+
+int
+rte_regexdev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
+ const struct rte_regexdev_qp_conf *qp_conf)
+{
+ struct rte_regexdev *dev;
+
+ RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
+ dev = &rte_regex_devices[dev_id];
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_qp_setup, -ENOTSUP);
+ if (dev->data->dev_started) {
+ RTE_REGEXDEV_LOG
+ (ERR, "Dev %u must be stopped to allow configuration\n",
+ dev_id);
+ return -EBUSY;
+ }
+ if (queue_pair_id >= dev->data->dev_conf.nb_queue_pairs) {
+ RTE_REGEXDEV_LOG(ERR,
+ "Dev %u invalid queue %d > %d\n",
+ dev_id, queue_pair_id,
+ dev->data->dev_conf.nb_queue_pairs);
+ return -EINVAL;
+ }
+ if (dev->data->dev_started) {
+ RTE_REGEXDEV_LOG
+ (ERR, "Dev %u must be stopped to allow configuration\n",
+ dev_id);
+ return -EBUSY;
+ }
+ return (*dev->dev_ops->dev_qp_setup)(dev, queue_pair_id, qp_conf);
+}
+
+int
+rte_regexdev_start(uint8_t dev_id)
+{
+ struct rte_regexdev *dev;
+ int ret;
+
+ RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
+ dev = &rte_regex_devices[dev_id];
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_start, -ENOTSUP);
+ ret = (*dev->dev_ops->dev_start)(dev);
+ if (ret == 0)
+ dev->data->dev_started = 1;
+ return ret;
+}
+
+int
+rte_regexdev_stop(uint8_t dev_id)
+{
+ struct rte_regexdev *dev;
+
+ RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
+ dev = &rte_regex_devices[dev_id];
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_stop, -ENOTSUP);
+ (*dev->dev_ops->dev_stop)(dev);
+ dev->data->dev_started = 0;
+ return 0;
+}
+
+int
+rte_regexdev_close(uint8_t dev_id)
+{
+ struct rte_regexdev *dev;
+
+ RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
+ dev = &rte_regex_devices[dev_id];
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP);
+ (*dev->dev_ops->dev_close)(dev);
+ dev->data->dev_started = 0;
+ dev->state = RTE_REGEXDEV_UNUSED;
+ return 0;
+}
+
+int
+rte_regexdev_attr_get(uint8_t dev_id, enum rte_regexdev_attr_id attr_id,
+ void *attr_value)
+{
+ struct rte_regexdev *dev;
+
+ RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
+ dev = &rte_regex_devices[dev_id];
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_attr_get, -ENOTSUP);
+ if (attr_value == NULL) {
+ RTE_REGEXDEV_LOG(ERR, "Dev %d attribute value can't be NULL\n",
+ dev_id);
+ return -EINVAL;
+ }
+ return (*dev->dev_ops->dev_attr_get)(dev, attr_id, attr_value);
+}
+
+int
+rte_regexdev_attr_set(uint8_t dev_id, enum rte_regexdev_attr_id attr_id,
+ const void *attr_value)
+{
+ struct rte_regexdev *dev;
+
+ RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
+ dev = &rte_regex_devices[dev_id];
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_attr_set, -ENOTSUP);
+ if (attr_value == NULL) {
+ RTE_REGEXDEV_LOG(ERR, "Dev %d attribute value can't be NULL\n",
+ dev_id);
+ return -EINVAL;
+ }
+ return (*dev->dev_ops->dev_attr_set)(dev, attr_id, attr_value);
+}
+
+int
+rte_regexdev_rule_db_update(uint8_t dev_id,
+ const struct rte_regexdev_rule *rules,
+ uint32_t nb_rules)
+{
+ struct rte_regexdev *dev;
+
+ RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
+ dev = &rte_regex_devices[dev_id];
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_rule_db_update, -ENOTSUP);
+ if (rules == NULL) {
+ RTE_REGEXDEV_LOG(ERR, "Dev %d rules can't be NULL\n",
+ dev_id);
+ return -EINVAL;
+ }
+ return (*dev->dev_ops->dev_rule_db_update)(dev, rules, nb_rules);
+}
+
+int
+rte_regexdev_rule_db_compile_activate(uint8_t dev_id)
+{
+ struct rte_regexdev *dev;
+
+ RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
+ dev = &rte_regex_devices[dev_id];
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_rule_db_compile_activate,
+ -ENOTSUP);
+ return (*dev->dev_ops->dev_rule_db_compile_activate)(dev);
+}
+
+int
+rte_regexdev_rule_db_import(uint8_t dev_id, const char *rule_db,
+ uint32_t rule_db_len)
+{
+ struct rte_regexdev *dev;
+
+ RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
+ dev = &rte_regex_devices[dev_id];
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_db_import,
+ -ENOTSUP);
+ if (rule_db == NULL) {
+ RTE_REGEXDEV_LOG(ERR, "Dev %d rules can't be NULL\n",
+ dev_id);
+ return -EINVAL;
+ }
+ return (*dev->dev_ops->dev_db_import)(dev, rule_db, rule_db_len);
+}
+
+int
+rte_regexdev_rule_db_export(uint8_t dev_id, char *rule_db)
+{
+ struct rte_regexdev *dev;
+
+ RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
+ dev = &rte_regex_devices[dev_id];
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_db_export,
+ -ENOTSUP);
+ if (rule_db == NULL) {
+ RTE_REGEXDEV_LOG(ERR, "Dev %d rules can't be NULL\n",
+ dev_id);
+ return -EINVAL;
+ }
+ return (*dev->dev_ops->dev_db_export)(dev, rule_db);
+}
+
+int
+rte_regexdev_xstats_names_get(uint8_t dev_id,
+ struct rte_regexdev_xstats_map *xstats_map)
+{
+ struct rte_regexdev *dev;
+
+ RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
+ dev = &rte_regex_devices[dev_id];
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_xstats_names_get,
+ -ENOTSUP);
+ if (xstats_map == NULL) {
+ RTE_REGEXDEV_LOG(ERR, "Dev %d xstats map can't be NULL\n",
+ dev_id);
+ return -EINVAL;
+ }
+ return (*dev->dev_ops->dev_xstats_names_get)(dev, xstats_map);
+}
+
+int
+rte_regexdev_xstats_get(uint8_t dev_id, const uint16_t *ids,
+ uint64_t *values, uint16_t n)
+{
+ struct rte_regexdev *dev;
+
+ RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
+ dev = &rte_regex_devices[dev_id];
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_xstats_get, -ENOTSUP);
+ if (ids == NULL) {
+ RTE_REGEXDEV_LOG(ERR, "Dev %d ids can't be NULL\n", dev_id);
+ return -EINVAL;
+ }
+ if (values == NULL) {
+ RTE_REGEXDEV_LOG(ERR, "Dev %d values can't be NULL\n", dev_id);
+ return -EINVAL;
+ }
+ return (*dev->dev_ops->dev_xstats_get)(dev, ids, values, n);
+}
+
+int
+rte_regexdev_xstats_by_name_get(uint8_t dev_id, const char *name,
+ uint16_t *id, uint64_t *value)
+{
+ struct rte_regexdev *dev;
+
+ RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
+ dev = &rte_regex_devices[dev_id];
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_xstats_by_name_get,
+ -ENOTSUP);
+ if (name == NULL) {
+ RTE_REGEXDEV_LOG(ERR, "Dev %d name can't be NULL\n", dev_id);
+ return -EINVAL;
+ }
+ if (id == NULL) {
+ RTE_REGEXDEV_LOG(ERR, "Dev %d id can't be NULL\n", dev_id);
+ return -EINVAL;
+ }
+ if (value == NULL) {
+ RTE_REGEXDEV_LOG(ERR, "Dev %d value can't be NULL\n", dev_id);
+ return -EINVAL;
+ }
+ return (*dev->dev_ops->dev_xstats_by_name_get)(dev, name, id, value);
+}
+
+int
+rte_regexdev_xstats_reset(uint8_t dev_id, const uint16_t *ids,
+ uint16_t nb_ids)
+{
+ struct rte_regexdev *dev;
+
+ RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
+ dev = &rte_regex_devices[dev_id];
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_xstats_reset, -ENOTSUP);
+ if (ids == NULL) {
+ RTE_REGEXDEV_LOG(ERR, "Dev %d ids can't be NULL\n", dev_id);
+ return -EINVAL;
+ }
+ return (*dev->dev_ops->dev_xstats_reset)(dev, ids, nb_ids);
+}
+
+int
+rte_regexdev_selftest(uint8_t dev_id)
+{
+ struct rte_regexdev *dev;
+
+ RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
+ dev = &rte_regex_devices[dev_id];
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_selftest, -ENOTSUP);
+ return (*dev->dev_ops->dev_selftest)(dev);
+}
+
+int
+rte_regexdev_dump(uint8_t dev_id, FILE *f)
+{
+ struct rte_regexdev *dev;
+
+ RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
+ dev = &rte_regex_devices[dev_id];
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_dump, -ENOTSUP);
+ if (f == NULL) {
+ RTE_REGEXDEV_LOG(ERR, "Dev %d file can't be NULL\n", dev_id);
+ return -EINVAL;
+ }
+ return (*dev->dev_ops->dev_dump)(dev, f);
+}
@@ -213,6 +213,33 @@
#define RTE_REGEXDEV_LOG(level, ...) \
rte_log(RTE_LOG_ ## level, rte_regexdev_logtype, "" __VA_ARGS__)
+/* Macros to check for valid port */
+#define RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, retval) do { \
+ if (!rte_regexdev_is_valid_dev(dev_id)) { \
+ RTE_REGEXDEV_LOG(ERR, "Invalid dev_id=%u\n", dev_id); \
+ return retval; \
+ } \
+} while (0)
+
+#define RTE_REGEXDEV_VALID_DEV_ID_OR_RET(dev_id) do { \
+ if (!rte_regexdev_is_valid_dev(dev_id)) { \
+ RTE_REGEXDEV_LOG(ERR, "Invalid dev_id=%u\n", dev_id); \
+ return; \
+ } \
+} while (0)
+
+/**
+ * Check if dev_id is ready.
+ *
+ * @param dev_id
+ * The dev identifier of the RegEx device.
+ *
+ * @return
+ * - 0 if device state is not in ready state.
+ * - 1 if device state is ready state.
+ */
+int rte_regexdev_is_valid_dev(uint16_t dev_id);
+
/**
* @warning
* @b EXPERIMENTAL: this API may change without prior notice.
@@ -803,10 +830,11 @@ struct rte_regexdev_qp_conf {
* @param dev_id
* RegEx device identifier.
*
- * @see struct rte_regexdev_qp_conf::cb, rte_regexdev_queue_pair_setup()
+ * @return
+ * 0 on success. Otherwise negative errno is returned.
*/
__rte_experimental
-void
+int
rte_regexdev_stop(uint8_t dev_id);
/**
@@ -1384,6 +1412,8 @@ struct rte_regex_ops {
*/
};
+#include "rte_regexdev_core.h"
+
/**
* @warning
* @b EXPERIMENTAL: this API may change without prior notice.
@@ -1422,9 +1452,21 @@ struct rte_regex_ops {
* to take care of them.
*/
__rte_experimental
-uint16_t
+static inline uint16_t
rte_regexdev_enqueue_burst(uint8_t dev_id, uint16_t qp_id,
- struct rte_regex_ops **ops, uint16_t nb_ops);
+ struct rte_regex_ops **ops, uint16_t nb_ops)
+{
+ struct rte_regexdev *dev = &rte_regex_devices[dev_id];
+#ifdef RTE_LIBRTE_REGEXDEV_DEBUG
+ RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->enqueue, -ENOTSUP);
+ if (qp_id >= dev->data->dev_conf.nb_queue_pairs) {
+ RTE_REGEXDEV_LOG(ERR, "Invalid queue %d\n", qp_id);
+ return -EINVAL;
+ }
+#endif
+ return (*dev->enqueue)(dev, qp_id, ops, nb_ops);
+}
/**
* @warning
@@ -1469,11 +1511,21 @@ struct rte_regex_ops {
* of them.
*/
__rte_experimental
-uint16_t
+static inline uint16_t
rte_regexdev_dequeue_burst(uint8_t dev_id, uint16_t qp_id,
- struct rte_regex_ops **ops, uint16_t nb_ops);
-
-#include "rte_regexdev_core.h"
+ struct rte_regex_ops **ops, uint16_t nb_ops)
+{
+ struct rte_regexdev *dev = &rte_regex_devices[dev_id];
+#ifdef RTE_LIBRTE_REGEXDEV_DEBUG
+ RTE_REGEXDEV_VALID_DEV_ID_OR_ERR_RET(dev_id, -EINVAL);
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dequeue, -ENOTSUP);
+ if (qp_id >= dev->data->dev_conf.nb_queue_pairs) {
+ RTE_REGEXDEV_LOG(ERR, "Invalid queue %d\n", qp_id);
+ return -EINVAL;
+ }
+#endif
+ return (*dev->dequeue)(dev, qp_id, ops, nb_ops);
+}
#ifdef __cplusplus
}
@@ -149,6 +149,8 @@ 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. */
+ struct rte_regexdev_config dev_conf; /**< RegEx configuration. */
+ uint8_t dev_started : 1; /**< Device started to work. */
} __rte_cache_aligned;
/**
@@ -171,4 +173,11 @@ struct rte_regexdev {
struct rte_regexdev_data *data; /**< Pointer to device data. */
} __rte_cache_aligned;
+/**
+ * @internal
+ * The pool of *rte_regexdev* structures. The size of the pool
+ * is configured at compile-time in the <rte_regexdev.c> file.
+ */
+extern struct rte_regexdev rte_regex_devices[];
+
#endif /* _RTE_REGEX_CORE_H_ */