/* SPDX-License-Identifier: BSD-3-Clause * Copyright (c) 2023 Marvell. */ #ifndef RTE_EVENT_DMA_ADAPTER #define RTE_EVENT_DMA_ADAPTER /** * @file rte_event_dma_adapter.h * * @warning * @b EXPERIMENTAL: * All functions in this file may be changed or removed without prior notice. * * DMA Event Adapter API. * * Eventdev library provides adapters to bridge between various components for providing new * event source. The event DMA adapter is one of those adapters which is intended to bridge * between event devices and DMA devices. * * The DMA adapter adds support to enqueue / dequeue DMA operations to / from event device. The * packet flow between DMA device and the event device can be accomplished using both SW and HW * based transfer mechanisms. The adapter uses an EAL service core function for SW based packet * transfer and uses the eventdev PMD functions to configure HW based packet transfer between the * DMA device and the event device. * * The application can choose to submit a DMA operation directly to an DMA device or send it to the * DMA adapter via eventdev based on RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_FWD capability. The * first mode is known as the event new (RTE_EVENT_DMA_ADAPTER_OP_NEW) mode and the second as the * event forward (RTE_EVENT_DMA_ADAPTER_OP_FORWARD) mode. The choice of mode can be specified while * creating the adapter. In the former mode, it is an application responsibility to enable ingress * packet ordering. In the latter mode, it is the adapter responsibility to enable the ingress * packet ordering. * * * Working model of RTE_EVENT_DMA_ADAPTER_OP_NEW mode: * * +--------------+ +--------------+ * | | | DMA stage | * | Application |---[2]-->| + enqueue to | * | | | dmadev | * +--------------+ +--------------+ * ^ ^ | * | | [3] * [6] [1] | * | | | * +--------------+ | * | | | * | Event device | | * | | | * +--------------+ | * ^ | * | | * [5] | * | v * +--------------+ +--------------+ * | | | | * | DMA adapter |<--[4]---| dmadev | * | | | | * +--------------+ +--------------+ * * * [1] Application dequeues events from the previous stage. * [2] Application prepares the DMA operations. * [3] DMA operations are submitted to dmadev by application. * [4] DMA adapter dequeues DMA completions from dmadev. * [5] DMA adapter enqueues events to the eventdev. * [6] Application dequeues from eventdev for further processing. * * In the RTE_EVENT_DMA_ADAPTER_OP_NEW mode, application submits DMA operations directly to DMA * device. The DMA adapter then dequeues DMA completions from DMA device and enqueue events to the * event device. This mode does not ensure ingress ordering, if the application directly enqueues * to dmadev without going through DMA / atomic stage i.e. removing item [1] and [2]. * * Events dequeued from the adapter will be treated as new events. In this mode, application needs * to specify event information (response information) which is needed to enqueue an event after the * DMA operation is completed. * * * Working model of RTE_EVENT_DMA_ADAPTER_OP_FORWARD mode: * * +--------------+ +--------------+ * --[1]-->| |---[2]-->| Application | * | Event device | | in | * <--[8]--| |<--[3]---| Ordered stage| * +--------------+ +--------------+ * ^ | * | [4] * [7] | * | v * +----------------+ +--------------+ * | |--[5]->| | * | DMA adapter | | dmadev | * | |<-[6]--| | * +----------------+ +--------------+ * * * [1] Events from the previous stage. * [2] Application in ordered stage dequeues events from eventdev. * [3] Application enqueues DMA operations as events to eventdev. * [4] DMA adapter dequeues event from eventdev. * [5] DMA adapter submits DMA operations to dmadev (Atomic stage). * [6] DMA adapter dequeues DMA completions from dmadev * [7] DMA adapter enqueues events to the eventdev * [8] Events to the next stage * * In the event forward (RTE_EVENT_DMA_ADAPTER_OP_FORWARD) mode, if the HW supports the capability * RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_FWD, application can directly submit the DMA * operations to the dmadev. If not, application retrieves the event port of the DMA adapter * through the API, rte_event_DMA_adapter_event_port_get(). Then, links its event queue to this * port and starts enqueuing DMA operations as events to the eventdev. The adapter then dequeues * the events and submits the DMA operations to the dmadev. After the DMA completions, the adapter * enqueues events to the event device. * * Application can use this mode, when ingress packet ordering is needed. Events dequeued from the * adapter will be treated as forwarded events. In this mode, the application needs to specify the * dmadev ID and queue pair ID (request information) needed to enqueue an DMA operation in addition * to the event information (response information) needed to enqueue an event after the DMA * operation has completed. * * The event DMA adapter provides common APIs to configure the packet flow from the DMA device to * event devices for both SW and HW based transfers. The DMA event adapter's functions are: * * - rte_event_dma_adapter_create_ext() * - rte_event_dma_adapter_create() * - rte_event_dma_adapter_free() * - rte_event_dma_adapter_vchan_add() * - rte_event_dma_adapter_vchan_del() * - rte_event_dma_adapter_start() * - rte_event_dma_adapter_stop() * - rte_event_dma_adapter_stats_get() * - rte_event_dma_adapter_stats_reset() * * The application creates an instance using rte_event_dma_adapter_create() or * rte_event_dma_adapter_create_ext(). * * dmadev queue pair addition / deletion is done using the rte_event_dma_adapter_vchan_add() / * rte_event_dma_adapter_vchan_del() APIs. If HW supports the capability * RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_VCHAN_EV_BIND, event information must be passed to the * add API. * */ #include #include #include #include #ifdef __cplusplus extern "C" { #endif /** * A structure used to hold event based DMA operation entry. All the information * required for a DMA transfer shall be populated in "struct rte_event_dma_adapter_op" * instance. */ struct rte_event_dma_adapter_op { uint64_t flags; /**< Flags related to the operation. * @see RTE_DMA_OP_FLAG_* */ struct rte_mempool *op_mp; /**< Mempool from which op is allocated. */ enum rte_dma_status_code status; /**< Status code for this operation. */ uint32_t rsvd; /**< Reserved for future use. */ uint64_t impl_opaque[2]; /**< Implementation-specific opaque data. * An dma device implementation use this field to hold * implementation specific values to share between dequeue and enqueue * operations. * The application should not modify this field. */ uint64_t user_meta; /**< Memory to store user specific metadata. * The dma device implementation should not modify this area. */ uint64_t event_meta; /**< Event metadata of DMA completion event. * Used when RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_VCHAN_EV_BIND is not * supported in OP_NEW mode. * @see rte_event_dma_adapter_mode::RTE_EVENT_DMA_ADAPTER_OP_NEW * @see RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_VCHAN_EV_BIND * * Used when RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_FWD is not * supported in OP_FWD mode. * @see rte_event_dma_adapter_mode::RTE_EVENT_DMA_ADAPTER_OP_FORWARD * @see RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_FWD * * @see struct rte_event::event */ int16_t dma_dev_id; /**< DMA device ID to be used with OP_FORWARD mode. * @see rte_event_dma_adapter_mode::RTE_EVENT_DMA_ADAPTER_OP_FORWARD */ uint16_t vchan; /**< DMA vchan ID to be used with OP_FORWARD mode * @see rte_event_dma_adapter_mode::RTE_EVENT_DMA_ADAPTER_OP_FORWARD */ uint16_t nb_src; /**< Number of source segments. */ uint16_t nb_dst; /**< Number of destination segments. */ struct rte_dma_sge src_dst_seg[]; /**< Source and destination segments. */ }; /** * DMA event adapter mode */ enum rte_event_dma_adapter_mode { RTE_EVENT_DMA_ADAPTER_OP_NEW, /**< Start the DMA adapter in event new mode. * @see RTE_EVENT_OP_NEW. * * Application submits DMA operations to the dmadev. Adapter only dequeues the DMA * completions from dmadev and enqueue events to the eventdev. */ RTE_EVENT_DMA_ADAPTER_OP_FORWARD, /**< Start the DMA adapter in event forward mode. * @see RTE_EVENT_OP_FORWARD. * * Application submits DMA requests as events to the DMA adapter or DMA device based on * RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_FWD capability. DMA completions are enqueued * back to the eventdev by DMA adapter. */ }; /** * Adapter configuration structure that the adapter configuration callback function is expected to * fill out. * * @see rte_event_dma_adapter_conf_cb */ struct rte_event_dma_adapter_conf { uint8_t event_port_id; /** < Event port identifier, the adapter enqueues events to this port and dequeues DMA * request events in RTE_EVENT_DMA_ADAPTER_OP_FORWARD mode. */ uint32_t max_nb; /**< The adapter can return early if it has processed at least max_nb DMA ops. This isn't * treated as a requirement; batching may cause the adapter to process more than max_nb DMA * ops. */ }; /** * Adapter runtime configuration parameters */ struct rte_event_dma_adapter_runtime_params { uint32_t max_nb; /**< The adapter can return early if it has processed at least max_nb DMA ops. This isn't * treated as a requirement; batching may cause the adapter to process more than max_nb DMA * ops. * * Callback function passed to rte_event_dma_adapter_create_ext() configures the adapter * with default value of max_nb. * rte_event_dma_adapter_runtime_params_set() allows to re-configure max_nb during runtime * (after adding at least one queue pair) * * This is valid for the devices without RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_FWD or * RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_NEW capability. */ uint32_t rsvd[15]; /**< Reserved fields for future expansion */ }; /** * Function type used for adapter configuration callback. The callback is used to fill in members of * the struct rte_event_dma_adapter_conf, this callback is invoked when creating a SW service for * packet transfer from dmadev vchan to the event device. The SW service is created within the * function, rte_event_dma_adapter_vchan_add(), if SW based packet transfers from dmadev vchan * to the event device are required. * * @param id * Adapter identifier. * @param evdev_id * Event device identifier. * @param conf * Structure that needs to be populated by this callback. * @param arg * Argument to the callback. This is the same as the conf_arg passed to the * rte_event_dma_adapter_create_ext(). */ typedef int (*rte_event_dma_adapter_conf_cb)(uint8_t id, uint8_t evdev_id, struct rte_event_dma_adapter_conf *conf, void *arg); /** * A structure used to retrieve statistics for an event DMA adapter instance. */ struct rte_event_dma_adapter_stats { uint64_t event_poll_count; /**< Event port poll count */ uint64_t event_deq_count; /**< Event dequeue count */ uint64_t dma_enq_count; /**< dmadev enqueue count */ uint64_t dma_enq_fail_count; /**< dmadev enqueue failed count */ uint64_t dma_deq_count; /**< dmadev dequeue count */ uint64_t event_enq_count; /**< Event enqueue count */ uint64_t event_enq_retry_count; /**< Event enqueue retry count */ uint64_t event_enq_fail_count; /**< Event enqueue fail count */ }; /** * Create a new event DMA adapter with the specified identifier. * * @param id * Adapter identifier. * @param evdev_id * Event device identifier. * @param conf_cb * Callback function that fills in members of a struct rte_event_dma_adapter_conf struct passed * into it. * @param mode * Flag to indicate the mode of the adapter. * @see rte_event_dma_adapter_mode * @param conf_arg * Argument that is passed to the conf_cb function. * * @return * - 0: Success * - <0: Error code on failure */ __rte_experimental int rte_event_dma_adapter_create_ext(uint8_t id, uint8_t evdev_id, rte_event_dma_adapter_conf_cb conf_cb, enum rte_event_dma_adapter_mode mode, void *conf_arg); /** * Create a new event DMA adapter with the specified identifier. This function uses an internal * configuration function that creates an event port. This default function reconfigures the event * device with an additional event port and set up the event port using the port_config parameter * passed into this function. In case the application needs more control in configuration of the * service, it should use the rte_event_dma_adapter_create_ext() version. * * @param id * Adapter identifier. * @param evdev_id * Event device identifier. * @param port_config * Argument of type *rte_event_port_conf* that is passed to the conf_cb function. * @param mode * Flag to indicate the mode of the adapter. * @see rte_event_dma_adapter_mode * * @return * - 0: Success * - <0: Error code on failure */ __rte_experimental int rte_event_dma_adapter_create(uint8_t id, uint8_t evdev_id, struct rte_event_port_conf *port_config, enum rte_event_dma_adapter_mode mode); /** * Free an event DMA adapter * * @param id * Adapter identifier. * @return * - 0: Success * - <0: Error code on failure, If the adapter still has queue pairs added to it, the function * returns -EBUSY. */ __rte_experimental int rte_event_dma_adapter_free(uint8_t id); /** * Retrieve the event port of an adapter. * * @param id * Adapter identifier. * * @param [out] event_port_id * Application links its event queue to this adapter port which is used in * RTE_EVENT_DMA_ADAPTER_OP_FORWARD mode. * * @return * - 0: Success * - <0: Error code on failure. */ __rte_experimental int rte_event_dma_adapter_event_port_get(uint8_t id, uint8_t *event_port_id); /** * Add a vchan to an event DMA adapter. * * @param id * Adapter identifier. * @param dmadev_id * dmadev identifier. * @param vchan * DMA device vchan identifier. If vchan is set -1, adapter adds all the * preconfigured vchan to the instance. * @param event * If HW supports dmadev vchan to event queue binding, application is expected to fill in * event information, else it will be NULL. * @see RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_VCHAN_EV_BIND * * @return * - 0: Success, vchan added correctly. * - <0: Error code on failure. */ __rte_experimental int rte_event_dma_adapter_vchan_add(uint8_t id, int16_t dmadev_id, uint16_t vchan, const struct rte_event *event); /** * Delete a vchan from an event DMA adapter. * * @param id * Adapter identifier. * @param dmadev_id * DMA device identifier. * @param vchan * DMA device vchan identifier. * * @return * - 0: Success, vchan deleted successfully. * - <0: Error code on failure. */ __rte_experimental int rte_event_dma_adapter_vchan_del(uint8_t id, int16_t dmadev_id, uint16_t vchan); /** * Retrieve the service ID of an adapter. If the adapter doesn't use a rte_service function, this * function returns -ESRCH. * * @param id * Adapter identifier. * @param [out] service_id * A pointer to a uint32_t, to be filled in with the service id. * * @return * - 0: Success * - <0: Error code on failure, if the adapter doesn't use a rte_service function, this function * returns -ESRCH. */ __rte_experimental int rte_event_dma_adapter_service_id_get(uint8_t id, uint32_t *service_id); /** * Start event DMA adapter * * @param id * Adapter identifier. * * @return * - 0: Success, adapter started successfully. * - <0: Error code on failure. * * @note The eventdev and dmadev to which the event_dma_adapter is connected should be started * before calling rte_event_dma_adapter_start(). */ __rte_experimental int rte_event_dma_adapter_start(uint8_t id); /** * Stop event DMA adapter * * @param id * Adapter identifier. * * @return * - 0: Success, adapter stopped successfully. * - <0: Error code on failure. */ __rte_experimental int rte_event_dma_adapter_stop(uint8_t id); /** * Initialize the adapter runtime configuration parameters * * @param params * A pointer to structure of type struct rte_event_dma_adapter_runtime_params * * @return * - 0: Success * - <0: Error code on failure */ __rte_experimental int rte_event_dma_adapter_runtime_params_init(struct rte_event_dma_adapter_runtime_params *params); /** * Set the adapter runtime configuration parameters * * @param id * Adapter identifier * * @param params * A pointer to structure of type struct rte_event_dma_adapter_runtime_params with configuration * parameter values. The reserved fields of this structure must be initialized to zero and the valid * fields need to be set appropriately. This struct can be initialized using * rte_event_dma_adapter_runtime_params_init() API to default values or application may reset this * struct and update required fields. * * @return * - 0: Success * - <0: Error code on failure */ __rte_experimental int rte_event_dma_adapter_runtime_params_set(uint8_t id, struct rte_event_dma_adapter_runtime_params *params); /** * Get the adapter runtime configuration parameters * * @param id * Adapter identifier * * @param[out] params * A pointer to structure of type struct rte_event_dma_adapter_runtime_params containing valid * adapter parameters when return value is 0. * * @return * - 0: Success * - <0: Error code on failure */ __rte_experimental int rte_event_dma_adapter_runtime_params_get(uint8_t id, struct rte_event_dma_adapter_runtime_params *params); /** * Retrieve statistics for an adapter * * @param id * Adapter identifier. * @param [out] stats * A pointer to structure used to retrieve statistics for an adapter. * * @return * - 0: Success, retrieved successfully. * - <0: Error code on failure. */ __rte_experimental int rte_event_dma_adapter_stats_get(uint8_t id, struct rte_event_dma_adapter_stats *stats); /** * Reset statistics for an adapter. * * @param id * Adapter identifier. * * @return * - 0: Success, statistics reset successfully. * - <0: Error code on failure. */ __rte_experimental int rte_event_dma_adapter_stats_reset(uint8_t id); /** * Enqueue a burst of DMA operations as event objects supplied in *rte_event* structure on an event * DMA adapter designated by its event *evdev_id* through the event port specified by *port_id*. * This function is supported if the eventdev PMD has the * #RTE_EVENT_DMA_ADAPTER_CAP_INTERNAL_PORT_OP_FWD capability flag set. * * The *nb_events* parameter is the number of event objects to enqueue that are supplied in the * *ev* array of *rte_event* structure. * * The rte_event_dma_adapter_enqueue() function returns the number of event objects it actually * enqueued. A return value equal to *nb_events* means that all event objects have been enqueued. * * @param evdev_id * The identifier of the device. * @param port_id * The identifier of the event port. * @param ev * Points to an array of *nb_events* objects of type *rte_event* structure which contain the * event object enqueue operations to be processed. * @param nb_events * The number of event objects to enqueue, typically number of * rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...) available for this port. * * @return * The number of event objects actually enqueued on the event device. The return value can be * less than the value of the *nb_events* parameter when the event devices queue is full or if * invalid parameters are specified in a *rte_event*. If the return value is less than *nb_events*, * the remaining events at the end of ev[] are not consumed and the caller has to take care of them, * and rte_errno is set accordingly. Possible errno values include: * - EINVAL: The port ID is invalid, device ID is invalid, an event's queue ID is invalid, or an * event's sched type doesn't match the capabilities of the destination queue. * - ENOSPC: The event port was backpressured and unable to enqueue one or more events. This * error code is only applicable to closed systems. */ __rte_experimental uint16_t rte_event_dma_adapter_enqueue(uint8_t evdev_id, uint8_t port_id, struct rte_event ev[], uint16_t nb_events); #ifdef __cplusplus } #endif #endif /* RTE_EVENT_DMA_ADAPTER */