* Re: [PATCH 2/4] eventdev: implement the northbound APIs
From: Eads, Gage @ 2016-11-21 17:45 UTC (permalink / raw)
To: Jerin Jacob, dev@dpdk.org
Cc: Richardson, Bruce, Van Haaren, Harry, hemant.agrawal@nxp.com
In-Reply-To: <1479447902-3700-3-git-send-email-jerin.jacob@caviumnetworks.com>
Hi Jerin,
I did a quick review and overall this implementation looks good. I noticed just one issue in rte_event_queue_setup(): the check of nb_atomic_order_sequences is being applied to atomic-type queues, but that field applies to ordered-type queues.
One open issue I noticed is the "typical workflow" description starting in rte_eventdev.h:204 conflicts with the centralized software PMD that Harry posted last week. Specifically, that PMD expects a single core to call the schedule function. We could extend the documentation to account for this alternative style of scheduler invocation, or discuss ways to make the software PMD work with the documented workflow. I prefer the former, but either way I think we ought to expose the scheduler's expected usage to the user -- perhaps through an RTE_EVENT_DEV_CAP flag?
Thanks,
Gage
> -----Original Message-----
> From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
> Sent: Thursday, November 17, 2016 11:45 PM
> To: dev@dpdk.org
> Cc: Richardson, Bruce <bruce.richardson@intel.com>; Van Haaren, Harry
> <harry.van.haaren@intel.com>; hemant.agrawal@nxp.com; Eads, Gage
> <gage.eads@intel.com>; Jerin Jacob <jerin.jacob@caviumnetworks.com>
> Subject: [dpdk-dev] [PATCH 2/4] eventdev: implement the northbound APIs
>
> This patch set defines the southbound driver interface
> and implements the common code required for northbound
> eventdev API interface.
>
> Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> ---
> config/common_base | 6 +
> lib/Makefile | 1 +
> lib/librte_eal/common/include/rte_log.h | 1 +
> lib/librte_eventdev/Makefile | 57 ++
> lib/librte_eventdev/rte_eventdev.c | 1211
> ++++++++++++++++++++++++++
> lib/librte_eventdev/rte_eventdev_pmd.h | 504 +++++++++++
> lib/librte_eventdev/rte_eventdev_version.map | 39 +
> mk/rte.app.mk | 1 +
> 8 files changed, 1820 insertions(+)
> create mode 100644 lib/librte_eventdev/Makefile
> create mode 100644 lib/librte_eventdev/rte_eventdev.c
> create mode 100644 lib/librte_eventdev/rte_eventdev_pmd.h
> create mode 100644 lib/librte_eventdev/rte_eventdev_version.map
>
> diff --git a/config/common_base b/config/common_base
> index 4bff83a..7a8814e 100644
> --- a/config/common_base
> +++ b/config/common_base
> @@ -411,6 +411,12 @@ CONFIG_RTE_LIBRTE_PMD_ZUC_DEBUG=n
> CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO=y
>
> #
> +# Compile generic event device library
> +#
> +CONFIG_RTE_LIBRTE_EVENTDEV=y
> +CONFIG_RTE_LIBRTE_EVENTDEV_DEBUG=n
> +CONFIG_RTE_EVENT_MAX_DEVS=16
> +CONFIG_RTE_EVENT_MAX_QUEUES_PER_DEV=64
> # Compile librte_ring
> #
> CONFIG_RTE_LIBRTE_RING=y
> diff --git a/lib/Makefile b/lib/Makefile
> index 990f23a..1a067bf 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -41,6 +41,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_CFGFILE) += librte_cfgfile
> DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += librte_cmdline
> DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether
> DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += librte_cryptodev
> +DIRS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += librte_eventdev
> DIRS-$(CONFIG_RTE_LIBRTE_VHOST) += librte_vhost
> DIRS-$(CONFIG_RTE_LIBRTE_HASH) += librte_hash
> DIRS-$(CONFIG_RTE_LIBRTE_LPM) += librte_lpm
> diff --git a/lib/librte_eal/common/include/rte_log.h
> b/lib/librte_eal/common/include/rte_log.h
> index 29f7d19..9a07d92 100644
> --- a/lib/librte_eal/common/include/rte_log.h
> +++ b/lib/librte_eal/common/include/rte_log.h
> @@ -79,6 +79,7 @@ extern struct rte_logs rte_logs;
> #define RTE_LOGTYPE_PIPELINE 0x00008000 /**< Log related to pipeline. */
> #define RTE_LOGTYPE_MBUF 0x00010000 /**< Log related to mbuf. */
> #define RTE_LOGTYPE_CRYPTODEV 0x00020000 /**< Log related to
> cryptodev. */
> +#define RTE_LOGTYPE_EVENTDEV 0x00040000 /**< Log related to eventdev.
> */
>
> /* these log types can be used in an application */
> #define RTE_LOGTYPE_USER1 0x01000000 /**< User-defined log type 1. */
> diff --git a/lib/librte_eventdev/Makefile b/lib/librte_eventdev/Makefile
> new file mode 100644
> index 0000000..dac0663
> --- /dev/null
> +++ b/lib/librte_eventdev/Makefile
> @@ -0,0 +1,57 @@
> +# BSD LICENSE
> +#
> +# Copyright(c) 2016 Cavium networks. All rights reserved.
> +#
> +# Redistribution and use in source and binary forms, with or without
> +# modification, are permitted provided that the following conditions
> +# are met:
> +#
> +# * Redistributions of source code must retain the above copyright
> +# notice, this list of conditions and the following disclaimer.
> +# * Redistributions in binary form must reproduce the above copyright
> +# notice, this list of conditions and the following disclaimer in
> +# the documentation and/or other materials provided with the
> +# distribution.
> +# * Neither the name of Cavium networks nor the names of its
> +# contributors may be used to endorse or promote products derived
> +# from this software without specific prior written permission.
> +#
> +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> CONTRIBUTORS
> +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
> NOT
> +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
> FITNESS FOR
> +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
> COPYRIGHT
> +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
> INCIDENTAL,
> +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> NOT
> +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
> OF USE,
> +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> ON ANY
> +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
> TORT
> +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
> THE USE
> +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
> DAMAGE.
> +
> +include $(RTE_SDK)/mk/rte.vars.mk
> +
> +# library name
> +LIB = librte_eventdev.a
> +
> +# library version
> +LIBABIVER := 1
> +
> +# build flags
> +CFLAGS += -O3
> +CFLAGS += $(WERROR_FLAGS)
> +
> +# library source files
> +SRCS-y += rte_eventdev.c
> +
> +# export include files
> +SYMLINK-y-include += rte_eventdev.h
> +SYMLINK-y-include += rte_eventdev_pmd.h
> +
> +# versioning export map
> +EXPORT_MAP := rte_eventdev_version.map
> +
> +# library dependencies
> +DEPDIRS-y += lib/librte_eal
> +DEPDIRS-y += lib/librte_mbuf
> +
> +include $(RTE_SDK)/mk/rte.lib.mk
> diff --git a/lib/librte_eventdev/rte_eventdev.c
> b/lib/librte_eventdev/rte_eventdev.c
> new file mode 100644
> index 0000000..17ce5c3
> --- /dev/null
> +++ b/lib/librte_eventdev/rte_eventdev.c
> @@ -0,0 +1,1211 @@
> +/*
> + * BSD LICENSE
> + *
> + * Copyright(c) 2016 Cavium networks. All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * * Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * * Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in
> + * the documentation and/or other materials provided with the
> + * distribution.
> + * * Neither the name of Cavium networks nor the names of its
> + * contributors may be used to endorse or promote products derived
> + * from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
> NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
> FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
> COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
> INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
> OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
> AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
> TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
> THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
> DAMAGE.
> + */
> +
> +#include <ctype.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <stdarg.h>
> +#include <errno.h>
> +#include <stdint.h>
> +#include <inttypes.h>
> +#include <sys/types.h>
> +#include <sys/queue.h>
> +
> +#include <rte_byteorder.h>
> +#include <rte_log.h>
> +#include <rte_debug.h>
> +#include <rte_dev.h>
> +#include <rte_pci.h>
> +#include <rte_memory.h>
> +#include <rte_memcpy.h>
> +#include <rte_memzone.h>
> +#include <rte_eal.h>
> +#include <rte_per_lcore.h>
> +#include <rte_lcore.h>
> +#include <rte_atomic.h>
> +#include <rte_branch_prediction.h>
> +#include <rte_common.h>
> +#include <rte_malloc.h>
> +#include <rte_errno.h>
> +
> +#include "rte_eventdev.h"
> +#include "rte_eventdev_pmd.h"
> +
> +struct rte_eventdev rte_event_devices[RTE_EVENT_MAX_DEVS];
> +
> +struct rte_eventdev *rte_eventdevs = &rte_event_devices[0];
> +
> +static struct rte_eventdev_global eventdev_globals = {
> + .nb_devs = 0
> +};
> +
> +struct rte_eventdev_global *rte_eventdev_globals = &eventdev_globals;
> +
> +/* Event dev north bound API implementation */
> +
> +uint8_t
> +rte_event_dev_count(void)
> +{
> + return rte_eventdev_globals->nb_devs;
> +}
> +
> +int
> +rte_event_dev_get_dev_id(const char *name)
> +{
> + int i;
> +
> + if (!name)
> + return -EINVAL;
> +
> + for (i = 0; i < rte_eventdev_globals->nb_devs; i++)
> + if ((strcmp(rte_event_devices[i].data->name, name)
> + == 0) &&
> + (rte_event_devices[i].attached ==
> + RTE_EVENTDEV_ATTACHED))
> + return i;
> + return -ENODEV;
> +}
> +
> +int
> +rte_event_dev_socket_id(uint8_t dev_id)
> +{
> + struct rte_eventdev *dev;
> +
> + RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> + dev = &rte_eventdevs[dev_id];
> +
> + return dev->data->socket_id;
> +}
> +
> +int
> +rte_event_dev_info_get(uint8_t dev_id, struct rte_event_dev_info *dev_info)
> +{
> + struct rte_eventdev *dev;
> +
> + RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> + dev = &rte_eventdevs[dev_id];
> +
> + if (dev_info == NULL)
> + return -EINVAL;
> +
> + memset(dev_info, 0, sizeof(struct rte_event_dev_info));
> +
> + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -
> ENOTSUP);
> + (*dev->dev_ops->dev_infos_get)(dev, dev_info);
> +
> + dev_info->pci_dev = dev->pci_dev;
> + if (dev->driver)
> + dev_info->driver_name = dev->driver->pci_drv.driver.name;
> + return 0;
> +}
> +
> +static inline int
> +rte_event_dev_queue_config(struct rte_eventdev *dev, uint8_t nb_queues)
> +{
> + uint8_t old_nb_queues = dev->data->nb_queues;
> + void **queues;
> + uint8_t *queues_prio;
> + unsigned int i;
> +
> + EDEV_LOG_DEBUG("Setup %d queues on device %u", nb_queues,
> + dev->data->dev_id);
> +
> + /* First time configuration */
> + if (dev->data->queues == NULL && nb_queues != 0) {
> + dev->data->queues = rte_zmalloc_socket("eventdev->data-
> >queues",
> + sizeof(dev->data->queues[0]) * nb_queues,
> + RTE_CACHE_LINE_SIZE, dev->data-
> >socket_id);
> + if (dev->data->queues == NULL) {
> + dev->data->nb_queues = 0;
> + EDEV_LOG_ERR("failed to get memory for queue meta
> data,"
> + "nb_queues %u", nb_queues);
> + return -(ENOMEM);
> + }
> + /* Allocate memory to store queue priority */
> + dev->data->queues_prio = rte_zmalloc_socket(
> + "eventdev->data->queues_prio",
> + sizeof(dev->data->queues_prio[0]) *
> nb_queues,
> + RTE_CACHE_LINE_SIZE, dev->data-
> >socket_id);
> + if (dev->data->queues_prio == NULL) {
> + dev->data->nb_queues = 0;
> + EDEV_LOG_ERR("failed to get memory for queue
> priority,"
> + "nb_queues %u", nb_queues);
> + return -(ENOMEM);
> + }
> +
> + } else if (dev->data->queues != NULL && nb_queues != 0) {/* re-config
> */
> + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops-
> >queue_release, -ENOTSUP);
> +
> + queues = dev->data->queues;
> + for (i = nb_queues; i < old_nb_queues; i++)
> + (*dev->dev_ops->queue_release)(queues[i]);
> +
> + queues = rte_realloc(queues, sizeof(queues[0]) * nb_queues,
> + RTE_CACHE_LINE_SIZE);
> + if (queues == NULL) {
> + EDEV_LOG_ERR("failed to realloc queue meta data,"
> + " nb_queues %u",
> nb_queues);
> + return -(ENOMEM);
> + }
> + dev->data->queues = queues;
> +
> + /* Re allocate memory to store queue priority */
> + queues_prio = dev->data->queues_prio;
> + queues_prio = rte_realloc(queues_prio,
> + sizeof(queues_prio[0]) * nb_queues,
> + RTE_CACHE_LINE_SIZE);
> + if (queues_prio == NULL) {
> + EDEV_LOG_ERR("failed to realloc queue priority,"
> + " nb_queues %u",
> nb_queues);
> + return -(ENOMEM);
> + }
> + dev->data->queues_prio = queues_prio;
> +
> + if (nb_queues > old_nb_queues) {
> + uint8_t new_qs = nb_queues - old_nb_queues;
> +
> + memset(queues + old_nb_queues, 0,
> + sizeof(queues[0]) * new_qs);
> + memset(queues_prio + old_nb_queues, 0,
> + sizeof(queues_prio[0]) * new_qs);
> + }
> + } else if (dev->data->queues != NULL && nb_queues == 0) {
> + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops-
> >queue_release, -ENOTSUP);
> +
> + queues = dev->data->queues;
> + for (i = nb_queues; i < old_nb_queues; i++)
> + (*dev->dev_ops->queue_release)(queues[i]);
> + }
> +
> + dev->data->nb_queues = nb_queues;
> + return 0;
> +}
> +
> +static inline int
> +rte_event_dev_port_config(struct rte_eventdev *dev, uint8_t nb_ports)
> +{
> + uint8_t old_nb_ports = dev->data->nb_ports;
> + void **ports;
> + uint16_t *links_map;
> + uint8_t *ports_dequeue_depth;
> + uint8_t *ports_enqueue_depth;
> + unsigned int i;
> +
> + EDEV_LOG_DEBUG("Setup %d ports on device %u", nb_ports,
> + dev->data->dev_id);
> +
> + /* First time configuration */
> + if (dev->data->ports == NULL && nb_ports != 0) {
> + dev->data->ports = rte_zmalloc_socket("eventdev->data-
> >ports",
> + sizeof(dev->data->ports[0]) * nb_ports,
> + RTE_CACHE_LINE_SIZE, dev->data-
> >socket_id);
> + if (dev->data->ports == NULL) {
> + dev->data->nb_ports = 0;
> + EDEV_LOG_ERR("failed to get memory for port meta
> data,"
> + "nb_ports %u", nb_ports);
> + return -(ENOMEM);
> + }
> +
> + /* Allocate memory to store ports dequeue depth */
> + dev->data->ports_dequeue_depth =
> + rte_zmalloc_socket("eventdev-
> >ports_dequeue_depth",
> + sizeof(dev->data->ports_dequeue_depth[0]) *
> nb_ports,
> + RTE_CACHE_LINE_SIZE, dev->data->socket_id);
> + if (dev->data->ports_dequeue_depth == NULL) {
> + dev->data->nb_ports = 0;
> + EDEV_LOG_ERR("failed to get memory for port deq
> meta,"
> + "nb_ports %u", nb_ports);
> + return -(ENOMEM);
> + }
> +
> + /* Allocate memory to store ports enqueue depth */
> + dev->data->ports_enqueue_depth =
> + rte_zmalloc_socket("eventdev-
> >ports_enqueue_depth",
> + sizeof(dev->data->ports_enqueue_depth[0]) *
> nb_ports,
> + RTE_CACHE_LINE_SIZE, dev->data->socket_id);
> + if (dev->data->ports_enqueue_depth == NULL) {
> + dev->data->nb_ports = 0;
> + EDEV_LOG_ERR("failed to get memory for port enq
> meta,"
> + "nb_ports %u", nb_ports);
> + return -(ENOMEM);
> + }
> +
> + /* Allocate memory to store queue to port link connection */
> + dev->data->links_map =
> + rte_zmalloc_socket("eventdev->links_map",
> + sizeof(dev->data->links_map[0]) * nb_ports *
> + RTE_EVENT_MAX_QUEUES_PER_DEV,
> + RTE_CACHE_LINE_SIZE, dev->data->socket_id);
> + if (dev->data->links_map == NULL) {
> + dev->data->nb_ports = 0;
> + EDEV_LOG_ERR("failed to get memory for port_map
> area,"
> + "nb_ports %u", nb_ports);
> + return -(ENOMEM);
> + }
> + } else if (dev->data->ports != NULL && nb_ports != 0) {/* re-config */
> + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->port_release,
> -ENOTSUP);
> +
> + ports = dev->data->ports;
> + ports_dequeue_depth = dev->data->ports_dequeue_depth;
> + ports_enqueue_depth = dev->data->ports_enqueue_depth;
> + links_map = dev->data->links_map;
> +
> + for (i = nb_ports; i < old_nb_ports; i++)
> + (*dev->dev_ops->port_release)(ports[i]);
> +
> + /* Realloc memory for ports */
> + ports = rte_realloc(ports, sizeof(ports[0]) * nb_ports,
> + RTE_CACHE_LINE_SIZE);
> + if (ports == NULL) {
> + EDEV_LOG_ERR("failed to realloc port meta data,"
> + " nb_ports %u", nb_ports);
> + return -(ENOMEM);
> + }
> +
> + /* Realloc memory for ports_dequeue_depth */
> + ports_dequeue_depth = rte_realloc(ports_dequeue_depth,
> + sizeof(ports_dequeue_depth[0]) * nb_ports,
> + RTE_CACHE_LINE_SIZE);
> + if (ports_dequeue_depth == NULL) {
> + EDEV_LOG_ERR("failed to realloc port deqeue meta
> data,"
> + " nb_ports %u", nb_ports);
> + return -(ENOMEM);
> + }
> +
> + /* Realloc memory for ports_enqueue_depth */
> + ports_enqueue_depth = rte_realloc(ports_enqueue_depth,
> + sizeof(ports_enqueue_depth[0]) * nb_ports,
> + RTE_CACHE_LINE_SIZE);
> + if (ports_enqueue_depth == NULL) {
> + EDEV_LOG_ERR("failed to realloc port enqueue meta
> data,"
> + " nb_ports %u", nb_ports);
> + return -(ENOMEM);
> + }
> +
> + /* Realloc memory to store queue to port link connection */
> + links_map = rte_realloc(links_map,
> + sizeof(dev->data->links_map[0]) * nb_ports *
> + RTE_EVENT_MAX_QUEUES_PER_DEV,
> + RTE_CACHE_LINE_SIZE);
> + if (dev->data->links_map == NULL) {
> + dev->data->nb_ports = 0;
> + EDEV_LOG_ERR("failed to realloc mem for port_map
> area,"
> + "nb_ports %u", nb_ports);
> + return -(ENOMEM);
> + }
> +
> + if (nb_ports > old_nb_ports) {
> + uint8_t new_ps = nb_ports - old_nb_ports;
> +
> + memset(ports + old_nb_ports, 0,
> + sizeof(ports[0]) * new_ps);
> + memset(ports_dequeue_depth + old_nb_ports, 0,
> + sizeof(ports_dequeue_depth[0]) * new_ps);
> + memset(ports_enqueue_depth + old_nb_ports, 0,
> + sizeof(ports_enqueue_depth[0]) * new_ps);
> + memset(links_map +
> + (old_nb_ports *
> RTE_EVENT_MAX_QUEUES_PER_DEV),
> + 0, sizeof(ports_enqueue_depth[0]) * new_ps);
> + }
> +
> + dev->data->ports = ports;
> + dev->data->ports_dequeue_depth = ports_dequeue_depth;
> + dev->data->ports_enqueue_depth = ports_enqueue_depth;
> + dev->data->links_map = links_map;
> + } else if (dev->data->ports != NULL && nb_ports == 0) {
> + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->port_release,
> -ENOTSUP);
> +
> + ports = dev->data->ports;
> + for (i = nb_ports; i < old_nb_ports; i++)
> + (*dev->dev_ops->port_release)(ports[i]);
> + }
> +
> + dev->data->nb_ports = nb_ports;
> + return 0;
> +}
> +
> +int
> +rte_event_dev_configure(uint8_t dev_id, struct rte_event_dev_config
> *dev_conf)
> +{
> + struct rte_eventdev *dev;
> + struct rte_event_dev_info info;
> + int diag;
> +
> + RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> + dev = &rte_eventdevs[dev_id];
> +
> + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -
> ENOTSUP);
> + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -
> ENOTSUP);
> +
> + if (dev->data->dev_started) {
> + EDEV_LOG_ERR(
> + "device %d must be stopped to allow configuration",
> dev_id);
> + return -EBUSY;
> + }
> +
> + if (dev_conf == NULL)
> + return -EINVAL;
> +
> + (*dev->dev_ops->dev_infos_get)(dev, &info);
> +
> + /* Check dequeue_wait_ns value is in limit */
> + if (!dev_conf->event_dev_cfg &
> RTE_EVENT_DEV_CFG_PER_DEQUEUE_WAIT) {
> + if (dev_conf->dequeue_wait_ns < info.min_dequeue_wait_ns
> ||
> + dev_conf->dequeue_wait_ns >
> info.max_dequeue_wait_ns) {
> + EDEV_LOG_ERR("dev%d invalid dequeue_wait_ns=%d"
> + " min_dequeue_wait_ns=%d
> max_dequeue_wait_ns=%d",
> + dev_id, dev_conf->dequeue_wait_ns,
> + info.min_dequeue_wait_ns,
> + info.max_dequeue_wait_ns);
> + return -EINVAL;
> + }
> + }
> +
> + /* Check nb_events_limit is in limit */
> + if (dev_conf->nb_events_limit > info.max_num_events) {
> + EDEV_LOG_ERR("dev%d nb_events_limit=%d >
> max_num_events=%d",
> + dev_id, dev_conf->nb_events_limit, info.max_num_events);
> + return -EINVAL;
> + }
> +
> + /* Check nb_event_queues is in limit */
> + if (!dev_conf->nb_event_queues) {
> + EDEV_LOG_ERR("dev%d nb_event_queues cannot be zero",
> dev_id);
> + return -EINVAL;
> + }
> + if (dev_conf->nb_event_queues > info.max_event_queues) {
> + EDEV_LOG_ERR("dev%d nb_event_queues=%d >
> max_event_queues=%d",
> + dev_id, dev_conf->nb_event_queues,
> info.max_event_queues);
> + return -EINVAL;
> + }
> +
> + /* Check nb_event_ports is in limit */
> + if (!dev_conf->nb_event_ports) {
> + EDEV_LOG_ERR("dev%d nb_event_ports cannot be zero",
> dev_id);
> + return -EINVAL;
> + }
> + if (dev_conf->nb_event_ports > info.max_event_ports) {
> + EDEV_LOG_ERR("dev%d nb_event_ports=%d >
> max_event_ports= %d",
> + dev_id, dev_conf->nb_event_ports, info.max_event_ports);
> + return -EINVAL;
> + }
> +
> + /* Check nb_event_queue_flows is in limit */
> + if (!dev_conf->nb_event_queue_flows) {
> + EDEV_LOG_ERR("dev%d nb_flows cannot be zero", dev_id);
> + return -EINVAL;
> + }
> + if (dev_conf->nb_event_queue_flows > info.max_event_queue_flows)
> {
> + EDEV_LOG_ERR("dev%d nb_flows=%x > max_flows=%x",
> + dev_id, dev_conf->nb_event_queue_flows,
> + info.max_event_queue_flows);
> + return -EINVAL;
> + }
> +
> + /* Check nb_event_port_dequeue_depth is in limit */
> + if (!dev_conf->nb_event_port_dequeue_depth) {
> + EDEV_LOG_ERR("dev%d nb_dequeue_depth cannot be zero",
> dev_id);
> + return -EINVAL;
> + }
> + if (dev_conf->nb_event_port_dequeue_depth >
> + info.max_event_port_dequeue_depth) {
> + EDEV_LOG_ERR("dev%d nb_dequeue_depth=%d >
> max_dequeue_depth=%d",
> + dev_id, dev_conf->nb_event_port_dequeue_depth,
> + info.max_event_port_dequeue_depth);
> + return -EINVAL;
> + }
> +
> + /* Check nb_event_port_enqueue_depth is in limit */
> + if (!dev_conf->nb_event_port_enqueue_depth) {
> + EDEV_LOG_ERR("dev%d nb_enqueue_depth cannot be zero",
> dev_id);
> + return -EINVAL;
> + }
> + if (dev_conf->nb_event_port_enqueue_depth >
> + info.max_event_port_enqueue_depth) {
> + EDEV_LOG_ERR("dev%d nb_enqueue_depth=%d >
> max_enqueue_depth=%d",
> + dev_id, dev_conf->nb_event_port_enqueue_depth,
> + info.max_event_port_enqueue_depth);
> + return -EINVAL;
> + }
> +
> + /* Copy the dev_conf parameter into the dev structure */
> + memcpy(&dev->data->dev_conf, dev_conf, sizeof(dev->data-
> >dev_conf));
> +
> + /* Setup new number of queues and reconfigure device. */
> + diag = rte_event_dev_queue_config(dev, dev_conf-
> >nb_event_queues);
> + if (diag != 0) {
> + EDEV_LOG_ERR("dev%d rte_event_dev_queue_config = %d",
> + dev_id, diag);
> + return diag;
> + }
> +
> + /* Setup new number of ports and reconfigure device. */
> + diag = rte_event_dev_port_config(dev, dev_conf->nb_event_ports);
> + if (diag != 0) {
> + rte_event_dev_queue_config(dev, 0);
> + EDEV_LOG_ERR("dev%d rte_event_dev_port_config = %d",
> + dev_id, diag);
> + return diag;
> + }
> +
> + /* Configure the device */
> + diag = (*dev->dev_ops->dev_configure)(dev);
> + if (diag != 0) {
> + EDEV_LOG_ERR("dev%d dev_configure = %d", dev_id, diag);
> + rte_event_dev_queue_config(dev, 0);
> + rte_event_dev_port_config(dev, 0);
> + }
> +
> + dev->data->event_dev_cap = info.event_dev_cap;
> + return diag;
> +}
> +
> +static inline int
> +is_valid_queue(struct rte_eventdev *dev, uint8_t queue_id)
> +{
> + if (queue_id < dev->data->nb_queues && queue_id <
> + RTE_EVENT_MAX_QUEUES_PER_DEV)
> + return 1;
> + else
> + return 0;
> +}
> +
> +int
> +rte_event_queue_default_conf_get(uint8_t dev_id, uint8_t queue_id,
> + struct rte_event_queue_conf *queue_conf)
> +{
> + struct rte_eventdev *dev;
> +
> + RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> + dev = &rte_eventdevs[dev_id];
> +
> + if (queue_conf == NULL)
> + return -EINVAL;
> +
> + if (!is_valid_queue(dev, queue_id)) {
> + EDEV_LOG_ERR("Invalid queue_id=%" PRIu8, queue_id);
> + return -EINVAL;
> + }
> +
> + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_def_conf, -
> ENOTSUP);
> + memset(queue_conf, 0, sizeof(struct rte_event_queue_conf));
> + (*dev->dev_ops->queue_def_conf)(dev, queue_id, queue_conf);
> + return 0;
> +}
> +
> +static inline int
> +is_valid_atomic_queue_conf(struct rte_event_queue_conf *queue_conf)
> +{
> + if (queue_conf && (
> + ((queue_conf->event_queue_cfg &
> RTE_EVENT_QUEUE_CFG_TYPE_MASK)
> + == RTE_EVENT_QUEUE_CFG_ALL_TYPES) ||
> + ((queue_conf->event_queue_cfg &
> RTE_EVENT_QUEUE_CFG_TYPE_MASK)
> + == RTE_EVENT_QUEUE_CFG_ATOMIC_ONLY)
> + ))
> + return 1;
> + else
> + return 0;
> +}
> +
> +int
> +rte_event_queue_setup(uint8_t dev_id, uint8_t queue_id,
> + struct rte_event_queue_conf *queue_conf)
> +{
> + struct rte_eventdev *dev;
> + struct rte_event_queue_conf def_conf;
> +
> + RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> + dev = &rte_eventdevs[dev_id];
> +
> + if (!is_valid_queue(dev, queue_id)) {
> + EDEV_LOG_ERR("Invalid queue_id=%" PRIu8, queue_id);
> + return -EINVAL;
> + }
> +
> + /* Check nb_atomic_flows limit */
> + if (is_valid_atomic_queue_conf(queue_conf)) {
> + if (queue_conf->nb_atomic_flows == 0 ||
> + queue_conf->nb_atomic_flows >
> + dev->data->dev_conf.nb_event_queue_flows) {
> + EDEV_LOG_ERR(
> + "dev%d queue%d Invalid nb_atomic_flows=%d
> max_flows=%d",
> + dev_id, queue_id, queue_conf->nb_atomic_flows,
> + dev->data->dev_conf.nb_event_queue_flows);
> + return -EINVAL;
> + }
> + }
> +
> + /* Check nb_atomic_order_sequences limit */
> + if (is_valid_atomic_queue_conf(queue_conf)) {
> + if (queue_conf->nb_atomic_order_sequences == 0 ||
> + queue_conf->nb_atomic_order_sequences >
> + dev->data->dev_conf.nb_event_queue_flows) {
> + EDEV_LOG_ERR(
> + "dev%d queue%d Invalid nb_atomic_order_seq=%d
> max_flows=%d",
> + dev_id, queue_id, queue_conf-
> >nb_atomic_order_sequences,
> + dev->data->dev_conf.nb_event_queue_flows);
> + return -EINVAL;
> + }
> + }
> +
> + if (dev->data->dev_started) {
> + EDEV_LOG_ERR(
> + "device %d must be stopped to allow queue setup", dev_id);
> + return -EBUSY;
> + }
> +
> + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_setup, -
> ENOTSUP);
> +
> + if (queue_conf == NULL) {
> + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops-
> >queue_def_conf,
> + -ENOTSUP);
> + (*dev->dev_ops->queue_def_conf)(dev, queue_id, &def_conf);
> + def_conf.event_queue_cfg =
> RTE_EVENT_QUEUE_CFG_DEFAULT;
> + queue_conf = &def_conf;
> + }
> +
> + dev->data->queues_prio[queue_id] = queue_conf->priority;
> + return (*dev->dev_ops->queue_setup)(dev, queue_id, queue_conf);
> +}
> +
> +uint8_t
> +rte_event_queue_count(uint8_t dev_id)
> +{
> + struct rte_eventdev *dev;
> +
> + dev = &rte_eventdevs[dev_id];
> + return dev->data->nb_queues;
> +}
> +
> +uint8_t
> +rte_event_queue_priority(uint8_t dev_id, uint8_t queue_id)
> +{
> + struct rte_eventdev *dev;
> +
> + dev = &rte_eventdevs[dev_id];
> + if (dev->data->event_dev_cap & RTE_EVENT_DEV_CAP_QUEUE_QOS)
> + return dev->data->queues_prio[queue_id];
> + else
> + return RTE_EVENT_QUEUE_PRIORITY_NORMAL;
> +}
> +
> +static inline int
> +is_valid_port(struct rte_eventdev *dev, uint8_t port_id)
> +{
> + if (port_id < dev->data->nb_ports)
> + return 1;
> + else
> + return 0;
> +}
> +
> +int
> +rte_event_port_default_conf_get(uint8_t dev_id, uint8_t port_id,
> + struct rte_event_port_conf *port_conf)
> +{
> + struct rte_eventdev *dev;
> +
> + RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> + dev = &rte_eventdevs[dev_id];
> +
> + if (port_conf == NULL)
> + return -EINVAL;
> +
> + if (!is_valid_port(dev, port_id)) {
> + EDEV_LOG_ERR("Invalid port_id=%" PRIu8, port_id);
> + return -EINVAL;
> + }
> +
> + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->port_def_conf, -
> ENOTSUP);
> + memset(port_conf, 0, sizeof(struct rte_event_port_conf));
> + (*dev->dev_ops->port_def_conf)(dev, port_id, port_conf);
> + return 0;
> +}
> +
> +int
> +rte_event_port_setup(uint8_t dev_id, uint8_t port_id,
> + struct rte_event_port_conf *port_conf)
> +{
> + struct rte_eventdev *dev;
> + struct rte_event_port_conf def_conf;
> + int diag;
> +
> + RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> + dev = &rte_eventdevs[dev_id];
> +
> + if (!is_valid_port(dev, port_id)) {
> + EDEV_LOG_ERR("Invalid port_id=%" PRIu8, port_id);
> + return -EINVAL;
> + }
> +
> + /* Check new_event_threshold limit */
> + if ((port_conf && !port_conf->new_event_threshold) ||
> + (port_conf && port_conf->new_event_threshold >
> + dev->data->dev_conf.nb_events_limit)) {
> + EDEV_LOG_ERR(
> + "dev%d port%d Invalid event_threshold=%d
> nb_events_limit=%d",
> + dev_id, port_id, port_conf->new_event_threshold,
> + dev->data->dev_conf.nb_events_limit);
> + return -EINVAL;
> + }
> +
> + /* Check dequeue_depth limit */
> + if ((port_conf && !port_conf->dequeue_depth) ||
> + (port_conf && port_conf->dequeue_depth >
> + dev->data->dev_conf.nb_event_port_dequeue_depth)) {
> + EDEV_LOG_ERR(
> + "dev%d port%d Invalid dequeue depth=%d
> max_dequeue_depth=%d",
> + dev_id, port_id, port_conf->dequeue_depth,
> + dev->data-
> >dev_conf.nb_event_port_dequeue_depth);
> + return -EINVAL;
> + }
> +
> + /* Check enqueue_depth limit */
> + if ((port_conf && !port_conf->enqueue_depth) ||
> + (port_conf && port_conf->enqueue_depth >
> + dev->data->dev_conf.nb_event_port_enqueue_depth)) {
> + EDEV_LOG_ERR(
> + "dev%d port%d Invalid enqueue depth=%d
> max_enqueue_depth=%d",
> + dev_id, port_id, port_conf->enqueue_depth,
> + dev->data-
> >dev_conf.nb_event_port_enqueue_depth);
> + return -EINVAL;
> + }
> +
> + if (dev->data->dev_started) {
> + EDEV_LOG_ERR(
> + "device %d must be stopped to allow port setup", dev_id);
> + return -EBUSY;
> + }
> +
> + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->port_setup, -
> ENOTSUP);
> +
> + if (port_conf == NULL) {
> + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops-
> >port_def_conf,
> + -ENOTSUP);
> + (*dev->dev_ops->port_def_conf)(dev, port_id, &def_conf);
> + port_conf = &def_conf;
> + }
> +
> + dev->data->ports_dequeue_depth[port_id] =
> + port_conf->dequeue_depth;
> + dev->data->ports_enqueue_depth[port_id] =
> + port_conf->enqueue_depth;
> +
> + diag = (*dev->dev_ops->port_setup)(dev, port_id, port_conf);
> +
> + /* Unlink all the queues from this port(default state after setup) */
> + if (!diag)
> + diag = rte_event_port_unlink(dev_id, port_id, NULL, 0);
> +
> + if (diag < 0)
> + return diag;
> +
> + return 0;
> +}
> +
> +uint8_t
> +rte_event_port_dequeue_depth(uint8_t dev_id, uint8_t port_id)
> +{
> + struct rte_eventdev *dev;
> +
> + dev = &rte_eventdevs[dev_id];
> + return dev->data->ports_dequeue_depth[port_id];
> +}
> +
> +uint8_t
> +rte_event_port_enqueue_depth(uint8_t dev_id, uint8_t port_id)
> +{
> + struct rte_eventdev *dev;
> +
> + dev = &rte_eventdevs[dev_id];
> + return dev->data->ports_enqueue_depth[port_id];
> +}
> +
> +uint8_t
> +rte_event_port_count(uint8_t dev_id)
> +{
> + struct rte_eventdev *dev;
> +
> + dev = &rte_eventdevs[dev_id];
> + return dev->data->nb_ports;
> +}
> +
> +int
> +rte_event_port_link(uint8_t dev_id, uint8_t port_id,
> + struct rte_event_queue_link link[], uint16_t nb_links)
> +{
> + struct rte_eventdev *dev;
> + struct rte_event_queue_link
> all_queues[RTE_EVENT_MAX_QUEUES_PER_DEV];
> + uint16_t *links_map;
> + int i, diag;
> +
> + RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> + dev = &rte_eventdevs[dev_id];
> + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->port_link, -ENOTSUP);
> +
> + if (!is_valid_port(dev, port_id)) {
> + EDEV_LOG_ERR("Invalid port_id=%" PRIu8, port_id);
> + return -EINVAL;
> + }
> +
> + if (link == NULL) {
> + for (i = 0; i < dev->data->nb_queues; i++) {
> + all_queues[i].queue_id = i;
> + all_queues[i].priority =
> +
> RTE_EVENT_QUEUE_SERVICE_PRIORITY_NORMAL;
> + }
> + link = all_queues;
> + nb_links = dev->data->nb_queues;
> + }
> +
> + for (i = 0; i < nb_links; i++)
> + if (link[i].queue_id >= RTE_EVENT_MAX_QUEUES_PER_DEV)
> + return -EINVAL;
> +
> + diag = (*dev->dev_ops->port_link)(dev->data->ports[port_id], link,
> + nb_links);
> + if (diag < 0)
> + return diag;
> +
> + links_map = dev->data->links_map;
> + /* Point links_map to this port specific area */
> + links_map += (port_id * RTE_EVENT_MAX_QUEUES_PER_DEV);
> + for (i = 0; i < diag; i++)
> + links_map[link[i].queue_id] = (uint8_t)link[i].priority;
> +
> + return diag;
> +}
> +
> +#define EVENT_QUEUE_SERVICE_PRIORITY_INVALID (0xdead)
> +
> +int
> +rte_event_port_unlink(uint8_t dev_id, uint8_t port_id,
> + uint8_t queues[], uint16_t nb_unlinks)
> +{
> + struct rte_eventdev *dev;
> + uint8_t all_queues[RTE_EVENT_MAX_QUEUES_PER_DEV];
> + int i, diag;
> + uint16_t *links_map;
> +
> + RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> + dev = &rte_eventdevs[dev_id];
> + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->port_unlink, -
> ENOTSUP);
> +
> + if (!is_valid_port(dev, port_id)) {
> + EDEV_LOG_ERR("Invalid port_id=%" PRIu8, port_id);
> + return -EINVAL;
> + }
> +
> + if (queues == NULL) {
> + for (i = 0; i < dev->data->nb_queues; i++)
> + all_queues[i] = i;
> + queues = all_queues;
> + nb_unlinks = dev->data->nb_queues;
> + }
> +
> + for (i = 0; i < nb_unlinks; i++)
> + if (queues[i] >= RTE_EVENT_MAX_QUEUES_PER_DEV)
> + return -EINVAL;
> +
> + diag = (*dev->dev_ops->port_unlink)(dev->data->ports[port_id],
> queues,
> + nb_unlinks);
> +
> + if (diag < 0)
> + return diag;
> +
> + links_map = dev->data->links_map;
> + /* Point links_map to this port specific area */
> + links_map += (port_id * RTE_EVENT_MAX_QUEUES_PER_DEV);
> + for (i = 0; i < diag; i++)
> + links_map[queues[i]] =
> EVENT_QUEUE_SERVICE_PRIORITY_INVALID;
> +
> + return diag;
> +}
> +
> +int
> +rte_event_port_links_get(uint8_t dev_id, uint8_t port_id,
> + struct rte_event_queue_link link[])
> +{
> + struct rte_eventdev *dev;
> + uint16_t *links_map;
> + int i, count = 0;
> +
> + RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> + dev = &rte_eventdevs[dev_id];
> + if (!is_valid_port(dev, port_id)) {
> + EDEV_LOG_ERR("Invalid port_id=%" PRIu8, port_id);
> + return -EINVAL;
> + }
> +
> + links_map = dev->data->links_map;
> + /* Point links_map to this port specific area */
> + links_map += (port_id * RTE_EVENT_MAX_QUEUES_PER_DEV);
> + for (i = 0; i < RTE_EVENT_MAX_QUEUES_PER_DEV; i++) {
> + if (links_map[i] !=
> EVENT_QUEUE_SERVICE_PRIORITY_INVALID) {
> + link[count].queue_id = i;
> + link[count].priority = (uint8_t)links_map[i];
> + ++count;
> + }
> + }
> + return count;
> +}
> +
> +int
> +rte_event_dequeue_wait_time(uint8_t dev_id, uint64_t ns, uint64_t
> *wait_ticks)
> +{
> + struct rte_eventdev *dev;
> +
> + RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> + dev = &rte_eventdevs[dev_id];
> + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->wait_time, -
> ENOTSUP);
> +
> + if (wait_ticks == NULL)
> + return -EINVAL;
> +
> + (*dev->dev_ops->wait_time)(dev, ns, wait_ticks);
> + return 0;
> +}
> +
> +int
> +rte_event_dev_dump(uint8_t dev_id, FILE *f)
> +{
> + struct rte_eventdev *dev;
> +
> + RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> + dev = &rte_eventdevs[dev_id];
> + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dump, -ENOTSUP);
> +
> + (*dev->dev_ops->dump)(dev, f);
> + return 0;
> +
> +}
> +
> +int
> +rte_event_dev_start(uint8_t dev_id)
> +{
> + struct rte_eventdev *dev;
> + int diag;
> +
> + EDEV_LOG_DEBUG("Start dev_id=%" PRIu8, dev_id);
> +
> + RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> + dev = &rte_eventdevs[dev_id];
> + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_start, -ENOTSUP);
> +
> + if (dev->data->dev_started != 0) {
> + EDEV_LOG_ERR("Device with dev_id=%" PRIu8 " already
> started",
> + dev_id);
> + return 0;
> + }
> +
> + diag = (*dev->dev_ops->dev_start)(dev);
> + if (diag == 0)
> + dev->data->dev_started = 1;
> + else
> + return diag;
> +
> + return 0;
> +}
> +
> +void
> +rte_event_dev_stop(uint8_t dev_id)
> +{
> + struct rte_eventdev *dev;
> +
> + EDEV_LOG_DEBUG("Stop dev_id=%" PRIu8, dev_id);
> +
> + RTE_EVENTDEV_VALID_DEVID_OR_RET(dev_id);
> + dev = &rte_eventdevs[dev_id];
> + RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_stop);
> +
> + if (dev->data->dev_started == 0) {
> + EDEV_LOG_ERR("Device with dev_id=%" PRIu8 " already
> stopped",
> + dev_id);
> + return;
> + }
> +
> + dev->data->dev_started = 0;
> + (*dev->dev_ops->dev_stop)(dev);
> +}
> +
> +int
> +rte_event_dev_close(uint8_t dev_id)
> +{
> + struct rte_eventdev *dev;
> +
> + RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL);
> + dev = &rte_eventdevs[dev_id];
> + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -
> ENOTSUP);
> +
> + /* Device must be stopped before it can be closed */
> + if (dev->data->dev_started == 1) {
> + EDEV_LOG_ERR("Device %u must be stopped before closing",
> + dev_id);
> + return -EBUSY;
> + }
> +
> + return (*dev->dev_ops->dev_close)(dev);
> +}
> +
> +static inline int
> +rte_eventdev_data_alloc(uint8_t dev_id, struct rte_eventdev_data **data,
> + int socket_id)
> +{
> + char mz_name[RTE_EVENTDEV_NAME_MAX_LEN];
> + const struct rte_memzone *mz;
> + int n;
> +
> + /* Generate memzone name */
> + n = snprintf(mz_name, sizeof(mz_name), "rte_eventdev_data_%u",
> dev_id);
> + if (n >= (int)sizeof(mz_name))
> + return -EINVAL;
> +
> + if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> + mz = rte_memzone_reserve(mz_name,
> + sizeof(struct rte_eventdev_data),
> + socket_id, 0);
> + } else
> + mz = rte_memzone_lookup(mz_name);
> +
> + if (mz == NULL)
> + return -ENOMEM;
> +
> + *data = mz->addr;
> + if (rte_eal_process_type() == RTE_PROC_PRIMARY)
> + memset(*data, 0, sizeof(struct rte_eventdev_data));
> +
> + return 0;
> +}
> +
> +static uint8_t
> +rte_eventdev_find_free_device_index(void)
> +{
> + uint8_t dev_id;
> +
> + for (dev_id = 0; dev_id < RTE_EVENT_MAX_DEVS; dev_id++) {
> + if (rte_eventdevs[dev_id].attached ==
> + RTE_EVENTDEV_DETACHED)
> + return dev_id;
> + }
> + return RTE_EVENT_MAX_DEVS;
> +}
> +
> +struct rte_eventdev *
> +rte_eventdev_pmd_allocate(const char *name, int socket_id)
> +{
> + struct rte_eventdev *eventdev;
> + uint8_t dev_id;
> +
> + if (rte_eventdev_pmd_get_named_dev(name) != NULL) {
> + EDEV_LOG_ERR("Event device with name %s already "
> + "allocated!", name);
> + return NULL;
> + }
> +
> + dev_id = rte_eventdev_find_free_device_index();
> + if (dev_id == RTE_EVENT_MAX_DEVS) {
> + EDEV_LOG_ERR("Reached maximum number of event
> devices");
> + return NULL;
> + }
> +
> + eventdev = &rte_eventdevs[dev_id];
> +
> + if (eventdev->data == NULL) {
> + struct rte_eventdev_data *eventdev_data = NULL;
> +
> + int retval = rte_eventdev_data_alloc(dev_id, &eventdev_data,
> + socket_id);
> +
> + if (retval < 0 || eventdev_data == NULL)
> + return NULL;
> +
> + eventdev->data = eventdev_data;
> +
> + snprintf(eventdev->data->name,
> RTE_EVENTDEV_NAME_MAX_LEN,
> + "%s", name);
> +
> + eventdev->data->dev_id = dev_id;
> + eventdev->data->socket_id = socket_id;
> + eventdev->data->dev_started = 0;
> +
> + eventdev->attached = RTE_EVENTDEV_ATTACHED;
> +
> + eventdev_globals.nb_devs++;
> + }
> +
> + return eventdev;
> +}
> +
> +int
> +rte_eventdev_pmd_release(struct rte_eventdev *eventdev)
> +{
> + int ret;
> +
> + if (eventdev == NULL)
> + return -EINVAL;
> +
> + ret = rte_event_dev_close(eventdev->data->dev_id);
> + if (ret < 0)
> + return ret;
> +
> + eventdev->attached = RTE_EVENTDEV_DETACHED;
> + eventdev_globals.nb_devs--;
> + eventdev->data = NULL;
> +
> + return 0;
> +}
> +
> +struct rte_eventdev *
> +rte_eventdev_pmd_vdev_init(const char *name, size_t dev_private_size,
> + int socket_id)
> +{
> + struct rte_eventdev *eventdev;
> +
> + /* Allocate device structure */
> + eventdev = rte_eventdev_pmd_allocate(name, socket_id);
> + if (eventdev == NULL)
> + return NULL;
> +
> + /* Allocate private device structure */
> + if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> + eventdev->data->dev_private =
> + rte_zmalloc_socket("eventdev device private",
> + dev_private_size,
> + RTE_CACHE_LINE_SIZE,
> + socket_id);
> +
> + if (eventdev->data->dev_private == NULL)
> + rte_panic("Cannot allocate memzone for private
> device"
> + " data");
> + }
> +
> + return eventdev;
> +}
> +
> +int
> +rte_eventdev_pmd_pci_probe(struct rte_pci_driver *pci_drv,
> + struct rte_pci_device *pci_dev)
> +{
> + struct rte_eventdev_driver *eventdrv;
> + struct rte_eventdev *eventdev;
> +
> + char eventdev_name[RTE_EVENTDEV_NAME_MAX_LEN];
> +
> + int retval;
> +
> + eventdrv = (struct rte_eventdev_driver *)pci_drv;
> + if (eventdrv == NULL)
> + return -ENODEV;
> +
> + rte_eal_pci_device_name(&pci_dev->addr, eventdev_name,
> + sizeof(eventdev_name));
> +
> + eventdev = rte_eventdev_pmd_allocate(eventdev_name,
> + pci_dev->device.numa_node);
> + if (eventdev == NULL)
> + return -ENOMEM;
> +
> + if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> + eventdev->data->dev_private =
> + rte_zmalloc_socket(
> + "eventdev private structure",
> + eventdrv->dev_private_size,
> + RTE_CACHE_LINE_SIZE,
> + rte_socket_id());
> +
> + if (eventdev->data->dev_private == NULL)
> + rte_panic("Cannot allocate memzone for private "
> + "device data");
> + }
> +
> + eventdev->pci_dev = pci_dev;
> + eventdev->driver = eventdrv;
> +
> + /* Invoke PMD device initialization function */
> + retval = (*eventdrv->eventdev_init)(eventdev);
> + if (retval == 0)
> + return 0;
> +
> + EDEV_LOG_ERR("driver %s: event_dev_init(vendor_id=0x%x
> device_id=0x%x)"
> + " failed", pci_drv->driver.name,
> + (unsigned int) pci_dev->id.vendor_id,
> + (unsigned int) pci_dev->id.device_id);
> +
> + if (rte_eal_process_type() == RTE_PROC_PRIMARY)
> + rte_free(eventdev->data->dev_private);
> +
> + eventdev->attached = RTE_EVENTDEV_DETACHED;
> + eventdev_globals.nb_devs--;
> +
> + return -ENXIO;
> +}
> +
> +int
> +rte_eventdev_pmd_pci_remove(struct rte_pci_device *pci_dev)
> +{
> + const struct rte_eventdev_driver *eventdrv;
> + struct rte_eventdev *eventdev;
> + char eventdev_name[RTE_EVENTDEV_NAME_MAX_LEN];
> + int ret;
> +
> + if (pci_dev == NULL)
> + return -EINVAL;
> +
> + rte_eal_pci_device_name(&pci_dev->addr, eventdev_name,
> + sizeof(eventdev_name));
> +
> + eventdev = rte_eventdev_pmd_get_named_dev(eventdev_name);
> + if (eventdev == NULL)
> + return -ENODEV;
> +
> + eventdrv = (const struct rte_eventdev_driver *)pci_dev->driver;
> + if (eventdrv == NULL)
> + return -ENODEV;
> +
> + /* Invoke PMD device uninit function */
> + if (*eventdrv->eventdev_uninit) {
> + ret = (*eventdrv->eventdev_uninit)(eventdev);
> + if (ret)
> + return ret;
> + }
> +
> + /* Free event device */
> + rte_eventdev_pmd_release(eventdev);
> +
> + if (rte_eal_process_type() == RTE_PROC_PRIMARY)
> + rte_free(eventdev->data->dev_private);
> +
> + eventdev->pci_dev = NULL;
> + eventdev->driver = NULL;
> +
> + return 0;
> +}
> diff --git a/lib/librte_eventdev/rte_eventdev_pmd.h
> b/lib/librte_eventdev/rte_eventdev_pmd.h
> new file mode 100644
> index 0000000..e9d9b83
> --- /dev/null
> +++ b/lib/librte_eventdev/rte_eventdev_pmd.h
> @@ -0,0 +1,504 @@
> +/*
> + *
> + * Copyright(c) 2016 Cavium networks. All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * * Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * * Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in
> + * the documentation and/or other materials provided with the
> + * distribution.
> + * * Neither the name of Cavium networks nor the names of its
> + * contributors may be used to endorse or promote products derived
> + * from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
> NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
> FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
> COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
> INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
> OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
> AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
> TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
> THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
> DAMAGE.
> + */
> +
> +#ifndef _RTE_EVENTDEV_PMD_H_
> +#define _RTE_EVENTDEV_PMD_H_
> +
> +/** @file
> + * RTE Event PMD APIs
> + *
> + * @note
> + * These API are from event PMD only and user applications should not call
> + * them directly.
> + */
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#include <string.h>
> +
> +#include <rte_dev.h>
> +#include <rte_pci.h>
> +#include <rte_malloc.h>
> +#include <rte_log.h>
> +#include <rte_common.h>
> +
> +#include "rte_eventdev.h"
> +
> +#ifdef RTE_LIBRTE_EVENTDEV_DEBUG
> +#define RTE_PMD_DEBUG_TRACE(...) \
> + rte_pmd_debug_trace(__func__, __VA_ARGS__)
> +#else
> +#define RTE_PMD_DEBUG_TRACE(...)
> +#endif
> +
> +/* Logging Macros */
> +#define EDEV_LOG_ERR(fmt, args...) \
> + RTE_LOG(ERR, EVENTDEV, "%s() line %u: " fmt "\n", \
> + __func__, __LINE__, ## args)
> +
> +#ifdef RTE_LIBRTE_EVENTDEV_DEBUG
> +#define EDEV_LOG_DEBUG(fmt, args...) \
> + RTE_LOG(DEBUG, EVENTDEV, "%s() line %u: " fmt "\n", \
> + __func__, __LINE__, ## args)
> +#else
> +#define EDEV_LOG_DEBUG(fmt, args...) (void)0
> +#endif
> +
> +/* Macros to check for valid device */
> +#define RTE_EVENTDEV_VALID_DEVID_OR_ERR_RET(dev_id, retval) do { \
> + if (!rte_eventdev_pmd_is_valid_dev((dev_id))) { \
> + EDEV_LOG_ERR("Invalid dev_id=%d\n", dev_id); \
> + return retval; \
> + } \
> +} while (0)
> +
> +#define RTE_EVENTDEV_VALID_DEVID_OR_RET(dev_id) do { \
> + if (!rte_eventdev_pmd_is_valid_dev((dev_id))) { \
> + EDEV_LOG_ERR("Invalid dev_id=%d\n", dev_id); \
> + return; \
> + } \
> +} while (0)
> +
> +#define RTE_EVENTDEV_DETACHED (0)
> +#define RTE_EVENTDEV_ATTACHED (1)
> +
> +/**
> + * Initialisation function of a event driver invoked for each matching
> + * event PCI device detected during the PCI probing phase.
> + *
> + * @param dev
> + * The dev pointer is the address of the *rte_eventdev* structure associated
> + * with the matching device and which has been [automatically] allocated in
> + * the *rte_event_devices* array.
> + *
> + * @return
> + * - 0: Success, the device is properly initialised by the driver.
> + * In particular, the driver MUST have set up the *dev_ops* pointer
> + * of the *dev* structure.
> + * - <0: Error code of the device initialisation failure.
> + */
> +typedef int (*eventdev_init_t)(struct rte_eventdev *dev);
> +
> +/**
> + * Finalisation function of a driver invoked for each matching
> + * PCI device detected during the PCI closing phase.
> + *
> + * @param dev
> + * The dev pointer is the address of the *rte_eventdev* structure associated
> + * with the matching device and which has been [automatically] allocated in
> + * the *rte_event_devices* array.
> + *
> + * @return
> + * - 0: Success, the device is properly finalised by the driver.
> + * In particular, the driver MUST free the *dev_ops* pointer
> + * of the *dev* structure.
> + * - <0: Error code of the device initialisation failure.
> + */
> +typedef int (*eventdev_uninit_t)(struct rte_eventdev *dev);
> +
> +/**
> + * The structure associated with a PMD driver.
> + *
> + * Each driver acts as a PCI driver and is represented by a generic
> + * *event_driver* structure that holds:
> + *
> + * - An *rte_pci_driver* structure (which must be the first field).
> + *
> + * - The *eventdev_init* function invoked for each matching PCI device.
> + *
> + * - The size of the private data to allocate for each matching device.
> + */
> +struct rte_eventdev_driver {
> + struct rte_pci_driver pci_drv; /**< The PMD is also a PCI driver. */
> + unsigned int dev_private_size; /**< Size of device private data. */
> +
> + eventdev_init_t eventdev_init; /**< Device init function. */
> + eventdev_uninit_t eventdev_uninit; /**< Device uninit function. */
> +};
> +
> +/** Global structure used for maintaining state of allocated event devices */
> +struct rte_eventdev_global {
> + uint8_t nb_devs; /**< Number of devices found */
> + uint8_t max_devs; /**< Max number of devices */
> +};
> +
> +extern struct rte_eventdev_global *rte_eventdev_globals;
> +/** Pointer to global event devices data structure. */
> +extern struct rte_eventdev *rte_eventdevs;
> +/** The pool of rte_eventdev structures. */
> +
> +/**
> + * Get the rte_eventdev structure device pointer for the named device.
> + *
> + * @param name
> + * device name to select the device structure.
> + *
> + * @return
> + * - The rte_eventdev structure pointer for the given device ID.
> + */
> +static inline struct rte_eventdev *
> +rte_eventdev_pmd_get_named_dev(const char *name)
> +{
> + struct rte_eventdev *dev;
> + unsigned int i;
> +
> + if (name == NULL)
> + return NULL;
> +
> + for (i = 0, dev = &rte_eventdevs[i];
> + i < rte_eventdev_globals->max_devs; i++) {
> + if ((dev->attached == RTE_EVENTDEV_ATTACHED) &&
> + (strcmp(dev->data->name, name) == 0))
> + return dev;
> + }
> +
> + return NULL;
> +}
> +
> +/**
> + * Validate if the event device index is valid attached event device.
> + *
> + * @param dev_id
> + * Event device index.
> + *
> + * @return
> + * - If the device index is valid (1) or not (0).
> + */
> +static inline unsigned
> +rte_eventdev_pmd_is_valid_dev(uint8_t dev_id)
> +{
> + struct rte_eventdev *dev;
> +
> + if (dev_id >= rte_eventdev_globals->nb_devs)
> + return 0;
> +
> + dev = &rte_eventdevs[dev_id];
> + if (dev->attached != RTE_EVENTDEV_ATTACHED)
> + return 0;
> + else
> + return 1;
> +}
> +
> +/**
> + * Definitions of all functions exported by a driver through the
> + * the generic structure of type *event_dev_ops* supplied in the
> + * *rte_eventdev* structure associated with a device.
> + */
> +
> +/**
> + * Get device information of a device.
> + *
> + * @param dev
> + * Event device pointer
> + * @param dev_info
> + * Event device information structure
> + *
> + * @return
> + * Returns 0 on success
> + */
> +typedef void (*eventdev_info_get_t)(struct rte_eventdev *dev,
> + struct rte_event_dev_info *dev_info);
> +
> +/**
> + * Configure a device.
> + *
> + * @param dev
> + * Event device pointer
> + *
> + * @return
> + * Returns 0 on success
> + */
> +typedef int (*eventdev_configure_t)(struct rte_eventdev *dev);
> +
> +/**
> + * Start a configured device.
> + *
> + * @param dev
> + * Event device pointer
> + *
> + * @return
> + * Returns 0 on success
> + */
> +typedef int (*eventdev_start_t)(struct rte_eventdev *dev);
> +
> +/**
> + * Stop a configured device.
> + *
> + * @param dev
> + * Event device pointer
> + */
> +typedef void (*eventdev_stop_t)(struct rte_eventdev *dev);
> +
> +/**
> + * Close a configured device.
> + *
> + * @param dev
> + * Event device pointer
> + *
> + * @return
> + * - 0 on success
> + * - (-EAGAIN) if can't close as device is busy
> + */
> +typedef int (*eventdev_close_t)(struct rte_eventdev *dev);
> +
> +/**
> + * Retrieve the default event queue configuration.
> + *
> + * @param dev
> + * Event device pointer
> + * @param queue_id
> + * Event queue index
> + * @param[out] queue_conf
> + * Event queue configuration structure
> + *
> + */
> +typedef void (*eventdev_queue_default_conf_get_t)(struct rte_eventdev
> *dev,
> + uint8_t queue_id, struct rte_event_queue_conf *queue_conf);
> +
> +/**
> + * Setup an event queue.
> + *
> + * @param dev
> + * Event device pointer
> + * @param queue_id
> + * Event queue index
> + * @param queue_conf
> + * Event queue configuration structure
> + *
> + * @return
> + * Returns 0 on success.
> + */
> +typedef int (*eventdev_queue_setup_t)(struct rte_eventdev *dev,
> + uint8_t queue_id, struct rte_event_queue_conf *queue_conf);
> +
> +/**
> + * Release memory resources allocated by given event queue.
> + *
> + * @param queue
> + * Event queue pointer
> + *
> + */
> +typedef void (*eventdev_queue_release_t)(void *queue);
> +
> +/**
> + * Retrieve the default event port configuration.
> + *
> + * @param dev
> + * Event device pointer
> + * @param port_id
> + * Event port index
> + * @param[out] port_conf
> + * Event port configuration structure
> + *
> + */
> +typedef void (*eventdev_port_default_conf_get_t)(struct rte_eventdev *dev,
> + uint8_t port_id, struct rte_event_port_conf *port_conf);
> +
> +/**
> + * Setup an event port.
> + *
> + * @param dev
> + * Event device pointer
> + * @param port_id
> + * Event port index
> + * @param port_conf
> + * Event port configuration structure
> + *
> + * @return
> + * Returns 0 on success.
> + */
> +typedef int (*eventdev_port_setup_t)(struct rte_eventdev *dev,
> + uint8_t port_id, struct rte_event_port_conf *port_conf);
> +
> +/**
> + * Release memory resources allocated by given event port.
> + *
> + * @param port
> + * Event port pointer
> + *
> + */
> +typedef void (*eventdev_port_release_t)(void *port);
> +
> +/**
> + * Link multiple source event queues to destination event port.
> + *
> + * @param port
> + * Event port pointer
> + * @param link
> + * An array of *nb_links* pointers to *rte_event_queue_link* structure
> + * @param nb_links
> + * The number of links to establish
> + *
> + * @return
> + * Returns 0 on success.
> + *
> + */
> +typedef int (*eventdev_port_link_t)(void *port,
> + struct rte_event_queue_link link[], uint16_t nb_links);
> +
> +/**
> + * Unlink multiple source event queues from destination event port.
> + *
> + * @param port
> + * Event port pointer
> + * @param queues
> + * An array of *nb_unlinks* event queues to be unlinked from the event port.
> + * @param nb_unlinks
> + * The number of unlinks to establish
> + *
> + * @return
> + * Returns 0 on success.
> + *
> + */
> +typedef int (*eventdev_port_unlink_t)(void *port,
> + uint8_t queues[], uint16_t nb_unlinks);
> +
> +/**
> + * Converts nanoseconds to *wait* value for rte_event_dequeue()
> + *
> + * @param dev
> + * Event device pointer
> + * @param ns
> + * Wait time in nanosecond
> + * @param[out] wait_ticks
> + * Value for the *wait* parameter in rte_event_dequeue() function
> + *
> + */
> +typedef void (*eventdev_dequeue_wait_time_t)(struct rte_eventdev *dev,
> + uint64_t ns, uint64_t *wait_ticks);
> +
> +/**
> + * Dump internal information
> + *
> + * @param dev
> + * Event device pointer
> + * @param f
> + * A pointer to a file for output
> + *
> + */
> +typedef void (*eventdev_dump_t)(struct rte_eventdev *dev, FILE *f);
> +
> +/** Event device operations function pointer table */
> +struct rte_eventdev_ops {
> + eventdev_info_get_t dev_infos_get; /**< Get device info. */
> + eventdev_configure_t dev_configure; /**< Configure device. */
> + eventdev_start_t dev_start; /**< Start device. */
> + eventdev_stop_t dev_stop; /**< Stop device. */
> + eventdev_close_t dev_close; /**< Close device. */
> +
> + eventdev_queue_default_conf_get_t queue_def_conf;
> + /**< Get default queue configuration. */
> + eventdev_queue_setup_t queue_setup;
> + /**< Set up an event queue. */
> + eventdev_queue_release_t queue_release;
> + /**< Release an event queue. */
> +
> + eventdev_port_default_conf_get_t port_def_conf;
> + /**< Get default port configuration. */
> + eventdev_port_setup_t port_setup;
> + /**< Set up an event port. */
> + eventdev_port_release_t port_release;
> + /**< Release an event port. */
> +
> + eventdev_port_link_t port_link;
> + /**< Link event queues to an event port. */
> + eventdev_port_unlink_t port_unlink;
> + /**< Unlink event queues from an event port. */
> + eventdev_dequeue_wait_time_t wait_time;
> + /**< Converts nanoseconds to *wait* value for rte_event_dequeue()
> */
> + eventdev_dump_t dump;
> + /* Dump internal information */
> +};
> +
> +/**
> + * Allocates a new eventdev slot for an event device and returns the pointer
> + * to that slot for the driver to use.
> + *
> + * @param name
> + * Unique identifier name for each device
> + * @param socket_id
> + * Socket to allocate resources on.
> + * @return
> + * - Slot in the rte_dev_devices array for a new device;
> + */
> +struct rte_eventdev *
> +rte_eventdev_pmd_allocate(const char *name, int socket_id);
> +
> +/**
> + * Release the specified eventdev device.
> + *
> + * @param eventdev
> + * The *eventdev* pointer is the address of the *rte_eventdev* structure.
> + * @return
> + * - 0 on success, negative on error
> + */
> +int
> +rte_eventdev_pmd_release(struct rte_eventdev *eventdev);
> +
> +/**
> + * Creates a new virtual event device and returns the pointer to that device.
> + *
> + * @param name
> + * PMD type name
> + * @param dev_private_size
> + * Size of event PMDs private data
> + * @param socket_id
> + * Socket to allocate resources on.
> + *
> + * @return
> + * - Eventdev pointer if device is successfully created.
> + * - NULL if device cannot be created.
> + */
> +struct rte_eventdev *
> +rte_eventdev_pmd_vdev_init(const char *name, size_t dev_private_size,
> + int socket_id);
> +
> +
> +/**
> + * Wrapper for use by pci drivers as a .probe function to attach to a event
> + * interface.
> + */
> +int rte_eventdev_pmd_pci_probe(struct rte_pci_driver *pci_drv,
> + struct rte_pci_device *pci_dev);
> +
> +/**
> + * Wrapper for use by pci drivers as a .remove function to detach a event
> + * interface.
> + */
> +int rte_eventdev_pmd_pci_remove(struct rte_pci_device *pci_dev);
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _RTE_EVENTDEV_PMD_H_ */
> diff --git a/lib/librte_eventdev/rte_eventdev_version.map
> b/lib/librte_eventdev/rte_eventdev_version.map
> new file mode 100644
> index 0000000..ef40aae
> --- /dev/null
> +++ b/lib/librte_eventdev/rte_eventdev_version.map
> @@ -0,0 +1,39 @@
> +DPDK_17.02 {
> + global:
> +
> + rte_eventdevs;
> +
> + rte_event_dev_count;
> + rte_event_dev_get_dev_id;
> + rte_event_dev_socket_id;
> + rte_event_dev_info_get;
> + rte_event_dev_configure;
> + rte_event_dev_start;
> + rte_event_dev_stop;
> + rte_event_dev_close;
> + rte_event_dev_dump;
> +
> + rte_event_port_default_conf_get;
> + rte_event_port_setup;
> + rte_event_port_dequeue_depth;
> + rte_event_port_enqueue_depth;
> + rte_event_port_count;
> + rte_event_port_link;
> + rte_event_port_unlink;
> + rte_event_port_links_get;
> +
> + rte_event_queue_default_conf_get
> + rte_event_queue_setup;
> + rte_event_queue_count;
> + rte_event_queue_priority;
> +
> + rte_event_dequeue_wait_time;
> +
> + rte_eventdev_pmd_allocate;
> + rte_eventdev_pmd_release;
> + rte_eventdev_pmd_vdev_init;
> + rte_eventdev_pmd_pci_probe;
> + rte_eventdev_pmd_pci_remove;
> +
> + local: *;
> +};
> diff --git a/mk/rte.app.mk b/mk/rte.app.mk
> index f75f0e2..716725a 100644
> --- a/mk/rte.app.mk
> +++ b/mk/rte.app.mk
> @@ -93,6 +93,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_MBUF) += -
> lrte_mbuf
> _LDLIBS-$(CONFIG_RTE_LIBRTE_NET) += -lrte_net
> _LDLIBS-$(CONFIG_RTE_LIBRTE_ETHER) += -lrte_ethdev
> _LDLIBS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += -lrte_cryptodev
> +_LDLIBS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += -lrte_eventdev
> _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += -lrte_mempool
> _LDLIBS-$(CONFIG_RTE_LIBRTE_RING) += -lrte_ring
> _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL) += -lrte_eal
> --
> 2.5.5
^ permalink raw reply
* Re: [PATCH] eal: postpone vdev initialization
From: Ferruh Yigit @ 2016-11-21 17:35 UTC (permalink / raw)
To: Jerin Jacob; +Cc: dev, declan.doherty, david.marchand, thomas.monjalon
In-Reply-To: <20161121170202.GB5717@svelivela-lt.caveonetworks.com>
On 11/21/2016 5:02 PM, Jerin Jacob wrote:
> On Mon, Nov 21, 2016 at 09:54:57AM +0000, Ferruh Yigit wrote:
>> On 11/20/2016 8:00 AM, Jerin Jacob wrote:
>>> Some platform like octeontx may use pci and
>>> vdev based combined device to represent a logical
>>> dpdk functional device.In such case, postponing the
>>> vdev initialization after pci device
>>> initialization will provide the better view of
>>> the pci device resources in the system in
>>> vdev's probe function, and it allows better
>>> functional subsystem registration in vdev probe
>>> function.
>>>
>>> As a bonus, This patch fixes a bond device
>>> initialization use case.
>>>
>>> example command to reproduce the issue:
>>> ./testpmd -c 0x2 --vdev 'eth_bond0,mode=0,
>>> slave=0000:02:00.0,slave=0000:03:00.0' --
>>> --port-topology=chained
>>>
>>> root cause:
>>> In existing case(vdev initialization and then pci
>>> initialization), creates three Ethernet ports with
>>> following port ids
>>> 0 - Bond device
>>> 1 - PCI device 0
>>> 2 - PCI devive 1
>>>
>>> Since testpmd, calls the configure/start on all the ports on
>>> start up,it will translate to following illegal setup sequence
>>>
>>> 1)bond device configure/start
>>> 1.1) pci device0 stop/configure/start
>>> 1.2) pci device1 stop/configure/start
>>> 2)pci device 0 configure(illegal setup case,
>>> as device in start state)
>>>
>>> The fix changes the initialization sequence and
>>> allow initialization in following valid setup order
>>> 1) pcie device 0 configure/start
>>> 2) pcie device 1 configure/start
>>> 3) bond device 2 configure/start
>>> 3.1) pcie device 0/stop/configure/start
>>> 3.2) pcie device 1/stop/configure/start
>>>
>>> Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
>>> ---
>>
>> This changes the port id assignments to the devices, right?
>>
>> Previously virtual devices get first available port ids (0..N1), later
>> physical devices (N1..N2). Now this becomes reverse.
>>
>> Can this change break some existing user applications?
>
> I guess it may be effected only to ethdev bond pmd based application,
> which is broken anyway.
My concern is, this may effect the applications that use "--vdev" eal
parameter and has an assumption about port assignment.
And if this breaks any userspace application, does it require a
deprecation notice?
> Let me know what it takes to make forward progress on this patch. I can
> fix the same in v2.
>
> Jerin
>
^ permalink raw reply
* Re: [PATCH] eal: postpone vdev initialization
From: Jerin Jacob @ 2016-11-21 17:02 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: dev, declan.doherty, david.marchand, thomas.monjalon
In-Reply-To: <2bc2559f-5e83-5deb-65f9-750b78a0254a@intel.com>
On Mon, Nov 21, 2016 at 09:54:57AM +0000, Ferruh Yigit wrote:
> On 11/20/2016 8:00 AM, Jerin Jacob wrote:
> > Some platform like octeontx may use pci and
> > vdev based combined device to represent a logical
> > dpdk functional device.In such case, postponing the
> > vdev initialization after pci device
> > initialization will provide the better view of
> > the pci device resources in the system in
> > vdev's probe function, and it allows better
> > functional subsystem registration in vdev probe
> > function.
> >
> > As a bonus, This patch fixes a bond device
> > initialization use case.
> >
> > example command to reproduce the issue:
> > ./testpmd -c 0x2 --vdev 'eth_bond0,mode=0,
> > slave=0000:02:00.0,slave=0000:03:00.0' --
> > --port-topology=chained
> >
> > root cause:
> > In existing case(vdev initialization and then pci
> > initialization), creates three Ethernet ports with
> > following port ids
> > 0 - Bond device
> > 1 - PCI device 0
> > 2 - PCI devive 1
> >
> > Since testpmd, calls the configure/start on all the ports on
> > start up,it will translate to following illegal setup sequence
> >
> > 1)bond device configure/start
> > 1.1) pci device0 stop/configure/start
> > 1.2) pci device1 stop/configure/start
> > 2)pci device 0 configure(illegal setup case,
> > as device in start state)
> >
> > The fix changes the initialization sequence and
> > allow initialization in following valid setup order
> > 1) pcie device 0 configure/start
> > 2) pcie device 1 configure/start
> > 3) bond device 2 configure/start
> > 3.1) pcie device 0/stop/configure/start
> > 3.2) pcie device 1/stop/configure/start
> >
> > Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> > ---
>
> This changes the port id assignments to the devices, right?
>
> Previously virtual devices get first available port ids (0..N1), later
> physical devices (N1..N2). Now this becomes reverse.
>
> Can this change break some existing user applications?
I guess it may be effected only to ethdev bond pmd based application,
which is broken anyway.
Let me know what it takes to make forward progress on this patch. I can
fix the same in v2.
Jerin
^ permalink raw reply
* Re: [PATCH 2/7] eal: Helper to convert to struct rte_pci_device
From: Jan Blunck @ 2016-11-21 16:57 UTC (permalink / raw)
To: David Marchand; +Cc: dev@dpdk.org, Shreyansh Jain
In-Reply-To: <CALwxeUvju4tv6Z5WXXpYzZkWis3qqH0vOqwYtvvJG3sFYhekmg@mail.gmail.com>
On Sun, Nov 20, 2016 at 4:20 PM, David Marchand
<david.marchand@6wind.com> wrote:
> Hello Jan,
>
> On Sun, Nov 20, 2016 at 11:05 AM, Jan Blunck <jblunck@infradead.org> wrote:
>> Signed-off-by: Jan Blunck <jblunck@infradead.org>
>> ---
>> lib/librte_eal/common/include/rte_pci.h | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
>> index 9ce8847..0376160 100644
>> --- a/lib/librte_eal/common/include/rte_pci.h
>> +++ b/lib/librte_eal/common/include/rte_pci.h
>> @@ -160,6 +160,8 @@ struct rte_pci_device {
>> enum rte_kernel_driver kdrv; /**< Kernel driver passthrough */
>> };
>>
>> +#define ETH_DEV_PCI_DEV(ptr) ((ptr)->pci_dev)
>> +
>> /** Any PCI device identifier (vendor, device, ...) */
>> #define PCI_ANY_ID (0xffff)
>> #define RTE_CLASS_ANY_ID (0xffffff)
>
> This should come from ethdev, not eal.
>
Fixed in v2.
Thanks,
Jan
^ permalink raw reply
* [PATCH v2 8/8] ethdev: Decouple interrupt handling from PCI device
From: Jan Blunck @ 2016-11-21 16:55 UTC (permalink / raw)
To: dev; +Cc: shreyansh.jain, david.marchand
In-Reply-To: <1479747322-5774-1-git-send-email-jblunck@infradead.org>
The struct rte_intr_handle is an abstraction layer for different types of
interrupt mechanisms. It is embedded in the low-level device (e.g. PCI).
On allocation of a struct rte_eth_dev a reference to the intr_handle
should be stored for devices supporting interrupts.
Signed-off-by: Jan Blunck <jblunck@infradead.org>
---
lib/librte_ether/rte_ethdev.c | 18 ++++++++++++++++--
lib/librte_ether/rte_ethdev.h | 1 +
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 4288577..4ecea50 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -258,6 +258,7 @@ rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
rte_panic("Cannot allocate memzone for private port data\n");
}
eth_dev->pci_dev = pci_dev;
+ eth_dev->intr_handle = &pci_dev->intr_handle;
eth_dev->driver = eth_drv;
eth_dev->data->rx_mbuf_alloc_failed = 0;
@@ -2543,7 +2544,13 @@ rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
- intr_handle = &dev->pci_dev->intr_handle;
+
+ if (!dev->intr_handle) {
+ RTE_PMD_DEBUG_TRACE("RX Intr handle unset\n");
+ return -ENOTSUP;
+ }
+
+ intr_handle = dev->intr_handle;
if (!intr_handle->intr_vec) {
RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
return -EPERM;
@@ -2603,7 +2610,12 @@ rte_eth_dev_rx_intr_ctl_q(uint8_t port_id, uint16_t queue_id,
return -EINVAL;
}
- intr_handle = &dev->pci_dev->intr_handle;
+ if (!dev->intr_handle) {
+ RTE_PMD_DEBUG_TRACE("RX Intr handle unset\n");
+ return -ENOTSUP;
+ }
+
+ intr_handle = dev->intr_handle;
if (!intr_handle->intr_vec) {
RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
return -EPERM;
@@ -3205,6 +3217,8 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev, struct rte_pci_device *pci_de
return;
}
+ eth_dev->intr_handle = &pci_dev->intr_handle;
+
eth_dev->data->dev_flags = 0;
if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_LSC)
eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 3adbb2b..f1f656a 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1629,6 +1629,7 @@ struct rte_eth_dev {
const struct eth_driver *driver;/**< Driver for this device */
const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
struct rte_pci_device *pci_dev; /**< PCI info. supplied by probing */
+ struct rte_intr_handle *intr_handle; /**< Device interrupt handle */
/** User application callbacks for NIC interrupts */
struct rte_eth_dev_cb_list link_intr_cbs;
/**
--
2.7.4
^ permalink raw reply related
* [PATCH v2 7/8] ethdev: Move filling of rte_eth_dev_info->pci_dev to dev_infos_get()
From: Jan Blunck @ 2016-11-21 16:55 UTC (permalink / raw)
To: dev; +Cc: shreyansh.jain, david.marchand
In-Reply-To: <1479747322-5774-1-git-send-email-jblunck@infradead.org>
Only the device itself can decide its PCI or not.
Signed-off-by: Jan Blunck <jblunck@infradead.org>
---
drivers/net/bnx2x/bnx2x_ethdev.c | 1 +
drivers/net/bnxt/bnxt_ethdev.c | 2 ++
drivers/net/cxgbe/cxgbe_ethdev.c | 2 ++
drivers/net/e1000/em_ethdev.c | 1 +
drivers/net/e1000/igb_ethdev.c | 2 ++
drivers/net/ena/ena_ethdev.c | 2 ++
drivers/net/enic/enic_ethdev.c | 1 +
drivers/net/fm10k/fm10k_ethdev.c | 1 +
drivers/net/i40e/i40e_ethdev.c | 1 +
drivers/net/i40e/i40e_ethdev_vf.c | 1 +
drivers/net/ixgbe/ixgbe_ethdev.c | 2 ++
drivers/net/mlx4/mlx4.c | 2 ++
drivers/net/mlx5/mlx5_ethdev.c | 2 ++
drivers/net/nfp/nfp_net.c | 1 +
drivers/net/qede/qede_ethdev.c | 1 +
drivers/net/szedata2/rte_eth_szedata2.c | 1 +
drivers/net/thunderx/nicvf_ethdev.c | 2 ++
drivers/net/virtio/virtio_ethdev.c | 1 +
drivers/net/vmxnet3/vmxnet3_ethdev.c | 2 ++
lib/librte_ether/rte_ethdev.c | 1 -
20 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index 0eae433..06453fe 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -431,6 +431,7 @@ static void
bnx2x_dev_infos_get(struct rte_eth_dev *dev, __rte_unused struct rte_eth_dev_info *dev_info)
{
struct bnx2x_softc *sc = dev->data->dev_private;
+ dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
dev_info->max_rx_queues = sc->max_rx_queues;
dev_info->max_tx_queues = sc->max_tx_queues;
dev_info->min_rx_bufsize = BNX2X_MIN_RX_BUF_SIZE;
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index cd50f11..bf39fbe 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -303,6 +303,8 @@ static void bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
uint16_t max_vnics, i, j, vpool, vrxq;
+ dev_info->pci_dev = ETH_DEV_PCI_DEV(eth_dev);
+
/* MAC Specifics */
dev_info->max_mac_addrs = MAX_NUM_MAC_ADDR;
dev_info->max_hash_mac_addrs = 0;
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 8bfdda8..8938b08 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -147,6 +147,8 @@ static void cxgbe_dev_info_get(struct rte_eth_dev *eth_dev,
.nb_align = 1,
};
+ device_info->pci_dev = ETH_DEV_PCI_DEV(eth_dev);
+
device_info->min_rx_bufsize = CXGBE_MIN_RX_BUFSIZE;
device_info->max_rx_pktlen = CXGBE_MAX_RX_PKTLEN;
device_info->max_rx_queues = max_queues;
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 7f2f521..3d34e5b 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -1048,6 +1048,7 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
{
struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
dev_info->min_rx_bufsize = 256; /* See BSIZE field of RCTL register. */
dev_info->max_rx_pktlen = em_get_max_pktlen(hw);
dev_info->max_mac_addrs = hw->mac.rar_entry_count;
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index b25c66e..7d77561 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1983,6 +1983,7 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
{
struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
dev_info->min_rx_bufsize = 256; /* See BSIZE field of RCTL register. */
dev_info->max_rx_pktlen = 0x3FFF; /* See RLPML register. */
dev_info->max_mac_addrs = hw->mac.rar_entry_count;
@@ -2111,6 +2112,7 @@ eth_igbvf_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
{
struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
dev_info->min_rx_bufsize = 256; /* See BSIZE field of RCTL register. */
dev_info->max_rx_pktlen = 0x3FFF; /* See RLPML register. */
dev_info->max_mac_addrs = hw->mac.rar_entry_count;
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index c17d969..051275e 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -1436,6 +1436,8 @@ static void ena_infos_get(struct rte_eth_dev *dev,
ena_dev = &adapter->ena_dev;
ena_assert_msg(ena_dev != NULL, "Uninitialized device");
+ dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
+
dev_info->speed_capa =
ETH_LINK_SPEED_1G |
ETH_LINK_SPEED_2_5G |
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 553a88e..bb5dfe6 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -459,6 +459,7 @@ static void enicpmd_dev_info_get(struct rte_eth_dev *eth_dev,
struct enic *enic = pmd_priv(eth_dev);
ENICPMD_FUNC_TRACE();
+ device_info->pci_dev = ETH_DEV_PCI_DEV(eth_dev);
/* Scattered Rx uses two receive queues per rx queue exposed to dpdk */
device_info->max_rx_queues = enic->conf_rq_count / 2;
device_info->max_tx_queues = enic->conf_wq_count;
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index e1250f6..5d0bce5 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1392,6 +1392,7 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
PMD_INIT_FUNC_TRACE();
+ dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
dev_info->min_rx_bufsize = FM10K_MIN_RX_BUF_SIZE;
dev_info->max_rx_pktlen = FM10K_MAX_PKT_SIZE;
dev_info->max_rx_queues = hw->mac.max_queues;
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 8a63a8c..29c0277 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -2583,6 +2583,7 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct i40e_vsi *vsi = pf->main_vsi;
+ dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
dev_info->max_rx_queues = vsi->nb_qps;
dev_info->max_tx_queues = vsi->nb_qps;
dev_info->min_rx_bufsize = I40E_BUF_SIZE_MIN;
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 781e658..caef72c 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -2217,6 +2217,7 @@ i40evf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
memset(dev_info, 0, sizeof(*dev_info));
+ dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
dev_info->max_rx_queues = vf->vsi_res->num_queue_pairs;
dev_info->max_tx_queues = vf->vsi_res->num_queue_pairs;
dev_info->min_rx_bufsize = I40E_BUF_SIZE_MIN;
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index f17da46..c88b7bf 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -3043,6 +3043,7 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
+ dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
dev_info->max_rx_queues = (uint16_t)hw->mac.max_rx_queues;
dev_info->max_tx_queues = (uint16_t)hw->mac.max_tx_queues;
if (RTE_ETH_DEV_SRIOV(dev).active == 0) {
@@ -3175,6 +3176,7 @@ ixgbevf_dev_info_get(struct rte_eth_dev *dev,
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
+ dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
dev_info->max_rx_queues = (uint16_t)hw->mac.max_rx_queues;
dev_info->max_tx_queues = (uint16_t)hw->mac.max_tx_queues;
dev_info->min_rx_bufsize = 1024; /* cf BSIZEPACKET in SRRCTL reg */
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index da61a85..5455fea 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4421,6 +4421,8 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
unsigned int max;
char ifname[IF_NAMESIZE];
+ info->pci_dev = ETH_DEV_PCI_DEV(dev);
+
if (priv == NULL)
return;
priv_lock(priv);
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index c0f73e9..489a4f6 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -562,6 +562,8 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
unsigned int max;
char ifname[IF_NAMESIZE];
+ info->pci_dev = ETH_DEV_PCI_DEV(dev);
+
priv_lock(priv);
/* FIXME: we should ask the device for these values. */
info->min_rx_bufsize = 32;
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index c6b1587..41eaf90 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1006,6 +1006,7 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
dev_info->driver_name = dev->driver->pci_drv.driver.name;
dev_info->max_rx_queues = (uint16_t)hw->max_rx_queues;
dev_info->max_tx_queues = (uint16_t)hw->max_tx_queues;
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index 959ff0f..2c4de92 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -652,6 +652,7 @@ qede_dev_info_get(struct rte_eth_dev *eth_dev,
PMD_INIT_FUNC_TRACE(edev);
+ dev_info->pci_dev = ETH_DEV_PCI_DEV(eth_dev);
dev_info->min_rx_bufsize = (uint32_t)(ETHER_MIN_MTU +
QEDE_ETH_OVERHEAD);
dev_info->max_rx_pktlen = (uint32_t)ETH_TX_MAX_NON_LSO_PKT_LEN;
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index f3cd52d..585087a 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1030,6 +1030,7 @@ eth_dev_info(struct rte_eth_dev *dev,
struct rte_eth_dev_info *dev_info)
{
struct pmd_internals *internals = dev->data->dev_private;
+ dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
dev_info->if_index = 0;
dev_info->max_mac_addrs = 1;
dev_info->max_rx_pktlen = (uint32_t)-1;
diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index 466e49c..42ad340 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -1338,6 +1338,8 @@ nicvf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
PMD_INIT_FUNC_TRACE();
+ dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
+
dev_info->min_rx_bufsize = ETHER_MIN_MTU;
dev_info->max_rx_pktlen = NIC_HW_MAX_FRS;
dev_info->max_rx_queues =
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 023101d..2eb6a06 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1625,6 +1625,7 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
uint64_t tso_mask;
struct virtio_hw *hw = dev->data->dev_private;
+ dev_info->pci_dev = hw->dev;
dev_info->max_rx_queues =
RTE_MIN(hw->max_queue_pairs, VIRTIO_MAX_RX_QUEUES);
dev_info->max_tx_queues =
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index bcb3751..f7c0382 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -709,6 +709,8 @@ static void
vmxnet3_dev_info_get(__rte_unused struct rte_eth_dev *dev,
struct rte_eth_dev_info *dev_info)
{
+ dev_info->pci_dev = ETH_DEV_PCI_DEV(dev);
+
dev_info->max_rx_queues = VMXNET3_MAX_RX_QUEUES;
dev_info->max_tx_queues = VMXNET3_MAX_TX_QUEUES;
dev_info->min_rx_bufsize = 1518 + RTE_PKTMBUF_HEADROOM;
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index fde8112..4288577 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1556,7 +1556,6 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
(*dev->dev_ops->dev_infos_get)(dev, dev_info);
- dev_info->pci_dev = dev->pci_dev;
dev_info->driver_name = dev->data->drv_name;
dev_info->nb_rx_queues = dev->data->nb_rx_queues;
dev_info->nb_tx_queues = dev->data->nb_tx_queues;
--
2.7.4
^ permalink raw reply related
* [PATCH v2 6/8] virtio: Don't depend on struct rte_eth_dev's pci_dev
From: Jan Blunck @ 2016-11-21 16:55 UTC (permalink / raw)
To: dev; +Cc: shreyansh.jain, david.marchand
In-Reply-To: <1479747322-5774-1-git-send-email-jblunck@infradead.org>
We don't need to depend on rte_eth_dev->pci_dev to differentiate between
the virtio_user and the virtio_pci case. Instead we can use the private
virtio_hw struct to get that information.
Signed-off-by: Jan Blunck <jblunck@infradead.org>
---
drivers/net/virtio/virtio_ethdev.c | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index da9668e..023101d 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -483,11 +483,11 @@ virtio_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_queue_idx)
hw->cvq = cvq;
}
- /* For virtio_user case (that is when dev->pci_dev is NULL), we use
+ /* For virtio_user case (that is when hw->dev is NULL), we use
* virtual address. And we need properly set _offset_, please see
* VIRTIO_MBUF_DATA_DMA_ADDR in virtqueue.h for more information.
*/
- if (dev->pci_dev)
+ if (hw->dev)
vq->offset = offsetof(struct rte_mbuf, buf_physaddr);
else {
vq->vq_ring_mem = (uintptr_t)mz->addr;
@@ -1190,7 +1190,7 @@ virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
struct virtio_hw *hw = eth_dev->data->dev_private;
struct virtio_net_config *config;
struct virtio_net_config local_config;
- struct rte_pci_device *pci_dev = eth_dev->pci_dev;
+ struct rte_pci_device *pci_dev = hw->dev;
int ret;
/* Reset the device although not necessary at startup */
@@ -1294,7 +1294,6 @@ int
eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
{
struct virtio_hw *hw = eth_dev->data->dev_private;
- struct rte_pci_device *pci_dev;
uint32_t dev_flags = RTE_ETH_DEV_DETACHABLE;
int ret;
@@ -1317,10 +1316,11 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
return -ENOMEM;
}
- pci_dev = eth_dev->pci_dev;
-
- if (pci_dev) {
- ret = vtpci_init(pci_dev, hw, &dev_flags);
+ /* For virtio_user case the hw->virtio_user_dev is populated by
+ * virtio_user_eth_dev_alloc() before eth_virtio_dev_init() is called.
+ */
+ if (!hw->virtio_user_dev) {
+ ret = vtpci_init(ETH_DEV_PCI_DEV(eth_dev), hw, &dev_flags);
if (ret)
return ret;
}
@@ -1343,7 +1343,6 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
static int
eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
{
- struct rte_pci_device *pci_dev;
struct virtio_hw *hw = eth_dev->data->dev_private;
PMD_INIT_FUNC_TRACE();
@@ -1353,7 +1352,6 @@ eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
virtio_dev_stop(eth_dev);
virtio_dev_close(eth_dev);
- pci_dev = eth_dev->pci_dev;
eth_dev->dev_ops = NULL;
eth_dev->tx_pkt_burst = NULL;
@@ -1367,7 +1365,8 @@ eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
rte_intr_callback_unregister(vtpci_intr_handle(hw),
virtio_interrupt_handler,
eth_dev);
- rte_eal_pci_unmap_device(pci_dev);
+ if (hw->dev)
+ rte_eal_pci_unmap_device(hw->dev);
PMD_INIT_LOG(DEBUG, "dev_uninit completed");
--
2.7.4
^ permalink raw reply related
* [PATCH v2 5/8] virtio: Add vtpci_intr_handle() helper to get rte_intr_handle
From: Jan Blunck @ 2016-11-21 16:55 UTC (permalink / raw)
To: dev; +Cc: shreyansh.jain, david.marchand
In-Reply-To: <1479747322-5774-1-git-send-email-jblunck@infradead.org>
This adds a helper to get the rte_intr_handle from the virtio_hw. This is
safe to do since the usage of the helper is guarded by RTE_ETH_DEV_INTR_LSC
which is only set if we found a PCI device during initialization.
Signed-off-by: Jan Blunck <jblunck@infradead.org>
---
drivers/net/virtio/virtio_ethdev.c | 12 +++++++-----
drivers/net/virtio/virtio_pci.h | 6 ++++++
2 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 741688e..da9668e 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1162,7 +1162,7 @@ virtio_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
isr = vtpci_isr(hw);
PMD_DRV_LOG(INFO, "interrupt status = %#x", isr);
- if (rte_intr_enable(&dev->pci_dev->intr_handle) < 0)
+ if (rte_intr_enable(vtpci_intr_handle(hw)) < 0)
PMD_DRV_LOG(ERR, "interrupt enable failed");
if (isr & VIRTIO_PCI_ISR_CONFIG) {
@@ -1334,7 +1334,7 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
/* Setup interrupt callback */
if (eth_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
- rte_intr_callback_register(&pci_dev->intr_handle,
+ rte_intr_callback_register(vtpci_intr_handle(hw),
virtio_interrupt_handler, eth_dev);
return 0;
@@ -1344,6 +1344,7 @@ static int
eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
{
struct rte_pci_device *pci_dev;
+ struct virtio_hw *hw = eth_dev->data->dev_private;
PMD_INIT_FUNC_TRACE();
@@ -1363,7 +1364,7 @@ eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
/* reset interrupt callback */
if (eth_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
- rte_intr_callback_unregister(&pci_dev->intr_handle,
+ rte_intr_callback_unregister(vtpci_intr_handle(hw),
virtio_interrupt_handler,
eth_dev);
rte_eal_pci_unmap_device(pci_dev);
@@ -1481,7 +1482,7 @@ virtio_dev_start(struct rte_eth_dev *dev)
return -ENOTSUP;
}
- if (rte_intr_enable(&dev->pci_dev->intr_handle) < 0) {
+ if (rte_intr_enable(vtpci_intr_handle(hw)) < 0) {
PMD_DRV_LOG(ERR, "interrupt enable failed");
return -EIO;
}
@@ -1573,12 +1574,13 @@ static void virtio_dev_free_mbufs(struct rte_eth_dev *dev)
static void
virtio_dev_stop(struct rte_eth_dev *dev)
{
+ struct virtio_hw *hw = dev->data->dev_private;
struct rte_eth_link link;
PMD_INIT_LOG(DEBUG, "stop");
if (dev->data->dev_conf.intr_conf.lsc)
- rte_intr_disable(&dev->pci_dev->intr_handle);
+ rte_intr_disable(vtpci_intr_handle(hw));
memset(&link, 0, sizeof(link));
virtio_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index de271bf..5373e39 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -317,4 +317,10 @@ uint8_t vtpci_isr(struct virtio_hw *);
uint16_t vtpci_irq_config(struct virtio_hw *, uint16_t);
+static inline struct rte_intr_handle *
+vtpci_intr_handle(struct virtio_hw *hw)
+{
+ return hw->dev ? &hw->dev->intr_handle : NULL;
+}
+
#endif /* _VIRTIO_PCI_H_ */
--
2.7.4
^ permalink raw reply related
* [PATCH v2 4/8] virtio: Don't fill dev_info->driver_name
From: Jan Blunck @ 2016-11-21 16:55 UTC (permalink / raw)
To: dev; +Cc: shreyansh.jain, david.marchand
In-Reply-To: <1479747322-5774-1-git-send-email-jblunck@infradead.org>
This is overwritten in rte_eth_dev_info_get().
Signed-off-by: Jan Blunck <jblunck@infradead.org>
---
drivers/net/virtio/virtio_ethdev.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 079fd6c..741688e 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1624,10 +1624,6 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
uint64_t tso_mask;
struct virtio_hw *hw = dev->data->dev_private;
- if (dev->pci_dev)
- dev_info->driver_name = dev->driver->pci_drv.driver.name;
- else
- dev_info->driver_name = "virtio_user PMD";
dev_info->max_rx_queues =
RTE_MIN(hw->max_queue_pairs, VIRTIO_MAX_RX_QUEUES);
dev_info->max_tx_queues =
--
2.7.4
^ permalink raw reply related
* [PATCH v2 3/8] drivers: Use ETH_DEV_PCI_DEV() helper
From: Jan Blunck @ 2016-11-21 16:55 UTC (permalink / raw)
To: dev; +Cc: shreyansh.jain, david.marchand
In-Reply-To: <1479747322-5774-1-git-send-email-jblunck@infradead.org>
The drivers should not directly access the rte_eth_dev->pci_dev but use
a macro instead. This is a preparation for replacing the pci_dev with
a struct rte_device member in the future.
Signed-off-by: Jan Blunck <jblunck@infradead.org>
---
drivers/net/bnxt/bnxt_ethdev.c | 19 ++++++-----
drivers/net/bnxt/bnxt_ring.c | 11 +++---
drivers/net/cxgbe/cxgbe_ethdev.c | 2 +-
drivers/net/e1000/em_ethdev.c | 20 ++++++-----
drivers/net/e1000/igb_ethdev.c | 50 +++++++++++++++------------
drivers/net/e1000/igb_pf.c | 3 +-
drivers/net/ena/ena_ethdev.c | 2 +-
drivers/net/enic/enic_ethdev.c | 2 +-
drivers/net/fm10k/fm10k_ethdev.c | 49 ++++++++++++++-------------
drivers/net/i40e/i40e_ethdev.c | 44 ++++++++++++------------
drivers/net/i40e/i40e_ethdev.h | 4 +++
drivers/net/i40e/i40e_ethdev_vf.c | 38 ++++++++++-----------
drivers/net/ixgbe/ixgbe_ethdev.c | 65 +++++++++++++++++++++---------------
drivers/net/ixgbe/ixgbe_pf.c | 2 +-
drivers/net/qede/qede_ethdev.c | 17 +++++-----
drivers/net/vmxnet3/vmxnet3_ethdev.c | 4 +--
16 files changed, 185 insertions(+), 147 deletions(-)
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 035fe07..cd50f11 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -743,6 +743,7 @@ static int bnxt_reta_query_op(struct rte_eth_dev *eth_dev,
{
struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(eth_dev);
/* Retrieve from the default VNIC */
if (!vnic)
@@ -759,7 +760,7 @@ static int bnxt_reta_query_op(struct rte_eth_dev *eth_dev,
/* EW - need to revisit here copying from u64 to u16 */
memcpy(reta_conf, vnic->rss_table, reta_size);
- if (rte_intr_allow_others(ð_dev->pci_dev->intr_handle)) {
+ if (rte_intr_allow_others(&pci_dev->intr_handle)) {
if (eth_dev->data->dev_conf.intr_conf.lsc != 0)
bnxt_dev_lsc_intr_setup(eth_dev);
}
@@ -1011,9 +1012,10 @@ static int bnxt_init_board(struct rte_eth_dev *eth_dev)
{
int rc;
struct bnxt *bp = eth_dev->data->dev_private;
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(eth_dev);
/* enable device (incl. PCI PM wakeup), and bus-mastering */
- if (!eth_dev->pci_dev->mem_resource[0].addr) {
+ if (!pci_dev->mem_resource[0].addr) {
RTE_LOG(ERR, PMD,
"Cannot find PCI device base address, aborting\n");
rc = -ENODEV;
@@ -1021,9 +1023,9 @@ static int bnxt_init_board(struct rte_eth_dev *eth_dev)
}
bp->eth_dev = eth_dev;
- bp->pdev = eth_dev->pci_dev;
+ bp->pdev = pci_dev;
- bp->bar0 = (void *)eth_dev->pci_dev->mem_resource[0].addr;
+ bp->bar0 = (void *)pci_dev->mem_resource[0].addr;
if (!bp->bar0) {
RTE_LOG(ERR, PMD, "Cannot map device registers, aborting\n");
rc = -ENOMEM;
@@ -1043,6 +1045,7 @@ static int bnxt_init_board(struct rte_eth_dev *eth_dev)
static int
bnxt_dev_init(struct rte_eth_dev *eth_dev)
{
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(eth_dev);
static int version_printed;
struct bnxt *bp;
int rc;
@@ -1050,10 +1053,10 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
if (version_printed++ == 0)
RTE_LOG(INFO, PMD, "%s", bnxt_version);
- rte_eth_copy_pci_info(eth_dev, eth_dev->pci_dev);
+ rte_eth_copy_pci_info(eth_dev, pci_dev);
bp = eth_dev->data->dev_private;
- if (bnxt_vf_pciid(eth_dev->pci_dev->id.device_id))
+ if (bnxt_vf_pciid(pci_dev->id.device_id))
bp->flags |= BNXT_FLAG_VF;
rc = bnxt_init_board(eth_dev);
@@ -1121,8 +1124,8 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
RTE_LOG(INFO, PMD,
DRV_MODULE_NAME " found at mem %" PRIx64 ", node addr %pM\n",
- eth_dev->pci_dev->mem_resource[0].phys_addr,
- eth_dev->pci_dev->mem_resource[0].addr);
+ pci_dev->mem_resource[0].phys_addr,
+ pci_dev->mem_resource[0].addr);
bp->dev_stopped = 0;
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 3f81ffc..6793d75 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -209,6 +209,7 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
*/
int bnxt_alloc_hwrm_rings(struct bnxt *bp)
{
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(bp->eth_dev);
unsigned int i;
int rc = 0;
@@ -223,7 +224,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
if (rc)
goto err_out;
cpr->cp_doorbell =
- (char *)bp->eth_dev->pci_dev->mem_resource[2].addr;
+ (char *)pci_dev->mem_resource[2].addr;
B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
bp->grp_info[0].cp_fw_ring_id = cp_ring->fw_ring_id;
}
@@ -243,7 +244,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
if (rc)
goto err_out;
cpr->cp_doorbell =
- (char *)bp->eth_dev->pci_dev->mem_resource[2].addr +
+ (char *)pci_dev->mem_resource[2].addr +
idx * 0x80;
bp->grp_info[idx].cp_fw_ring_id = cp_ring->fw_ring_id;
B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
@@ -256,7 +257,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
goto err_out;
rxr->rx_prod = 0;
rxr->rx_doorbell =
- (char *)bp->eth_dev->pci_dev->mem_resource[2].addr +
+ (char *)pci_dev->mem_resource[2].addr +
idx * 0x80;
bp->grp_info[idx].rx_fw_ring_id = ring->fw_ring_id;
B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
@@ -284,7 +285,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
goto err_out;
cpr->cp_doorbell =
- (char *)bp->eth_dev->pci_dev->mem_resource[2].addr +
+ (char *)pci_dev->mem_resource[2].addr +
idx * 0x80;
bp->grp_info[idx].cp_fw_ring_id = cp_ring->fw_ring_id;
B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
@@ -297,7 +298,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
goto err_out;
txr->tx_doorbell =
- (char *)bp->eth_dev->pci_dev->mem_resource[2].addr +
+ (char *)pci_dev->mem_resource[2].addr +
idx * 0x80;
}
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index b7f28eb..8bfdda8 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -1005,7 +1005,7 @@ static int eth_cxgbe_dev_init(struct rte_eth_dev *eth_dev)
if (rte_eal_process_type() != RTE_PROC_PRIMARY)
return 0;
- pci_dev = eth_dev->pci_dev;
+ pci_dev = ETH_DEV_PCI_DEV(eth_dev);
snprintf(name, sizeof(name), "cxgbeadapter%d", eth_dev->data->port_id);
adapter = rte_zmalloc(name, sizeof(*adapter), 0);
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index aee3d34..7f2f521 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -295,7 +295,7 @@ eth_em_dev_init(struct rte_eth_dev *eth_dev)
struct e1000_vfta * shadow_vfta =
E1000_DEV_PRIVATE_TO_VFTA(eth_dev->data->dev_private);
- pci_dev = eth_dev->pci_dev;
+ pci_dev = ETH_DEV_PCI_DEV(eth_dev);
eth_dev->dev_ops = ð_em_ops;
eth_dev->rx_pkt_burst = (eth_rx_burst_t)ð_em_recv_pkts;
@@ -369,7 +369,7 @@ eth_em_dev_uninit(struct rte_eth_dev *eth_dev)
if (rte_eal_process_type() != RTE_PROC_PRIMARY)
return -EPERM;
- pci_dev = eth_dev->pci_dev;
+ pci_dev = ETH_DEV_PCI_DEV(eth_dev);
if (adapter->stopped == 0)
eth_em_close(eth_dev);
@@ -556,7 +556,8 @@ eth_em_start(struct rte_eth_dev *dev)
E1000_DEV_PRIVATE(dev->data->dev_private);
struct e1000_hw *hw =
E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
int ret, mask;
uint32_t intr_vector = 0;
uint32_t *speeds;
@@ -738,7 +739,8 @@ eth_em_stop(struct rte_eth_dev *dev)
{
struct rte_eth_link link;
struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
em_rxq_intr_disable(hw);
em_lsc_intr_disable(hw);
@@ -999,9 +1001,10 @@ static int
eth_em_rx_queue_intr_enable(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id)
{
struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
em_rxq_intr_enable(hw);
- rte_intr_enable(&dev->pci_dev->intr_handle);
+ rte_intr_enable(&pci_dev->intr_handle);
return 0;
}
@@ -1542,6 +1545,7 @@ eth_em_interrupt_action(struct rte_eth_dev *dev)
E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct e1000_interrupt *intr =
E1000_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
uint32_t tctl, rctl;
struct rte_eth_link link;
int ret;
@@ -1550,7 +1554,7 @@ eth_em_interrupt_action(struct rte_eth_dev *dev)
return -1;
intr->flags &= ~E1000_FLAG_NEED_LINK_UPDATE;
- rte_intr_enable(&(dev->pci_dev->intr_handle));
+ rte_intr_enable(&pci_dev->intr_handle);
/* set get_link_status to check register later */
hw->mac.get_link_status = 1;
@@ -1571,8 +1575,8 @@ eth_em_interrupt_action(struct rte_eth_dev *dev)
PMD_INIT_LOG(INFO, " Port %d: Link Down", dev->data->port_id);
}
PMD_INIT_LOG(DEBUG, "PCI Address: %04d:%02d:%02d:%d",
- dev->pci_dev->addr.domain, dev->pci_dev->addr.bus,
- dev->pci_dev->addr.devid, dev->pci_dev->addr.function);
+ pci_dev->addr.domain, pci_dev->addr.bus,
+ pci_dev->addr.devid, pci_dev->addr.function);
tctl = E1000_READ_REG(hw, E1000_TCTL);
rctl = E1000_READ_REG(hw, E1000_RCTL);
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 2fddf0c..b25c66e 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -672,11 +672,11 @@ igb_identify_hardware(struct rte_eth_dev *dev)
{
struct e1000_hw *hw =
E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-
- hw->vendor_id = dev->pci_dev->id.vendor_id;
- hw->device_id = dev->pci_dev->id.device_id;
- hw->subsystem_vendor_id = dev->pci_dev->id.subsystem_vendor_id;
- hw->subsystem_device_id = dev->pci_dev->id.subsystem_device_id;
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
+ hw->vendor_id = pci_dev->id.vendor_id;
+ hw->device_id = pci_dev->id.device_id;
+ hw->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id;
+ hw->subsystem_device_id = pci_dev->id.subsystem_device_id;
e1000_set_mac_type(hw);
@@ -755,7 +755,7 @@ eth_igb_dev_init(struct rte_eth_dev *eth_dev)
uint32_t ctrl_ext;
- pci_dev = eth_dev->pci_dev;
+ pci_dev = ETH_DEV_PCI_DEV(eth_dev);
eth_dev->dev_ops = ð_igb_ops;
eth_dev->rx_pkt_burst = ð_igb_recv_pkts;
@@ -918,7 +918,7 @@ eth_igb_dev_uninit(struct rte_eth_dev *eth_dev)
return -EPERM;
hw = E1000_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
- pci_dev = eth_dev->pci_dev;
+ pci_dev = ETH_DEV_PCI_DEV(eth_dev);
if (adapter->stopped == 0)
eth_igb_close(eth_dev);
@@ -973,7 +973,7 @@ eth_igbvf_dev_init(struct rte_eth_dev *eth_dev)
return 0;
}
- pci_dev = eth_dev->pci_dev;
+ pci_dev = ETH_DEV_PCI_DEV(eth_dev);
rte_eth_copy_pci_info(eth_dev, pci_dev);
@@ -1050,7 +1050,7 @@ eth_igbvf_dev_uninit(struct rte_eth_dev *eth_dev)
{
struct e1000_adapter *adapter =
E1000_DEV_PRIVATE(eth_dev->data->dev_private);
- struct rte_pci_device *pci_dev = eth_dev->pci_dev;
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(eth_dev);
PMD_INIT_FUNC_TRACE();
@@ -1217,7 +1217,8 @@ eth_igb_start(struct rte_eth_dev *dev)
E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct e1000_adapter *adapter =
E1000_DEV_PRIVATE(dev->data->dev_private);
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle =
+ Ð_DEV_PCI_DEV(dev)->intr_handle;
int ret, mask;
uint32_t intr_vector = 0;
uint32_t ctrl_ext;
@@ -1429,7 +1430,8 @@ eth_igb_stop(struct rte_eth_dev *dev)
struct e1000_flex_filter *p_flex;
struct e1000_5tuple_filter *p_5tuple, *p_5tuple_next;
struct e1000_2tuple_filter *p_2tuple, *p_2tuple_next;
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle =
+ Ð_DEV_PCI_DEV(dev)->intr_handle;
igb_intr_disable(hw);
@@ -1549,7 +1551,7 @@ eth_igb_close(struct rte_eth_dev *dev)
igb_dev_free_queues(dev);
- pci_dev = dev->pci_dev;
+ pci_dev = ETH_DEV_PCI_DEV(dev);
if (pci_dev->intr_handle.intr_vec) {
rte_free(pci_dev->intr_handle.intr_vec);
pci_dev->intr_handle.intr_vec = NULL;
@@ -2639,6 +2641,7 @@ eth_igb_interrupt_action(struct rte_eth_dev *dev)
E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct e1000_interrupt *intr =
E1000_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
uint32_t tctl, rctl;
struct rte_eth_link link;
int ret;
@@ -2649,7 +2652,7 @@ eth_igb_interrupt_action(struct rte_eth_dev *dev)
}
igb_intr_enable(dev);
- rte_intr_enable(&(dev->pci_dev->intr_handle));
+ rte_intr_enable(&pci_dev->intr_handle);
if (intr->flags & E1000_FLAG_NEED_LINK_UPDATE) {
intr->flags &= ~E1000_FLAG_NEED_LINK_UPDATE;
@@ -2677,10 +2680,10 @@ eth_igb_interrupt_action(struct rte_eth_dev *dev)
}
PMD_INIT_LOG(DEBUG, "PCI Address: %04d:%02d:%02d:%d",
- dev->pci_dev->addr.domain,
- dev->pci_dev->addr.bus,
- dev->pci_dev->addr.devid,
- dev->pci_dev->addr.function);
+ pci_dev->addr.domain,
+ pci_dev->addr.bus,
+ pci_dev->addr.devid,
+ pci_dev->addr.function);
tctl = E1000_READ_REG(hw, E1000_TCTL);
rctl = E1000_READ_REG(hw, E1000_RCTL);
if (link.link_status) {
@@ -2770,7 +2773,7 @@ eth_igbvf_interrupt_action(struct rte_eth_dev *dev)
}
igbvf_intr_enable(dev);
- rte_intr_enable(&dev->pci_dev->intr_handle);
+ rte_intr_enable(Ð_DEV_PCI_DEV(dev)->intr_handle);
return 0;
}
@@ -3056,7 +3059,8 @@ igbvf_dev_start(struct rte_eth_dev *dev)
struct e1000_adapter *adapter =
E1000_DEV_PRIVATE(dev->data->dev_private);
int ret;
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle =
+ Ð_DEV_PCI_DEV(dev)->intr_handle;
uint32_t intr_vector = 0;
PMD_INIT_FUNC_TRACE();
@@ -3110,7 +3114,8 @@ igbvf_dev_start(struct rte_eth_dev *dev)
static void
igbvf_dev_stop(struct rte_eth_dev *dev)
{
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle =
+ Ð_DEV_PCI_DEV(dev)->intr_handle;
PMD_INIT_FUNC_TRACE();
@@ -5102,7 +5107,7 @@ eth_igb_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
E1000_WRITE_REG(hw, E1000_EIMS, regval | mask);
E1000_WRITE_FLUSH(hw);
- rte_intr_enable(&dev->pci_dev->intr_handle);
+ rte_intr_enable(Ð_DEV_PCI_DEV(dev)->intr_handle);
return 0;
}
@@ -5167,7 +5172,8 @@ eth_igb_configure_msix_intr(struct rte_eth_dev *dev)
uint32_t base = E1000_MISC_VEC_ID;
uint32_t misc_shift = 0;
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle =
+ Ð_DEV_PCI_DEV(dev)->intr_handle;
/* won't configure msix register if no mapping is done
* between intr vector and event fd
diff --git a/drivers/net/e1000/igb_pf.c b/drivers/net/e1000/igb_pf.c
index 5845bc2..6a72ee1 100644
--- a/drivers/net/e1000/igb_pf.c
+++ b/drivers/net/e1000/igb_pf.c
@@ -57,7 +57,8 @@
static inline uint16_t
dev_num_vf(struct rte_eth_dev *eth_dev)
{
- return eth_dev->pci_dev->max_vfs;
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(eth_dev);
+ return pci_dev->max_vfs;
}
static inline
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index ab9a178..c17d969 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -1278,7 +1278,7 @@ static int eth_ena_dev_init(struct rte_eth_dev *eth_dev)
if (rte_eal_process_type() != RTE_PROC_PRIMARY)
return 0;
- pci_dev = eth_dev->pci_dev;
+ pci_dev = ETH_DEV_PCI_DEV(eth_dev);
adapter->pdev = pci_dev;
PMD_INIT_LOG(INFO, "Initializing %x:%x:%x.%d\n",
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 2b154ec..553a88e 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -621,7 +621,7 @@ static int eth_enicpmd_dev_init(struct rte_eth_dev *eth_dev)
eth_dev->rx_pkt_burst = &enic_recv_pkts;
eth_dev->tx_pkt_burst = &enic_xmit_pkts;
- pdev = eth_dev->pci_dev;
+ pdev = ETH_DEV_PCI_DEV(eth_dev);
rte_eth_copy_pci_info(eth_dev, pdev);
enic->pdev = pdev;
addr = &pdev->addr;
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 923690c..e1250f6 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -59,7 +59,8 @@
#define BIT_MASK_PER_UINT32 ((1 << CHARS_PER_UINT32) - 1)
/* default 1:1 map from queue ID to interrupt vector ID */
-#define Q2V(dev, queue_id) (dev->pci_dev->intr_handle.intr_vec[queue_id])
+#define D2IH(dev) (Ð_DEV_PCI_DEV(dev)->intr_handle)
+#define Q2V(dev, queue_id) (D2IH(dev)->intr_vec[queue_id])
/* First 64 Logical ports for PF/VMDQ, second 64 for Flow director */
#define MAX_LPORT_NUM 128
@@ -711,7 +712,7 @@ fm10k_dev_rx_init(struct rte_eth_dev *dev)
{
struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct fm10k_macvlan_filter_info *macvlan;
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = D2IH(dev);
int i, ret;
struct fm10k_rx_queue *rxq;
uint64_t base_addr;
@@ -1171,7 +1172,7 @@ static void
fm10k_dev_stop(struct rte_eth_dev *dev)
{
struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = D2IH(dev);
int i;
PMD_INIT_FUNC_TRACE();
@@ -1387,6 +1388,7 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
struct rte_eth_dev_info *dev_info)
{
struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
PMD_INIT_FUNC_TRACE();
@@ -1396,7 +1398,7 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
dev_info->max_tx_queues = hw->mac.max_queues;
dev_info->max_mac_addrs = FM10K_MAX_MACADDR_NUM;
dev_info->max_hash_mac_addrs = 0;
- dev_info->max_vfs = dev->pci_dev->max_vfs;
+ dev_info->max_vfs = pci_dev->max_vfs;
dev_info->vmdq_pool_base = 0;
dev_info->vmdq_queue_base = 0;
dev_info->max_vmdq_pools = ETH_32_POOLS;
@@ -2341,7 +2343,7 @@ fm10k_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
else
FM10K_WRITE_REG(hw, FM10K_VFITR(Q2V(dev, queue_id)),
FM10K_ITR_AUTOMASK | FM10K_ITR_MASK_CLEAR);
- rte_intr_enable(&dev->pci_dev->intr_handle);
+ rte_intr_enable(D2IH(dev));
return 0;
}
@@ -2364,7 +2366,7 @@ static int
fm10k_dev_rxq_interrupt_setup(struct rte_eth_dev *dev)
{
struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = D2IH(dev);
uint32_t intr_vector, vec;
uint16_t queue_id;
int result = 0;
@@ -2380,7 +2382,7 @@ fm10k_dev_rxq_interrupt_setup(struct rte_eth_dev *dev)
intr_vector = dev->data->nb_rx_queues;
/* disable interrupt first */
- rte_intr_disable(&dev->pci_dev->intr_handle);
+ rte_intr_disable(intr_handle);
if (hw->mac.type == fm10k_mac_pf)
fm10k_dev_disable_intr_pf(dev);
else
@@ -2415,7 +2417,7 @@ fm10k_dev_rxq_interrupt_setup(struct rte_eth_dev *dev)
fm10k_dev_enable_intr_pf(dev);
else
fm10k_dev_enable_intr_vf(dev);
- rte_intr_enable(&dev->pci_dev->intr_handle);
+ rte_intr_enable(intr_handle);
hw->mac.ops.update_int_moderator(hw);
return result;
}
@@ -2581,7 +2583,7 @@ fm10k_dev_interrupt_handler_pf(
FM10K_WRITE_REG(hw, FM10K_ITR(0), FM10K_ITR_AUTOMASK |
FM10K_ITR_MASK_CLEAR);
/* Re-enable interrupt from host side */
- rte_intr_enable(&(dev->pci_dev->intr_handle));
+ rte_intr_enable(D2IH(dev));
}
/**
@@ -2615,7 +2617,7 @@ fm10k_dev_interrupt_handler_vf(
FM10K_WRITE_REG(hw, FM10K_VFITR(0), FM10K_ITR_AUTOMASK |
FM10K_ITR_MASK_CLEAR);
/* Re-enable interrupt from host side */
- rte_intr_enable(&(dev->pci_dev->intr_handle));
+ rte_intr_enable(D2IH(dev));
}
/* Mailbox message handler in VF */
@@ -2827,6 +2829,7 @@ static int
eth_fm10k_dev_init(struct rte_eth_dev *dev)
{
struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
int diag, i;
struct fm10k_macvlan_filter_info *macvlan;
@@ -2840,18 +2843,18 @@ eth_fm10k_dev_init(struct rte_eth_dev *dev)
if (rte_eal_process_type() != RTE_PROC_PRIMARY)
return 0;
- rte_eth_copy_pci_info(dev, dev->pci_dev);
+ rte_eth_copy_pci_info(dev, pci_dev);
macvlan = FM10K_DEV_PRIVATE_TO_MACVLAN(dev->data->dev_private);
memset(macvlan, 0, sizeof(*macvlan));
/* Vendor and Device ID need to be set before init of shared code */
memset(hw, 0, sizeof(*hw));
- hw->device_id = dev->pci_dev->id.device_id;
- hw->vendor_id = dev->pci_dev->id.vendor_id;
- hw->subsystem_device_id = dev->pci_dev->id.subsystem_device_id;
- hw->subsystem_vendor_id = dev->pci_dev->id.subsystem_vendor_id;
+ hw->device_id = pci_dev->id.device_id;
+ hw->vendor_id = pci_dev->id.vendor_id;
+ hw->subsystem_device_id = pci_dev->id.subsystem_device_id;
+ hw->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id;
hw->revision_id = 0;
- hw->hw_addr = (void *)dev->pci_dev->mem_resource[0].addr;
+ hw->hw_addr = (void *)pci_dev->mem_resource[0].addr;
if (hw->hw_addr == NULL) {
PMD_INIT_LOG(ERR, "Bad mem resource."
" Try to blacklist unused devices.");
@@ -2921,20 +2924,20 @@ eth_fm10k_dev_init(struct rte_eth_dev *dev)
/*PF/VF has different interrupt handling mechanism */
if (hw->mac.type == fm10k_mac_pf) {
/* register callback func to eal lib */
- rte_intr_callback_register(&(dev->pci_dev->intr_handle),
+ rte_intr_callback_register(D2IH(dev),
fm10k_dev_interrupt_handler_pf, (void *)dev);
/* enable MISC interrupt */
fm10k_dev_enable_intr_pf(dev);
} else { /* VF */
- rte_intr_callback_register(&(dev->pci_dev->intr_handle),
+ rte_intr_callback_register(D2IH(dev),
fm10k_dev_interrupt_handler_vf, (void *)dev);
fm10k_dev_enable_intr_vf(dev);
}
/* Enable intr after callback registered */
- rte_intr_enable(&(dev->pci_dev->intr_handle));
+ rte_intr_enable(D2IH(dev));
hw->mac.ops.update_int_moderator(hw);
@@ -3004,7 +3007,7 @@ static int
eth_fm10k_dev_uninit(struct rte_eth_dev *dev)
{
struct fm10k_hw *hw = FM10K_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-
+ struct rte_intr_handle *intr_handle = D2IH(dev);
PMD_INIT_FUNC_TRACE();
/* only uninitialize in the primary process */
@@ -3019,7 +3022,7 @@ eth_fm10k_dev_uninit(struct rte_eth_dev *dev)
dev->tx_pkt_burst = NULL;
/* disable uio/vfio intr */
- rte_intr_disable(&(dev->pci_dev->intr_handle));
+ rte_intr_disable(intr_handle);
/*PF/VF has different interrupt handling mechanism */
if (hw->mac.type == fm10k_mac_pf) {
@@ -3027,13 +3030,13 @@ eth_fm10k_dev_uninit(struct rte_eth_dev *dev)
fm10k_dev_disable_intr_pf(dev);
/* unregister callback func to eal lib */
- rte_intr_callback_unregister(&(dev->pci_dev->intr_handle),
+ rte_intr_callback_unregister(intr_handle,
fm10k_dev_interrupt_handler_pf, (void *)dev);
} else {
/* disable interrupt */
fm10k_dev_disable_intr_vf(dev);
- rte_intr_callback_unregister(&(dev->pci_dev->intr_handle),
+ rte_intr_callback_unregister(intr_handle,
fm10k_dev_interrupt_handler_vf, (void *)dev);
}
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 67778ba..8a63a8c 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -907,7 +907,7 @@ is_floating_veb_supported(struct rte_devargs *devargs)
static void
config_floating_veb(struct rte_eth_dev *dev)
{
- struct rte_pci_device *pci_dev = dev->pci_dev;
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -952,7 +952,7 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
i40e_set_tx_function(dev);
return 0;
}
- pci_dev = dev->pci_dev;
+ pci_dev = ETH_DEV_PCI_DEV(dev);
rte_eth_copy_pci_info(dev, pci_dev);
@@ -1215,7 +1215,7 @@ eth_i40e_dev_uninit(struct rte_eth_dev *dev)
return 0;
hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- pci_dev = dev->pci_dev;
+ pci_dev = ETH_DEV_PCI_DEV(dev);
if (hw->adapter_stopped == 0)
i40e_dev_close(dev);
@@ -1335,7 +1335,7 @@ void
i40e_vsi_queues_unbind_intr(struct i40e_vsi *vsi)
{
struct rte_eth_dev *dev = vsi->adapter->eth_dev;
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
uint16_t msix_vect = vsi->msix_intr;
uint16_t i;
@@ -1448,7 +1448,7 @@ void
i40e_vsi_queues_bind_intr(struct i40e_vsi *vsi)
{
struct rte_eth_dev *dev = vsi->adapter->eth_dev;
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
uint16_t msix_vect = vsi->msix_intr;
uint16_t nb_msix = RTE_MIN(vsi->nb_msix, intr_handle->nb_efd);
@@ -1519,7 +1519,7 @@ static void
i40e_vsi_enable_queues_intr(struct i40e_vsi *vsi)
{
struct rte_eth_dev *dev = vsi->adapter->eth_dev;
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
uint16_t interval = i40e_calc_itr_interval(\
RTE_LIBRTE_I40E_ITR_INTERVAL);
@@ -1550,7 +1550,7 @@ static void
i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi)
{
struct rte_eth_dev *dev = vsi->adapter->eth_dev;
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
uint16_t msix_intr, i;
@@ -1675,7 +1675,7 @@ i40e_dev_start(struct rte_eth_dev *dev)
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct i40e_vsi *main_vsi = pf->main_vsi;
int ret, i;
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
uint32_t intr_vector = 0;
hw->adapter_stopped = 0;
@@ -1808,7 +1808,7 @@ i40e_dev_stop(struct rte_eth_dev *dev)
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct i40e_vsi *main_vsi = pf->main_vsi;
struct i40e_mirror_rule *p_mirror;
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
int i;
/* Disable all queues */
@@ -1870,7 +1870,7 @@ i40e_dev_close(struct rte_eth_dev *dev)
/* Disable interrupt */
i40e_pf_disable_irq0(hw);
- rte_intr_disable(&(dev->pci_dev->intr_handle));
+ rte_intr_disable(ETH_DEV_TO_INTR_HANDLE(dev));
/* shutdown and destroy the HMC */
i40e_shutdown_lan_hmc(hw);
@@ -2588,7 +2588,7 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
dev_info->min_rx_bufsize = I40E_BUF_SIZE_MIN;
dev_info->max_rx_pktlen = I40E_FRAME_SIZE_MAX;
dev_info->max_mac_addrs = vsi->max_macaddrs;
- dev_info->max_vfs = dev->pci_dev->max_vfs;
+ dev_info->max_vfs = ETH_DEV_PCI_DEV(dev)->max_vfs;
dev_info->rx_offload_capa =
DEV_RX_OFFLOAD_VLAN_STRIP |
DEV_RX_OFFLOAD_QINQ_STRIP |
@@ -3488,11 +3488,12 @@ i40e_get_cap(struct i40e_hw *hw)
static int
i40e_pf_parameter_init(struct rte_eth_dev *dev)
{
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct i40e_hw *hw = I40E_PF_TO_HW(pf);
uint16_t qp_count = 0, vsi_count = 0;
- if (dev->pci_dev->max_vfs && !hw->func_caps.sr_iov_1_1) {
+ if (pci_dev->max_vfs && !hw->func_caps.sr_iov_1_1) {
PMD_INIT_LOG(ERR, "HW configuration doesn't support SRIOV");
return -EINVAL;
}
@@ -3533,10 +3534,10 @@ i40e_pf_parameter_init(struct rte_eth_dev *dev)
/* VF queue/VSI allocation */
pf->vf_qp_offset = pf->lan_qp_offset + pf->lan_nb_qps;
- if (hw->func_caps.sr_iov_1_1 && dev->pci_dev->max_vfs) {
+ if (hw->func_caps.sr_iov_1_1 && pci_dev->max_vfs) {
pf->flags |= I40E_FLAG_SRIOV;
pf->vf_nb_qps = RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF;
- pf->vf_num = dev->pci_dev->max_vfs;
+ pf->vf_num = pci_dev->max_vfs;
PMD_DRV_LOG(DEBUG, "%u VF VSIs, %u queues per VF VSI, "
"in total %u queues", pf->vf_num, pf->vf_nb_qps,
pf->vf_nb_qps * pf->vf_num);
@@ -5573,7 +5574,7 @@ i40e_dev_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
done:
/* Enable interrupt */
i40e_pf_enable_irq0(hw);
- rte_intr_enable(&(dev->pci_dev->intr_handle));
+ rte_intr_enable(ETH_DEV_TO_INTR_HANDLE(dev));
}
static int
@@ -8124,10 +8125,11 @@ i40e_dev_filter_ctrl(struct rte_eth_dev *dev,
static void
i40e_enable_extended_tag(struct rte_eth_dev *dev)
{
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
uint32_t buf = 0;
int ret;
- ret = rte_eal_pci_read_config(dev->pci_dev, &buf, sizeof(buf),
+ ret = rte_eal_pci_read_config(pci_dev, &buf, sizeof(buf),
PCI_DEV_CAP_REG);
if (ret < 0) {
PMD_DRV_LOG(ERR, "Failed to read PCI offset 0x%x",
@@ -8140,7 +8142,7 @@ i40e_enable_extended_tag(struct rte_eth_dev *dev)
}
buf = 0;
- ret = rte_eal_pci_read_config(dev->pci_dev, &buf, sizeof(buf),
+ ret = rte_eal_pci_read_config(pci_dev, &buf, sizeof(buf),
PCI_DEV_CTRL_REG);
if (ret < 0) {
PMD_DRV_LOG(ERR, "Failed to read PCI offset 0x%x",
@@ -8152,7 +8154,7 @@ i40e_enable_extended_tag(struct rte_eth_dev *dev)
return;
}
buf |= PCI_DEV_CTRL_EXT_TAG_MASK;
- ret = rte_eal_pci_write_config(dev->pci_dev, &buf, sizeof(buf),
+ ret = rte_eal_pci_write_config(pci_dev, &buf, sizeof(buf),
PCI_DEV_CTRL_REG);
if (ret < 0) {
PMD_DRV_LOG(ERR, "Failed to write PCI offset 0x%x",
@@ -9555,7 +9557,7 @@ i40e_dev_get_dcb_info(struct rte_eth_dev *dev,
static int
i40e_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
{
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint16_t interval =
i40e_calc_itr_interval(RTE_LIBRTE_I40E_ITR_INTERVAL);
@@ -9580,7 +9582,7 @@ i40e_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT));
I40E_WRITE_FLUSH(hw);
- rte_intr_enable(&dev->pci_dev->intr_handle);
+ rte_intr_enable(ETH_DEV_TO_INTR_HANDLE(dev));
return 0;
}
@@ -9588,7 +9590,7 @@ i40e_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
static int
i40e_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
{
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint16_t msix_intr;
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 298cef4..9d4bea7 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -671,6 +671,10 @@ i40e_get_vsi_from_adapter(struct i40e_adapter *adapter)
#define I40E_VF_TO_HW(vf) \
(&(((struct i40e_vf *)vf)->adapter->hw))
+/* ETH_DEV_TO_INTR_HANDLE */
+#define ETH_DEV_TO_INTR_HANDLE(ptr) \
+ (&(ETH_DEV_PCI_DEV(ptr)->intr_handle))
+
static inline void
i40e_init_adminq_parameter(struct i40e_hw *hw)
{
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index aa306d6..781e658 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -718,7 +718,7 @@ i40evf_config_irq_map(struct rte_eth_dev *dev)
uint8_t cmd_buffer[sizeof(struct i40e_virtchnl_irq_map_info) + \
sizeof(struct i40e_virtchnl_vector_map)];
struct i40e_virtchnl_irq_map_info *map_info;
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
uint32_t vector_id;
int i, err;
@@ -1431,7 +1431,7 @@ i40evf_dev_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
done:
i40evf_enable_irq0(hw);
- rte_intr_enable(&dev->pci_dev->intr_handle);
+ rte_intr_enable(ETH_DEV_TO_INTR_HANDLE(dev));
}
static int
@@ -1439,7 +1439,7 @@ i40evf_dev_init(struct rte_eth_dev *eth_dev)
{
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(\
eth_dev->data->dev_private);
- struct rte_pci_device *pci_dev = eth_dev->pci_dev;
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(eth_dev);
PMD_INIT_FUNC_TRACE();
@@ -1458,15 +1458,15 @@ i40evf_dev_init(struct rte_eth_dev *eth_dev)
return 0;
}
- rte_eth_copy_pci_info(eth_dev, eth_dev->pci_dev);
+ rte_eth_copy_pci_info(eth_dev, pci_dev);
- hw->vendor_id = eth_dev->pci_dev->id.vendor_id;
- hw->device_id = eth_dev->pci_dev->id.device_id;
- hw->subsystem_vendor_id = eth_dev->pci_dev->id.subsystem_vendor_id;
- hw->subsystem_device_id = eth_dev->pci_dev->id.subsystem_device_id;
- hw->bus.device = eth_dev->pci_dev->addr.devid;
- hw->bus.func = eth_dev->pci_dev->addr.function;
- hw->hw_addr = (void *)eth_dev->pci_dev->mem_resource[0].addr;
+ hw->vendor_id = pci_dev->id.vendor_id;
+ hw->device_id = pci_dev->id.device_id;
+ hw->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id;
+ hw->subsystem_device_id = pci_dev->id.subsystem_device_id;
+ hw->bus.device = pci_dev->addr.devid;
+ hw->bus.func = pci_dev->addr.function;
+ hw->hw_addr = (void *)pci_dev->mem_resource[0].addr;
hw->adapter_stopped = 0;
if(i40evf_init_vf(eth_dev) != 0) {
@@ -1853,7 +1853,7 @@ i40evf_enable_queues_intr(struct rte_eth_dev *dev)
{
struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
if (!rte_intr_allow_others(intr_handle)) {
I40E_WRITE_REG(hw,
@@ -1885,7 +1885,7 @@ i40evf_disable_queues_intr(struct rte_eth_dev *dev)
{
struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
if (!rte_intr_allow_others(intr_handle)) {
I40E_WRITE_REG(hw, I40E_VFINT_DYN_CTL01,
@@ -1911,7 +1911,7 @@ i40evf_disable_queues_intr(struct rte_eth_dev *dev)
static int
i40evf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
{
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint16_t interval =
i40e_calc_itr_interval(RTE_LIBRTE_I40E_ITR_INTERVAL);
@@ -1937,7 +1937,7 @@ i40evf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
I40EVF_WRITE_FLUSH(hw);
- rte_intr_enable(&dev->pci_dev->intr_handle);
+ rte_intr_enable(ETH_DEV_TO_INTR_HANDLE(dev));
return 0;
}
@@ -1945,7 +1945,7 @@ i40evf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
static int
i40evf_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
{
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint16_t msix_intr;
@@ -2025,7 +2025,7 @@ i40evf_dev_start(struct rte_eth_dev *dev)
{
struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
uint32_t intr_vector = 0;
PMD_INIT_FUNC_TRACE();
@@ -2090,7 +2090,7 @@ i40evf_dev_start(struct rte_eth_dev *dev)
static void
i40evf_dev_stop(struct rte_eth_dev *dev)
{
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
PMD_INIT_FUNC_TRACE();
@@ -2285,7 +2285,7 @@ static void
i40evf_dev_close(struct rte_eth_dev *dev)
{
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- struct rte_pci_device *pci_dev = dev->pci_dev;
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
i40evf_dev_stop(dev);
hw->adapter_stopped = 1;
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index edc9b22..f17da46 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -427,6 +427,9 @@ static int ixgbe_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
(r) = (h)->bitmap[idx] >> bit & 1;\
} while (0)
+#define ETH_DEV_TO_INTR_HANDLE(ptr) \
+ (&(ETH_DEV_PCI_DEV(ptr)->intr_handle))
+
/*
* The set of PCI devices this driver supports
*/
@@ -1127,7 +1130,7 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev)
return 0;
}
- pci_dev = eth_dev->pci_dev;
+ pci_dev = ETH_DEV_PCI_DEV(eth_dev);
rte_eth_copy_pci_info(eth_dev, pci_dev);
@@ -1302,7 +1305,7 @@ eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev)
return -EPERM;
hw = IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
- pci_dev = eth_dev->pci_dev;
+ pci_dev = ETH_DEV_PCI_DEV(eth_dev);
if (hw->adapter_stopped == 0)
ixgbe_dev_close(eth_dev);
@@ -1419,7 +1422,7 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev)
return 0;
}
- pci_dev = eth_dev->pci_dev;
+ pci_dev = ETH_DEV_PCI_DEV(eth_dev);
rte_eth_copy_pci_info(eth_dev, pci_dev);
@@ -1532,7 +1535,9 @@ static int
eth_ixgbevf_dev_uninit(struct rte_eth_dev *eth_dev)
{
struct ixgbe_hw *hw;
- struct rte_pci_device *pci_dev = eth_dev->pci_dev;
+ struct rte_pci_device *pci_dev;
+
+ pci_dev = ETH_DEV_PCI_DEV(eth_dev);
PMD_INIT_FUNC_TRACE();
@@ -1960,7 +1965,8 @@ ixgbe_check_vf_rss_rxq_num(struct rte_eth_dev *dev, uint16_t nb_rx_q)
}
RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool = nb_rx_q;
- RTE_ETH_DEV_SRIOV(dev).def_pool_q_idx = dev->pci_dev->max_vfs * nb_rx_q;
+ RTE_ETH_DEV_SRIOV(dev).def_pool_q_idx =
+ ETH_DEV_PCI_DEV(dev)->max_vfs * nb_rx_q;
return 0;
}
@@ -2191,7 +2197,8 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct ixgbe_vf_info *vfinfo =
*IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private);
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
uint32_t intr_vector = 0;
int err, link_up = 0, negotiate = 0;
uint32_t speed = 0;
@@ -2291,7 +2298,7 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
/* Restore vf rate limit */
if (vfinfo != NULL) {
- for (vf = 0; vf < dev->pci_dev->max_vfs; vf++)
+ for (vf = 0; vf < pci_dev->max_vfs; vf++)
for (idx = 0; idx < IXGBE_MAX_QUEUE_NUM_PER_VF; idx++)
if (vfinfo[vf].tx_rate[idx] != 0)
ixgbe_set_vf_rate_limit(dev, vf,
@@ -2408,7 +2415,8 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
struct ixgbe_filter_info *filter_info =
IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
struct ixgbe_5tuple_filter *p_5tuple, *p_5tuple_next;
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
int vf;
PMD_INIT_FUNC_TRACE();
@@ -2424,7 +2432,7 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
ixgbe_stop_adapter(hw);
for (vf = 0; vfinfo != NULL &&
- vf < dev->pci_dev->max_vfs; vf++)
+ vf < pci_dev->max_vfs; vf++)
vfinfo[vf].clear_to_send = false;
if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper) {
@@ -3033,6 +3041,7 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
{
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
dev_info->max_rx_queues = (uint16_t)hw->mac.max_rx_queues;
dev_info->max_tx_queues = (uint16_t)hw->mac.max_tx_queues;
@@ -3049,7 +3058,7 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
dev_info->max_rx_pktlen = 15872; /* includes CRC, cf MAXFRS register */
dev_info->max_mac_addrs = hw->mac.num_rar_entries;
dev_info->max_hash_mac_addrs = IXGBE_VMDQ_NUM_UC_MAC;
- dev_info->max_vfs = dev->pci_dev->max_vfs;
+ dev_info->max_vfs = pci_dev->max_vfs;
if (hw->mac.type == ixgbe_mac_82598EB)
dev_info->max_vmdq_pools = ETH_16_POOLS;
else
@@ -3164,6 +3173,7 @@ ixgbevf_dev_info_get(struct rte_eth_dev *dev,
struct rte_eth_dev_info *dev_info)
{
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
dev_info->max_rx_queues = (uint16_t)hw->mac.max_rx_queues;
dev_info->max_tx_queues = (uint16_t)hw->mac.max_tx_queues;
@@ -3171,7 +3181,7 @@ ixgbevf_dev_info_get(struct rte_eth_dev *dev,
dev_info->max_rx_pktlen = 15872; /* includes CRC, cf MAXFRS reg */
dev_info->max_mac_addrs = hw->mac.num_rar_entries;
dev_info->max_hash_mac_addrs = IXGBE_VMDQ_NUM_UC_MAC;
- dev_info->max_vfs = dev->pci_dev->max_vfs;
+ dev_info->max_vfs = pci_dev->max_vfs;
if (hw->mac.type == ixgbe_mac_82598EB)
dev_info->max_vmdq_pools = ETH_16_POOLS;
else
@@ -3434,6 +3444,7 @@ static void
ixgbe_dev_link_status_print(struct rte_eth_dev *dev)
{
struct rte_eth_link link;
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
memset(&link, 0, sizeof(link));
rte_ixgbe_dev_atomic_read_link_status(dev, &link);
@@ -3448,10 +3459,10 @@ ixgbe_dev_link_status_print(struct rte_eth_dev *dev)
(int)(dev->data->port_id));
}
PMD_INIT_LOG(DEBUG, "PCI Address: " PCI_PRI_FMT,
- dev->pci_dev->addr.domain,
- dev->pci_dev->addr.bus,
- dev->pci_dev->addr.devid,
- dev->pci_dev->addr.function);
+ pci_dev->addr.domain,
+ pci_dev->addr.bus,
+ pci_dev->addr.devid,
+ pci_dev->addr.function);
}
/*
@@ -3515,7 +3526,7 @@ ixgbe_dev_interrupt_action(struct rte_eth_dev *dev)
} else {
PMD_DRV_LOG(DEBUG, "enable intr immediately");
ixgbe_enable_intr(dev);
- rte_intr_enable(&(dev->pci_dev->intr_handle));
+ rte_intr_enable(ETH_DEV_TO_INTR_HANDLE(dev));
}
@@ -3564,7 +3575,7 @@ ixgbe_dev_interrupt_delayed_handler(void *param)
PMD_DRV_LOG(DEBUG, "enable intr in delayed handler S[%08x]", eicr);
ixgbe_enable_intr(dev);
- rte_intr_enable(&(dev->pci_dev->intr_handle));
+ rte_intr_enable(ETH_DEV_TO_INTR_HANDLE(dev));
}
/**
@@ -4196,7 +4207,7 @@ ixgbevf_dev_start(struct rte_eth_dev *dev)
struct ixgbe_hw *hw =
IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint32_t intr_vector = 0;
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
int err, mask = 0;
@@ -4259,7 +4270,7 @@ static void
ixgbevf_dev_stop(struct rte_eth_dev *dev)
{
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
PMD_INIT_FUNC_TRACE();
@@ -5070,7 +5081,7 @@ ixgbevf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
RTE_SET_USED(queue_id);
IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask);
- rte_intr_enable(&dev->pci_dev->intr_handle);
+ rte_intr_enable(ETH_DEV_TO_INTR_HANDLE(dev));
return 0;
}
@@ -5112,7 +5123,7 @@ ixgbe_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
mask &= (1 << (queue_id - 32));
IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(1), mask);
}
- rte_intr_enable(&dev->pci_dev->intr_handle);
+ rte_intr_enable(ETH_DEV_TO_INTR_HANDLE(dev));
return 0;
}
@@ -5216,7 +5227,7 @@ ixgbe_set_ivar_map(struct ixgbe_hw *hw, int8_t direction,
static void
ixgbevf_configure_msix(struct rte_eth_dev *dev)
{
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
struct ixgbe_hw *hw =
IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint32_t q_idx;
@@ -5249,7 +5260,7 @@ ixgbevf_configure_msix(struct rte_eth_dev *dev)
static void
ixgbe_configure_msix(struct rte_eth_dev *dev)
{
- struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
+ struct rte_intr_handle *intr_handle = ETH_DEV_TO_INTR_HANDLE(dev);
struct ixgbe_hw *hw =
IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint32_t queue_id, base = IXGBE_MISC_VEC_ID;
@@ -5381,7 +5392,8 @@ static int ixgbe_set_vf_rate_limit(struct rte_eth_dev *dev, uint16_t vf,
return -EINVAL;
if (vfinfo != NULL) {
- for (vf_idx = 0; vf_idx < dev->pci_dev->max_vfs; vf_idx++) {
+ for (vf_idx = 0; vf_idx < ETH_DEV_PCI_DEV(dev)->max_vfs;
+ vf_idx++) {
if (vf_idx == vf)
continue;
for (idx = 0; idx < RTE_DIM(vfinfo[vf_idx].tx_rate);
@@ -7197,12 +7209,13 @@ ixgbe_e_tag_insertion_en_dis(struct rte_eth_dev *dev,
int ret = 0;
uint32_t vmtir, vmvir;
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(dev);
- if (l2_tunnel->vf_id >= dev->pci_dev->max_vfs) {
+ if (l2_tunnel->vf_id >= pci_dev->max_vfs) {
PMD_DRV_LOG(ERR,
"VF id %u should be less than %u",
l2_tunnel->vf_id,
- dev->pci_dev->max_vfs);
+ pci_dev->max_vfs);
return -EINVAL;
}
diff --git a/drivers/net/ixgbe/ixgbe_pf.c b/drivers/net/ixgbe/ixgbe_pf.c
index 26395e4..139d816 100644
--- a/drivers/net/ixgbe/ixgbe_pf.c
+++ b/drivers/net/ixgbe/ixgbe_pf.c
@@ -61,7 +61,7 @@
static inline uint16_t
dev_num_vf(struct rte_eth_dev *eth_dev)
{
- return eth_dev->pci_dev->max_vfs;
+ return ETH_DEV_PCI_DEV(eth_dev)->max_vfs;
}
static inline
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index d106dd0..959ff0f 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -178,11 +178,12 @@ static void
qede_interrupt_handler(__rte_unused struct rte_intr_handle *handle, void *param)
{
struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param;
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(eth_dev);
struct qede_dev *qdev = eth_dev->data->dev_private;
struct ecore_dev *edev = &qdev->edev;
qede_interrupt_action(ECORE_LEADING_HWFN(edev));
- if (rte_intr_enable(ð_dev->pci_dev->intr_handle))
+ if (rte_intr_enable(&pci_dev->intr_handle))
DP_ERR(edev, "rte_intr_enable failed\n");
}
@@ -809,6 +810,7 @@ static void qede_poll_sp_sb_cb(void *param)
static void qede_dev_close(struct rte_eth_dev *eth_dev)
{
+ struct rte_pci_device *pci_dev = ETH_DEV_PCI_DEV(eth_dev);
struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
int rc;
@@ -835,9 +837,9 @@ static void qede_dev_close(struct rte_eth_dev *eth_dev)
qdev->ops->common->remove(edev);
- rte_intr_disable(ð_dev->pci_dev->intr_handle);
+ rte_intr_disable(&pci_dev->intr_handle);
- rte_intr_callback_unregister(ð_dev->pci_dev->intr_handle,
+ rte_intr_callback_unregister(&pci_dev->intr_handle,
qede_interrupt_handler, (void *)eth_dev);
if (edev->num_hwfns > 1)
@@ -1403,7 +1405,8 @@ static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf)
/* Extract key data structures */
adapter = eth_dev->data->dev_private;
edev = &adapter->edev;
- pci_addr = eth_dev->pci_dev->addr;
+ pci_dev = ETH_DEV_PCI_DEV(eth_dev);
+ pci_addr = pci_dev->addr;
PMD_INIT_FUNC_TRACE(edev);
@@ -1420,8 +1423,6 @@ static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf)
return 0;
}
- pci_dev = eth_dev->pci_dev;
-
rte_eth_copy_pci_info(eth_dev, pci_dev);
qed_ops = qed_get_eth_ops();
@@ -1442,10 +1443,10 @@ static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf)
qede_update_pf_params(edev);
- rte_intr_callback_register(ð_dev->pci_dev->intr_handle,
+ rte_intr_callback_register(&pci_dev->intr_handle,
qede_interrupt_handler, (void *)eth_dev);
- if (rte_intr_enable(ð_dev->pci_dev->intr_handle)) {
+ if (rte_intr_enable(&pci_dev->intr_handle)) {
DP_ERR(edev, "rte_intr_enable() failed\n");
return -ENODEV;
}
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 8bb13e5..bcb3751 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -138,7 +138,7 @@ gpa_zone_reserve(struct rte_eth_dev *dev, uint32_t size,
const struct rte_memzone *mz;
snprintf(z_name, sizeof(z_name), "%s_%d_%s",
- dev->driver->pci_drv.driver.name, dev->data->port_id, post_string);
+ dev->data->drv_name, dev->data->port_id, post_string);
mz = rte_memzone_lookup(z_name);
if (!reuse) {
@@ -237,7 +237,7 @@ eth_vmxnet3_dev_init(struct rte_eth_dev *eth_dev)
eth_dev->dev_ops = &vmxnet3_eth_dev_ops;
eth_dev->rx_pkt_burst = &vmxnet3_recv_pkts;
eth_dev->tx_pkt_burst = &vmxnet3_xmit_pkts;
- pci_dev = eth_dev->pci_dev;
+ pci_dev = ETH_DEV_PCI_DEV(eth_dev);
/*
* for secondary processes, we don't initialize any further as primary
--
2.7.4
^ permalink raw reply related
* [PATCH v2 2/8] ethdev: Helper to convert to struct rte_pci_device
From: Jan Blunck @ 2016-11-21 16:55 UTC (permalink / raw)
To: dev; +Cc: shreyansh.jain, david.marchand
In-Reply-To: <1479747322-5774-1-git-send-email-jblunck@infradead.org>
Signed-off-by: Jan Blunck <jblunck@infradead.org>
---
lib/librte_ether/rte_ethdev.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 9678179..3adbb2b 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1644,6 +1644,12 @@ struct rte_eth_dev {
uint8_t attached; /**< Flag indicating the port is attached */
} __rte_cache_aligned;
+/**
+ * @internal
+ * Helper for drivers that need to convert from rte_eth_dev to rte_pci_device.
+ */
+#define ETH_DEV_PCI_DEV(ptr) ((ptr)->pci_dev)
+
struct rte_eth_dev_sriov {
uint8_t active; /**< SRIOV is active with 16, 32 or 64 pools */
uint8_t nb_q_per_pool; /**< rx queue number per pool */
--
2.7.4
^ permalink raw reply related
* [PATCH v2 1/8] eal: define container_of macro
From: Jan Blunck @ 2016-11-21 16:55 UTC (permalink / raw)
To: dev; +Cc: shreyansh.jain, david.marchand, Jan Viktorin
This macro is based on Jan Viktorin's original patch but also checks the
type of the passed pointer against the type of the member.
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
[jblunck@infradead.org: add type checking and __extension__]
Signed-off-by: Jan Blunck <jblunck@infradead.org>
---
lib/librte_eal/common/include/rte_common.h | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/lib/librte_eal/common/include/rte_common.h b/lib/librte_eal/common/include/rte_common.h
index db5ac91..8dda3e2 100644
--- a/lib/librte_eal/common/include/rte_common.h
+++ b/lib/librte_eal/common/include/rte_common.h
@@ -331,6 +331,26 @@ rte_bsf32(uint32_t v)
#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
#endif
+/**
+ * Return pointer to the wrapping struct instance.
+ *
+ * Example:
+ *
+ * struct wrapper {
+ * ...
+ * struct child c;
+ * ...
+ * };
+ *
+ * struct child *x = obtain(...);
+ * struct wrapper *w = container_of(x, struct wrapper, c);
+ */
+#ifndef container_of
+#define container_of(ptr, type, member) __extension__ ({ \
+ typeof(((type *)0)->member) *_ptr = (ptr); \
+ (type *)(((char *)_ptr) - offsetof(type, member)); })
+#endif
+
#define _RTE_STR(x) #x
/** Take a macro value and get a string version of it */
#define RTE_STR(x) _RTE_STR(x)
--
2.7.4
^ permalink raw reply related
* Re: [PATCH] eal: postpone vdev initialization
From: Jerin Jacob @ 2016-11-21 16:56 UTC (permalink / raw)
To: Shreyansh Jain; +Cc: dev, declan.doherty, david.marchand, thomas.monjalon
In-Reply-To: <8457ded8-e9ee-76ba-671e-a76aed08f6d0@nxp.com>
On Mon, Nov 21, 2016 at 10:39:00AM +0530, Shreyansh Jain wrote:
> On Sunday 20 November 2016 01:30 PM, Jerin Jacob wrote:
> > Some platform like octeontx may use pci and
> > vdev based combined device to represent a logical
> > dpdk functional device.In such case, postponing the
> > vdev initialization after pci device
> > initialization will provide the better view of
> > the pci device resources in the system in
> > vdev's probe function, and it allows better
> > functional subsystem registration in vdev probe
> > function.
> >
> > As a bonus, This patch fixes a bond device
> > initialization use case.
> >
> > example command to reproduce the issue:
> > ../testpmd -c 0x2 --vdev 'eth_bond0,mode=0,
> > slave=0000:02:00.0,slave=0000:03:00.0' --
> > --port-topology=chained
> >
> > root cause:
> > In existing case(vdev initialization and then pci
> > initialization), creates three Ethernet ports with
> > following port ids
> > 0 - Bond device
> > 1 - PCI device 0
> > 2 - PCI devive 1
> >
> > Since testpmd, calls the configure/start on all the ports on
> > start up,it will translate to following illegal setup sequence
> >
> > 1)bond device configure/start
> > 1.1) pci device0 stop/configure/start
> > 1.2) pci device1 stop/configure/start
> > 2)pci device 0 configure(illegal setup case,
> > as device in start state)
> >
> > The fix changes the initialization sequence and
> > allow initialization in following valid setup order
> > 1) pcie device 0 configure/start
> > 2) pcie device 1 configure/start
> > 3) bond device 2 configure/start
> > 3.1) pcie device 0/stop/configure/start
> > 3.2) pcie device 1/stop/configure/start
> >
> > Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> > ---
> > lib/librte_eal/bsdapp/eal/eal.c | 6 +++---
> > lib/librte_eal/linuxapp/eal/eal.c | 6 +++---
> > 2 files changed, 6 insertions(+), 6 deletions(-)
> >
> > diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
> > index 35e3117..2206277 100644
> > --- a/lib/librte_eal/bsdapp/eal/eal.c
> > +++ b/lib/librte_eal/bsdapp/eal/eal.c
> > @@ -577,9 +577,6 @@ rte_eal_init(int argc, char **argv)
> > rte_config.master_lcore, thread_id, cpuset,
> > ret == 0 ? "" : "...");
> >
> > - if (rte_eal_dev_init() < 0)
> > - rte_panic("Cannot init pmd devices\n");
> > -
> > RTE_LCORE_FOREACH_SLAVE(i) {
> >
> > /*
> > @@ -616,6 +613,9 @@ rte_eal_init(int argc, char **argv)
> > if (rte_eal_pci_probe())
> > rte_panic("Cannot probe PCI\n");
> >
> > + if (rte_eal_dev_init() < 0)
> > + rte_panic("Cannot init pmd devices\n");
> > +
> > rte_eal_mcfg_complete();
> >
> > return fctret;
> > diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
> > index 2075282..16dd5b9 100644
> > --- a/lib/librte_eal/linuxapp/eal/eal.c
> > +++ b/lib/librte_eal/linuxapp/eal/eal.c
> > @@ -841,9 +841,6 @@ rte_eal_init(int argc, char **argv)
> > rte_config.master_lcore, (int)thread_id, cpuset,
> > ret == 0 ? "" : "...");
> >
> > - if (rte_eal_dev_init() < 0)
> > - rte_panic("Cannot init pmd devices\n");
> > -
> > if (rte_eal_intr_init() < 0)
> > rte_panic("Cannot init interrupt-handling thread\n");
> >
> > @@ -887,6 +884,9 @@ rte_eal_init(int argc, char **argv)
> > if (rte_eal_pci_probe())
> > rte_panic("Cannot probe PCI\n");
> >
> > + if (rte_eal_dev_init() < 0)
> > + rte_panic("Cannot init pmd devices\n");
> > +
> > rte_eal_mcfg_complete();
> >
> > return fctret;
> >
>
> Movement looks fine to me.
>
> IMO, rte_eal_dev_init() is a misleading name. It actually performs a
> driver->probe for vdev - which is parallel to rte_eal_pci_probe.
Looks good to me. If there are no objection, I can change to rte_eal_vdev_probe()
as a separate patch in v2. Let the order change patch be separate.
>
> -
> Shreyansh
^ permalink raw reply
* Re: [PATCH 4/7] virtio: Don't fill dev_info->driver_name
From: Jan Blunck @ 2016-11-21 16:52 UTC (permalink / raw)
To: David Marchand; +Cc: dev@dpdk.org, Shreyansh Jain
In-Reply-To: <CALwxeUsR1Gmtmtx94K7PDB7rf_==bAdSTCJYdiPZPsjgisiXQg@mail.gmail.com>
On Mon, Nov 21, 2016 at 5:49 PM, David Marchand
<david.marchand@6wind.com> wrote:
> On Mon, Nov 21, 2016 at 5:34 PM, Jan Blunck <jblunck@infradead.org> wrote:
>> On Sun, Nov 20, 2016 at 4:22 PM, David Marchand
>>> I posted something similar [1], so looks good to me :-)
>>>
>>> [1]: http://dpdk.org/dev/patchwork/patch/16991/
>>>
>>
>> Thanks for reviewing. Do we go with your proposal then? Do you plan to
>> follow up on the comments?
>
> Yes will do.
> Out of curiosity how did you catch the qede driver ? Did you check all
> other drivers ?
>
$ grep drivername -r drivers/
^ permalink raw reply
* Re: [PATCH 4/7] virtio: Don't fill dev_info->driver_name
From: David Marchand @ 2016-11-21 16:49 UTC (permalink / raw)
To: Jan Blunck; +Cc: dev@dpdk.org, Shreyansh Jain
In-Reply-To: <CALe+Z015KyNZKrasimQCuM6V6ggfSgDJJO4y00K-Zx32kUT0EQ@mail.gmail.com>
On Mon, Nov 21, 2016 at 5:34 PM, Jan Blunck <jblunck@infradead.org> wrote:
> On Sun, Nov 20, 2016 at 4:22 PM, David Marchand
>> I posted something similar [1], so looks good to me :-)
>>
>> [1]: http://dpdk.org/dev/patchwork/patch/16991/
>>
>
> Thanks for reviewing. Do we go with your proposal then? Do you plan to
> follow up on the comments?
Yes will do.
Out of curiosity how did you catch the qede driver ? Did you check all
other drivers ?
--
David Marchand
^ permalink raw reply
* Re: [PATCH 4/7] virtio: Don't fill dev_info->driver_name
From: Jan Blunck @ 2016-11-21 16:34 UTC (permalink / raw)
To: David Marchand; +Cc: dev@dpdk.org, Shreyansh Jain
In-Reply-To: <CALwxeUt0d+s9hBCX-TcL-Fms-v7ozqEg7zOYy6NsJsV5rUHRGA@mail.gmail.com>
On Sun, Nov 20, 2016 at 4:22 PM, David Marchand
<david.marchand@6wind.com> wrote:
> On Sun, Nov 20, 2016 at 11:05 AM, Jan Blunck <jblunck@infradead.org> wrote:
>> This is overwritten in rte_eth_dev_info_get().
>>
>> Signed-off-by: Jan Blunck <jblunck@infradead.org>
>> ---
>> drivers/net/virtio/virtio_ethdev.c | 4 ----
>> 1 file changed, 4 deletions(-)
>>
>> diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
>> index 079fd6c..741688e 100644
>> --- a/drivers/net/virtio/virtio_ethdev.c
>> +++ b/drivers/net/virtio/virtio_ethdev.c
>> @@ -1624,10 +1624,6 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
>> uint64_t tso_mask;
>> struct virtio_hw *hw = dev->data->dev_private;
>>
>> - if (dev->pci_dev)
>> - dev_info->driver_name = dev->driver->pci_drv.driver.name;
>> - else
>> - dev_info->driver_name = "virtio_user PMD";
>> dev_info->max_rx_queues =
>> RTE_MIN(hw->max_queue_pairs, VIRTIO_MAX_RX_QUEUES);
>> dev_info->max_tx_queues =
>> --
>> 2.7.4
>>
>
> I posted something similar [1], so looks good to me :-)
>
> [1]: http://dpdk.org/dev/patchwork/patch/16991/
>
Thanks for reviewing. Do we go with your proposal then? Do you plan to
follow up on the comments?
^ permalink raw reply
* Re: [PATCH 1/2] net: remove dead driver names
From: Jan Blunck @ 2016-11-21 16:31 UTC (permalink / raw)
To: David Marchand
Cc: Thomas Monjalon, dev, linville, Declan Doherty, zlu, lsun,
alejandro.lucero, mtetsuyah, nicolas.pernas.maradei, Ferruh Yigit,
harish.patil, rasesh.mody, sony.chacko, Bruce Richardson,
huawei.xie, Yuanhan Liu, jianfeng.tan
In-Reply-To: <1478785884-29273-1-git-send-email-david.marchand@6wind.com>
On Thu, Nov 10, 2016 at 2:51 PM, David Marchand
<david.marchand@6wind.com> wrote:
> Since b1fb53a39d88 ("ethdev: remove some PCI specific handling"),
Please fix this checkpatch finding.
> rte_eth_dev_info_get() relies on dev->data->drv_name to report the driver
> name to caller.
>
> Having the pmds set driver_info->driver_name in the pmds is useless,
> since ethdev overwrites it right after.
> The only thing the pmd must do is:
> - for pci drivers, call rte_eth_copy_pci_info() which then sets
> data->drv_name
> - for vdev drivers, manually set data->drv_name
>
> At this stage, virtio-user does not properly report a driver name (fixed in
> next commit).
>
> Signed-off-by: David Marchand <david.marchand@6wind.com>
> ---
> drivers/net/af_packet/rte_eth_af_packet.c | 5 +----
> drivers/net/nfp/nfp_net.c | 1 -
> drivers/net/null/rte_eth_null.c | 4 +---
> drivers/net/pcap/rte_eth_pcap.c | 4 +---
> drivers/net/qede/qede_ethdev.c | 1 -
There is another stale variable drivername in qede_ethdev.c. Might be
the right time to remove it.
Thanks,
Jan
> drivers/net/ring/rte_eth_ring.c | 4 +---
> drivers/net/vhost/rte_eth_vhost.c | 3 ---
> drivers/net/virtio/virtio_ethdev.c | 4 ----
> drivers/net/xenvirt/rte_eth_xenvirt.c | 5 +----
> 9 files changed, 5 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c
> index ff45068..a66a657 100644
> --- a/drivers/net/af_packet/rte_eth_af_packet.c
> +++ b/drivers/net/af_packet/rte_eth_af_packet.c
> @@ -115,8 +115,6 @@ static const char *valid_arguments[] = {
> NULL
> };
>
> -static const char *drivername = "AF_PACKET PMD";
> -
> static struct rte_eth_link pmd_link = {
> .link_speed = ETH_SPEED_NUM_10G,
> .link_duplex = ETH_LINK_FULL_DUPLEX,
> @@ -280,7 +278,6 @@ eth_dev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
> {
> struct pmd_internals *internals = dev->data->dev_private;
>
> - dev_info->driver_name = drivername;
> dev_info->if_index = internals->if_index;
> dev_info->max_mac_addrs = 1;
> dev_info->max_rx_pktlen = (uint32_t)ETH_FRAME_LEN;
> @@ -693,7 +690,7 @@ rte_pmd_init_internals(const char *name,
> (*eth_dev)->dev_ops = &ops;
> (*eth_dev)->driver = NULL;
> (*eth_dev)->data->dev_flags = RTE_ETH_DEV_DETACHABLE;
> - (*eth_dev)->data->drv_name = drivername;
> + (*eth_dev)->data->drv_name = "AF_PACKET PMD";
> (*eth_dev)->data->kdrv = RTE_KDRV_NONE;
> (*eth_dev)->data->numa_node = numa_node;
>
> diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
> index c6b1587..0c342ab 100644
> --- a/drivers/net/nfp/nfp_net.c
> +++ b/drivers/net/nfp/nfp_net.c
> @@ -1006,7 +1006,6 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
>
> hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
>
> - dev_info->driver_name = dev->driver->pci_drv.driver.name;
> dev_info->max_rx_queues = (uint16_t)hw->max_rx_queues;
> dev_info->max_tx_queues = (uint16_t)hw->max_tx_queues;
> dev_info->min_rx_bufsize = ETHER_MIN_MTU;
> diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c
> index 836d982..09d77fd 100644
> --- a/drivers/net/null/rte_eth_null.c
> +++ b/drivers/net/null/rte_eth_null.c
> @@ -88,7 +88,6 @@ struct pmd_internals {
>
>
> static struct ether_addr eth_addr = { .addr_bytes = {0} };
> -static const char *drivername = "Null PMD";
> static struct rte_eth_link pmd_link = {
> .link_speed = ETH_SPEED_NUM_10G,
> .link_duplex = ETH_LINK_FULL_DUPLEX,
> @@ -295,7 +294,6 @@ eth_dev_info(struct rte_eth_dev *dev,
> return;
>
> internals = dev->data->dev_private;
> - dev_info->driver_name = drivername;
> dev_info->max_mac_addrs = 1;
> dev_info->max_rx_pktlen = (uint32_t)-1;
> dev_info->max_rx_queues = RTE_DIM(internals->rx_null_queues);
> @@ -555,7 +553,7 @@ eth_dev_null_create(const char *name,
> eth_dev->driver = NULL;
> data->dev_flags = RTE_ETH_DEV_DETACHABLE;
> data->kdrv = RTE_KDRV_NONE;
> - data->drv_name = drivername;
> + data->drv_name = "Null PMD";
> data->numa_node = numa_node;
>
> /* finally assign rx and tx ops */
> diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
> index 0162f44..8b4fba7 100644
> --- a/drivers/net/pcap/rte_eth_pcap.c
> +++ b/drivers/net/pcap/rte_eth_pcap.c
> @@ -119,7 +119,6 @@ static struct ether_addr eth_addr = {
> .addr_bytes = { 0, 0, 0, 0x1, 0x2, 0x3 }
> };
>
> -static const char *drivername = "Pcap PMD";
> static struct rte_eth_link pmd_link = {
> .link_speed = ETH_SPEED_NUM_10G,
> .link_duplex = ETH_LINK_FULL_DUPLEX,
> @@ -552,7 +551,6 @@ eth_dev_info(struct rte_eth_dev *dev,
> {
> struct pmd_internals *internals = dev->data->dev_private;
>
> - dev_info->driver_name = drivername;
> dev_info->if_index = internals->if_index;
> dev_info->max_mac_addrs = 1;
> dev_info->max_rx_pktlen = (uint32_t) -1;
> @@ -842,7 +840,7 @@ pmd_init_internals(const char *name, const unsigned int nb_rx_queues,
> (*eth_dev)->driver = NULL;
> data->dev_flags = RTE_ETH_DEV_DETACHABLE;
> data->kdrv = RTE_KDRV_NONE;
> - data->drv_name = drivername;
> + data->drv_name = "Pcap PMD";
> data->numa_node = numa_node;
>
> return 0;
> diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
> index 59129f2..a56ba90 100644
> --- a/drivers/net/qede/qede_ethdev.c
> +++ b/drivers/net/qede/qede_ethdev.c
> @@ -662,7 +662,6 @@ qede_dev_info_get(struct rte_eth_dev *eth_dev,
> dev_info->max_vfs = 0;
> else
> dev_info->max_vfs = (uint16_t)NUM_OF_VFS(&qdev->edev);
> - dev_info->driver_name = qdev->drv_ver;
> dev_info->reta_size = ECORE_RSS_IND_TABLE_SIZE;
> dev_info->flow_type_rss_offloads = (uint64_t)QEDE_RSS_OFFLOAD_ALL;
>
> diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c
> index c1767c4..56afaf2 100644
> --- a/drivers/net/ring/rte_eth_ring.c
> +++ b/drivers/net/ring/rte_eth_ring.c
> @@ -75,7 +75,6 @@ struct pmd_internals {
> };
>
>
> -static const char *drivername = "Rings PMD";
> static struct rte_eth_link pmd_link = {
> .link_speed = ETH_SPEED_NUM_10G,
> .link_duplex = ETH_LINK_FULL_DUPLEX,
> @@ -173,7 +172,6 @@ eth_dev_info(struct rte_eth_dev *dev,
> struct rte_eth_dev_info *dev_info)
> {
> struct pmd_internals *internals = dev->data->dev_private;
> - dev_info->driver_name = drivername;
> dev_info->max_mac_addrs = 1;
> dev_info->max_rx_pktlen = (uint32_t)-1;
> dev_info->max_rx_queues = (uint16_t)internals->max_rx_queues;
> @@ -343,7 +341,7 @@ do_eth_dev_ring_create(const char *name,
> eth_dev->dev_ops = &ops;
> data->dev_flags = RTE_ETH_DEV_DETACHABLE;
> data->kdrv = RTE_KDRV_NONE;
> - data->drv_name = drivername;
> + data->drv_name = "Rings PMD";
> data->numa_node = numa_node;
>
> TAILQ_INIT(&(eth_dev->link_intr_cbs));
> diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
> index 766d4ef..96bf391 100644
> --- a/drivers/net/vhost/rte_eth_vhost.c
> +++ b/drivers/net/vhost/rte_eth_vhost.c
> @@ -53,8 +53,6 @@
> #define ETH_VHOST_CLIENT_ARG "client"
> #define ETH_VHOST_DEQUEUE_ZERO_COPY "dequeue-zero-copy"
>
> -static const char *drivername = "VHOST PMD";
> -
> static const char *valid_arguments[] = {
> ETH_VHOST_IFACE_ARG,
> ETH_VHOST_QUEUES_ARG,
> @@ -861,7 +859,6 @@ eth_dev_info(struct rte_eth_dev *dev,
> return;
> }
>
> - dev_info->driver_name = drivername;
> dev_info->max_mac_addrs = 1;
> dev_info->max_rx_pktlen = (uint32_t)-1;
> dev_info->max_rx_queues = internal->max_queues;
> diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
> index 079fd6c..741688e 100644
> --- a/drivers/net/virtio/virtio_ethdev.c
> +++ b/drivers/net/virtio/virtio_ethdev.c
> @@ -1624,10 +1624,6 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
> uint64_t tso_mask;
> struct virtio_hw *hw = dev->data->dev_private;
>
> - if (dev->pci_dev)
> - dev_info->driver_name = dev->driver->pci_drv.driver.name;
> - else
> - dev_info->driver_name = "virtio_user PMD";
> dev_info->max_rx_queues =
> RTE_MIN(hw->max_queue_pairs, VIRTIO_MAX_RX_QUEUES);
> dev_info->max_tx_queues =
> diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
> index c08a056..f74d72c 100644
> --- a/drivers/net/xenvirt/rte_eth_xenvirt.c
> +++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
> @@ -70,8 +70,6 @@
> /* virtio_idx is increased after new device is created.*/
> static int virtio_idx = 0;
>
> -static const char *drivername = "xen virtio PMD";
> -
> static struct rte_eth_link pmd_link = {
> .link_speed = ETH_SPEED_NUM_10G,
> .link_duplex = ETH_LINK_FULL_DUPLEX,
> @@ -331,7 +329,6 @@ eth_dev_info(struct rte_eth_dev *dev,
> struct pmd_internals *internals = dev->data->dev_private;
>
> RTE_SET_USED(internals);
> - dev_info->driver_name = drivername;
> dev_info->max_mac_addrs = 1;
> dev_info->max_rx_pktlen = (uint32_t)2048;
> dev_info->max_rx_queues = (uint16_t)1;
> @@ -675,7 +672,7 @@ eth_dev_xenvirt_create(const char *name, const char *params,
>
> eth_dev->data->dev_flags = RTE_PCI_DRV_DETACHABLE;
> eth_dev->data->kdrv = RTE_KDRV_NONE;
> - eth_dev->data->drv_name = drivername;
> + eth_dev->data->drv_name = "xen virtio PMD";
> eth_dev->driver = NULL;
> eth_dev->data->numa_node = numa_node;
>
> --
> 2.7.4
>
^ permalink raw reply
* Re: Adding API to force freeing consumed buffers in TX ring
From: Bruce Richardson @ 2016-11-21 15:25 UTC (permalink / raw)
To: Olivier Matz; +Cc: Wiles, Keith, Damjan Marion (damarion), dev@dpdk.org
In-Reply-To: <aae1d111-4be0-4d5a-d436-6795cf18155e@6wind.com>
On Mon, Nov 21, 2016 at 04:06:32PM +0100, Olivier Matz wrote:
> Hi,
>
> On 11/21/2016 03:33 PM, Wiles, Keith wrote:
> >
> >> On Nov 21, 2016, at 4:48 AM, Damjan Marion (damarion) <damarion@cisco.com> wrote:
> >>
> >>
> >> Hi,
> >>
> >> Currently in VPP we do memcpy of whole packet when we need to do
> >> replication as we cannot know if specific buffer is transmitted
> >> from tx ring before we update it again (i.e. l2 header rewrite).
> >>
> >> Unless there is already a way to address this issue in DPDK which I’m not aware
> >> of my proposal is that we provide mechanism for polling TX ring
> >> for consumed buffers. This can be either completely new API or
> >> extension of rte_etx_tx_burst (i.e. special case when nb_pkts=0).
> >>
> >> This will allows us to start polling tx ring when we expect some
> >> mbuf back, instead of waiting for next tx burst (which we don’t know
> >> when it will happen) and hoping that we will reach free_threshold soon.
> >
> > +1
> >
> > In Pktgen I have the problem of not being able to reclaim all of the TX mbufs to update them for the next set of packets to send. I know this is not a common case, but I do see the case where the application needs its mbufs freed off the TX ring. Currently you need to have at least a TX ring size of mbufs on hand to make sure you can send to a TX ring. If you allocate too few you run into a deadlock case as the number of mbufs on a TX ring does not hit the flush mark. If you are sending to multiple TX rings on the same numa node from the a single TX pool you have to understand the total number of mbufs you need to have allocated to hit the TX flush on each ring. Not a clean way to handle the problems as you may have limited memory or require some logic to add more mbufs for dynamic po
rts.
> >
> > Anyway it would be great to require a way to clean up the TX done ring, using nb_pkts == 0 is the simplest way, but a new API is fine too.
> >>
> >> Any thoughts?
>
> Yes, it looks useful to have a such API.
>
> I would prefer another function instead of diverting the meaning of
> nb_pkts. Maybe this?
>
> void rte_eth_tx_free_bufs(uint8_t port_id, uint16_t queue_id);
>
Third parameter for a limit(hint) of the number of bufs to free? If the
TX ring is big, we might not want to stall other work for a long time
while we free a huge number of buffers.
/Bruce
^ permalink raw reply
* Re: Solarflare PMD submission question
From: Andrew Rybchenko @ 2016-11-21 15:03 UTC (permalink / raw)
To: Ferruh Yigit, Thomas Monjalon; +Cc: dev
In-Reply-To: <f0a999ba-6170-816a-7a5f-1763bc1179e8@intel.com>
On 11/21/2016 01:30 PM, Ferruh Yigit wrote:
> On 11/21/2016 8:59 AM, Thomas Monjalon wrote:
>> 2016-11-21 11:46, Andrew Rybchenko:
>>> On 11/21/2016 11:19 AM, Thomas Monjalon wrote:
>>>>> Before submitting 56 patches I'd like to double-check that checkpatch.pl
>>>>> errors (for example, because of assignments in the 'if' condition,
>>>>> parenthesis around return value) is not a show-stopper for base driver
>>>>> import.
>>>> You can run checkpatches.sh or send the patches to checkpatch@dpdk.org.
>>>> The script check-git-log.sh can also guide you for the expected formatting.
>>> Yes, I did it and it helped me to find and fix some coding standard
>>> violations.
>>>
>>> The problem with libefx (base driver) is that it is existing code which
>>> follows FreeBSD and illumos coding conventions which contradict to
>>> checkpatches.sh sometimes (e.g. require parenthesis around return
>>> value). Other example of error produced by checkpatches.sh is assign in
>>> if. It is widely used in the code to assign return code value and
>>> compare it vs 0 in one line. It is not a coding standard conflict, but
>>> it is very wide-spread in the code (so changing it will produce too many
>>> changes not strictly required/useful).
>>>
>>> So, may I repeat my question if it is a show-stopper for base driver or
>>> acceptable.
>> I would vote to accept these minor style warnings for the base driver.
>> Ferruh, any comment?
>>
> For _base driver_, I am also OK for having checkpatch warnings.
In term of checkpatshes.sh return value in parenthesis is an error (not
warning). Hopefully it changes nothing.
Andrew.
^ permalink raw reply
* Re: Adding API to force freeing consumed buffers in TX ring
From: Olivier Matz @ 2016-11-21 15:06 UTC (permalink / raw)
To: Wiles, Keith, Damjan Marion (damarion); +Cc: dev@dpdk.org
In-Reply-To: <27853C4C-2482-49E0-8F60-178473276CF5@intel.com>
Hi,
On 11/21/2016 03:33 PM, Wiles, Keith wrote:
>
>> On Nov 21, 2016, at 4:48 AM, Damjan Marion (damarion) <damarion@cisco.com> wrote:
>>
>>
>> Hi,
>>
>> Currently in VPP we do memcpy of whole packet when we need to do
>> replication as we cannot know if specific buffer is transmitted
>> from tx ring before we update it again (i.e. l2 header rewrite).
>>
>> Unless there is already a way to address this issue in DPDK which I’m not aware
>> of my proposal is that we provide mechanism for polling TX ring
>> for consumed buffers. This can be either completely new API or
>> extension of rte_etx_tx_burst (i.e. special case when nb_pkts=0).
>>
>> This will allows us to start polling tx ring when we expect some
>> mbuf back, instead of waiting for next tx burst (which we don’t know
>> when it will happen) and hoping that we will reach free_threshold soon.
>
> +1
>
> In Pktgen I have the problem of not being able to reclaim all of the TX mbufs to update them for the next set of packets to send. I know this is not a common case, but I do see the case where the application needs its mbufs freed off the TX ring. Currently you need to have at least a TX ring size of mbufs on hand to make sure you can send to a TX ring. If you allocate too few you run into a deadlock case as the number of mbufs on a TX ring does not hit the flush mark. If you are sending to multiple TX rings on the same numa node from the a single TX pool you have to understand the total number of mbufs you need to have allocated to hit the TX flush on each ring. Not a clean way to handle the problems as you may have limited memory or require some logic to add more mbufs for dynamic port
s.
>
> Anyway it would be great to require a way to clean up the TX done ring, using nb_pkts == 0 is the simplest way, but a new API is fine too.
>>
>> Any thoughts?
Yes, it looks useful to have a such API.
I would prefer another function instead of diverting the meaning of
nb_pkts. Maybe this?
void rte_eth_tx_free_bufs(uint8_t port_id, uint16_t queue_id);
Regards,
Olivier
^ permalink raw reply
* [PATCH 54/56] net/sfc: add callbacks to set up and release Tx queues
From: Andrew Rybchenko @ 2016-11-21 15:01 UTC (permalink / raw)
To: dev; +Cc: Ivan Malov
In-Reply-To: <1479740470-6723-1-git-send-email-arybchenko@solarflare.com>
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
drivers/net/sfc/efx/sfc_ethdev.c | 58 ++++++++++++++
drivers/net/sfc/efx/sfc_ev.h | 2 +
drivers/net/sfc/efx/sfc_tx.c | 167 +++++++++++++++++++++++++++++++++++++++
drivers/net/sfc/efx/sfc_tx.h | 36 +++++++++
4 files changed, 263 insertions(+)
diff --git a/drivers/net/sfc/efx/sfc_ethdev.c b/drivers/net/sfc/efx/sfc_ethdev.c
index 4afd30c..98e5d83 100644
--- a/drivers/net/sfc/efx/sfc_ethdev.c
+++ b/drivers/net/sfc/efx/sfc_ethdev.c
@@ -39,6 +39,7 @@
#include "sfc_kvargs.h"
#include "sfc_ev.h"
#include "sfc_rx.h"
+#include "sfc_tx.h"
static void
@@ -266,6 +267,61 @@ sfc_rx_queue_release(void *queue)
sfc_adapter_unlock(sa);
}
+static int
+sfc_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,
+ uint16_t nb_tx_desc, unsigned int socket_id,
+ const struct rte_eth_txconf *tx_conf)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ int rc;
+
+ sfc_log_init(sa, "TxQ = %u, nb_tx_desc = %u, socket_id = %u",
+ tx_queue_id, nb_tx_desc, socket_id);
+
+ sfc_adapter_lock(sa);
+
+ rc = sfc_tx_qinit(sa, tx_queue_id, nb_tx_desc, socket_id, tx_conf);
+ if (rc != 0)
+ goto fail_tx_qinit;
+
+ dev->data->tx_queues[tx_queue_id] = sa->txq_info[tx_queue_id].txq;
+
+ sfc_adapter_unlock(sa);
+ return 0;
+
+fail_tx_qinit:
+ sfc_adapter_unlock(sa);
+ SFC_ASSERT(rc > 0);
+ return -rc;
+}
+
+static void
+sfc_tx_queue_release(void *queue)
+{
+ struct sfc_txq *txq = queue;
+ unsigned int sw_index;
+ struct sfc_adapter *sa;
+
+ if (txq == NULL)
+ return;
+
+ sw_index = sfc_txq_sw_index(txq);
+
+ SFC_ASSERT(txq->evq != NULL);
+ sa = txq->evq->sa;
+
+ sfc_log_init(sa, "TxQ = %u", sw_index);
+
+ sfc_adapter_lock(sa);
+
+ SFC_ASSERT(sw_index < sa->eth_dev->data->nb_tx_queues);
+ sa->eth_dev->data->tx_queues[sw_index] = NULL;
+
+ sfc_tx_qfini(sa, sw_index);
+
+ sfc_adapter_unlock(sa);
+}
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
@@ -275,6 +331,8 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_infos_get = sfc_dev_infos_get,
.rx_queue_setup = sfc_rx_queue_setup,
.rx_queue_release = sfc_rx_queue_release,
+ .tx_queue_setup = sfc_tx_queue_setup,
+ .tx_queue_release = sfc_tx_queue_release,
};
static int
diff --git a/drivers/net/sfc/efx/sfc_ev.h b/drivers/net/sfc/efx/sfc_ev.h
index d053182..71e51a5 100644
--- a/drivers/net/sfc/efx/sfc_ev.h
+++ b/drivers/net/sfc/efx/sfc_ev.h
@@ -41,6 +41,7 @@ extern "C" {
struct sfc_adapter;
struct sfc_rxq;
+struct sfc_txq;
enum sfc_evq_state {
SFC_EVQ_UNINITIALIZED = 0,
@@ -58,6 +59,7 @@ struct sfc_evq {
boolean_t exception;
efsys_mem_t mem;
struct sfc_rxq *rxq;
+ struct sfc_txq *txq;
/* Not used on datapath */
struct sfc_adapter *sa;
diff --git a/drivers/net/sfc/efx/sfc_tx.c b/drivers/net/sfc/efx/sfc_tx.c
index fecd058..a4ffe9c 100644
--- a/drivers/net/sfc/efx/sfc_tx.c
+++ b/drivers/net/sfc/efx/sfc_tx.c
@@ -33,6 +33,165 @@
#include "sfc_tx.h"
static int
+sfc_tx_qcheck_conf(struct sfc_adapter *sa,
+ const struct rte_eth_txconf *tx_conf)
+{
+ unsigned int flags = tx_conf->txq_flags;
+ int rc = 0;
+
+ if (tx_conf->tx_rs_thresh != 0) {
+ sfc_err(sa, "RS bit in transmit descriptor is not supported");
+ rc = EINVAL;
+ }
+
+ if (tx_conf->tx_free_thresh != 0) {
+ sfc_err(sa,
+ "setting explicit TX free threshold is not supported");
+ rc = EINVAL;
+ }
+
+ if (tx_conf->tx_deferred_start != 0) {
+ sfc_err(sa, "TX queue deferred start is not supported (yet)");
+ rc = EINVAL;
+ }
+
+ if (tx_conf->tx_thresh.pthresh != 0 ||
+ tx_conf->tx_thresh.hthresh != 0 ||
+ tx_conf->tx_thresh.wthresh != 0) {
+ sfc_err(sa,
+ "prefetch/host/writeback thresholds are not supported");
+ rc = EINVAL;
+ }
+
+ if ((flags & ETH_TXQ_FLAGS_NOVLANOFFL) == 0) {
+ sfc_err(sa, "VLAN offload is not supported");
+ rc = EINVAL;
+ }
+
+ if ((flags & ETH_TXQ_FLAGS_NOXSUMSCTP) == 0) {
+ sfc_err(sa, "SCTP offload is not supported");
+ rc = EINVAL;
+ }
+
+ /* We either perform both TCP and UDP offload, or no offload at all */
+ if (((flags & ETH_TXQ_FLAGS_NOXSUMTCP) == 0) !=
+ ((flags & ETH_TXQ_FLAGS_NOXSUMUDP) == 0)) {
+ sfc_err(sa, "TCP and UDP offloads can't be set independently");
+ rc = EINVAL;
+ }
+
+ return rc;
+}
+
+int
+sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
+ uint16_t nb_tx_desc, unsigned int socket_id,
+ const struct rte_eth_txconf *tx_conf)
+{
+ struct sfc_txq_info *txq_info;
+ struct sfc_evq *evq;
+ struct sfc_txq *txq;
+ unsigned int evq_index = sfc_evq_index_by_txq_sw_index(sa, sw_index);
+ int rc = 0;
+
+ sfc_log_init(sa, "TxQ = %u", sw_index);
+
+ rc = sfc_tx_qcheck_conf(sa, tx_conf);
+ if (rc != 0)
+ goto fail_bad_conf;
+
+ SFC_ASSERT(sw_index < sa->txq_count);
+ txq_info = &sa->txq_info[sw_index];
+
+ SFC_ASSERT(nb_tx_desc <= sa->txq_max_entries);
+ txq_info->entries = nb_tx_desc;
+
+ rc = sfc_ev_qinit(sa, evq_index, txq_info->entries, socket_id);
+ if (rc != 0)
+ goto fail_ev_qinit;
+
+ evq = sa->evq_info[evq_index].evq;
+
+ rc = ENOMEM;
+ txq = rte_zmalloc_socket("sfc-txq", sizeof(*txq), 0, socket_id);
+ if (txq == NULL)
+ goto fail_txq_alloc;
+
+ rc = sfc_dma_alloc(sa, "txq", sw_index, EFX_TXQ_SIZE(txq_info->entries),
+ socket_id, &txq->mem);
+ if (rc != 0)
+ goto fail_dma_alloc;
+
+ rc = ENOMEM;
+ txq->pend_desc = rte_calloc_socket("sfc-txq-pend-desc",
+ EFX_TXQ_LIMIT(txq_info->entries),
+ sizeof(efx_desc_t), 0, socket_id);
+ if (txq->pend_desc == NULL)
+ goto fail_pend_desc_alloc;
+
+ rc = ENOMEM;
+ txq->sw_ring = rte_calloc_socket("sfc-txq-desc", txq_info->entries,
+ sizeof(*txq->sw_ring), 0, socket_id);
+ if (txq->sw_ring == NULL)
+ goto fail_desc_alloc;
+
+ txq->state = SFC_TXQ_INITIALIZED;
+ txq->ptr_mask = txq_info->entries - 1;
+ txq->hw_index = sw_index;
+ txq->flags = tx_conf->txq_flags;
+ txq->evq = evq;
+
+ evq->txq = txq;
+
+ txq_info->txq = txq;
+
+ return 0;
+
+fail_desc_alloc:
+ rte_free(txq->pend_desc);
+
+fail_pend_desc_alloc:
+ sfc_dma_free(sa, &txq->mem);
+
+fail_dma_alloc:
+ rte_free(txq);
+
+fail_txq_alloc:
+ sfc_ev_qfini(sa, evq_index);
+
+fail_ev_qinit:
+ txq_info->entries = 0;
+
+fail_bad_conf:
+ sfc_log_init(sa, "failed (TxQ = %u, rc = %d)", sw_index, rc);
+ return rc;
+}
+
+void
+sfc_tx_qfini(struct sfc_adapter *sa, unsigned int sw_index)
+{
+ struct sfc_txq_info *txq_info;
+ struct sfc_txq *txq;
+
+ sfc_log_init(sa, "TxQ = %u", sw_index);
+
+ SFC_ASSERT(sw_index < sa->txq_count);
+ txq_info = &sa->txq_info[sw_index];
+
+ txq = txq_info->txq;
+ SFC_ASSERT(txq != NULL);
+ SFC_ASSERT(txq->state == SFC_TXQ_INITIALIZED);
+
+ txq_info->txq = NULL;
+ txq_info->entries = 0;
+
+ rte_free(txq->sw_ring);
+ rte_free(txq->pend_desc);
+ sfc_dma_free(sa, &txq->mem);
+ rte_free(txq);
+}
+
+static int
sfc_tx_qinit_info(struct sfc_adapter *sa, unsigned int sw_index)
{
struct sfc_txq_info *txq_info = &sa->txq_info[sw_index];
@@ -121,6 +280,14 @@ sfc_tx_init(struct sfc_adapter *sa)
void
sfc_tx_fini(struct sfc_adapter *sa)
{
+ int sw_index;
+
+ sw_index = sa->txq_count;
+ while (--sw_index >= 0) {
+ if (sa->txq_info[sw_index].txq != NULL)
+ sfc_tx_qfini(sa, sw_index);
+ }
+
rte_free(sa->txq_info);
sa->txq_info = NULL;
sa->txq_count = 0;
diff --git a/drivers/net/sfc/efx/sfc_tx.h b/drivers/net/sfc/efx/sfc_tx.h
index b2d4875..3278797 100644
--- a/drivers/net/sfc/efx/sfc_tx.h
+++ b/drivers/net/sfc/efx/sfc_tx.h
@@ -40,13 +40,49 @@ extern "C" {
#endif
struct sfc_adapter;
+struct sfc_evq;
+
+struct sfc_tx_sw_desc {
+ struct rte_mbuf *mbuf;
+};
+
+enum sfc_txq_state_bit {
+ SFC_TXQ_INITIALIZED_BIT = 0,
+#define SFC_TXQ_INITIALIZED (1 << SFC_TXQ_INITIALIZED_BIT)
+};
+
+struct sfc_txq {
+ struct sfc_evq *evq;
+ struct sfc_tx_sw_desc *sw_ring;
+ unsigned int state;
+ unsigned int ptr_mask;
+ efx_desc_t *pend_desc;
+ efx_txq_t *common;
+ efsys_mem_t mem;
+
+ unsigned int hw_index;
+ unsigned int flags;
+};
+
+static inline unsigned int
+sfc_txq_sw_index(const struct sfc_txq *txq)
+{
+ return txq->hw_index;
+}
struct sfc_txq_info {
+ unsigned int entries;
+ struct sfc_txq *txq;
};
int sfc_tx_init(struct sfc_adapter *sa);
void sfc_tx_fini(struct sfc_adapter *sa);
+int sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
+ uint16_t nb_tx_desc, unsigned int socket_id,
+ const struct rte_eth_txconf *tx_conf);
+void sfc_tx_qfini(struct sfc_adapter *sa, unsigned int sw_index);
+
#ifdef __cplusplus
}
#endif
--
2.5.5
^ permalink raw reply related
* [PATCH 30/56] net/sfc: include libefx in build
From: Andrew Rybchenko @ 2016-11-21 15:00 UTC (permalink / raw)
To: dev; +Cc: Artem Andreev
In-Reply-To: <1479740470-6723-1-git-send-email-arybchenko@solarflare.com>
From: Artem Andreev <Artem.Andreev@oktetlabs.ru>
Implement efsys.h for the PMD.
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
Signed-off-by: Artem Andreev <Artem.Andreev@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
drivers/net/sfc/efx/Makefile | 54 +++
drivers/net/sfc/efx/efsys.h | 767 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 821 insertions(+)
create mode 100644 drivers/net/sfc/efx/efsys.h
diff --git a/drivers/net/sfc/efx/Makefile b/drivers/net/sfc/efx/Makefile
index 71f07ca..de95ea8 100644
--- a/drivers/net/sfc/efx/Makefile
+++ b/drivers/net/sfc/efx/Makefile
@@ -33,6 +33,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
#
LIB = librte_pmd_sfc_efx.a
+CFLAGS += -I$(SRCDIR)/base/
+CFLAGS += -I$(SRCDIR)
CFLAGS += -O3
# Enable basic warnings but disable some which are accepted
@@ -60,6 +62,17 @@ CFLAGS += -Wstrict-prototypes
CFLAGS += -Wundef
CFLAGS += -Wwrite-strings
+# Extra CFLAGS for base driver files
+CFLAGS_BASE_DRIVER += -Wno-unused-variable
+CFLAGS_BASE_DRIVER += -Wno-unused-but-set-variable
+
+#
+# List of base driver object files for which
+# special CFLAGS above should be applied
+#
+BASE_DRIVER_OBJS=$(patsubst %.c,%.o,$(notdir $(wildcard $(SRCDIR)/base/*.c)))
+$(foreach obj, $(BASE_DRIVER_OBJS), $(eval CFLAGS+=$(CFLAGS_BASE_DRIVER)))
+
EXPORT_MAP := rte_pmd_sfc_efx_version.map
LIBABIVER := 1
@@ -70,6 +83,47 @@ LIBABIVER := 1
SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_ethdev.c
SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_kvargs.c
+VPATH += $(SRCDIR)/base
+
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_bootcfg.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_crc32.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_ev.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_filter.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_hash.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_intr.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_lic.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_mac.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_mcdi.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_mon.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_nic.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_nvram.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_phy.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_port.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_rx.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_sram.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_tx.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += efx_vpd.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += mcdi_mon.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += siena_mac.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += siena_mcdi.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += siena_nic.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += siena_nvram.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += siena_phy.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += siena_sram.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += siena_vpd.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_ev.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_filter.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_intr.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_mac.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_mcdi.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_nic.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_nvram.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_phy.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_rx.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_tx.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += ef10_vpd.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += hunt_nic.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += medford_nic.c
# this lib depends upon:
DEPDIRS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += lib/librte_eal
diff --git a/drivers/net/sfc/efx/efsys.h b/drivers/net/sfc/efx/efsys.h
new file mode 100644
index 0000000..2eef996
--- /dev/null
+++ b/drivers/net/sfc/efx/efsys.h
@@ -0,0 +1,767 @@
+/*-
+ * Copyright (c) 2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * This software was jointly developed between OKTET Labs (under contract
+ * for Solarflare) and Solarflare Communications, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SFC_COMMON_EFSYS_H
+#define _SFC_COMMON_EFSYS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_spinlock.h>
+#include <rte_byteorder.h>
+#include <rte_debug.h>
+#include <rte_memzone.h>
+#include <rte_memory.h>
+#include <rte_memcpy.h>
+#include <rte_cycles.h>
+#include <rte_prefetch.h>
+#include <rte_common.h>
+#include <rte_malloc.h>
+#include <rte_log.h>
+
+#include "sfc_debug.h"
+
+
+#define EFSYS_HAS_UINT64 1
+#define EFSYS_USE_UINT64 1
+#define EFSYS_HAS_SSE2_M128 1
+
+#if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+#define EFSYS_IS_BIG_ENDIAN 1
+#define EFSYS_IS_LITTLE_ENDIAN 0
+#elif RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+#define EFSYS_IS_BIG_ENDIAN 0
+#define EFSYS_IS_LITTLE_ENDIAN 1
+#else
+#error "Cannot determine system endianness"
+#endif
+#include "efx_types.h"
+
+
+#ifndef _NOTE
+#define _NOTE(s)
+#endif
+
+typedef uint8_t boolean_t;
+
+#ifndef B_FALSE
+#define B_FALSE 0
+#endif
+#ifndef B_TRUE
+#define B_TRUE 1
+#endif
+
+/*
+ * RTE_MAX() and RTE_MIN() cannot be used since braced-group within
+ * expression allowed only inside a function, but MAX() is used as
+ * a number of elements in array.
+ */
+#ifndef MAX
+#define MAX(v1, v2) ((v1) > (v2) ? (v1) : (v2))
+#endif
+#ifndef MIN
+#define MIN(v1, v2) ((v1) < (v2) ? (v1) : (v2))
+#endif
+
+/* There are macros for alignment in DPDK, but we need to make a proper
+ * correspondence here, if we want to re-use them at all
+ */
+#ifndef IS_P2ALIGNED
+#define IS_P2ALIGNED(v, a) ((((uintptr_t)(v)) & ((uintptr_t)(a) - 1)) == 0)
+#endif
+
+#ifndef P2ROUNDUP
+#define P2ROUNDUP(x, align) (-(-(x) & -(align)))
+#endif
+
+#ifndef P2ALIGN
+#define P2ALIGN(_x, _a) ((_x) & -(_a))
+#endif
+
+#ifndef IS2P
+#define ISP2(x) rte_is_power_of_2(x)
+#endif
+
+#define ENOTACTIVE ENOTCONN
+
+static inline void
+prefetch_read_many(const volatile void *addr)
+{
+ rte_prefetch0(addr);
+}
+
+static inline void
+prefetch_read_once(const volatile void *addr)
+{
+ rte_prefetch_non_temporal(addr);
+}
+
+/* Modifiers used for Windows builds */
+#define __in
+#define __in_opt
+#define __in_ecount(_n)
+#define __in_ecount_opt(_n)
+#define __in_bcount(_n)
+#define __in_bcount_opt(_n)
+
+#define __out
+#define __out_opt
+#define __out_ecount(_n)
+#define __out_ecount_opt(_n)
+#define __out_bcount(_n)
+#define __out_bcount_opt(_n)
+
+#define __deref_out
+
+#define __inout
+#define __inout_opt
+#define __inout_ecount(_n)
+#define __inout_ecount_opt(_n)
+#define __inout_bcount(_n)
+#define __inout_bcount_opt(_n)
+#define __inout_bcount_full_opt(_n)
+
+#define __deref_out_bcount_opt(n)
+
+#define __checkReturn
+#define __success(_x)
+
+#define __drv_when(_p, _c)
+
+/* Code inclusion options */
+
+
+#define EFSYS_OPT_NAMES 0
+
+#define EFSYS_OPT_SIENA 0
+#define EFSYS_OPT_HUNTINGTON 1
+#define EFSYS_OPT_MEDFORD 1
+#ifdef RTE_LIBRTE_SFC_EFX_DEBUG
+#define EFSYS_OPT_CHECK_REG 1
+#else
+#define EFSYS_OPT_CHECK_REG 0
+#endif
+
+#define EFSYS_OPT_MCDI 1
+#define EFSYS_OPT_MCDI_LOGGING 0
+#define EFSYS_OPT_MCDI_PROXY_AUTH 0
+
+#define EFSYS_OPT_MAC_STATS 0
+
+#define EFSYS_OPT_LOOPBACK 0
+
+#define EFSYS_OPT_MON_MCDI 0
+#define EFSYS_OPT_MON_STATS 0
+
+#define EFSYS_OPT_PHY_STATS 0
+#define EFSYS_OPT_BIST 0
+#define EFSYS_OPT_PHY_LED_CONTROL 0
+#define EFSYS_OPT_PHY_FLAGS 0
+
+#define EFSYS_OPT_VPD 0
+#define EFSYS_OPT_NVRAM 0
+#define EFSYS_OPT_BOOTCFG 0
+
+#define EFSYS_OPT_DIAG 0
+#define EFSYS_OPT_RX_SCALE 0
+#define EFSYS_OPT_QSTATS 0
+#define EFSYS_OPT_FILTER 1
+#define EFSYS_OPT_RX_SCATTER 0
+
+#define EFSYS_OPT_EV_PREFETCH 0
+
+#define EFSYS_OPT_DECODE_INTR_FATAL 0
+
+#define EFSYS_OPT_LICENSING 0
+
+#define EFSYS_OPT_ALLOW_UNCONFIGURED_NIC 0
+
+#define EFSYS_OPT_RX_PACKED_STREAM 0
+
+/* ID */
+
+typedef struct __efsys_identifier_s efsys_identifier_t;
+
+
+#define EFSYS_PROBE(_name) \
+ do { } while (0)
+
+#define EFSYS_PROBE1(_name, _type1, _arg1) \
+ do { } while (0)
+
+#define EFSYS_PROBE2(_name, _type1, _arg1, _type2, _arg2) \
+ do { } while (0)
+
+#define EFSYS_PROBE3(_name, _type1, _arg1, _type2, _arg2, \
+ _type3, _arg3) \
+ do { } while (0)
+
+#define EFSYS_PROBE4(_name, _type1, _arg1, _type2, _arg2, \
+ _type3, _arg3, _type4, _arg4) \
+ do { } while (0)
+
+#define EFSYS_PROBE5(_name, _type1, _arg1, _type2, _arg2, \
+ _type3, _arg3, _type4, _arg4, _type5, _arg5) \
+ do { } while (0)
+
+#define EFSYS_PROBE6(_name, _type1, _arg1, _type2, _arg2, \
+ _type3, _arg3, _type4, _arg4, _type5, _arg5, \
+ _type6, _arg6) \
+ do { } while (0)
+
+#define EFSYS_PROBE7(_name, _type1, _arg1, _type2, _arg2, \
+ _type3, _arg3, _type4, _arg4, _type5, _arg5, \
+ _type6, _arg6, _type7, _arg7) \
+ do { } while (0)
+
+
+/* DMA */
+
+typedef phys_addr_t efsys_dma_addr_t;
+
+typedef struct efsys_mem_s {
+ const struct rte_memzone *esm_mz;
+ /*
+ * Ideally it should have volatile qualifier to denote that
+ * the memory may be updated by someone else. However, it adds
+ * qualifier discard warnings when the pointer or its derivative
+ * is passed to memset() or rte_mov16().
+ * So, skip the qualifier here, but make sure that it is added
+ * below in access macros.
+ */
+ void *esm_base;
+ efsys_dma_addr_t esm_addr;
+} efsys_mem_t;
+
+
+#define EFSYS_MEM_ZERO(_esmp, _size) \
+ do { \
+ (void)memset((void *)(_esmp)->esm_base, 0, (_size)); \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+#define EFSYS_MEM_READD(_esmp, _offset, _edp) \
+ do { \
+ volatile uint8_t *_base = (_esmp)->esm_base; \
+ volatile uint32_t *_addr; \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_dword_t))); \
+ \
+ _addr = (volatile uint32_t *)(_base + (_offset)); \
+ (_edp)->ed_u32[0] = _addr[0]; \
+ \
+ EFSYS_PROBE2(mem_readl, unsigned int, (_offset), \
+ uint32_t, (_edp)->ed_u32[0]); \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+#define EFSYS_MEM_READQ(_esmp, _offset, _eqp) \
+ do { \
+ volatile uint8_t *_base = (_esmp)->esm_base; \
+ volatile uint64_t *_addr; \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_qword_t))); \
+ \
+ _addr = (volatile uint64_t *)(_base + (_offset)); \
+ (_eqp)->eq_u64[0] = _addr[0]; \
+ \
+ EFSYS_PROBE3(mem_readq, unsigned int, (_offset), \
+ uint32_t, (_eqp)->eq_u32[1], \
+ uint32_t, (_eqp)->eq_u32[0]); \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+#define EFSYS_MEM_READO(_esmp, _offset, _eop) \
+ do { \
+ volatile uint8_t *_base = (_esmp)->esm_base; \
+ volatile __m128i *_addr; \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_oword_t))); \
+ \
+ _addr = (volatile __m128i *)(_base + (_offset)); \
+ (_eop)->eo_u128[0] = _addr[0]; \
+ \
+ EFSYS_PROBE5(mem_reado, unsigned int, (_offset), \
+ uint32_t, (_eop)->eo_u32[3], \
+ uint32_t, (_eop)->eo_u32[2], \
+ uint32_t, (_eop)->eo_u32[1], \
+ uint32_t, (_eop)->eo_u32[0]); \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+
+#define EFSYS_MEM_WRITED(_esmp, _offset, _edp) \
+ do { \
+ volatile uint8_t *_base = (_esmp)->esm_base; \
+ volatile uint32_t *_addr; \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_dword_t))); \
+ \
+ EFSYS_PROBE2(mem_writed, unsigned int, (_offset), \
+ uint32_t, (_edp)->ed_u32[0]); \
+ \
+ _addr = (volatile uint32_t *)(_base + (_offset)); \
+ _addr[0] = (_edp)->ed_u32[0]; \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+#define EFSYS_MEM_WRITEQ(_esmp, _offset, _eqp) \
+ do { \
+ volatile uint8_t *_base = (_esmp)->esm_base; \
+ volatile uint64_t *_addr; \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_qword_t))); \
+ \
+ EFSYS_PROBE3(mem_writeq, unsigned int, (_offset), \
+ uint32_t, (_eqp)->eq_u32[1], \
+ uint32_t, (_eqp)->eq_u32[0]); \
+ \
+ _addr = (volatile uint64_t *)(_base + (_offset)); \
+ _addr[0] = (_eqp)->eq_u64[0]; \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+#define EFSYS_MEM_WRITEO(_esmp, _offset, _eop) \
+ do { \
+ volatile uint8_t *_base = (_esmp)->esm_base; \
+ volatile __m128i *_addr; \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_oword_t))); \
+ \
+ \
+ EFSYS_PROBE5(mem_writeo, unsigned int, (_offset), \
+ uint32_t, (_eop)->eo_u32[3], \
+ uint32_t, (_eop)->eo_u32[2], \
+ uint32_t, (_eop)->eo_u32[1], \
+ uint32_t, (_eop)->eo_u32[0]); \
+ \
+ _addr = (volatile __m128i *)(_base + (_offset)); \
+ _addr[0] = (_eop)->eo_u128[0]; \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+
+#define EFSYS_MEM_ADDR(_esmp) \
+ ((_esmp)->esm_addr)
+
+#define EFSYS_MEM_IS_NULL(_esmp) \
+ ((_esmp)->esm_base == NULL)
+
+#define EFSYS_MEM_PREFETCH(_esmp, _offset) \
+ do { \
+ volatile uint8_t *_base = (_esmp)->esm_base; \
+ \
+ rte_prefetch0(_base + (_offset)); \
+ } while (0)
+
+
+/* BAR */
+
+typedef struct efsys_bar_s {
+ rte_spinlock_t esb_lock;
+ int esb_rid;
+ struct rte_pci_device *esb_dev;
+ /*
+ * Ideally it should have volatile qualifier to denote that
+ * the memory may be updated by someone else. However, it adds
+ * qualifier discard warnings when the pointer or its derivative
+ * is passed to memset() or rte_mov16().
+ * So, skip the qualifier here, but make sure that it is added
+ * below in access macros.
+ */
+ void *esb_base;
+} efsys_bar_t;
+
+#define SFC_BAR_LOCK_INIT(_esbp, _ifname) \
+ do { \
+ rte_spinlock_init(&(_esbp)->esb_lock); \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+#define SFC_BAR_LOCK_DESTROY(_esbp) ((void)0)
+#define SFC_BAR_LOCK(_esbp) rte_spinlock_lock(&(_esbp)->esb_lock)
+#define SFC_BAR_UNLOCK(_esbp) rte_spinlock_unlock(&(_esbp)->esb_lock)
+
+#define EFSYS_BAR_READD(_esbp, _offset, _edp, _lock) \
+ do { \
+ volatile uint8_t *_base = (_esbp)->esb_base; \
+ volatile uint32_t *_addr; \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_dword_t))); \
+ _NOTE(CONSTANTCONDITION); \
+ if (_lock) \
+ SFC_BAR_LOCK(_esbp); \
+ \
+ _addr = (volatile uint32_t *)(_base + (_offset)); \
+ rte_rmb(); \
+ (_edp)->ed_u32[0] = _addr[0]; \
+ \
+ EFSYS_PROBE2(bar_readd, unsigned int, (_offset), \
+ uint32_t, (_edp)->ed_u32[0]); \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ if (_lock) \
+ SFC_BAR_UNLOCK(_esbp); \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+#define EFSYS_BAR_READQ(_esbp, _offset, _eqp) \
+ do { \
+ volatile uint8_t *_base = (_esbp)->esb_base; \
+ volatile uint64_t *_addr; \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_qword_t))); \
+ \
+ SFC_BAR_LOCK(_esbp); \
+ \
+ _addr = (volatile uint64_t *)(_base + (_offset)); \
+ rte_rmb(); \
+ (_eqp)->eq_u64[0] = _addr[0]; \
+ \
+ EFSYS_PROBE3(bar_readq, unsigned int, (_offset), \
+ uint32_t, (_eqp)->eq_u32[1], \
+ uint32_t, (_eqp)->eq_u32[0]); \
+ \
+ SFC_BAR_UNLOCK(_esbp); \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+#define EFSYS_BAR_READO(_esbp, _offset, _eop, _lock) \
+ do { \
+ volatile uint8_t *_base = (_esbp)->esb_base; \
+ volatile __m128i *_addr; \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_oword_t))); \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ if (_lock) \
+ SFC_BAR_LOCK(_esbp); \
+ \
+ _addr = (volatile __m128i *)(_base + (_offset)); \
+ rte_rmb(); \
+ (_eop)->eo_u128[0] = _addr[0]; \
+ \
+ EFSYS_PROBE5(bar_reado, unsigned int, (_offset), \
+ uint32_t, (_eop)->eo_u32[3], \
+ uint32_t, (_eop)->eo_u32[2], \
+ uint32_t, (_eop)->eo_u32[1], \
+ uint32_t, (_eop)->eo_u32[0]); \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ if (_lock) \
+ SFC_BAR_UNLOCK(_esbp); \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+
+#define EFSYS_BAR_WRITED(_esbp, _offset, _edp, _lock) \
+ do { \
+ volatile uint8_t *_base = (_esbp)->esb_base; \
+ volatile uint32_t *_addr; \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_dword_t))); \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ if (_lock) \
+ SFC_BAR_LOCK(_esbp); \
+ \
+ EFSYS_PROBE2(bar_writed, unsigned int, (_offset), \
+ uint32_t, (_edp)->ed_u32[0]); \
+ \
+ _addr = (volatile uint32_t *)(_base + (_offset)); \
+ _addr[0] = (_edp)->ed_u32[0]; \
+ rte_wmb(); \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ if (_lock) \
+ SFC_BAR_UNLOCK(_esbp); \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+#define EFSYS_BAR_WRITEQ(_esbp, _offset, _eqp) \
+ do { \
+ volatile uint8_t *_base = (_esbp)->esb_base; \
+ volatile uint64_t *_addr; \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_qword_t))); \
+ \
+ SFC_BAR_LOCK(_esbp); \
+ \
+ EFSYS_PROBE3(bar_writeq, unsigned int, (_offset), \
+ uint32_t, (_eqp)->eq_u32[1], \
+ uint32_t, (_eqp)->eq_u32[0]); \
+ \
+ _addr = (volatile uint64_t *)(_base + (_offset)); \
+ _addr[0] = (_eqp)->eq_u64[0]; \
+ rte_wmb(); \
+ \
+ SFC_BAR_UNLOCK(_esbp); \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+/*
+ * Guarantees 64bit aligned 64bit writes to write combined BAR mapping
+ * (required by PIO hardware).
+ *
+ * Neither VFIO, nor UIO, nor NIC UIO (on FreeBSD) support
+ * write-combined memory mapped to user-land, so just abort if used.
+ */
+#define EFSYS_BAR_WC_WRITEQ(_esbp, _offset, _eqp) \
+ do { \
+ rte_panic("Write-combined BAR access not supported"); \
+ } while (B_FALSE)
+
+#define EFSYS_BAR_WRITEO(_esbp, _offset, _eop, _lock) \
+ do { \
+ volatile uint8_t *_base = (_esbp)->esb_base; \
+ volatile __m128i *_addr; \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ SFC_ASSERT(IS_P2ALIGNED(_offset, sizeof(efx_oword_t))); \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ if (_lock) \
+ SFC_BAR_LOCK(_esbp); \
+ \
+ EFSYS_PROBE5(bar_writeo, unsigned int, (_offset), \
+ uint32_t, (_eop)->eo_u32[3], \
+ uint32_t, (_eop)->eo_u32[2], \
+ uint32_t, (_eop)->eo_u32[1], \
+ uint32_t, (_eop)->eo_u32[0]); \
+ \
+ _addr = (volatile __m128i *)(_base + (_offset)); \
+ _addr[0] = (_eop)->eo_u128[0]; \
+ rte_wmb(); \
+ \
+ _NOTE(CONSTANTCONDITION); \
+ if (_lock) \
+ SFC_BAR_UNLOCK(_esbp); \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+/* Use the standard octo-word write for doorbell writes */
+#define EFSYS_BAR_DOORBELL_WRITEO(_esbp, _offset, _eop) \
+ do { \
+ EFSYS_BAR_WRITEO((_esbp), (_offset), (_eop), B_FALSE); \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+/* SPIN */
+
+#define EFSYS_SPIN(_us) \
+ do { \
+ rte_delay_us(_us); \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+#define EFSYS_SLEEP EFSYS_SPIN
+
+/* BARRIERS */
+
+#define EFSYS_MEM_READ_BARRIER() rte_rmb()
+#define EFSYS_PIO_WRITE_BARRIER() rte_wmb()
+
+/* DMA SYNC */
+
+/*
+ * DPDK does not provide any DMA syncing API, and no PMD drivers
+ * have any traces of explicit DMA syncing.
+ * DMA mapping is assumed to be coherent.
+ */
+
+#define EFSYS_DMA_SYNC_FOR_KERNEL(_esmp, _offset, _size) ((void)0)
+#define EFSYS_DMA_SYNC_FOR_DEVICE(_esmp, _offset, _size) ((void)0)
+
+/* TIMESTAMP */
+
+typedef uint64_t efsys_timestamp_t;
+
+#define EFSYS_TIMESTAMP(_usp) \
+ do { \
+ *(_usp) = rte_get_timer_cycles() * 1000000 / \
+ rte_get_timer_hz(); \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+/* KMEM */
+
+#define EFSYS_KMEM_ALLOC(_esip, _size, _p) \
+ do { \
+ (_esip) = (_esip); \
+ (_p) = rte_zmalloc("sfc", (_size), 0); \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+#define EFSYS_KMEM_FREE(_esip, _size, _p) \
+ do { \
+ (void)(_esip); \
+ (void)(_size); \
+ rte_free((_p)); \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+/* LOCK */
+
+typedef rte_spinlock_t efsys_lock_t;
+
+#define SFC_EFSYS_LOCK_INIT(_eslp, _ifname, _label) \
+ rte_spinlock_init((_eslp))
+#define SFC_EFSYS_LOCK_DESTROY(_eslp) ((void)0)
+#define SFC_EFSYS_LOCK(_eslp) \
+ rte_spinlock_lock((_eslp))
+#define SFC_EFSYS_UNLOCK(_eslp) \
+ rte_spinlock_unlock((_eslp))
+#define SFC_EFSYS_LOCK_ASSERT_OWNED(_eslp) \
+ SFC_ASSERT(rte_spinlock_is_locked((_eslp)))
+
+typedef int efsys_lock_state_t;
+
+#define EFSYS_LOCK_MAGIC 0x000010c4
+
+#define EFSYS_LOCK(_lockp, _state) \
+ do { \
+ SFC_EFSYS_LOCK(_lockp); \
+ (_state) = EFSYS_LOCK_MAGIC; \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+#define EFSYS_UNLOCK(_lockp, _state) \
+ do { \
+ SFC_ASSERT((_state) == EFSYS_LOCK_MAGIC); \
+ SFC_EFSYS_UNLOCK(_lockp); \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+/* STAT */
+
+typedef uint64_t efsys_stat_t;
+
+#define EFSYS_STAT_INCR(_knp, _delta) \
+ do { \
+ *(_knp) += (_delta); \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+#define EFSYS_STAT_DECR(_knp, _delta) \
+ do { \
+ *(_knp) -= (_delta); \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+#define EFSYS_STAT_SET(_knp, _val) \
+ do { \
+ *(_knp) = (_val); \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+#define EFSYS_STAT_SET_QWORD(_knp, _valp) \
+ do { \
+ *(_knp) = rte_le_to_cpu_64((_valp)->eq_u64[0]); \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+#define EFSYS_STAT_SET_DWORD(_knp, _valp) \
+ do { \
+ *(_knp) = rte_le_to_cpu_32((_valp)->ed_u32[0]); \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+#define EFSYS_STAT_INCR_QWORD(_knp, _valp) \
+ do { \
+ *(_knp) += rte_le_to_cpu_64((_valp)->eq_u64[0]); \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+#define EFSYS_STAT_SUBR_QWORD(_knp, _valp) \
+ do { \
+ *(_knp) -= rte_le_to_cpu_64((_valp)->eq_u64[0]); \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+
+/* ERR */
+
+#if EFSYS_OPT_DECODE_INTR_FATAL
+#define EFSYS_ERR(_esip, _code, _dword0, _dword1) \
+ do { \
+ (void)(_esip); \
+ RTE_LOG(ERR, PMD, "FATAL ERROR #%u (0x%08x%08x)\n", \
+ (_code), (_dword0), (_dword1)); \
+ _NOTE(CONSTANTCONDITION); \
+ } while (B_FALSE)
+#endif
+
+/* ASSERT */
+
+/* RTE_VERIFY from DPDK treats expressions with % operator incorrectly,
+ * so we re-implement it here
+ */
+#ifdef RTE_LIBRTE_SFC_EFX_DEBUG
+#define EFSYS_ASSERT(_exp) \
+ do { \
+ if (unlikely(!(_exp))) \
+ rte_panic("line %d\tassert \"%s\" failed\n", \
+ __LINE__, (#_exp)); \
+ } while (0)
+#else
+#define EFSYS_ASSERT(_exp) (void)(_exp)
+#endif
+
+#define EFSYS_ASSERT3(_x, _op, _y, _t) EFSYS_ASSERT((_t)(_x) _op (_t)(_y))
+
+#define EFSYS_ASSERT3U(_x, _op, _y) EFSYS_ASSERT3(_x, _op, _y, uint64_t)
+#define EFSYS_ASSERT3S(_x, _op, _y) EFSYS_ASSERT3(_x, _op, _y, int64_t)
+#define EFSYS_ASSERT3P(_x, _op, _y) EFSYS_ASSERT3(_x, _op, _y, uintptr_t)
+
+/* ROTATE */
+
+#define EFSYS_HAS_ROTL_DWORD 0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SFC_COMMON_EFSYS_H */
--
2.5.5
^ permalink raw reply related
* [PATCH 52/56] net/sfc: provide basic stubs for Tx subsystem
From: Andrew Rybchenko @ 2016-11-21 15:01 UTC (permalink / raw)
To: dev; +Cc: Ivan Malov
In-Reply-To: <1479740470-6723-1-git-send-email-arybchenko@solarflare.com>
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 2 +
doc/guides/nics/sfc_efx.rst | 2 +
drivers/net/sfc/efx/Makefile | 1 +
drivers/net/sfc/efx/sfc.c | 14 ++++++
drivers/net/sfc/efx/sfc.h | 6 +++
drivers/net/sfc/efx/sfc_ethdev.c | 17 ++++++++
drivers/net/sfc/efx/sfc_tx.c | 85 ++++++++++++++++++++++++++++++++++++
drivers/net/sfc/efx/sfc_tx.h | 53 ++++++++++++++++++++++
8 files changed, 180 insertions(+)
create mode 100644 drivers/net/sfc/efx/sfc_tx.c
create mode 100644 drivers/net/sfc/efx/sfc_tx.h
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 7dc2e92..67df1c6 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -5,6 +5,8 @@
;
[Features]
Link status = Y
+L3 checksum offload = P
+L4 checksum offload = P
BSD nic_uio = Y
Linux UIO = Y
Linux VFIO = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 8145a6b..aadd775 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -46,6 +46,8 @@ SFC EFX PMD has support for:
- Link state information
+- IPv4/IPv6 TCP/UDP transmit checksum offload
+
Non-supported Features
----------------------
diff --git a/drivers/net/sfc/efx/Makefile b/drivers/net/sfc/efx/Makefile
index eb82c89..8ecca83 100644
--- a/drivers/net/sfc/efx/Makefile
+++ b/drivers/net/sfc/efx/Makefile
@@ -88,6 +88,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_intr.c
SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_ev.c
SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_port.c
SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_rx.c
+SRCS-$(CONFIG_RTE_LIBRTE_SFC_EFX_PMD) += sfc_tx.c
VPATH += $(SRCDIR)/base
diff --git a/drivers/net/sfc/efx/sfc.c b/drivers/net/sfc/efx/sfc.c
index 1c0f59d..6990ccd 100644
--- a/drivers/net/sfc/efx/sfc.c
+++ b/drivers/net/sfc/efx/sfc.c
@@ -38,6 +38,7 @@
#include "sfc_log.h"
#include "sfc_ev.h"
#include "sfc_rx.h"
+#include "sfc_tx.h"
int
@@ -362,10 +363,17 @@ sfc_configure(struct sfc_adapter *sa)
if (rc != 0)
goto fail_rx_init;
+ rc = sfc_tx_init(sa);
+ if (rc != 0)
+ goto fail_tx_init;
+
sa->state = SFC_ADAPTER_CONFIGURED;
sfc_log_init(sa, "done");
return 0;
+fail_tx_init:
+ sfc_rx_fini(sa);
+
fail_rx_init:
sfc_port_fini(sa);
@@ -392,6 +400,7 @@ sfc_close(struct sfc_adapter *sa)
SFC_ASSERT(sa->state == SFC_ADAPTER_CONFIGURED);
sa->state = SFC_ADAPTER_CLOSING;
+ sfc_tx_fini(sa);
sfc_rx_fini(sa);
sfc_port_fini(sa);
sfc_ev_fini(sa);
@@ -438,6 +447,7 @@ int
sfc_attach(struct sfc_adapter *sa)
{
struct rte_pci_device *pci_dev = sa->eth_dev->pci_dev;
+ const efx_nic_cfg_t *encp;
efx_nic_t *enp;
int rc;
@@ -488,6 +498,10 @@ sfc_attach(struct sfc_adapter *sa)
if (rc != 0)
goto fail_estimate_rsrc_limits;
+ encp = efx_nic_cfg_get(sa->nic);
+ sa->txq_max_entries = encp->enc_txq_max_ndescs;
+ SFC_ASSERT(rte_is_power_of_2(sa->txq_max_entries));
+
rc = sfc_intr_attach(sa);
if (rc != 0)
goto fail_intr_attach;
diff --git a/drivers/net/sfc/efx/sfc.h b/drivers/net/sfc/efx/sfc.h
index a592b53..de0395e 100644
--- a/drivers/net/sfc/efx/sfc.h
+++ b/drivers/net/sfc/efx/sfc.h
@@ -115,6 +115,7 @@ struct sfc_intr {
struct sfc_evq_info;
struct sfc_rxq_info;
+struct sfc_txq_info;
struct sfc_port {
unsigned int flow_ctrl;
@@ -148,6 +149,8 @@ struct sfc_adapter {
unsigned int rxq_max;
unsigned int txq_max;
+ unsigned int txq_max_entries;
+
unsigned int evq_count;
struct sfc_evq_info *evq_info;
@@ -156,6 +159,9 @@ struct sfc_adapter {
unsigned int rxq_count;
struct sfc_rxq_info *rxq_info;
+
+ unsigned int txq_count;
+ struct sfc_txq_info *txq_info;
};
/*
diff --git a/drivers/net/sfc/efx/sfc_ethdev.c b/drivers/net/sfc/efx/sfc_ethdev.c
index 61ae1bd..4afd30c 100644
--- a/drivers/net/sfc/efx/sfc_ethdev.c
+++ b/drivers/net/sfc/efx/sfc_ethdev.c
@@ -51,16 +51,33 @@ sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
dev_info->max_rx_pktlen = EFX_MAC_PDU_MAX;
dev_info->max_rx_queues = sa->rxq_max;
+ dev_info->max_tx_queues = sa->txq_max;
/* By default packets are dropped if no descriptors are available */
dev_info->default_rxconf.rx_drop_en = 1;
+ dev_info->tx_offload_capa =
+ DEV_TX_OFFLOAD_IPV4_CKSUM |
+ DEV_TX_OFFLOAD_UDP_CKSUM |
+ DEV_TX_OFFLOAD_TCP_CKSUM;
+
+ dev_info->default_txconf.txq_flags = ETH_TXQ_FLAGS_NOVLANOFFL |
+ ETH_TXQ_FLAGS_NOXSUMSCTP;
+
dev_info->rx_desc_lim.nb_max = EFX_RXQ_MAXNDESCS;
dev_info->rx_desc_lim.nb_min = EFX_RXQ_MINNDESCS;
/* The RXQ hardware requires that the descriptor count is a power
* of 2, but rx_desc_lim cannot properly describe that constraint.
*/
dev_info->rx_desc_lim.nb_align = EFX_RXQ_MINNDESCS;
+
+ dev_info->tx_desc_lim.nb_max = sa->txq_max_entries;
+ dev_info->tx_desc_lim.nb_min = EFX_TXQ_MINNDESCS;
+ /*
+ * The TXQ hardware requires that the descriptor count is a power
+ * of 2, but tx_desc_lim cannot properly describe that constraint
+ */
+ dev_info->tx_desc_lim.nb_align = EFX_TXQ_MINNDESCS;
}
static int
diff --git a/drivers/net/sfc/efx/sfc_tx.c b/drivers/net/sfc/efx/sfc_tx.c
new file mode 100644
index 0000000..c418185
--- /dev/null
+++ b/drivers/net/sfc/efx/sfc_tx.c
@@ -0,0 +1,85 @@
+/*-
+ * Copyright (c) 2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * This software was jointly developed between OKTET Labs (under contract
+ * for Solarflare) and Solarflare Communications, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "sfc.h"
+#include "sfc_log.h"
+#include "sfc_ev.h"
+#include "sfc_tx.h"
+
+static int
+sfc_tx_qinit_info(struct sfc_adapter *sa, unsigned int sw_index)
+{
+ struct sfc_txq_info *txq_info = &sa->txq_info[sw_index];
+ int rc = 0;
+
+ sfc_log_init(sa, "TxQ = %u", sw_index);
+
+ return 0;
+}
+
+int
+sfc_tx_init(struct sfc_adapter *sa)
+{
+ int sw_index;
+ int rc = 0;
+
+ sa->txq_count = sa->eth_dev->data->nb_tx_queues;
+
+ sa->txq_info = rte_calloc_socket("sfc-txqs", sa->txq_count,
+ sizeof(sa->txq_info[0]), 0,
+ sa->socket_id);
+ if (sa->txq_info == NULL)
+ goto fail_txqs_alloc;
+
+ for (sw_index = 0; sw_index < sa->txq_count; ++sw_index) {
+ rc = sfc_tx_qinit_info(sa, sw_index);
+ if (rc != 0)
+ goto fail_tx_qinit_info;
+ }
+
+ return 0;
+
+fail_tx_qinit_info:
+ rte_free(sa->txq_info);
+ sa->txq_info = NULL;
+
+fail_txqs_alloc:
+ sa->txq_count = 0;
+
+ sfc_log_init(sa, "failed (rc = %d)", rc);
+ return rc;
+}
+
+void
+sfc_tx_fini(struct sfc_adapter *sa)
+{
+ rte_free(sa->txq_info);
+ sa->txq_info = NULL;
+ sa->txq_count = 0;
+}
diff --git a/drivers/net/sfc/efx/sfc_tx.h b/drivers/net/sfc/efx/sfc_tx.h
new file mode 100644
index 0000000..b2d4875
--- /dev/null
+++ b/drivers/net/sfc/efx/sfc_tx.h
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * This software was jointly developed between OKTET Labs (under contract
+ * for Solarflare) and Solarflare Communications, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SFC_TX_H
+#define _SFC_TX_H
+
+#include <rte_mbuf.h>
+#include <rte_ethdev.h>
+
+#include "efx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct sfc_adapter;
+
+struct sfc_txq_info {
+};
+
+int sfc_tx_init(struct sfc_adapter *sa);
+void sfc_tx_fini(struct sfc_adapter *sa);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _SFC_TX_H */
--
2.5.5
^ permalink raw reply related
* [PATCH 55/56] net/sfc: implement transmit path start / stop
From: Andrew Rybchenko @ 2016-11-21 15:01 UTC (permalink / raw)
To: dev; +Cc: Ivan Malov
In-Reply-To: <1479740470-6723-1-git-send-email-arybchenko@solarflare.com>
From: Ivan Malov <ivan.malov@oktetlabs.ru>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
drivers/net/sfc/efx/sfc.c | 8 ++
drivers/net/sfc/efx/sfc_ev.c | 12 ++-
drivers/net/sfc/efx/sfc_tx.c | 237 +++++++++++++++++++++++++++++++++++++++++++
drivers/net/sfc/efx/sfc_tx.h | 17 ++++
4 files changed, 271 insertions(+), 3 deletions(-)
diff --git a/drivers/net/sfc/efx/sfc.c b/drivers/net/sfc/efx/sfc.c
index 6990ccd..ef9e0d4 100644
--- a/drivers/net/sfc/efx/sfc.c
+++ b/drivers/net/sfc/efx/sfc.c
@@ -276,10 +276,17 @@ sfc_start(struct sfc_adapter *sa)
if (rc != 0)
goto fail_rx_start;
+ rc = sfc_tx_start(sa);
+ if (rc != 0)
+ goto fail_tx_start;
+
sa->state = SFC_ADAPTER_STARTED;
sfc_log_init(sa, "done");
return 0;
+fail_tx_start:
+ sfc_rx_stop(sa);
+
fail_rx_start:
sfc_port_stop(sa);
@@ -321,6 +328,7 @@ sfc_stop(struct sfc_adapter *sa)
sa->state = SFC_ADAPTER_STOPPING;
+ sfc_tx_stop(sa);
sfc_rx_stop(sa);
sfc_port_stop(sa);
sfc_ev_stop(sa);
diff --git a/drivers/net/sfc/efx/sfc_ev.c b/drivers/net/sfc/efx/sfc_ev.c
index 8f260e7..b3cecbb 100644
--- a/drivers/net/sfc/efx/sfc_ev.c
+++ b/drivers/net/sfc/efx/sfc_ev.c
@@ -38,6 +38,7 @@
#include "sfc_log.h"
#include "sfc_ev.h"
#include "sfc_rx.h"
+#include "sfc_tx.h"
/* Initial delay when waiting for event queue init complete event */
@@ -206,10 +207,15 @@ static boolean_t
sfc_ev_txq_flush_done(void *arg, uint32_t txq_hw_index)
{
struct sfc_evq *evq = arg;
+ struct sfc_txq *txq;
- sfc_err(evq->sa, "EVQ %u unexpected Tx flush done event",
- evq->evq_index);
- return B_TRUE;
+ txq = evq->txq;
+ SFC_ASSERT(txq != NULL);
+ SFC_ASSERT(txq->hw_index == txq_hw_index);
+ SFC_ASSERT(txq->evq == evq);
+ sfc_tx_qflush_done(txq);
+
+ return B_FALSE;
}
static boolean_t
diff --git a/drivers/net/sfc/efx/sfc_tx.c b/drivers/net/sfc/efx/sfc_tx.c
index a4ffe9c..99d845a 100644
--- a/drivers/net/sfc/efx/sfc_tx.c
+++ b/drivers/net/sfc/efx/sfc_tx.c
@@ -28,10 +28,30 @@
*/
#include "sfc.h"
+#include "sfc_debug.h"
#include "sfc_log.h"
#include "sfc_ev.h"
#include "sfc_tx.h"
+/*
+ * Maximum number of TX queue flush attempts in case of
+ * failure or flush timeout
+ */
+#define SFC_TX_QFLUSH_ATTEMPTS (3)
+
+/*
+ * Time to wait between event queue polling attempts when waiting for TX
+ * queue flush done or flush failed events
+ */
+#define SFC_TX_QFLUSH_POLL_WAIT_MS (1)
+
+/*
+ * Maximum number of event queue polling attempts when wating for TX queue
+ * flush done or flush failed events; it defines TX queue flush attempt timeout
+ * together with SFC_TX_QFLUSH_POLL_WAIT_MS
+ */
+#define SFC_TX_QFLUSH_POLL_ATTEMPTS (2000)
+
static int
sfc_tx_qcheck_conf(struct sfc_adapter *sa,
const struct rte_eth_txconf *tx_conf)
@@ -83,6 +103,36 @@ sfc_tx_qcheck_conf(struct sfc_adapter *sa,
return rc;
}
+void
+sfc_tx_qflush_done(struct sfc_txq *txq)
+{
+ txq->state |= SFC_TXQ_FLUSHED;
+ txq->state &= ~SFC_TXQ_FLUSHING;
+}
+
+static void
+sfc_tx_reap(struct sfc_txq *txq)
+{
+ unsigned int completed;
+
+
+ sfc_ev_qpoll(txq->evq);
+
+ for (completed = txq->completed;
+ completed != txq->pending; completed++) {
+ struct sfc_tx_sw_desc *txd;
+
+ txd = &txq->sw_ring[completed & txq->ptr_mask];
+
+ if (txd->mbuf != NULL) {
+ rte_pktmbuf_free(txd->mbuf);
+ txd->mbuf = NULL;
+ }
+ }
+
+ txq->completed = completed;
+}
+
int
sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
uint16_t nb_tx_desc, unsigned int socket_id,
@@ -292,3 +342,190 @@ sfc_tx_fini(struct sfc_adapter *sa)
sa->txq_info = NULL;
sa->txq_count = 0;
}
+
+int
+sfc_tx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
+{
+ struct rte_eth_dev_data *dev_data;
+ struct sfc_txq_info *txq_info;
+ struct sfc_txq *txq;
+ struct sfc_evq *evq;
+ uint16_t flags;
+ unsigned int desc_index;
+ int rc = 0;
+
+ sfc_log_init(sa, "TxQ = %u", sw_index);
+
+ SFC_ASSERT(sw_index < sa->txq_count);
+ txq_info = &sa->txq_info[sw_index];
+
+ txq = txq_info->txq;
+
+ SFC_ASSERT(txq->state == SFC_TXQ_INITIALIZED);
+
+ evq = txq->evq;
+
+ rc = sfc_ev_qstart(sa, evq->evq_index);
+ if (rc != 0)
+ goto fail_ev_qstart;
+
+ /*
+ * It seems that DPDK has no controls regarding IPv4 offloads,
+ * hence, we always enable it here
+ */
+ if ((txq->flags & ETH_TXQ_FLAGS_NOXSUMTCP) ||
+ (txq->flags & ETH_TXQ_FLAGS_NOXSUMUDP))
+ flags = EFX_TXQ_CKSUM_IPV4;
+ else
+ flags = EFX_TXQ_CKSUM_IPV4 | EFX_TXQ_CKSUM_TCPUDP;
+
+ rc = efx_tx_qcreate(sa->nic, sw_index, 0, &txq->mem,
+ txq_info->entries, 0 /* not used on EF10 */,
+ flags, evq->common,
+ &txq->common, &desc_index);
+ if (rc != 0)
+ goto fail_tx_qcreate;
+
+ txq->added = txq->pending = txq->completed = desc_index;
+
+ efx_tx_qenable(txq->common);
+
+ txq->state |= (SFC_TXQ_STARTED | SFC_TXQ_RUNNING);
+
+ /*
+ * It seems to be used by DPDK for debug purposes only ('rte_ether')
+ */
+ dev_data = sa->eth_dev->data;
+ dev_data->tx_queue_state[sw_index] = RTE_ETH_QUEUE_STATE_STARTED;
+
+ return 0;
+
+fail_tx_qcreate:
+ sfc_ev_qstop(sa, evq->evq_index);
+
+fail_ev_qstart:
+ return rc;
+}
+
+void
+sfc_tx_qstop(struct sfc_adapter *sa, unsigned int sw_index)
+{
+ struct rte_eth_dev_data *dev_data;
+ struct sfc_txq_info *txq_info;
+ struct sfc_txq *txq;
+ unsigned int retry_count;
+ unsigned int wait_count;
+ unsigned int txds;
+
+ sfc_log_init(sa, "TxQ = %u", sw_index);
+
+ SFC_ASSERT(sw_index < sa->txq_count);
+ txq_info = &sa->txq_info[sw_index];
+
+ txq = txq_info->txq;
+
+ SFC_ASSERT(txq->state & SFC_TXQ_STARTED);
+
+ txq->state &= ~SFC_TXQ_RUNNING;
+
+ /*
+ * Retry TX queue flushing in case of flush failed or
+ * timeout; in the worst case it can delay for 6 seconds
+ */
+ for (retry_count = 0;
+ ((txq->state & SFC_TXQ_FLUSHED) == 0) &&
+ (retry_count < SFC_TX_QFLUSH_ATTEMPTS);
+ ++retry_count) {
+ if (efx_tx_qflush(txq->common) != 0) {
+ txq->state |= SFC_TXQ_FLUSHING;
+ break;
+ }
+
+ /*
+ * Wait for TX queue flush done or flush failed event at least
+ * SFC_TX_QFLUSH_POLL_WAIT_MS milliseconds and not more
+ * than 2 seconds (SFC_TX_QFLUSH_POLL_WAIT_MS multiplied
+ * by SFC_TX_QFLUSH_POLL_ATTEMPTS)
+ */
+ wait_count = 0;
+ do {
+ rte_delay_ms(SFC_TX_QFLUSH_POLL_WAIT_MS);
+ sfc_ev_qpoll(txq->evq);
+ } while ((txq->state & SFC_TXQ_FLUSHING) &&
+ wait_count++ < SFC_TX_QFLUSH_POLL_ATTEMPTS);
+
+ if (txq->state & SFC_TXQ_FLUSHING)
+ sfc_err(sa, "TxQ %u flush timed out", sw_index);
+
+ if (txq->state & SFC_TXQ_FLUSHED)
+ sfc_info(sa, "TxQ %u flushed", sw_index);
+ }
+
+ sfc_tx_reap(txq);
+
+ for (txds = 0; txds < txq_info->entries; txds++) {
+ if (txq->sw_ring[txds].mbuf != NULL) {
+ rte_pktmbuf_free(txq->sw_ring[txds].mbuf);
+ txq->sw_ring[txds].mbuf = NULL;
+ }
+ }
+
+ txq->state = SFC_TXQ_INITIALIZED;
+
+ efx_tx_qdestroy(txq->common);
+
+ sfc_ev_qstop(sa, txq->evq->evq_index);
+
+ /*
+ * It seems to be used by DPDK for debug purposes only ('rte_ether')
+ */
+ dev_data = sa->eth_dev->data;
+ dev_data->tx_queue_state[sw_index] = RTE_ETH_QUEUE_STATE_STOPPED;
+}
+
+int
+sfc_tx_start(struct sfc_adapter *sa)
+{
+ int sw_index;
+ int rc = 0;
+
+ sfc_log_init(sa, "txq_count = %u", sa->txq_count);
+
+ rc = efx_tx_init(sa->nic);
+ if (rc != 0)
+ goto fail_efx_tx_init;
+
+ for (sw_index = 0; sw_index < sa->txq_count; ++sw_index) {
+ rc = sfc_tx_qstart(sa, sw_index);
+ if (rc != 0)
+ goto fail_tx_qstart;
+ }
+
+ return 0;
+
+fail_tx_qstart:
+ while (--sw_index >= 0)
+ sfc_tx_qstop(sa, sw_index);
+
+ efx_tx_fini(sa->nic);
+
+fail_efx_tx_init:
+ sfc_log_init(sa, "failed (rc = %d)", rc);
+ return rc;
+}
+
+void
+sfc_tx_stop(struct sfc_adapter *sa)
+{
+ int sw_index;
+
+ sfc_log_init(sa, "txq_count = %u", sa->txq_count);
+
+ sw_index = sa->txq_count;
+ while (--sw_index >= 0) {
+ if (sa->txq_info[sw_index].txq != NULL)
+ sfc_tx_qstop(sa, sw_index);
+ }
+
+ efx_tx_fini(sa->nic);
+}
diff --git a/drivers/net/sfc/efx/sfc_tx.h b/drivers/net/sfc/efx/sfc_tx.h
index 3278797..47970f9 100644
--- a/drivers/net/sfc/efx/sfc_tx.h
+++ b/drivers/net/sfc/efx/sfc_tx.h
@@ -49,6 +49,14 @@ struct sfc_tx_sw_desc {
enum sfc_txq_state_bit {
SFC_TXQ_INITIALIZED_BIT = 0,
#define SFC_TXQ_INITIALIZED (1 << SFC_TXQ_INITIALIZED_BIT)
+ SFC_TXQ_STARTED_BIT,
+#define SFC_TXQ_STARTED (1 << SFC_TXQ_STARTED_BIT)
+ SFC_TXQ_RUNNING_BIT,
+#define SFC_TXQ_RUNNING (1 << SFC_TXQ_RUNNING_BIT)
+ SFC_TXQ_FLUSHING_BIT,
+#define SFC_TXQ_FLUSHING (1 << SFC_TXQ_FLUSHING_BIT)
+ SFC_TXQ_FLUSHED_BIT,
+#define SFC_TXQ_FLUSHED (1 << SFC_TXQ_FLUSHED_BIT)
};
struct sfc_txq {
@@ -59,6 +67,9 @@ struct sfc_txq {
efx_desc_t *pend_desc;
efx_txq_t *common;
efsys_mem_t mem;
+ unsigned int added;
+ unsigned int pending;
+ unsigned int completed;
unsigned int hw_index;
unsigned int flags;
@@ -83,6 +94,12 @@ int sfc_tx_qinit(struct sfc_adapter *sa, unsigned int sw_index,
const struct rte_eth_txconf *tx_conf);
void sfc_tx_qfini(struct sfc_adapter *sa, unsigned int sw_index);
+void sfc_tx_qflush_done(struct sfc_txq *txq);
+int sfc_tx_qstart(struct sfc_adapter *sa, unsigned int sw_index);
+void sfc_tx_qstop(struct sfc_adapter *sa, unsigned int sw_index);
+int sfc_tx_start(struct sfc_adapter *sa);
+void sfc_tx_stop(struct sfc_adapter *sa);
+
#ifdef __cplusplus
}
#endif
--
2.5.5
^ permalink raw reply related
* [PATCH 43/56] net/sfc: implement device operation to retrieve link info
From: Andrew Rybchenko @ 2016-11-21 15:00 UTC (permalink / raw)
To: dev; +Cc: Artem Andreev
In-Reply-To: <1479740470-6723-1-git-send-email-arybchenko@solarflare.com>
From: Artem Andreev <Artem.Andreev@oktetlabs.ru>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
Signed-off-by: Artem Andreev <Artem.Andreev@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
doc/guides/nics/features/sfc_efx.ini | 1 +
doc/guides/nics/sfc_efx.rst | 2 ++
drivers/net/sfc/efx/sfc.h | 3 ++
drivers/net/sfc/efx/sfc_ethdev.c | 42 ++++++++++++++++++++++++++
drivers/net/sfc/efx/sfc_ev.c | 12 ++++++--
drivers/net/sfc/efx/sfc_port.c | 58 ++++++++++++++++++++++++++++++++++++
6 files changed, 115 insertions(+), 3 deletions(-)
diff --git a/doc/guides/nics/features/sfc_efx.ini b/doc/guides/nics/features/sfc_efx.ini
index 59eb830..7dc2e92 100644
--- a/doc/guides/nics/features/sfc_efx.ini
+++ b/doc/guides/nics/features/sfc_efx.ini
@@ -4,6 +4,7 @@
; Refer to default.ini for the full list of available PMD features.
;
[Features]
+Link status = Y
BSD nic_uio = Y
Linux UIO = Y
Linux VFIO = Y
diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 271c8c6..46c892b 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -44,6 +44,8 @@ SFC EFX PMD has support for:
- Multiple transmit and receive queues
+- Link state information
+
Non-supported Features
----------------------
diff --git a/drivers/net/sfc/efx/sfc.h b/drivers/net/sfc/efx/sfc.h
index ab867da..f328482 100644
--- a/drivers/net/sfc/efx/sfc.h
+++ b/drivers/net/sfc/efx/sfc.h
@@ -215,6 +215,9 @@ int sfc_port_init(struct sfc_adapter *sa);
void sfc_port_fini(struct sfc_adapter *sa);
int sfc_port_start(struct sfc_adapter *sa);
void sfc_port_stop(struct sfc_adapter *sa);
+void sfc_port_link_mode_to_info(efx_link_mode_t link_mode,
+ struct rte_eth_link *link_info);
+
#ifdef __cplusplus
}
diff --git a/drivers/net/sfc/efx/sfc_ethdev.c b/drivers/net/sfc/efx/sfc_ethdev.c
index a328232..a8a6a17 100644
--- a/drivers/net/sfc/efx/sfc_ethdev.c
+++ b/drivers/net/sfc/efx/sfc_ethdev.c
@@ -37,6 +37,7 @@
#include "sfc_debug.h"
#include "sfc_log.h"
#include "sfc_kvargs.h"
+#include "sfc_ev.h"
static void
@@ -98,6 +99,46 @@ sfc_dev_start(struct rte_eth_dev *dev)
return -rc;
}
+static int
+sfc_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
+{
+ struct sfc_adapter *sa = dev->data->dev_private;
+ struct rte_eth_link *dev_link = &dev->data->dev_link;
+ struct rte_eth_link old_link;
+ struct rte_eth_link current_link;
+
+ sfc_log_init(sa, "entry");
+
+ if (sa->state != SFC_ADAPTER_STARTED)
+ return 0;
+
+retry:
+ EFX_STATIC_ASSERT(sizeof(*dev_link) == sizeof(rte_atomic64_t));
+ *(int64_t *)&old_link = rte_atomic64_read((rte_atomic64_t *)dev_link);
+
+ if (wait_to_complete) {
+ efx_link_mode_t link_mode;
+
+ efx_port_poll(sa->nic, &link_mode);
+ sfc_port_link_mode_to_info(link_mode, ¤t_link);
+
+ if (!rte_atomic64_cmpset((volatile uint64_t *)dev_link,
+ *(uint64_t *)&old_link,
+ *(uint64_t *)¤t_link))
+ goto retry;
+ } else {
+ sfc_ev_mgmt_qpoll(sa);
+ *(int64_t *)¤t_link =
+ rte_atomic64_read((rte_atomic64_t *)dev_link);
+ }
+
+ if (old_link.link_status != current_link.link_status)
+ sfc_info(sa, "Link status is %s",
+ current_link.link_status ? "UP" : "DOWN");
+
+ return old_link.link_status == current_link.link_status ? 0 : -1;
+}
+
static void
sfc_dev_stop(struct rte_eth_dev *dev)
{
@@ -145,6 +186,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_start = sfc_dev_start,
.dev_stop = sfc_dev_stop,
.dev_close = sfc_dev_close,
+ .link_update = sfc_dev_link_update,
.dev_infos_get = sfc_dev_infos_get,
};
diff --git a/drivers/net/sfc/efx/sfc_ev.c b/drivers/net/sfc/efx/sfc_ev.c
index 1cb9771..8e2fc94 100644
--- a/drivers/net/sfc/efx/sfc_ev.c
+++ b/drivers/net/sfc/efx/sfc_ev.c
@@ -182,10 +182,16 @@ static boolean_t
sfc_ev_link_change(void *arg, efx_link_mode_t link_mode)
{
struct sfc_evq *evq = arg;
+ struct sfc_adapter *sa = evq->sa;
+ struct rte_eth_link *dev_link = &sa->eth_dev->data->dev_link;
+ struct rte_eth_link new_link;
- sfc_err(evq->sa, "EVQ %u unexpected link change",
- evq->evq_index);
- return B_TRUE;
+ EFX_STATIC_ASSERT(sizeof(*dev_link) == sizeof(rte_atomic64_t));
+
+ sfc_port_link_mode_to_info(link_mode, &new_link);
+ rte_atomic64_set((rte_atomic64_t *)dev_link, *(uint64_t *)&new_link);
+
+ return B_FALSE;
}
static const efx_ev_callbacks_t sfc_ev_callbacks = {
diff --git a/drivers/net/sfc/efx/sfc_port.c b/drivers/net/sfc/efx/sfc_port.c
index 844363c..c124181 100644
--- a/drivers/net/sfc/efx/sfc_port.c
+++ b/drivers/net/sfc/efx/sfc_port.c
@@ -129,3 +129,61 @@ sfc_port_fini(struct sfc_adapter *sa)
sfc_log_init(sa, "done");
}
+
+void
+sfc_port_link_mode_to_info(efx_link_mode_t link_mode,
+ struct rte_eth_link *link_info)
+{
+ SFC_ASSERT(link_mode < EFX_LINK_NMODES);
+
+ memset(link_info, 0, sizeof(*link_info));
+ if ((link_mode == EFX_LINK_DOWN) || (link_mode == EFX_LINK_UNKNOWN))
+ link_info->link_status = ETH_LINK_DOWN;
+ else
+ link_info->link_status = ETH_LINK_UP;
+
+ switch (link_mode) {
+ case EFX_LINK_10HDX:
+ link_info->link_speed = ETH_SPEED_NUM_10M;
+ link_info->link_duplex = ETH_LINK_HALF_DUPLEX;
+ break;
+ case EFX_LINK_10FDX:
+ link_info->link_speed = ETH_SPEED_NUM_10M;
+ link_info->link_duplex = ETH_LINK_FULL_DUPLEX;
+ break;
+ case EFX_LINK_100HDX:
+ link_info->link_speed = ETH_SPEED_NUM_100M;
+ link_info->link_duplex = ETH_LINK_HALF_DUPLEX;
+ break;
+ case EFX_LINK_100FDX:
+ link_info->link_speed = ETH_SPEED_NUM_100M;
+ link_info->link_duplex = ETH_LINK_FULL_DUPLEX;
+ break;
+ case EFX_LINK_1000HDX:
+ link_info->link_speed = ETH_SPEED_NUM_1G;
+ link_info->link_duplex = ETH_LINK_HALF_DUPLEX;
+ break;
+ case EFX_LINK_1000FDX:
+ link_info->link_speed = ETH_SPEED_NUM_1G;
+ link_info->link_duplex = ETH_LINK_FULL_DUPLEX;
+ break;
+ case EFX_LINK_10000FDX:
+ link_info->link_speed = ETH_SPEED_NUM_10G;
+ link_info->link_duplex = ETH_LINK_FULL_DUPLEX;
+ break;
+ case EFX_LINK_40000FDX:
+ link_info->link_speed = ETH_SPEED_NUM_40G;
+ link_info->link_duplex = ETH_LINK_FULL_DUPLEX;
+ break;
+ default:
+ SFC_ASSERT(B_FALSE);
+ /* FALLTHROUGH */
+ case EFX_LINK_UNKNOWN:
+ case EFX_LINK_DOWN:
+ link_info->link_speed = ETH_SPEED_NUM_NONE;
+ link_info->link_duplex = 0;
+ break;
+ }
+
+ link_info->link_autoneg = ETH_LINK_AUTONEG;
+}
--
2.5.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox