[dpdk-dev] [PATCH v4 06/22] event/dlb: add probe
Eads, Gage
gage.eads at intel.com
Thu Oct 8 20:51:53 CEST 2020
My "event/dlb2: add probe" review, referenced below:
[1] http://mails.dpdk.org/archives/dev/2020-October/184962.html
> -----Original Message-----
> From: McDaniel, Timothy <timothy.mcdaniel at intel.com>
> Sent: Friday, September 11, 2020 2:18 PM
> To: Burakov, Anatoly <anatoly.burakov at intel.com>
> Cc: dev at dpdk.org; Carrillo, Erik G <erik.g.carrillo at intel.com>; Eads, Gage
> <gage.eads at intel.com>; Van Haaren, Harry <harry.van.haaren at intel.com>;
> jerinj at marvell.com
> Subject: [PATCH v4 06/22] event/dlb: add probe
>
> The DLB hardware is a PCI device. This commit adds
> support for probe and other initialization.
Given the size, this commit warrants a more detailed commit message --
like the dlb2 PMD's "add probe" commit.
>
> Signed-off-by: Timothy McDaniel <timothy.mcdaniel at intel.com>
> ---
> drivers/event/dlb/dlb.c | 493 ++++++
> drivers/event/dlb/dlb_iface.c | 41 +
> drivers/event/dlb/dlb_iface.h | 27 +
> drivers/event/dlb/dlb_priv.h | 20 +-
> drivers/event/dlb/meson.build | 6 +-
> drivers/event/dlb/pf/base/dlb_hw_types.h | 334 ++++
> drivers/event/dlb/pf/base/dlb_osdep.h | 326 ++++
> drivers/event/dlb/pf/base/dlb_osdep_bitmap.h | 441 +++++
> drivers/event/dlb/pf/base/dlb_osdep_list.h | 131 ++
> drivers/event/dlb/pf/base/dlb_osdep_types.h | 31 +
> drivers/event/dlb/pf/base/dlb_regs.h | 2368
> ++++++++++++++++++++++++++
> drivers/event/dlb/pf/base/dlb_resource.c | 302 ++++
> drivers/event/dlb/pf/base/dlb_resource.h | 876 ++++++++++
> drivers/event/dlb/pf/dlb_main.c | 591 +++++++
> drivers/event/dlb/pf/dlb_main.h | 52 +
> drivers/event/dlb/pf/dlb_pf.c | 232 +++
> 16 files changed, 6254 insertions(+), 17 deletions(-)
> create mode 100644 drivers/event/dlb/dlb.c
> create mode 100644 drivers/event/dlb/dlb_iface.c
> create mode 100644 drivers/event/dlb/dlb_iface.h
> create mode 100644 drivers/event/dlb/pf/base/dlb_hw_types.h
> create mode 100644 drivers/event/dlb/pf/base/dlb_osdep.h
> create mode 100644 drivers/event/dlb/pf/base/dlb_osdep_bitmap.h
> create mode 100644 drivers/event/dlb/pf/base/dlb_osdep_list.h
> create mode 100644 drivers/event/dlb/pf/base/dlb_osdep_types.h
> create mode 100644 drivers/event/dlb/pf/base/dlb_regs.h
> create mode 100644 drivers/event/dlb/pf/base/dlb_resource.c
> create mode 100644 drivers/event/dlb/pf/base/dlb_resource.h
> create mode 100644 drivers/event/dlb/pf/dlb_main.c
> create mode 100644 drivers/event/dlb/pf/dlb_main.h
> create mode 100644 drivers/event/dlb/pf/dlb_pf.c
>
> diff --git a/drivers/event/dlb/dlb.c b/drivers/event/dlb/dlb.c
> new file mode 100644
> index 0000000..e2acb61
> --- /dev/null
> +++ b/drivers/event/dlb/dlb.c
> @@ -0,0 +1,493 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2016-2020 Intel Corporation
> + */
> +
> +#include <assert.h>
> +#include <errno.h>
> +#include <nmmintrin.h>
> +#include <pthread.h>
> +#include <stdbool.h>
> +#include <stdint.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <sys/fcntl.h>
> +#include <sys/mman.h>
> +#include <unistd.h>
> +
> +#include <rte_common.h>
> +#include <rte_config.h>
> +#include <rte_cycles.h>
> +#include <rte_debug.h>
> +#include <rte_dev.h>
> +#include <rte_errno.h>
> +#include <rte_io.h>
> +#include <rte_kvargs.h>
> +#include <rte_log.h>
> +#include <rte_malloc.h>
> +#include <rte_mbuf.h>
> +#include <rte_prefetch.h>
> +#include <rte_ring.h>
> +#include <rte_string_fns.h>
> +
> +#include <rte_eventdev.h>
> +#include <rte_eventdev_pmd.h>
> +
> +#include "dlb_priv.h"
> +#include "dlb_iface.h"
> +#include "dlb_inline_fns.h"
> +
> +/*
> + * Resources exposed to eventdev.
> + */
> +#if (RTE_EVENT_MAX_QUEUES_PER_DEV > UINT8_MAX)
> +#error "RTE_EVENT_MAX_QUEUES_PER_DEV cannot fit in member
> max_event_queues"
> +#endif
> +static struct rte_event_dev_info evdev_dlb_default_info = {
> + .driver_name = "", /* probe will set */
> + .min_dequeue_timeout_ns = DLB_MIN_DEQUEUE_TIMEOUT_NS,
> + .max_dequeue_timeout_ns = DLB_MAX_DEQUEUE_TIMEOUT_NS,
> +#if (RTE_EVENT_MAX_QUEUES_PER_DEV < DLB_MAX_NUM_LDB_QUEUES)
> + .max_event_queues = RTE_EVENT_MAX_QUEUES_PER_DEV,
> +#else
> + .max_event_queues = DLB_MAX_NUM_LDB_QUEUES,
> +#endif
> + .max_event_queue_flows = DLB_MAX_NUM_FLOWS,
> + .max_event_queue_priority_levels = DLB_QID_PRIORITIES,
> + .max_event_priority_levels = DLB_QID_PRIORITIES,
> + .max_event_ports = DLB_MAX_NUM_LDB_PORTS,
> + .max_event_port_dequeue_depth = DLB_MAX_CQ_DEPTH,
> + .max_event_port_enqueue_depth = DLB_MAX_ENQUEUE_DEPTH,
> + .max_event_port_links = DLB_MAX_NUM_QIDS_PER_LDB_CQ,
> + .max_num_events = DLB_MAX_NUM_LDB_CREDITS,
> + .max_single_link_event_port_queue_pairs =
> DLB_MAX_NUM_DIR_PORTS,
> + .event_dev_cap = (RTE_EVENT_DEV_CAP_QUEUE_QOS |
> + RTE_EVENT_DEV_CAP_EVENT_QOS |
> + RTE_EVENT_DEV_CAP_BURST_MODE |
> + RTE_EVENT_DEV_CAP_DISTRIBUTED_SCHED |
> + RTE_EVENT_DEV_CAP_IMPLICIT_RELEASE_DISABLE |
> + RTE_EVENT_DEV_CAP_QUEUE_ALL_TYPES),
> +};
> +
> +struct process_local_port_data
> +dlb_port[DLB_MAX_NUM_PORTS][NUM_DLB_PORT_TYPES];
> +
> +static int
> +dlb_hw_query_resources(struct dlb_eventdev *dlb)
> +{
> + struct dlb_hw_dev *handle = &dlb->qm_instance;
> + struct dlb_hw_resource_info *dlb_info = &handle->info;
> + int ret;
> +
> + ret = dlb_iface_get_num_resources(handle,
> + &dlb->hw_rsrc_query_results);
> + if (ret) {
> + DLB_LOG_ERR("ioctl get dlb num resources, err=%d\n",
> + ret);
This can fit on one line, and 'ioctl' in the print doesn't look right.
> + return ret;
> + }
> +
> + /* Complete filling in device resource info returned to evdev app,
> + * overriding any default values.
> + * The capabilities (CAPs) were set at compile time.
> + */
> +
> + evdev_dlb_default_info.max_event_queues =
> + dlb->hw_rsrc_query_results.num_ldb_queues;
> +
> + evdev_dlb_default_info.max_event_ports =
> + dlb->hw_rsrc_query_results.num_ldb_ports;
> +
> + evdev_dlb_default_info.max_num_events =
> + dlb->hw_rsrc_query_results.max_contiguous_ldb_credits;
> +
> + /* Save off values used when creating the scheduling domain. */
> +
> + handle->info.num_sched_domains =
> + dlb->hw_rsrc_query_results.num_sched_domains;
> +
> + handle->info.hw_rsrc_max.nb_events_limit =
> + dlb->hw_rsrc_query_results.max_contiguous_ldb_credits;
> +
> + handle->info.hw_rsrc_max.num_queues =
> + dlb->hw_rsrc_query_results.num_ldb_queues +
> + dlb->hw_rsrc_query_results.num_dir_ports;
> +
> + handle->info.hw_rsrc_max.num_ldb_queues =
> + dlb->hw_rsrc_query_results.num_ldb_queues;
> +
> + handle->info.hw_rsrc_max.num_ldb_ports =
> + dlb->hw_rsrc_query_results.num_ldb_ports;
> +
> + handle->info.hw_rsrc_max.num_dir_ports =
> + dlb->hw_rsrc_query_results.num_dir_ports;
> +
> + handle->info.hw_rsrc_max.reorder_window_size =
> + dlb->hw_rsrc_query_results.num_hist_list_entries;
> +
> + rte_memcpy(dlb_info, &handle->info.hw_rsrc_max, sizeof(*dlb_info));
> +
> + return 0;
> +}
> +
> +/* Wrapper for string to int conversion. Substituted for atoi(...), which is
> + * unsafe.
> + */
> +#define RTE_BASE_10 10
> +
> +static int
> +dlb_string_to_int(int *result, const char *str)
> +{
> + long ret;
> +
> + if (str == NULL || result == NULL)
> + return -EINVAL;
> +
> + errno = 0;
> + ret = strtol(str, NULL, RTE_BASE_10);
> + if (errno)
> + return -errno;
Same possible issue I mentioned in [1] -- doesn't look like this handles an invalid
string correctly.
> +
> + /* long int and int may be different width for some architectures */
> + if (ret < INT_MIN || ret > INT_MAX)
> + return -EINVAL;
> +
> + *result = ret;
> + return 0;
> +}
> +
> +static int
> +set_numa_node(const char *key __rte_unused, const char *value, void
> *opaque)
> +{
> + int *socket_id = opaque;
> + int ret;
> +
> + ret = dlb_string_to_int(socket_id, value);
> + if (ret < 0)
> + return ret;
> +
> + if (*socket_id > RTE_MAX_NUMA_NODES)
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> +static int
> +set_max_num_events(const char *key __rte_unused,
> + const char *value,
> + void *opaque)
> +{
> + int *max_num_events = opaque;
> + int ret;
> +
> + if (value == NULL || opaque == NULL) {
> + DLB_LOG_ERR("NULL pointer\n");
> + return -EINVAL;
> + }
> +
> + ret = dlb_string_to_int(max_num_events, value);
> + if (ret < 0)
> + return ret;
> +
> + if (*max_num_events < 0 || *max_num_events >
> DLB_MAX_NUM_LDB_CREDITS) {
> + DLB_LOG_ERR("dlb: max_num_events must be between 0 and
> %d\n",
> + DLB_MAX_NUM_LDB_CREDITS);
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> +static int
> +set_num_dir_credits(const char *key __rte_unused,
> + const char *value,
> + void *opaque)
> +{
> + int *num_dir_credits = opaque;
> + int ret;
> +
> + if (value == NULL || opaque == NULL) {
> + DLB_LOG_ERR("NULL pointer\n");
> + return -EINVAL;
> + }
> +
> + ret = dlb_string_to_int(num_dir_credits, value);
> + if (ret < 0)
> + return ret;
> +
> + if (*num_dir_credits < 0 ||
> + *num_dir_credits > DLB_MAX_NUM_DIR_CREDITS) {
> + DLB_LOG_ERR("dlb: num_dir_credits must be between 0 and
> %d\n",
> + DLB_MAX_NUM_DIR_CREDITS);
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> +static int
> +set_dev_id(const char *key __rte_unused,
> + const char *value,
> + void *opaque)
> +{
> + int *dev_id = opaque;
> + int ret;
> +
> + if (value == NULL || opaque == NULL) {
> + DLB_LOG_ERR("NULL pointer\n");
> + return -EINVAL;
> + }
> +
> + ret = dlb_string_to_int(dev_id, value);
> + if (ret < 0)
> + return ret;
> +
> + return 0;
> +}
> +
> +static int
> +set_defer_sched(const char *key __rte_unused,
> + const char *value,
> + void *opaque)
> +{
> + int *defer_sched = opaque;
> +
> + if (value == NULL || opaque == NULL) {
> + DLB_LOG_ERR("NULL pointer\n");
> + return -EINVAL;
> + }
> +
> + if (strncmp(value, "on", 2) != 0) {
> + DLB_LOG_ERR("Invalid defer_sched argument \"%s\" (expected
> \"on\")\n",
> + value);
> + return -EINVAL;
> + }
> +
> + *defer_sched = 1;
> +
> + return 0;
> +}
> +
> +static int
> +set_num_atm_inflights(const char *key __rte_unused,
> + const char *value,
> + void *opaque)
> +{
> + int *num_atm_inflights = opaque;
> + int ret;
> +
> + if (value == NULL || opaque == NULL) {
> + DLB_LOG_ERR("NULL pointer\n");
> + return -EINVAL;
> + }
> +
> + ret = dlb_string_to_int(num_atm_inflights, value);
> + if (ret < 0)
> + return ret;
> +
> + if (*num_atm_inflights < 0 ||
> + *num_atm_inflights > DLB_MAX_NUM_ATM_INFLIGHTS) {
> + DLB_LOG_ERR("dlb: atm_inflights must be between 0 and %d\n",
> + DLB_MAX_NUM_ATM_INFLIGHTS);
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> +void
> +dlb_entry_points_init(struct rte_eventdev *dev)
> +{
> + static struct rte_eventdev_ops dlb_eventdev_entry_ops = {
> + };
> +
> + /* Expose PMD's eventdev interface */
> + dev->dev_ops = &dlb_eventdev_entry_ops;
> +
Extra whitespace here, but this gets removed later in the series.
> +}
> +
> +int
> +dlb_primary_eventdev_probe(struct rte_eventdev *dev,
> + const char *name,
> + struct dlb_devargs *dlb_args)
> +{
> + struct dlb_eventdev *dlb;
> + int err, i;
> +
> + dlb = dev->data->dev_private;
> +
> + dlb->event_dev = dev; /* backlink */
> +
> + evdev_dlb_default_info.driver_name = name;
> +
> + dlb->max_num_events_override = dlb_args->max_num_events;
> + dlb->num_dir_credits_override = dlb_args->num_dir_credits_override;
> + dlb->qm_instance.device_path_id = dlb_args->dev_id;
> + dlb->defer_sched = dlb_args->defer_sched;
> + dlb->num_atm_inflights_per_queue = dlb_args->num_atm_inflights;
> +
> + /* Open the interface.
> + * For vdev mode, this means open the dlb kernel module.
> + */
> + err = dlb_iface_open(&dlb->qm_instance, name);
> + if (err < 0) {
> + DLB_LOG_ERR("could not open event hardware device,
> err=%d\n",
> + err);
> + return err;
> + }
> +
> + err = dlb_iface_get_device_version(&dlb->qm_instance, &dlb-
> >revision);
> + if (err < 0) {
> + DLB_LOG_ERR("dlb: failed to get the device version, err=%d\n",
> + err);
> + return err;
> + }
> +
> + err = dlb_hw_query_resources(dlb);
> + if (err) {
> + DLB_LOG_ERR("get resources err=%d for %s\n",
> + err, name);
Nit: this fits on one line
> + return err;
> + }
> +
> + err = dlb_iface_get_cq_poll_mode(&dlb->qm_instance, &dlb-
> >poll_mode);
> + if (err < 0) {
> + DLB_LOG_ERR("dlb: failed to get the poll mode, err=%d\n",
> + err);
Nit: this fits on one line
> + return err;
> + }
> +
> + /* Initialize each port's token pop mode */
> + for (i = 0; i < DLB_MAX_NUM_PORTS; i++)
> + dlb->ev_ports[i].qm_port.token_pop_mode = AUTO_POP;
> +
> + rte_spinlock_init(&dlb->qm_instance.resource_lock);
> +
> + dlb_iface_low_level_io_init(dlb);
> +
> + dlb_entry_points_init(dev);
> +
> + return 0;
> +}
> +
> +int
> +dlb_secondary_eventdev_probe(struct rte_eventdev *dev,
> + const char *name)
> +{
> + struct dlb_eventdev *dlb;
> + int err;
> +
> + dlb = dev->data->dev_private;
> +
> + evdev_dlb_default_info.driver_name = name;
> +
> + err = dlb_iface_open(&dlb->qm_instance, name);
> + if (err < 0) {
> + DLB_LOG_ERR("could not open event hardware device,
> err=%d\n",
> + err);
> + return err;
> + }
> +
> + err = dlb_hw_query_resources(dlb);
> + if (err) {
> + DLB_LOG_ERR("get resources err=%d for %s\n",
> + err, name);
Nit: this fits on one line
> + return err;
> + }
> +
> + dlb_iface_low_level_io_init(dlb);
> +
> + dlb_entry_points_init(dev);
> +
> + return 0;
> +}
> +
> +int
> +dlb_parse_params(const char *params,
> + const char *name,
> + struct dlb_devargs *dlb_args)
> +{
> + int ret = 0;
> + static const char * const args[] = { NUMA_NODE_ARG,
> + DLB_MAX_NUM_EVENTS,
> + DLB_NUM_DIR_CREDITS,
> + DEV_ID_ARG,
> + DLB_DEFER_SCHED_ARG,
> + DLB_NUM_ATM_INFLIGHTS_ARG,
> + NULL };
> +
> + if (params && params[0] != '\0') {
> + struct rte_kvargs *kvlist = rte_kvargs_parse(params, args);
> +
> + if (!kvlist) {
> + DLB_LOG_INFO("Ignoring unsupported parameters when
> creating device '%s'\n",
> + name);
> + } else {
> + int ret = rte_kvargs_process(kvlist, NUMA_NODE_ARG,
> + set_numa_node,
> + &dlb_args->socket_id);
> + if (ret != 0) {
> + DLB_LOG_ERR("%s: Error parsing numa node
> parameter",
> + name);
> + rte_kvargs_free(kvlist);
> + return ret;
> + }
> +
> + ret = rte_kvargs_process(kvlist,
> DLB_MAX_NUM_EVENTS,
> + set_max_num_events,
> + &dlb_args->max_num_events);
> + if (ret != 0) {
> + DLB_LOG_ERR("%s: Error parsing
> max_num_events parameter",
> + name);
> + rte_kvargs_free(kvlist);
> + return ret;
> + }
> +
> + ret = rte_kvargs_process(kvlist,
> + DLB_NUM_DIR_CREDITS,
> + set_num_dir_credits,
> + &dlb_args->num_dir_credits_override);
> + if (ret != 0) {
> + DLB_LOG_ERR("%s: Error parsing num_dir_credits
> parameter",
> + name);
> + rte_kvargs_free(kvlist);
> + return ret;
> + }
> +
> + ret = rte_kvargs_process(kvlist, DEV_ID_ARG,
> + set_dev_id,
> + &dlb_args->dev_id);
> + if (ret != 0) {
> + DLB_LOG_ERR("%s: Error parsing dev_id
> parameter",
> + name);
> + rte_kvargs_free(kvlist);
> + return ret;
> + }
> +
> + ret = rte_kvargs_process(kvlist, DLB_DEFER_SCHED_ARG,
> + set_defer_sched,
> + &dlb_args->defer_sched);
> + if (ret != 0) {
> + DLB_LOG_ERR("%s: Error parsing defer_sched
> parameter",
> + name);
> + rte_kvargs_free(kvlist);
> + return ret;
> + }
> +
> + ret = rte_kvargs_process(kvlist,
> +
> DLB_NUM_ATM_INFLIGHTS_ARG,
> + set_num_atm_inflights,
> + &dlb_args->num_atm_inflights);
> + if (ret != 0) {
> + DLB_LOG_ERR("%s: Error parsing atm_inflights
> parameter",
> + name);
> + rte_kvargs_free(kvlist);
> + return ret;
> + }
> +
> + rte_kvargs_free(kvlist);
> + }
> + }
> + return ret;
> +}
> +RTE_LOG_REGISTER(eventdev_dlb_log_level, pmd.event.dlb, NOTICE);
> +
Blank newline at the end of the file
> diff --git a/drivers/event/dlb/dlb_iface.c b/drivers/event/dlb/dlb_iface.c
> new file mode 100644
> index 0000000..3f17bd1
> --- /dev/null
> +++ b/drivers/event/dlb/dlb_iface.c
> @@ -0,0 +1,41 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2016-2020 Intel Corporation
> + */
> +
> +#include <stdbool.h>
> +#include <stdint.h>
> +
> +#include <rte_debug.h>
> +#include <rte_bus_pci.h>
> +#include <rte_log.h>
> +#include <rte_dev.h>
> +#include <rte_mbuf.h>
> +#include <rte_ring.h>
> +#include <rte_errno.h>
> +#include <rte_kvargs.h>
> +#include <rte_malloc.h>
> +#include <rte_cycles.h>
> +#include <rte_io.h>
> +#include <rte_eventdev.h>
As in [1], doesn't look like stdbool.h and the rte_*.h includes are needed.
[...]
> diff --git a/drivers/event/dlb/dlb_priv.h b/drivers/event/dlb/dlb_priv.h
> index 482c5b2..acb8158 100644
> --- a/drivers/event/dlb/dlb_priv.h
> +++ b/drivers/event/dlb/dlb_priv.h
> @@ -527,18 +527,14 @@ int test_dlb_eventdev(void);
>
> int dlb_primary_eventdev_probe(struct rte_eventdev *dev,
> const char *name,
> - struct dlb_devargs *dlb_args,
> - bool is_vdev);
> + struct dlb_devargs *dlb_args);
>
> int dlb_secondary_eventdev_probe(struct rte_eventdev *dev,
> - const char *name,
> - bool is_vdev);
> + const char *name);
> +
> uint32_t dlb_get_queue_depth(struct dlb_eventdev *dlb,
> struct dlb_eventdev_queue *queue);
>
> -int set_numa_node(const char *key __rte_unused, const char *value,
> - void *opaque);
> -
> int set_dir_ports(const char *key __rte_unused,
> const char *value __rte_unused,
> void *opaque __rte_unused);
> @@ -547,20 +543,12 @@ int set_dir_queues(const char *key __rte_unused,
> const char *value __rte_unused,
> void *opaque __rte_unused);
>
> -int set_max_num_events(const char *key __rte_unused, const char *value,
> - void *opaque);
> -
> -int set_num_dir_credits(const char *key __rte_unused, const char *value,
> - void *opaque);
> -
> void dlb_drain(struct rte_eventdev *dev);
>
> -void dlb_entry_points_init(struct rte_eventdev *dev);
> -
> int dlb_parse_params(const char *params,
> const char *name,
> struct dlb_devargs *dlb_args);
>
> -int dlb_string_to_int(int *result, const char *str);
> +void dlb_entry_points_init(struct rte_eventdev *dev);
>
> #endif /* _DLB_PRIV_H_ */
Looks like all these dlb_priv.h changes were intended for patch #3
[...]
> diff --git a/drivers/event/dlb/pf/base/dlb_osdep_bitmap.h
> b/drivers/event/dlb/pf/base/dlb_osdep_bitmap.h
> new file mode 100644
> index 0000000..3ebd4ea
> --- /dev/null
> +++ b/drivers/event/dlb/pf/base/dlb_osdep_bitmap.h
> @@ -0,0 +1,441 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2016-2020 Intel Corporation
> + */
> +
> +#ifndef __DLB_OSDEP_BITMAP_H__
> +#define __DLB_OSDEP_BITMAP_H__
> +
> +#include <stdint.h>
> +#include <stdbool.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <rte_bitmap.h>
> +#include <rte_string_fns.h>
> +#include <rte_malloc.h>
> +#include <rte_errno.h>
> +#include "../dlb_main.h"
> +
> +/*************************/
> +/*** Bitmap operations ***/
> +/*************************/
> +struct dlb_bitmap {
> + struct rte_bitmap *map;
> + unsigned int len;
> + struct dlb_hw *hw;
> +};
> +
> +/**
> + * dlb_bitmap_alloc() - alloc a bitmap data structure
> + * @bitmap: pointer to dlb_bitmap structure pointer.
> + * @len: number of entries in the bitmap.
> + *
> + * This function allocates a bitmap and initializes it with length @len. All
> + * entries are initially zero.
> + *
> + * Return:
> + * Returns 0 upon success, < 0 otherwise.
> + *
> + * Errors:
> + * EINVAL - bitmap is NULL or len is 0.
> + * ENOMEM - could not allocate memory for the bitmap data structure.
> + */
> +static inline int dlb_bitmap_alloc(struct dlb_hw *hw,
> + struct dlb_bitmap **bitmap,
> + unsigned int len)
> +{
> + struct dlb_bitmap *bm;
> + void *mem;
> + uint32_t alloc_size;
> + uint32_t nbits = (uint32_t) len;
> + RTE_SET_USED(hw);
> +
> + if (!bitmap || nbits == 0)
> + return -EINVAL;
> +
> + /* Allocate DLB bitmap control struct */
> + bm = rte_malloc("DLB_PF",
> + sizeof(struct dlb_bitmap),
> + RTE_CACHE_LINE_SIZE);
> +
> + if (!bm)
> + return -ENOMEM;
> +
> + /* Allocate bitmap memory */
> + alloc_size = rte_bitmap_get_memory_footprint(nbits);
> + mem = rte_malloc("DLB_PF_BITMAP", alloc_size,
> RTE_CACHE_LINE_SIZE);
> + if (!mem) {
> + rte_free(bm);
> + return -ENOMEM;
> + }
> +
> + bm->map = rte_bitmap_init(len, mem, alloc_size);
> + if (!bm->map) {
> + rte_free(mem);
> + rte_free(bm);
> + return -ENOMEM;
> + }
> +
> + bm->len = len;
> +
> + *bitmap = bm;
> +
> + return 0;
> +}
> +
> +/**
> + * dlb_bitmap_free() - free a previously allocated bitmap data structure
> + * @bitmap: pointer to dlb_bitmap structure.
> + *
> + * This function frees a bitmap that was allocated with dlb_bitmap_alloc().
> + */
> +static inline void dlb_bitmap_free(struct dlb_bitmap *bitmap)
> +{
> + if (!bitmap)
> + return;
> +
> + rte_free(bitmap->map);
> + rte_free(bitmap);
> +}
> +
> +/**
> + * dlb_bitmap_fill() - fill a bitmap with all 1s
> + * @bitmap: pointer to dlb_bitmap structure.
> + *
> + * This function sets all bitmap values to 1.
> + *
> + * Return:
> + * Returns 0 upon success, < 0 otherwise.
> + *
> + * Errors:
> + * EINVAL - bitmap is NULL or is uninitialized.
> + */
> +static inline int dlb_bitmap_fill(struct dlb_bitmap *bitmap)
> +{
> + unsigned int i;
> +
> + if (!bitmap || !bitmap->map)
> + return -EINVAL;
> +
> + for (i = 0; i != bitmap->len; i++)
> + rte_bitmap_set(bitmap->map, i);
> +
> + return 0;
> +}
> +
> +/**
> + * dlb_bitmap_fill() - fill a bitmap with all 0s
dlb_bitmap_fill -> dlb_bitmap_zero
[...]
> diff --git a/drivers/event/dlb/pf/dlb_main.c b/drivers/event/dlb/pf/dlb_main.c
> new file mode 100644
> index 0000000..7a55140
> --- /dev/null
> +++ b/drivers/event/dlb/pf/dlb_main.c
> @@ -0,0 +1,591 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2016-2020 Intel Corporation
> + */
> +
> +#include <stdint.h>
> +#include <stdbool.h>
> +#include <stdio.h>
> +#include <errno.h>
> +#include <assert.h>
> +#include <unistd.h>
> +#include <string.h>
> +
> +#include <rte_malloc.h>
> +#include <rte_errno.h>
> +
> +#include "base/dlb_resource.h"
> +#include "base/dlb_osdep.h"
> +#include "base/dlb_regs.h"
> +#include "../dlb_priv.h"
> +#include "../dlb_inline_fns.h"
> +#include "../dlb_user.h"
> +#include "dlb_main.h"
> +
> +unsigned int dlb_unregister_timeout_s =
> DLB_DEFAULT_UNREGISTER_TIMEOUT_S;
> +
> +#define DLB_PCI_CFG_SPACE_SIZE 256
> +#define DLB_PCI_CAP_POINTER 0x34
> +#define DLB_PCI_CAP_NEXT(hdr) (((hdr) >> 8) & 0xFC)
> +#define DLB_PCI_CAP_ID(hdr) ((hdr) & 0xFF)
> +#define DLB_PCI_EXT_CAP_NEXT(hdr) (((hdr) >> 20) & 0xFFC)
> +#define DLB_PCI_EXT_CAP_ID(hdr) ((hdr) & 0xFFFF)
> +#define DLB_PCI_EXT_CAP_ID_ERR 1
> +#define DLB_PCI_ERR_UNCOR_MASK 8
> +#define DLB_PCI_ERR_UNC_UNSUP 0x00100000
> +
> +#define DLB_PCI_EXP_DEVCTL 8
> +#define DLB_PCI_LNKCTL 16
> +#define DLB_PCI_SLTCTL 24
> +#define DLB_PCI_RTCTL 28
> +#define DLB_PCI_EXP_DEVCTL2 40
> +#define DLB_PCI_LNKCTL2 48
> +#define DLB_PCI_SLTCTL2 56
> +#define DLB_PCI_CMD 4
> +#define DLB_PCI_X_CMD 2
> +#define DLB_PCI_EXP_DEVSTA 10
> +#define DLB_PCI_EXP_DEVSTA_TRPND 0x20
> +#define DLB_PCI_EXP_DEVCTL_BCR_FLR 0x8000
> +#define DLB_PCI_PASID_CTRL 6
> +#define DLB_PCI_PASID_CAP 4
> +
> +#define DLB_PCI_CAP_ID_EXP 0x10
> +#define DLB_PCI_CAP_ID_MSIX 0x11
> +#define DLB_PCI_EXT_CAP_ID_PAS 0x1B
> +#define DLB_PCI_EXT_CAP_ID_PRI 0x13
> +#define DLB_PCI_EXT_CAP_ID_ACS 0xD
> +
> +#define DLB_PCI_PASID_CAP_EXEC 0x2
> +#define DLB_PCI_PASID_CAP_PRIV 0x4
> +#define DLB_PCI_PASID_CTRL_ENABLE 0x1
> +#define DLB_PCI_PRI_CTRL_ENABLE 0x1
> +#define DLB_PCI_PRI_ALLOC_REQ 0xC
> +#define DLB_PCI_PRI_CTRL 0x4
> +#define DLB_PCI_MSIX_FLAGS 0x2
> +#define DLB_PCI_MSIX_FLAGS_ENABLE 0x8000
> +#define DLB_PCI_MSIX_FLAGS_MASKALL 0x4000
> +#define DLB_PCI_ERR_ROOT_STATUS 0x30
> +#define DLB_PCI_ERR_COR_STATUS 0x10
> +#define DLB_PCI_ERR_UNCOR_STATUS 0x4
> +#define DLB_PCI_COMMAND_INTX_DISABLE 0x400
> +#define DLB_PCI_ACS_CAP 0x4
> +#define DLB_PCI_ACS_CTRL 0x6
> +#define DLB_PCI_ACS_SV 0x1
> +#define DLB_PCI_ACS_RR 0x4
> +#define DLB_PCI_ACS_CR 0x8
> +#define DLB_PCI_ACS_UF 0x10
> +#define DLB_PCI_ACS_EC 0x20
> +
> +static int dlb_pci_find_ext_capability(struct rte_pci_device *pdev, uint32_t id)
> +{
> + uint32_t hdr;
> + size_t sz;
> + int pos;
> +
> + pos = DLB_PCI_CFG_SPACE_SIZE;
> + sz = sizeof(hdr);
> +
> + while (pos > 0xFF) {
> + if (rte_pci_read_config(pdev, &hdr, sz, pos) != (int)sz)
> + return -1;
> +
> + if (DLB_PCI_EXT_CAP_ID(hdr) == id)
> + return pos;
> +
> + pos = DLB_PCI_EXT_CAP_NEXT(hdr);
> + }
> +
> + return -1;
> +}
> +
> +static int dlb_pci_find_capability(struct rte_pci_device *pdev, uint32_t id)
> +{
> + uint8_t pos;
> + int ret;
> + uint16_t hdr;
> +
> + ret = rte_pci_read_config(pdev, &pos, 1, DLB_PCI_CAP_POINTER);
> + pos &= 0xFC;
> +
> + if (ret != 1)
> + return -1;
> +
> + while (pos > 0x3F) {
> + ret = rte_pci_read_config(pdev, &hdr, 2, pos);
> + if (ret != 2)
> + return -1;
> +
> + if (DLB_PCI_CAP_ID(hdr) == id)
> + return pos;
> +
> + if (DLB_PCI_CAP_ID(hdr) == 0xFF)
> + return -1;
> +
> + pos = DLB_PCI_CAP_NEXT(hdr);
> + }
> +
> + return -1;
> +}
> +
> +static int dlb_mask_ur_err(struct rte_pci_device *pdev)
> +{
> + uint32_t mask;
> + size_t sz = sizeof(mask);
> + int pos = dlb_pci_find_ext_capability(pdev, DLB_PCI_EXT_CAP_ID_ERR);
> +
> + if (pos < 0) {
> + printf("[%s()] failed to find the aer capability\n",
> + __func__);
> + return pos;
> + }
> +
> + pos += DLB_PCI_ERR_UNCOR_MASK;
> +
> + if (rte_pci_read_config(pdev, &mask, sz, pos) != (int)sz) {
> + printf("[%s()] Failed to read uncorrectable error mask reg\n",
> + __func__);
> + return -1;
> + }
> +
> + /* Mask Unsupported Request errors */
> + mask |= DLB_PCI_ERR_UNC_UNSUP;
> +
> + if (rte_pci_write_config(pdev, &mask, sz, pos) != (int)sz) {
> + printf("[%s()] Failed to write uncorrectable error mask reg at
> offset %d\n",
> + __func__, pos);
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +struct dlb_dev *
> +dlb_probe(struct rte_pci_device *pdev)
> +{
> + struct dlb_dev *dlb_dev;
> + int ret = 0;
> +
> + DLB_INFO(dlb_dev, "probe\n");
> +
> + dlb_dev = rte_malloc("DLB_PF", sizeof(struct dlb_dev),
> + RTE_CACHE_LINE_SIZE);
> +
> + if (!dlb_dev) {
> + ret = -ENOMEM;
> + goto dlb_dev_malloc_fail;
> + }
> +
> + /* PCI Bus driver has already mapped bar space into process.
> + * Save off our IO register and FUNC addresses.
> + */
> +
> + /* BAR 0 */
> + if (pdev->mem_resource[0].addr == NULL) {
> + DLB_ERR(dlb_dev, "probe: BAR 0 addr (csr_kva) is NULL\n");
> + ret = -EINVAL;
> + goto pci_mmap_bad_addr;
> + }
> + dlb_dev->hw.func_kva = (void *)(uintptr_t)pdev-
> >mem_resource[0].addr;
> + dlb_dev->hw.func_phys_addr = pdev->mem_resource[0].phys_addr;
> +
> + DLB_INFO(dlb_dev, "DLB FUNC VA=%p, PA=%p, len=%"PRIu64"\n",
> + (void *)dlb_dev->hw.func_kva,
> + (void *)dlb_dev->hw.func_phys_addr,
> + pdev->mem_resource[0].len);
> +
> + /* BAR 2 */
> + if (pdev->mem_resource[2].addr == NULL) {
> + DLB_ERR(dlb_dev, "probe: BAR 2 addr (func_kva) is NULL\n");
> + ret = -EINVAL;
> + goto pci_mmap_bad_addr;
> + }
> + dlb_dev->hw.csr_kva = (void *)(uintptr_t)pdev-
> >mem_resource[2].addr;
> + dlb_dev->hw.csr_phys_addr = pdev->mem_resource[2].phys_addr;
> +
> + DLB_INFO(dlb_dev, "DLB CSR VA=%p, PA=%p, len=%"PRIu64"\n",
> + (void *)dlb_dev->hw.csr_kva,
> + (void *)dlb_dev->hw.csr_phys_addr,
> + pdev->mem_resource[2].len);
> +
> + dlb_dev->pdev = pdev;
> +
> + ret = dlb_pf_reset(dlb_dev);
> + if (ret)
> + goto dlb_reset_fail;
> +
> + /* DLB incorrectly sends URs in response to certain messages. Mask UR
> + * errors to prevent these from being propagated to the MCA.
> + */
> + ret = dlb_mask_ur_err(pdev);
> + if (ret)
> + goto mask_ur_err_fail;
> +
> + ret = dlb_pf_init_driver_state(dlb_dev);
> + if (ret)
> + goto init_driver_state_fail;
> +
> + ret = dlb_resource_init(&dlb_dev->hw);
> + if (ret)
> + goto resource_init_fail;
> +
> + dlb_dev->revision = os_get_dev_revision(&dlb_dev->hw);
> +
> + dlb_pf_init_hardware(dlb_dev);
> +
> + return dlb_dev;
> +
> +resource_init_fail:
> + dlb_resource_free(&dlb_dev->hw);
> +init_driver_state_fail:
> +mask_ur_err_fail:
> +dlb_reset_fail:
> +pci_mmap_bad_addr:
> + rte_free(dlb_dev);
> +dlb_dev_malloc_fail:
> + rte_errno = ret;
> + return NULL;
> +}
> +
> +int
> +dlb_pf_reset(struct dlb_dev *dlb_dev)
> +{
> + int msix_cap_offset, err_cap_offset, acs_cap_offset, wait_count;
> + uint16_t dev_ctl_word, dev_ctl2_word, lnk_word, lnk_word2;
> + uint16_t rt_ctl_word, pri_reqs_dword, pri_ctrl_word;
> + struct rte_pci_device *pdev = dlb_dev->pdev;
> + uint16_t devsta_busy_word, devctl_word;
> + int pcie_cap_offset, pri_cap_offset;
> + uint16_t slt_word, slt_word2, cmd;
> + int ret = 0, i = 0;
> + uint32_t dword[16];
> + off_t off;
> +
> + /* Save PCI config state */
> +
> + for (i = 0; i < 16; i++) {
> + if (rte_pci_read_config(pdev, &dword[i], 4, i * 4) != 4)
> + return ret;
> + }
> +
> + pcie_cap_offset = dlb_pci_find_capability(pdev, DLB_PCI_CAP_ID_EXP);
> +
> + if (pcie_cap_offset < 0) {
> + printf("[%s()] failed to find the pcie capability\n",
> + __func__);
> + return pcie_cap_offset;
> + }
> +
> + off = pcie_cap_offset + DLB_PCI_EXP_DEVCTL;
> + if (rte_pci_read_config(pdev, &dev_ctl_word, 2, off) != 2)
> + dev_ctl_word = 0;
> +
> + off = pcie_cap_offset + DLB_PCI_LNKCTL;
> + if (rte_pci_read_config(pdev, &lnk_word, 2, off) != 2)
> + lnk_word = 0;
> +
> + off = pcie_cap_offset + DLB_PCI_SLTCTL;
> + if (rte_pci_read_config(pdev, &slt_word, 2, off) != 2)
> + slt_word = 0;
> +
> + off = pcie_cap_offset + DLB_PCI_RTCTL;
> + if (rte_pci_read_config(pdev, &rt_ctl_word, 2, off) != 2)
> + rt_ctl_word = 0;
> +
> + off = pcie_cap_offset + DLB_PCI_EXP_DEVCTL2;
> + if (rte_pci_read_config(pdev, &dev_ctl2_word, 2, off) != 2)
> + dev_ctl2_word = 0;
> +
> + off = pcie_cap_offset + DLB_PCI_LNKCTL2;
> + if (rte_pci_read_config(pdev, &lnk_word2, 2, off) != 2)
> + lnk_word2 = 0;
> +
> + off = pcie_cap_offset + DLB_PCI_SLTCTL2;
> + if (rte_pci_read_config(pdev, &slt_word2, 2, off) != 2)
> + slt_word2 = 0;
> +
> + pri_cap_offset = dlb_pci_find_ext_capability(pdev,
> + DLB_PCI_EXT_CAP_ID_PRI);
> + if (pri_cap_offset >= 0) {
> + off = pri_cap_offset + DLB_PCI_PRI_ALLOC_REQ;
> + if (rte_pci_read_config(pdev, &pri_reqs_dword, 4, off) != 4)
> + pri_reqs_dword = 0;
> + }
> +
> + /* clear the PCI command register before issuing the FLR */
> +
> + off = DLB_PCI_CMD;
> + cmd = 0;
> + if (rte_pci_write_config(pdev, &cmd, 2, off) != 2) {
> + printf("[%s()] failed to write pci config space at offset %d\n",
> + __func__, (int)off);
> + return -1;
> + }
> +
> + /* issue the FLR */
> + for (wait_count = 0; wait_count < 4; wait_count++) {
> + int sleep_time;
> +
> + off = pcie_cap_offset + DLB_PCI_EXP_DEVSTA;
> + ret = rte_pci_read_config(pdev, &devsta_busy_word, 2, off);
> + if (ret != 2) {
> + printf("[%s()] failed to read the pci device status\n",
> + __func__);
> + return ret;
> + }
> +
> + if (!(devsta_busy_word & DLB_PCI_EXP_DEVSTA_TRPND))
> + break;
> +
> + sleep_time = (1 << (wait_count)) * 100;
> + rte_delay_ms(sleep_time);
> + }
> +
> + if (wait_count == 4) {
> + printf("[%s()] wait for pci pending transactions timed out\n",
> + __func__);
> + return -1;
> + }
> +
> + off = pcie_cap_offset + DLB_PCI_EXP_DEVCTL;
> + ret = rte_pci_read_config(pdev, &devctl_word, 2, off);
> + if (ret != 2) {
> + printf("[%s()] failed to read the pcie device control\n",
> + __func__);
> + return ret;
> + }
> +
> + devctl_word |= DLB_PCI_EXP_DEVCTL_BCR_FLR;
> +
> + if (rte_pci_write_config(pdev, &devctl_word, 2, off) != 2) {
> + printf("[%s()] failed to write the pcie device control at offset
> %d\n",
> + __func__, (int)off);
> + return -1;
> + }
> +
> + rte_delay_ms(100);
> +
> + /* Restore PCI config state */
> +
> + if (pcie_cap_offset >= 0) {
> + off = pcie_cap_offset + DLB_PCI_EXP_DEVCTL;
> + if (rte_pci_write_config(pdev, &dev_ctl_word, 2, off) != 2) {
> + printf("[%s()] failed to write the pcie device control at
> offset %d\n",
> + __func__, (int)off);
> + return -1;
> + }
> +
> + off = pcie_cap_offset + DLB_PCI_LNKCTL;
> + if (rte_pci_write_config(pdev, &lnk_word, 2, off) != 2) {
> + printf("[%s()] failed to write pci config space at offset
> %d\n",
> + __func__, (int)off);
> + return -1;
> + }
> +
> + off = pcie_cap_offset + DLB_PCI_SLTCTL;
> + if (rte_pci_write_config(pdev, &slt_word, 2, off) != 2) {
> + printf("[%s()] failed to write pci config space at offset
> %d\n",
> + __func__, (int)off);
> + return -1;
> + }
> +
> + off = pcie_cap_offset + DLB_PCI_RTCTL;
> + if (rte_pci_write_config(pdev, &rt_ctl_word, 2, off) != 2) {
> + printf("[%s()] failed to write pci config space at offset
> %d\n",
> + __func__, (int)off);
> + return -1;
> + }
> +
> + off = pcie_cap_offset + DLB_PCI_EXP_DEVCTL2;
> + if (rte_pci_write_config(pdev, &dev_ctl2_word, 2, off) != 2) {
> + printf("[%s()] failed to write pci config space at offset
> %d\n",
> + __func__, (int)off);
> + return -1;
> + }
> +
> + off = pcie_cap_offset + DLB_PCI_LNKCTL2;
> + if (rte_pci_write_config(pdev, &lnk_word2, 2, off) != 2) {
> + printf("[%s()] failed to write pci config space at offset
> %d\n",
> + __func__, (int)off);
> + return -1;
> + }
> +
> + off = pcie_cap_offset + DLB_PCI_SLTCTL2;
> + if (rte_pci_write_config(pdev, &slt_word2, 2, off) != 2) {
> + printf("[%s()] failed to write pci config space at offset
> %d\n",
> + __func__, (int)off);
> + return -1;
> + }
> + }
> +
> + if (pri_cap_offset >= 0) {
> + pri_ctrl_word = DLB_PCI_PRI_CTRL_ENABLE;
> +
> + off = pri_cap_offset + DLB_PCI_PRI_ALLOC_REQ;
> + if (rte_pci_write_config(pdev, &pri_reqs_dword, 4, off) != 4) {
> + printf("[%s()] failed to write pci config space at offset
> %d\n",
> + __func__, (int)off);
> + return -1;
> + }
> +
> + off = pri_cap_offset + DLB_PCI_PRI_CTRL;
> + if (rte_pci_write_config(pdev, &pri_ctrl_word, 2, off) != 2) {
> + printf("[%s()] failed to write pci config space at offset
> %d\n",
> + __func__, (int)off);
> + return -1;
> + }
> + }
> +
> + err_cap_offset = dlb_pci_find_ext_capability(pdev,
> + DLB_PCI_EXT_CAP_ID_ERR);
> + if (err_cap_offset >= 0) {
> + uint32_t tmp;
> +
> + off = err_cap_offset + DLB_PCI_ERR_ROOT_STATUS;
> + if (rte_pci_read_config(pdev, &tmp, 4, off) != 4)
> + tmp = 0;
> +
> + if (rte_pci_write_config(pdev, &tmp, 4, off) != 4) {
> + printf("[%s()] failed to write pci config space at offset
> %d\n",
> + __func__, (int)off);
> + return -1;
> + }
> +
> + off = err_cap_offset + DLB_PCI_ERR_COR_STATUS;
> + if (rte_pci_read_config(pdev, &tmp, 4, off) != 4)
> + tmp = 0;
> +
> + if (rte_pci_write_config(pdev, &tmp, 4, off) != 4) {
> + printf("[%s()] failed to write pci config space at offset
> %d\n",
> + __func__, (int)off);
> + return -1;
> + }
> +
> + off = err_cap_offset + DLB_PCI_ERR_UNCOR_STATUS;
> + if (rte_pci_read_config(pdev, &tmp, 4, off) != 4)
> + tmp = 0;
> +
> + if (rte_pci_write_config(pdev, &tmp, 4, off) != 4) {
> + printf("[%s()] failed to write pci config space at offset
> %d\n",
> + __func__, (int)off);
> + return -1;
> + }
> + }
> +
> + for (i = 16; i > 0; i--) {
> + off = (i - 1) * 4;
> + if (rte_pci_write_config(pdev, &dword[i - 1], 4, off) != 4) {
> + printf("[%s()] failed to write pci config space at offset
> %d\n",
> + __func__, (int)off);
> + return -1;
> + }
> + }
> +
> + off = DLB_PCI_CMD;
> + if (rte_pci_read_config(pdev, &cmd, 2, off) == 2) {
> + cmd &= ~DLB_PCI_COMMAND_INTX_DISABLE;
> + if (rte_pci_write_config(pdev, &cmd, 2, off) != 2) {
> + printf("[%s()] failed to write pci config space\n",
> + __func__);
> + return -1;
> + }
> + }
> +
> + msix_cap_offset = dlb_pci_find_capability(pdev,
> DLB_PCI_CAP_ID_MSIX);
> + if (msix_cap_offset >= 0) {
> + off = msix_cap_offset + DLB_PCI_MSIX_FLAGS;
> + if (rte_pci_read_config(pdev, &cmd, 2, off) == 2) {
> + cmd |= DLB_PCI_MSIX_FLAGS_ENABLE;
> + cmd |= DLB_PCI_MSIX_FLAGS_MASKALL;
> + if (rte_pci_write_config(pdev, &cmd, 2, off) != 2) {
> + printf("[%s()] failed to write msix flags\n",
> + __func__);
> + return -1;
> + }
> + }
> +
> + off = msix_cap_offset + DLB_PCI_MSIX_FLAGS;
> + if (rte_pci_read_config(pdev, &cmd, 2, off) == 2) {
> + cmd &= ~DLB_PCI_MSIX_FLAGS_MASKALL;
> + if (rte_pci_write_config(pdev, &cmd, 2, off) != 2) {
> + printf("[%s()] failed to write msix flags\n",
> + __func__);
> + return -1;
> + }
> + }
> + }
> +
> + acs_cap_offset = dlb_pci_find_ext_capability(pdev,
> + DLB_PCI_EXT_CAP_ID_ACS);
> + if (acs_cap_offset >= 0) {
> + uint16_t acs_cap, acs_ctrl, acs_mask;
> + off = acs_cap_offset + DLB_PCI_ACS_CAP;
> + if (rte_pci_read_config(pdev, &acs_cap, 2, off) != 2)
> + acs_cap = 0;
> +
> + off = acs_cap_offset + DLB_PCI_ACS_CTRL;
> + if (rte_pci_read_config(pdev, &acs_ctrl, 2, off) != 2)
> + acs_ctrl = 0;
> +
> + acs_mask = DLB_PCI_ACS_SV | DLB_PCI_ACS_RR;
> + acs_mask |= (DLB_PCI_ACS_CR | DLB_PCI_ACS_UF);
> + acs_ctrl |= (acs_cap & acs_mask);
> +
> + if (rte_pci_write_config(pdev, &acs_ctrl, 2, off) != 2) {
> + printf("[%s()] failed to write pci config space at offset
> %d\n",
> + __func__, (int)off);
> + return -1;
> + }
> +
> + off = acs_cap_offset + DLB_PCI_ACS_CTRL;
> + if (rte_pci_read_config(pdev, &acs_ctrl, 2, off) != 2)
> + acs_ctrl = 0;
> +
> + acs_mask = DLB_PCI_ACS_RR | DLB_PCI_ACS_CR |
> DLB_PCI_ACS_EC;
> + acs_ctrl &= ~acs_mask;
> +
> + off = acs_cap_offset + DLB_PCI_ACS_CTRL;
> + if (rte_pci_write_config(pdev, &acs_ctrl, 2, off) != 2) {
> + printf("[%s()] failed to write pci config space at offset
> %d\n",
> + __func__, (int)off);
> + return -1;
> + }
> + }
> +
> + return 0;
> +}
Like I suggested in [1], this PCI-specific code might be a good candidate for
a separate file.
Thanks,
Gage
More information about the dev
mailing list