1b36970f2SChengwen Feng /* SPDX-License-Identifier: BSD-3-Clause 2b36970f2SChengwen Feng * Copyright(c) 2021 HiSilicon Limited 3b36970f2SChengwen Feng * Copyright(c) 2021 Intel Corporation 4b36970f2SChengwen Feng * Copyright(c) 2021 Marvell International Ltd 5b36970f2SChengwen Feng * Copyright(c) 2021 SmartShare Systems 6b36970f2SChengwen Feng */ 7b36970f2SChengwen Feng 8b36970f2SChengwen Feng #ifndef RTE_DMADEV_H 9b36970f2SChengwen Feng #define RTE_DMADEV_H 10b36970f2SChengwen Feng 11b36970f2SChengwen Feng /** 12b36970f2SChengwen Feng * @file rte_dmadev.h 13b36970f2SChengwen Feng * 14b36970f2SChengwen Feng * DMA (Direct Memory Access) device API. 15b36970f2SChengwen Feng * 16b36970f2SChengwen Feng * The DMA framework is built on the following model: 17b36970f2SChengwen Feng * 18b36970f2SChengwen Feng * --------------- --------------- --------------- 19b36970f2SChengwen Feng * | virtual DMA | | virtual DMA | | virtual DMA | 20b36970f2SChengwen Feng * | channel | | channel | | channel | 21b36970f2SChengwen Feng * --------------- --------------- --------------- 22b36970f2SChengwen Feng * | | | 23b36970f2SChengwen Feng * ------------------ | 24b36970f2SChengwen Feng * | | 25b36970f2SChengwen Feng * ------------ ------------ 26b36970f2SChengwen Feng * | dmadev | | dmadev | 27b36970f2SChengwen Feng * ------------ ------------ 28b36970f2SChengwen Feng * | | 29b36970f2SChengwen Feng * ------------------ ------------------ 30b36970f2SChengwen Feng * | HW DMA channel | | HW DMA channel | 31b36970f2SChengwen Feng * ------------------ ------------------ 32b36970f2SChengwen Feng * | | 33b36970f2SChengwen Feng * -------------------------------- 34b36970f2SChengwen Feng * | 35b36970f2SChengwen Feng * --------------------- 36b36970f2SChengwen Feng * | HW DMA Controller | 37b36970f2SChengwen Feng * --------------------- 38b36970f2SChengwen Feng * 39b36970f2SChengwen Feng * The DMA controller could have multiple HW-DMA-channels (aka. HW-DMA-queues), 40b36970f2SChengwen Feng * each HW-DMA-channel should be represented by a dmadev. 41b36970f2SChengwen Feng * 42b36970f2SChengwen Feng * The dmadev could create multiple virtual DMA channels, each virtual DMA 43b36970f2SChengwen Feng * channel represents a different transfer context. The DMA operation request 44b36970f2SChengwen Feng * must be submitted to the virtual DMA channel. e.g. Application could create 45b36970f2SChengwen Feng * virtual DMA channel 0 for memory-to-memory transfer scenario, and create 46b36970f2SChengwen Feng * virtual DMA channel 1 for memory-to-device transfer scenario. 47b36970f2SChengwen Feng * 48b36970f2SChengwen Feng * This framework uses 'int16_t dev_id' as the device identifier of a dmadev, 49b36970f2SChengwen Feng * and 'uint16_t vchan' as the virtual DMA channel identifier in one dmadev. 50b36970f2SChengwen Feng * 51e0180db1SChengwen Feng * The functions exported by the dmadev API to setup a device designated by its 52e0180db1SChengwen Feng * device identifier must be invoked in the following order: 53e0180db1SChengwen Feng * - rte_dma_configure() 54e0180db1SChengwen Feng * - rte_dma_vchan_setup() 55e0180db1SChengwen Feng * - rte_dma_start() 56e0180db1SChengwen Feng * 57e0180db1SChengwen Feng * Then, the application can invoke dataplane functions to process jobs. 58e0180db1SChengwen Feng * 59e0180db1SChengwen Feng * If the application wants to change the configuration (i.e. invoke 60e0180db1SChengwen Feng * rte_dma_configure() or rte_dma_vchan_setup()), it must invoke 61e0180db1SChengwen Feng * rte_dma_stop() first to stop the device and then do the reconfiguration 62e0180db1SChengwen Feng * before invoking rte_dma_start() again. The dataplane functions should not 63e0180db1SChengwen Feng * be invoked when the device is stopped. 64e0180db1SChengwen Feng * 65e0180db1SChengwen Feng * Finally, an application can close a dmadev by invoking the rte_dma_close() 66e0180db1SChengwen Feng * function. 67e0180db1SChengwen Feng * 6891e581e5SChengwen Feng * The dataplane APIs include two parts: 6991e581e5SChengwen Feng * The first part is the submission of operation requests: 7091e581e5SChengwen Feng * - rte_dma_copy() 7191e581e5SChengwen Feng * - rte_dma_copy_sg() 7291e581e5SChengwen Feng * - rte_dma_fill() 7391e581e5SChengwen Feng * - rte_dma_submit() 7491e581e5SChengwen Feng * 7591e581e5SChengwen Feng * These APIs could work with different virtual DMA channels which have 7691e581e5SChengwen Feng * different contexts. 7791e581e5SChengwen Feng * 7891e581e5SChengwen Feng * The first three APIs are used to submit the operation request to the virtual 7991e581e5SChengwen Feng * DMA channel, if the submission is successful, a positive 8091e581e5SChengwen Feng * ring_idx <= UINT16_MAX is returned, otherwise a negative number is returned. 8191e581e5SChengwen Feng * 8291e581e5SChengwen Feng * The last API is used to issue doorbell to hardware, and also there are flags 8391e581e5SChengwen Feng * (@see RTE_DMA_OP_FLAG_SUBMIT) parameter of the first three APIs could do the 8491e581e5SChengwen Feng * same work. 8591e581e5SChengwen Feng * @note When enqueuing a set of jobs to the device, having a separate submit 8691e581e5SChengwen Feng * outside a loop makes for clearer code than having a check for the last 8791e581e5SChengwen Feng * iteration inside the loop to set a special submit flag. However, for cases 8891e581e5SChengwen Feng * where one item alone is to be submitted or there is a small set of jobs to 8991e581e5SChengwen Feng * be submitted sequentially, having a submit flag provides a lower-overhead 9091e581e5SChengwen Feng * way of doing the submission while still keeping the code clean. 9191e581e5SChengwen Feng * 9291e581e5SChengwen Feng * The second part is to obtain the result of requests: 9391e581e5SChengwen Feng * - rte_dma_completed() 9491e581e5SChengwen Feng * - return the number of operation requests completed successfully. 9591e581e5SChengwen Feng * - rte_dma_completed_status() 9691e581e5SChengwen Feng * - return the number of operation requests completed. 9791e581e5SChengwen Feng * 9891e581e5SChengwen Feng * @note If the dmadev works in silent mode (@see RTE_DMA_CAPA_SILENT), 9991e581e5SChengwen Feng * application does not invoke the above two completed APIs. 10091e581e5SChengwen Feng * 10191e581e5SChengwen Feng * About the ring_idx which enqueue APIs (e.g. rte_dma_copy(), rte_dma_fill()) 10291e581e5SChengwen Feng * return, the rules are as follows: 10391e581e5SChengwen Feng * - ring_idx for each virtual DMA channel are independent. 10491e581e5SChengwen Feng * - For a virtual DMA channel, the ring_idx is monotonically incremented, 10591e581e5SChengwen Feng * when it reach UINT16_MAX, it wraps back to zero. 10691e581e5SChengwen Feng * - This ring_idx can be used by applications to track per-operation 10791e581e5SChengwen Feng * metadata in an application-defined circular ring. 10891e581e5SChengwen Feng * - The initial ring_idx of a virtual DMA channel is zero, after the 10991e581e5SChengwen Feng * device is stopped, the ring_idx needs to be reset to zero. 11091e581e5SChengwen Feng * 11191e581e5SChengwen Feng * One example: 11291e581e5SChengwen Feng * - step-1: start one dmadev 11391e581e5SChengwen Feng * - step-2: enqueue a copy operation, the ring_idx return is 0 11491e581e5SChengwen Feng * - step-3: enqueue a copy operation again, the ring_idx return is 1 11591e581e5SChengwen Feng * - ... 11691e581e5SChengwen Feng * - step-101: stop the dmadev 11791e581e5SChengwen Feng * - step-102: start the dmadev 11891e581e5SChengwen Feng * - step-103: enqueue a copy operation, the ring_idx return is 0 11991e581e5SChengwen Feng * - ... 12091e581e5SChengwen Feng * - step-x+0: enqueue a fill operation, the ring_idx return is 65535 12191e581e5SChengwen Feng * - step-x+1: enqueue a copy operation, the ring_idx return is 0 12291e581e5SChengwen Feng * - ... 12391e581e5SChengwen Feng * 12491e581e5SChengwen Feng * The DMA operation address used in enqueue APIs (i.e. rte_dma_copy(), 12591e581e5SChengwen Feng * rte_dma_copy_sg(), rte_dma_fill()) is defined as rte_iova_t type. 12691e581e5SChengwen Feng * 12791e581e5SChengwen Feng * The dmadev supports two types of address: memory address and device address. 12891e581e5SChengwen Feng * 12991e581e5SChengwen Feng * - memory address: the source and destination address of the memory-to-memory 13091e581e5SChengwen Feng * transfer type, or the source address of the memory-to-device transfer type, 13191e581e5SChengwen Feng * or the destination address of the device-to-memory transfer type. 13291e581e5SChengwen Feng * @note If the device support SVA (@see RTE_DMA_CAPA_SVA), the memory address 13391e581e5SChengwen Feng * can be any VA address, otherwise it must be an IOVA address. 13491e581e5SChengwen Feng * 13591e581e5SChengwen Feng * - device address: the source and destination address of the device-to-device 13691e581e5SChengwen Feng * transfer type, or the source address of the device-to-memory transfer type, 13791e581e5SChengwen Feng * or the destination address of the memory-to-device transfer type. 13891e581e5SChengwen Feng * 139e0180db1SChengwen Feng * About MT-safe, all the functions of the dmadev API implemented by a PMD are 140e0180db1SChengwen Feng * lock-free functions which assume to not be invoked in parallel on different 141e0180db1SChengwen Feng * logical cores to work on the same target dmadev object. 142e0180db1SChengwen Feng * @note Different virtual DMA channels on the same dmadev *DO NOT* support 143e0180db1SChengwen Feng * parallel invocation because these virtual DMA channels share the same 144e0180db1SChengwen Feng * HW-DMA-channel. 145b36970f2SChengwen Feng */ 146b36970f2SChengwen Feng 147b36970f2SChengwen Feng #include <stdint.h> 148b36970f2SChengwen Feng 149b36970f2SChengwen Feng #include <rte_bitops.h> 150b36970f2SChengwen Feng #include <rte_common.h> 151b36970f2SChengwen Feng 152b36970f2SChengwen Feng #ifdef __cplusplus 153b36970f2SChengwen Feng extern "C" { 154b36970f2SChengwen Feng #endif 155b36970f2SChengwen Feng 156b36970f2SChengwen Feng /** Maximum number of devices if rte_dma_dev_max() is not called. */ 157b36970f2SChengwen Feng #define RTE_DMADEV_DEFAULT_MAX 64 158b36970f2SChengwen Feng 159b36970f2SChengwen Feng /** 160b36970f2SChengwen Feng * Configure the maximum number of dmadevs. 161b36970f2SChengwen Feng * @note This function can be invoked before the primary process rte_eal_init() 162b36970f2SChengwen Feng * to change the maximum number of dmadevs. If not invoked, the maximum number 163b36970f2SChengwen Feng * of dmadevs is @see RTE_DMADEV_DEFAULT_MAX 164b36970f2SChengwen Feng * 165b36970f2SChengwen Feng * @param dev_max 166b36970f2SChengwen Feng * maximum number of dmadevs. 167b36970f2SChengwen Feng * 168b36970f2SChengwen Feng * @return 169b36970f2SChengwen Feng * 0 on success. Otherwise negative value is returned. 170b36970f2SChengwen Feng */ 171b36970f2SChengwen Feng int rte_dma_dev_max(size_t dev_max); 172b36970f2SChengwen Feng 173b36970f2SChengwen Feng /** 174b36970f2SChengwen Feng * Get the device identifier for the named DMA device. 175b36970f2SChengwen Feng * 176b36970f2SChengwen Feng * @param name 177b36970f2SChengwen Feng * DMA device name. 178b36970f2SChengwen Feng * 179b36970f2SChengwen Feng * @return 180b36970f2SChengwen Feng * Returns DMA device identifier on success. 181b36970f2SChengwen Feng * - <0: Failure to find named DMA device. 182b36970f2SChengwen Feng */ 183b36970f2SChengwen Feng int rte_dma_get_dev_id_by_name(const char *name); 184b36970f2SChengwen Feng 185b36970f2SChengwen Feng /** 186b36970f2SChengwen Feng * Check whether the dev_id is valid. 187b36970f2SChengwen Feng * 188b36970f2SChengwen Feng * @param dev_id 189b36970f2SChengwen Feng * DMA device index. 190b36970f2SChengwen Feng * 191b36970f2SChengwen Feng * @return 192b36970f2SChengwen Feng * - If the device index is valid (true) or not (false). 193b36970f2SChengwen Feng */ 194b36970f2SChengwen Feng bool rte_dma_is_valid(int16_t dev_id); 195b36970f2SChengwen Feng 196b36970f2SChengwen Feng /** 197b36970f2SChengwen Feng * Get the total number of DMA devices that have been successfully 198b36970f2SChengwen Feng * initialised. 199b36970f2SChengwen Feng * 200b36970f2SChengwen Feng * @return 201b36970f2SChengwen Feng * The total number of usable DMA devices. 202b36970f2SChengwen Feng */ 203b36970f2SChengwen Feng uint16_t rte_dma_count_avail(void); 204b36970f2SChengwen Feng 205190f7e84SBruce Richardson /** 206190f7e84SBruce Richardson * Iterates over valid dmadev instances. 207190f7e84SBruce Richardson * 208190f7e84SBruce Richardson * @param start_dev_id 209190f7e84SBruce Richardson * The id of the next possible dmadev. 210190f7e84SBruce Richardson * @return 211190f7e84SBruce Richardson * Next valid dmadev, UINT16_MAX if there is none. 212190f7e84SBruce Richardson */ 213190f7e84SBruce Richardson int16_t rte_dma_next_dev(int16_t start_dev_id); 214190f7e84SBruce Richardson 215190f7e84SBruce Richardson /** Utility macro to iterate over all available dmadevs */ 216190f7e84SBruce Richardson #define RTE_DMA_FOREACH_DEV(p) \ 217190f7e84SBruce Richardson for (p = rte_dma_next_dev(0); \ 218190f7e84SBruce Richardson p != -1; \ 219190f7e84SBruce Richardson p = rte_dma_next_dev(p + 1)) 220190f7e84SBruce Richardson 221190f7e84SBruce Richardson 222e0180db1SChengwen Feng /**@{@name DMA capability 223e0180db1SChengwen Feng * @see struct rte_dma_info::dev_capa 224e0180db1SChengwen Feng */ 225e0180db1SChengwen Feng /** Support memory-to-memory transfer */ 226e0180db1SChengwen Feng #define RTE_DMA_CAPA_MEM_TO_MEM RTE_BIT64(0) 227e0180db1SChengwen Feng /** Support memory-to-device transfer. */ 228e0180db1SChengwen Feng #define RTE_DMA_CAPA_MEM_TO_DEV RTE_BIT64(1) 229e0180db1SChengwen Feng /** Support device-to-memory transfer. */ 230e0180db1SChengwen Feng #define RTE_DMA_CAPA_DEV_TO_MEM RTE_BIT64(2) 231e0180db1SChengwen Feng /** Support device-to-device transfer. */ 232e0180db1SChengwen Feng #define RTE_DMA_CAPA_DEV_TO_DEV RTE_BIT64(3) 233e0180db1SChengwen Feng /** Support SVA which could use VA as DMA address. 234e0180db1SChengwen Feng * If device support SVA then application could pass any VA address like memory 235e0180db1SChengwen Feng * from rte_malloc(), rte_memzone(), malloc, stack memory. 236e0180db1SChengwen Feng * If device don't support SVA, then application should pass IOVA address which 237e0180db1SChengwen Feng * from rte_malloc(), rte_memzone(). 238e0180db1SChengwen Feng */ 239e0180db1SChengwen Feng #define RTE_DMA_CAPA_SVA RTE_BIT64(4) 240e0180db1SChengwen Feng /** Support work in silent mode. 241e0180db1SChengwen Feng * In this mode, application don't required to invoke rte_dma_completed*() 242e0180db1SChengwen Feng * API. 243e0180db1SChengwen Feng * @see struct rte_dma_conf::silent_mode 244e0180db1SChengwen Feng */ 245e0180db1SChengwen Feng #define RTE_DMA_CAPA_SILENT RTE_BIT64(5) 2462e348d8fSBruce Richardson /** Supports error handling 2472e348d8fSBruce Richardson * 2482e348d8fSBruce Richardson * With this bit set, invalid input addresses will be reported as operation failures 2492e348d8fSBruce Richardson * to the user but other operations can continue. 2502e348d8fSBruce Richardson * Without this bit set, invalid data is not handled by either HW or driver, so user 2512e348d8fSBruce Richardson * must ensure that all memory addresses are valid and accessible by HW. 2522e348d8fSBruce Richardson */ 2532e348d8fSBruce Richardson #define RTE_DMA_CAPA_HANDLES_ERRORS RTE_BIT64(6) 254877cb3e3SAmit Prakash Shukla /** Support auto free for source buffer once mem to dev transfer is completed. 255877cb3e3SAmit Prakash Shukla * 256877cb3e3SAmit Prakash Shukla * @note Even though the DMA driver has this capability, it may not support all 257877cb3e3SAmit Prakash Shukla * mempool drivers. If the mempool is not supported by the DMA driver, 258877cb3e3SAmit Prakash Shukla * rte_dma_vchan_setup() will fail. 259877cb3e3SAmit Prakash Shukla */ 260877cb3e3SAmit Prakash Shukla #define RTE_DMA_CAPA_M2D_AUTO_FREE RTE_BIT64(7) 261*2dff0bcdSVamsi Attunuru /** Support strict priority scheduling. 262*2dff0bcdSVamsi Attunuru * 263*2dff0bcdSVamsi Attunuru * Application could assign fixed priority to the DMA device using 'priority' 264*2dff0bcdSVamsi Attunuru * field in struct rte_dma_conf. Number of supported priority levels will be 265*2dff0bcdSVamsi Attunuru * known from 'nb_priorities' field in struct rte_dma_info. 266*2dff0bcdSVamsi Attunuru */ 267*2dff0bcdSVamsi Attunuru #define RTE_DMA_CAPA_PRI_POLICY_SP RTE_BIT64(8) 268877cb3e3SAmit Prakash Shukla 269e0180db1SChengwen Feng /** Support copy operation. 270e0180db1SChengwen Feng * This capability start with index of 32, so that it could leave gap between 271e0180db1SChengwen Feng * normal capability and ops capability. 272e0180db1SChengwen Feng */ 273e0180db1SChengwen Feng #define RTE_DMA_CAPA_OPS_COPY RTE_BIT64(32) 274e0180db1SChengwen Feng /** Support scatter-gather list copy operation. */ 275e0180db1SChengwen Feng #define RTE_DMA_CAPA_OPS_COPY_SG RTE_BIT64(33) 276e0180db1SChengwen Feng /** Support fill operation. */ 277e0180db1SChengwen Feng #define RTE_DMA_CAPA_OPS_FILL RTE_BIT64(34) 278e0180db1SChengwen Feng /**@}*/ 279e0180db1SChengwen Feng 280e0180db1SChengwen Feng /** 281e0180db1SChengwen Feng * A structure used to retrieve the information of a DMA device. 282e0180db1SChengwen Feng * 283e0180db1SChengwen Feng * @see rte_dma_info_get 284e0180db1SChengwen Feng */ 285e0180db1SChengwen Feng struct rte_dma_info { 286e0180db1SChengwen Feng const char *dev_name; /**< Unique device name. */ 287e0180db1SChengwen Feng /** Device capabilities (RTE_DMA_CAPA_*). */ 288e0180db1SChengwen Feng uint64_t dev_capa; 289e0180db1SChengwen Feng /** Maximum number of virtual DMA channels supported. */ 290e0180db1SChengwen Feng uint16_t max_vchans; 291e0180db1SChengwen Feng /** Maximum allowed number of virtual DMA channel descriptors. */ 292e0180db1SChengwen Feng uint16_t max_desc; 293e0180db1SChengwen Feng /** Minimum allowed number of virtual DMA channel descriptors. */ 294e0180db1SChengwen Feng uint16_t min_desc; 295e0180db1SChengwen Feng /** Maximum number of source or destination scatter-gather entry 296e0180db1SChengwen Feng * supported. 297e0180db1SChengwen Feng * If the device does not support COPY_SG capability, this value can be 298e0180db1SChengwen Feng * zero. 299e0180db1SChengwen Feng * If the device supports COPY_SG capability, then rte_dma_copy_sg() 300e0180db1SChengwen Feng * parameter nb_src/nb_dst should not exceed this value. 301e0180db1SChengwen Feng */ 302e0180db1SChengwen Feng uint16_t max_sges; 303e0180db1SChengwen Feng /** NUMA node connection, -1 if unknown. */ 304e0180db1SChengwen Feng int16_t numa_node; 305e0180db1SChengwen Feng /** Number of virtual DMA channel configured. */ 306e0180db1SChengwen Feng uint16_t nb_vchans; 307*2dff0bcdSVamsi Attunuru /** Number of priority levels (must be > 1) if priority scheduling is supported, 308*2dff0bcdSVamsi Attunuru * 0 otherwise. 309*2dff0bcdSVamsi Attunuru */ 310*2dff0bcdSVamsi Attunuru uint16_t nb_priorities; 311e0180db1SChengwen Feng }; 312e0180db1SChengwen Feng 313e0180db1SChengwen Feng /** 314e0180db1SChengwen Feng * Retrieve information of a DMA device. 315e0180db1SChengwen Feng * 316e0180db1SChengwen Feng * @param dev_id 317e0180db1SChengwen Feng * The identifier of the device. 318e0180db1SChengwen Feng * @param[out] dev_info 319e0180db1SChengwen Feng * A pointer to a structure of type *rte_dma_info* to be filled with the 320e0180db1SChengwen Feng * information of the device. 321e0180db1SChengwen Feng * 322e0180db1SChengwen Feng * @return 323e0180db1SChengwen Feng * 0 on success. Otherwise negative value is returned. 324e0180db1SChengwen Feng */ 325e0180db1SChengwen Feng int rte_dma_info_get(int16_t dev_id, struct rte_dma_info *dev_info); 326e0180db1SChengwen Feng 327e0180db1SChengwen Feng /** 328e0180db1SChengwen Feng * A structure used to configure a DMA device. 329e0180db1SChengwen Feng * 330e0180db1SChengwen Feng * @see rte_dma_configure 331e0180db1SChengwen Feng */ 332e0180db1SChengwen Feng struct rte_dma_conf { 333e0180db1SChengwen Feng /** The number of virtual DMA channels to set up for the DMA device. 334e0180db1SChengwen Feng * This value cannot be greater than the field 'max_vchans' of struct 335e0180db1SChengwen Feng * rte_dma_info which get from rte_dma_info_get(). 336e0180db1SChengwen Feng */ 337e0180db1SChengwen Feng uint16_t nb_vchans; 338e0180db1SChengwen Feng /** Indicates whether to enable silent mode. 339e0180db1SChengwen Feng * false-default mode, true-silent mode. 340e0180db1SChengwen Feng * This value can be set to true only when the SILENT capability is 341e0180db1SChengwen Feng * supported. 342e0180db1SChengwen Feng * 343e0180db1SChengwen Feng * @see RTE_DMA_CAPA_SILENT 344e0180db1SChengwen Feng */ 345e0180db1SChengwen Feng bool enable_silent; 346*2dff0bcdSVamsi Attunuru /* The priority of the DMA device. 347*2dff0bcdSVamsi Attunuru * This value should be lower than the field 'nb_priorities' of struct 348*2dff0bcdSVamsi Attunuru * rte_dma_info which get from rte_dma_info_get(). If the DMA device 349*2dff0bcdSVamsi Attunuru * does not support priority scheduling, this value should be zero. 350*2dff0bcdSVamsi Attunuru * 351*2dff0bcdSVamsi Attunuru * Lowest value indicates higher priority and vice-versa. 352*2dff0bcdSVamsi Attunuru */ 353*2dff0bcdSVamsi Attunuru uint16_t priority; 354e0180db1SChengwen Feng }; 355e0180db1SChengwen Feng 356e0180db1SChengwen Feng /** 357e0180db1SChengwen Feng * Configure a DMA device. 358e0180db1SChengwen Feng * 359e0180db1SChengwen Feng * This function must be invoked first before any other function in the 360e0180db1SChengwen Feng * API. This function can also be re-invoked when a device is in the 361e0180db1SChengwen Feng * stopped state. 362e0180db1SChengwen Feng * 363e0180db1SChengwen Feng * @param dev_id 364e0180db1SChengwen Feng * The identifier of the device to configure. 365e0180db1SChengwen Feng * @param dev_conf 366e0180db1SChengwen Feng * The DMA device configuration structure encapsulated into rte_dma_conf 367e0180db1SChengwen Feng * object. 368e0180db1SChengwen Feng * 369e0180db1SChengwen Feng * @return 370e0180db1SChengwen Feng * 0 on success. Otherwise negative value is returned. 371e0180db1SChengwen Feng */ 372e0180db1SChengwen Feng int rte_dma_configure(int16_t dev_id, const struct rte_dma_conf *dev_conf); 373e0180db1SChengwen Feng 374e0180db1SChengwen Feng /** 375e0180db1SChengwen Feng * Start a DMA device. 376e0180db1SChengwen Feng * 377e0180db1SChengwen Feng * The device start step is the last one and consists of setting the DMA 378e0180db1SChengwen Feng * to start accepting jobs. 379e0180db1SChengwen Feng * 380e0180db1SChengwen Feng * @param dev_id 381e0180db1SChengwen Feng * The identifier of the device. 382e0180db1SChengwen Feng * 383e0180db1SChengwen Feng * @return 384e0180db1SChengwen Feng * 0 on success. Otherwise negative value is returned. 385e0180db1SChengwen Feng */ 386e0180db1SChengwen Feng int rte_dma_start(int16_t dev_id); 387e0180db1SChengwen Feng 388e0180db1SChengwen Feng /** 389e0180db1SChengwen Feng * Stop a DMA device. 390e0180db1SChengwen Feng * 391e0180db1SChengwen Feng * The device can be restarted with a call to rte_dma_start(). 392e0180db1SChengwen Feng * 393e0180db1SChengwen Feng * @param dev_id 394e0180db1SChengwen Feng * The identifier of the device. 395e0180db1SChengwen Feng * 396e0180db1SChengwen Feng * @return 397e0180db1SChengwen Feng * 0 on success. Otherwise negative value is returned. 398e0180db1SChengwen Feng */ 399e0180db1SChengwen Feng int rte_dma_stop(int16_t dev_id); 400e0180db1SChengwen Feng 401e0180db1SChengwen Feng /** 402e0180db1SChengwen Feng * Close a DMA device. 403e0180db1SChengwen Feng * 404e0180db1SChengwen Feng * The device cannot be restarted after this call. 405e0180db1SChengwen Feng * 406e0180db1SChengwen Feng * @param dev_id 407e0180db1SChengwen Feng * The identifier of the device. 408e0180db1SChengwen Feng * 409e0180db1SChengwen Feng * @return 410e0180db1SChengwen Feng * 0 on success. Otherwise negative value is returned. 411e0180db1SChengwen Feng */ 412e0180db1SChengwen Feng int rte_dma_close(int16_t dev_id); 413e0180db1SChengwen Feng 414e0180db1SChengwen Feng /** 415e0180db1SChengwen Feng * DMA transfer direction defines. 416e0180db1SChengwen Feng * 417e0180db1SChengwen Feng * @see struct rte_dma_vchan_conf::direction 418e0180db1SChengwen Feng */ 419e0180db1SChengwen Feng enum rte_dma_direction { 420e0180db1SChengwen Feng /** DMA transfer direction - from memory to memory. 421e0180db1SChengwen Feng * 422e0180db1SChengwen Feng * @see struct rte_dma_vchan_conf::direction 423e0180db1SChengwen Feng */ 424e0180db1SChengwen Feng RTE_DMA_DIR_MEM_TO_MEM, 425e0180db1SChengwen Feng /** DMA transfer direction - from memory to device. 426e0180db1SChengwen Feng * In a typical scenario, the SoCs are installed on host servers as 427e0180db1SChengwen Feng * iNICs through the PCIe interface. In this case, the SoCs works in 428e0180db1SChengwen Feng * EP(endpoint) mode, it could initiate a DMA move request from memory 429e0180db1SChengwen Feng * (which is SoCs memory) to device (which is host memory). 430e0180db1SChengwen Feng * 431e0180db1SChengwen Feng * @see struct rte_dma_vchan_conf::direction 432e0180db1SChengwen Feng */ 433e0180db1SChengwen Feng RTE_DMA_DIR_MEM_TO_DEV, 434e0180db1SChengwen Feng /** DMA transfer direction - from device to memory. 435e0180db1SChengwen Feng * In a typical scenario, the SoCs are installed on host servers as 436e0180db1SChengwen Feng * iNICs through the PCIe interface. In this case, the SoCs works in 437e0180db1SChengwen Feng * EP(endpoint) mode, it could initiate a DMA move request from device 438e0180db1SChengwen Feng * (which is host memory) to memory (which is SoCs memory). 439e0180db1SChengwen Feng * 440e0180db1SChengwen Feng * @see struct rte_dma_vchan_conf::direction 441e0180db1SChengwen Feng */ 442e0180db1SChengwen Feng RTE_DMA_DIR_DEV_TO_MEM, 443e0180db1SChengwen Feng /** DMA transfer direction - from device to device. 444e0180db1SChengwen Feng * In a typical scenario, the SoCs are installed on host servers as 445e0180db1SChengwen Feng * iNICs through the PCIe interface. In this case, the SoCs works in 446e0180db1SChengwen Feng * EP(endpoint) mode, it could initiate a DMA move request from device 447e0180db1SChengwen Feng * (which is host memory) to the device (which is another host memory). 448e0180db1SChengwen Feng * 449e0180db1SChengwen Feng * @see struct rte_dma_vchan_conf::direction 450e0180db1SChengwen Feng */ 451e0180db1SChengwen Feng RTE_DMA_DIR_DEV_TO_DEV, 452e0180db1SChengwen Feng }; 453e0180db1SChengwen Feng 454e0180db1SChengwen Feng /** 455e0180db1SChengwen Feng * DMA access port type defines. 456e0180db1SChengwen Feng * 457e0180db1SChengwen Feng * @see struct rte_dma_port_param::port_type 458e0180db1SChengwen Feng */ 459e0180db1SChengwen Feng enum rte_dma_port_type { 460e0180db1SChengwen Feng RTE_DMA_PORT_NONE, 461e0180db1SChengwen Feng RTE_DMA_PORT_PCIE, /**< The DMA access port is PCIe. */ 462e0180db1SChengwen Feng }; 463e0180db1SChengwen Feng 464e0180db1SChengwen Feng /** 465e0180db1SChengwen Feng * A structure used to descript DMA access port parameters. 466e0180db1SChengwen Feng * 467e0180db1SChengwen Feng * @see struct rte_dma_vchan_conf::src_port 468e0180db1SChengwen Feng * @see struct rte_dma_vchan_conf::dst_port 469e0180db1SChengwen Feng */ 470e0180db1SChengwen Feng struct rte_dma_port_param { 471e0180db1SChengwen Feng /** The device access port type. 472e0180db1SChengwen Feng * 473e0180db1SChengwen Feng * @see enum rte_dma_port_type 474e0180db1SChengwen Feng */ 475e0180db1SChengwen Feng enum rte_dma_port_type port_type; 476e0180db1SChengwen Feng union { 477e0180db1SChengwen Feng /** PCIe access port parameters. 478e0180db1SChengwen Feng * 479e0180db1SChengwen Feng * The following model shows SoC's PCIe module connects to 480e0180db1SChengwen Feng * multiple PCIe hosts and multiple endpoints. The PCIe module 481e0180db1SChengwen Feng * has an integrated DMA controller. 482e0180db1SChengwen Feng * 483e0180db1SChengwen Feng * If the DMA wants to access the memory of host A, it can be 484e0180db1SChengwen Feng * initiated by PF1 in core0, or by VF0 of PF0 in core0. 485e0180db1SChengwen Feng * 486e0180db1SChengwen Feng * \code{.unparsed} 487e0180db1SChengwen Feng * System Bus 488e0180db1SChengwen Feng * | ----------PCIe module---------- 489e0180db1SChengwen Feng * | Bus 490e0180db1SChengwen Feng * | Interface 491e0180db1SChengwen Feng * | ----- ------------------ 492e0180db1SChengwen Feng * | | | | PCIe Core0 | 493e0180db1SChengwen Feng * | | | | | ----------- 494e0180db1SChengwen Feng * | | | | PF-0 -- VF-0 | | Host A | 495e0180db1SChengwen Feng * | | |--------| |- VF-1 |--------| Root | 496e0180db1SChengwen Feng * | | | | PF-1 | | Complex | 497e0180db1SChengwen Feng * | | | | PF-2 | ----------- 498e0180db1SChengwen Feng * | | | ------------------ 499e0180db1SChengwen Feng * | | | 500e0180db1SChengwen Feng * | | | ------------------ 501e0180db1SChengwen Feng * | | | | PCIe Core1 | 502e0180db1SChengwen Feng * | | | | | ----------- 503e0180db1SChengwen Feng * | | | | PF-0 -- VF-0 | | Host B | 504e0180db1SChengwen Feng * |-----| |--------| PF-1 -- VF-0 |--------| Root | 505e0180db1SChengwen Feng * | | | | |- VF-1 | | Complex | 506e0180db1SChengwen Feng * | | | | PF-2 | ----------- 507e0180db1SChengwen Feng * | | | ------------------ 508e0180db1SChengwen Feng * | | | 509e0180db1SChengwen Feng * | | | ------------------ 510e0180db1SChengwen Feng * | |DMA| | | ------ 511e0180db1SChengwen Feng * | | | | |--------| EP | 512e0180db1SChengwen Feng * | | |--------| PCIe Core2 | ------ 513e0180db1SChengwen Feng * | | | | | ------ 514e0180db1SChengwen Feng * | | | | |--------| EP | 515e0180db1SChengwen Feng * | | | | | ------ 516e0180db1SChengwen Feng * | ----- ------------------ 517e0180db1SChengwen Feng * 518e0180db1SChengwen Feng * \endcode 519e0180db1SChengwen Feng * 520e0180db1SChengwen Feng * @note If some fields can not be supported by the 521e0180db1SChengwen Feng * hardware/driver, then the driver ignores those fields. 522e0180db1SChengwen Feng * Please check driver-specific documentation for limitations 5237be78d02SJosh Soref * and capabilities. 524e0180db1SChengwen Feng */ 525e0180db1SChengwen Feng __extension__ 526e0180db1SChengwen Feng struct { 527e0180db1SChengwen Feng uint64_t coreid : 4; /**< PCIe core id used. */ 528e0180db1SChengwen Feng uint64_t pfid : 8; /**< PF id used. */ 529e0180db1SChengwen Feng uint64_t vfen : 1; /**< VF enable bit. */ 530e0180db1SChengwen Feng uint64_t vfid : 16; /**< VF id used. */ 531e0180db1SChengwen Feng /** The pasid filed in TLP packet. */ 532e0180db1SChengwen Feng uint64_t pasid : 20; 533e0180db1SChengwen Feng /** The attributes filed in TLP packet. */ 534e0180db1SChengwen Feng uint64_t attr : 3; 535e0180db1SChengwen Feng /** The processing hint filed in TLP packet. */ 536e0180db1SChengwen Feng uint64_t ph : 2; 537e0180db1SChengwen Feng /** The steering tag filed in TLP packet. */ 538e0180db1SChengwen Feng uint64_t st : 16; 539e0180db1SChengwen Feng } pcie; 540e0180db1SChengwen Feng }; 541e0180db1SChengwen Feng uint64_t reserved[2]; /**< Reserved for future fields. */ 542e0180db1SChengwen Feng }; 543e0180db1SChengwen Feng 544e0180db1SChengwen Feng /** 545877cb3e3SAmit Prakash Shukla * A structure used for offload auto free params. 546877cb3e3SAmit Prakash Shukla */ 547877cb3e3SAmit Prakash Shukla struct rte_dma_auto_free_param { 548877cb3e3SAmit Prakash Shukla union { 549877cb3e3SAmit Prakash Shukla struct { 550877cb3e3SAmit Prakash Shukla /** 551877cb3e3SAmit Prakash Shukla * Mempool from which buffer is allocated. Mempool info 552877cb3e3SAmit Prakash Shukla * is used for freeing buffer by hardware. 553877cb3e3SAmit Prakash Shukla * 554877cb3e3SAmit Prakash Shukla * @note If the mempool is not supported by the DMA device, 555877cb3e3SAmit Prakash Shukla * rte_dma_vchan_setup() will fail. 556877cb3e3SAmit Prakash Shukla */ 557877cb3e3SAmit Prakash Shukla struct rte_mempool *pool; 558877cb3e3SAmit Prakash Shukla } m2d; 559877cb3e3SAmit Prakash Shukla }; 560877cb3e3SAmit Prakash Shukla /** Reserved for future fields. */ 561877cb3e3SAmit Prakash Shukla uint64_t reserved[2]; 562877cb3e3SAmit Prakash Shukla }; 563877cb3e3SAmit Prakash Shukla 564877cb3e3SAmit Prakash Shukla /** 565e0180db1SChengwen Feng * A structure used to configure a virtual DMA channel. 566e0180db1SChengwen Feng * 567e0180db1SChengwen Feng * @see rte_dma_vchan_setup 568e0180db1SChengwen Feng */ 569e0180db1SChengwen Feng struct rte_dma_vchan_conf { 570e0180db1SChengwen Feng /** Transfer direction 571e0180db1SChengwen Feng * 572e0180db1SChengwen Feng * @see enum rte_dma_direction 573e0180db1SChengwen Feng */ 574e0180db1SChengwen Feng enum rte_dma_direction direction; 575e0180db1SChengwen Feng /** Number of descriptor for the virtual DMA channel */ 576e0180db1SChengwen Feng uint16_t nb_desc; 577e0180db1SChengwen Feng /** 1) Used to describes the device access port parameter in the 578e0180db1SChengwen Feng * device-to-memory transfer scenario. 579e0180db1SChengwen Feng * 2) Used to describes the source device access port parameter in the 580e0180db1SChengwen Feng * device-to-device transfer scenario. 581e0180db1SChengwen Feng * 582e0180db1SChengwen Feng * @see struct rte_dma_port_param 583e0180db1SChengwen Feng */ 584e0180db1SChengwen Feng struct rte_dma_port_param src_port; 585e0180db1SChengwen Feng /** 1) Used to describes the device access port parameter in the 586e0180db1SChengwen Feng * memory-to-device transfer scenario. 587e0180db1SChengwen Feng * 2) Used to describes the destination device access port parameter in 588e0180db1SChengwen Feng * the device-to-device transfer scenario. 589e0180db1SChengwen Feng * 590e0180db1SChengwen Feng * @see struct rte_dma_port_param 591e0180db1SChengwen Feng */ 592e0180db1SChengwen Feng struct rte_dma_port_param dst_port; 593877cb3e3SAmit Prakash Shukla /** Buffer params to auto free buffer by hardware. To free the buffer 594877cb3e3SAmit Prakash Shukla * by hardware, RTE_DMA_OP_FLAG_AUTO_FREE must be set while calling 595877cb3e3SAmit Prakash Shukla * rte_dma_copy and rte_dma_copy_sg(). 596877cb3e3SAmit Prakash Shukla * 597877cb3e3SAmit Prakash Shukla * @see RTE_DMA_OP_FLAG_AUTO_FREE 598877cb3e3SAmit Prakash Shukla * @see struct rte_dma_auto_free_param 599877cb3e3SAmit Prakash Shukla */ 600877cb3e3SAmit Prakash Shukla struct rte_dma_auto_free_param auto_free; 601e0180db1SChengwen Feng }; 602e0180db1SChengwen Feng 603e0180db1SChengwen Feng /** 604e0180db1SChengwen Feng * Allocate and set up a virtual DMA channel. 605e0180db1SChengwen Feng * 606e0180db1SChengwen Feng * @param dev_id 607e0180db1SChengwen Feng * The identifier of the device. 608e0180db1SChengwen Feng * @param vchan 609e0180db1SChengwen Feng * The identifier of virtual DMA channel. The value must be in the range 610e0180db1SChengwen Feng * [0, nb_vchans - 1] previously supplied to rte_dma_configure(). 611e0180db1SChengwen Feng * @param conf 612e0180db1SChengwen Feng * The virtual DMA channel configuration structure encapsulated into 613e0180db1SChengwen Feng * rte_dma_vchan_conf object. 614e0180db1SChengwen Feng * 615e0180db1SChengwen Feng * @return 616e0180db1SChengwen Feng * 0 on success. Otherwise negative value is returned. 617e0180db1SChengwen Feng */ 618e0180db1SChengwen Feng int rte_dma_vchan_setup(int16_t dev_id, uint16_t vchan, 619e0180db1SChengwen Feng const struct rte_dma_vchan_conf *conf); 620e0180db1SChengwen Feng 621e0180db1SChengwen Feng /** 622e0180db1SChengwen Feng * A structure used to retrieve statistics. 623e0180db1SChengwen Feng * 624e0180db1SChengwen Feng * @see rte_dma_stats_get 625e0180db1SChengwen Feng */ 626e0180db1SChengwen Feng struct rte_dma_stats { 627e0180db1SChengwen Feng /** Count of operations which were submitted to hardware. */ 628e0180db1SChengwen Feng uint64_t submitted; 629e0180db1SChengwen Feng /** Count of operations which were completed, including successful and 630e0180db1SChengwen Feng * failed completions. 631e0180db1SChengwen Feng */ 632e0180db1SChengwen Feng uint64_t completed; 633e0180db1SChengwen Feng /** Count of operations which failed to complete. */ 634e0180db1SChengwen Feng uint64_t errors; 635e0180db1SChengwen Feng }; 636e0180db1SChengwen Feng 637e0180db1SChengwen Feng /** 638e0180db1SChengwen Feng * Special ID, which is used to represent all virtual DMA channels. 639e0180db1SChengwen Feng * 640e0180db1SChengwen Feng * @see rte_dma_stats_get 641e0180db1SChengwen Feng * @see rte_dma_stats_reset 642e0180db1SChengwen Feng */ 643e0180db1SChengwen Feng #define RTE_DMA_ALL_VCHAN 0xFFFFu 644e0180db1SChengwen Feng 645e0180db1SChengwen Feng /** 646e0180db1SChengwen Feng * Retrieve basic statistics of a or all virtual DMA channel(s). 647e0180db1SChengwen Feng * 648e0180db1SChengwen Feng * @param dev_id 649e0180db1SChengwen Feng * The identifier of the device. 650e0180db1SChengwen Feng * @param vchan 651e0180db1SChengwen Feng * The identifier of virtual DMA channel. 652e0180db1SChengwen Feng * If equal RTE_DMA_ALL_VCHAN means all channels. 653e0180db1SChengwen Feng * @param[out] stats 654e0180db1SChengwen Feng * The basic statistics structure encapsulated into rte_dma_stats 655e0180db1SChengwen Feng * object. 656e0180db1SChengwen Feng * 657e0180db1SChengwen Feng * @return 658e0180db1SChengwen Feng * 0 on success. Otherwise negative value is returned. 659e0180db1SChengwen Feng */ 660e0180db1SChengwen Feng int rte_dma_stats_get(int16_t dev_id, uint16_t vchan, 661e0180db1SChengwen Feng struct rte_dma_stats *stats); 662e0180db1SChengwen Feng 663e0180db1SChengwen Feng /** 664e0180db1SChengwen Feng * Reset basic statistics of a or all virtual DMA channel(s). 665e0180db1SChengwen Feng * 666e0180db1SChengwen Feng * @param dev_id 667e0180db1SChengwen Feng * The identifier of the device. 668e0180db1SChengwen Feng * @param vchan 669e0180db1SChengwen Feng * The identifier of virtual DMA channel. 670e0180db1SChengwen Feng * If equal RTE_DMA_ALL_VCHAN means all channels. 671e0180db1SChengwen Feng * 672e0180db1SChengwen Feng * @return 673e0180db1SChengwen Feng * 0 on success. Otherwise negative value is returned. 674e0180db1SChengwen Feng */ 675e0180db1SChengwen Feng int rte_dma_stats_reset(int16_t dev_id, uint16_t vchan); 676e0180db1SChengwen Feng 677e0180db1SChengwen Feng /** 6785e0f8591SBruce Richardson * device vchannel status 6795e0f8591SBruce Richardson * 6805e0f8591SBruce Richardson * Enum with the options for the channel status, either idle, active or halted due to error 6815e0f8591SBruce Richardson * @see rte_dma_vchan_status 6825e0f8591SBruce Richardson */ 6835e0f8591SBruce Richardson enum rte_dma_vchan_status { 6845e0f8591SBruce Richardson RTE_DMA_VCHAN_IDLE, /**< not processing, awaiting ops */ 6855e0f8591SBruce Richardson RTE_DMA_VCHAN_ACTIVE, /**< currently processing jobs */ 6865e0f8591SBruce Richardson RTE_DMA_VCHAN_HALTED_ERROR, /**< not processing due to error, cannot accept new ops */ 6875e0f8591SBruce Richardson }; 6885e0f8591SBruce Richardson 6895e0f8591SBruce Richardson /** 6905e0f8591SBruce Richardson * Determine if all jobs have completed on a device channel. 6915e0f8591SBruce Richardson * This function is primarily designed for testing use, as it allows a process to check if 6925e0f8591SBruce Richardson * all jobs are completed, without actually gathering completions from those jobs. 6935e0f8591SBruce Richardson * 6945e0f8591SBruce Richardson * @param dev_id 6955e0f8591SBruce Richardson * The identifier of the device. 6965e0f8591SBruce Richardson * @param vchan 6975e0f8591SBruce Richardson * The identifier of virtual DMA channel. 6985e0f8591SBruce Richardson * @param[out] status 6995e0f8591SBruce Richardson * The vchan status 7005e0f8591SBruce Richardson * @return 7015e0f8591SBruce Richardson * 0 - call completed successfully 7025e0f8591SBruce Richardson * < 0 - error code indicating there was a problem calling the API 7035e0f8591SBruce Richardson */ 7045e0f8591SBruce Richardson int 7055e0f8591SBruce Richardson rte_dma_vchan_status(int16_t dev_id, uint16_t vchan, enum rte_dma_vchan_status *status); 7065e0f8591SBruce Richardson 7075e0f8591SBruce Richardson /** 708e0180db1SChengwen Feng * Dump DMA device info. 709e0180db1SChengwen Feng * 710e0180db1SChengwen Feng * @param dev_id 711e0180db1SChengwen Feng * The identifier of the device. 712e0180db1SChengwen Feng * @param f 713e0180db1SChengwen Feng * The file to write the output to. 714e0180db1SChengwen Feng * 715e0180db1SChengwen Feng * @return 716e0180db1SChengwen Feng * 0 on success. Otherwise negative value is returned. 717e0180db1SChengwen Feng */ 718e0180db1SChengwen Feng int rte_dma_dump(int16_t dev_id, FILE *f); 719e0180db1SChengwen Feng 72091e581e5SChengwen Feng /** 72191e581e5SChengwen Feng * DMA transfer result status code defines. 72291e581e5SChengwen Feng * 72391e581e5SChengwen Feng * @see rte_dma_completed_status 72491e581e5SChengwen Feng */ 72591e581e5SChengwen Feng enum rte_dma_status_code { 72691e581e5SChengwen Feng /** The operation completed successfully. */ 72791e581e5SChengwen Feng RTE_DMA_STATUS_SUCCESSFUL, 72891e581e5SChengwen Feng /** The operation failed to complete due abort by user. 7297be78d02SJosh Soref * This is mainly used when processing dev_stop, user could modify the 73091e581e5SChengwen Feng * descriptors (e.g. change one bit to tell hardware abort this job), 73191e581e5SChengwen Feng * it allows outstanding requests to be complete as much as possible, 73291e581e5SChengwen Feng * so reduce the time to stop the device. 73391e581e5SChengwen Feng */ 73491e581e5SChengwen Feng RTE_DMA_STATUS_USER_ABORT, 73591e581e5SChengwen Feng /** The operation failed to complete due to following scenarios: 73691e581e5SChengwen Feng * The jobs in a particular batch are not attempted because they 73791e581e5SChengwen Feng * appeared after a fence where a previous job failed. In some HW 73891e581e5SChengwen Feng * implementation it's possible for jobs from later batches would be 73991e581e5SChengwen Feng * completed, though, so report the status from the not attempted jobs 74091e581e5SChengwen Feng * before reporting those newer completed jobs. 74191e581e5SChengwen Feng */ 74291e581e5SChengwen Feng RTE_DMA_STATUS_NOT_ATTEMPTED, 74391e581e5SChengwen Feng /** The operation failed to complete due invalid source address. */ 74491e581e5SChengwen Feng RTE_DMA_STATUS_INVALID_SRC_ADDR, 74591e581e5SChengwen Feng /** The operation failed to complete due invalid destination address. */ 74691e581e5SChengwen Feng RTE_DMA_STATUS_INVALID_DST_ADDR, 74791e581e5SChengwen Feng /** The operation failed to complete due invalid source or destination 74891e581e5SChengwen Feng * address, cover the case that only knows the address error, but not 74991e581e5SChengwen Feng * sure which address error. 75091e581e5SChengwen Feng */ 75191e581e5SChengwen Feng RTE_DMA_STATUS_INVALID_ADDR, 75291e581e5SChengwen Feng /** The operation failed to complete due invalid length. */ 75391e581e5SChengwen Feng RTE_DMA_STATUS_INVALID_LENGTH, 75491e581e5SChengwen Feng /** The operation failed to complete due invalid opcode. 75591e581e5SChengwen Feng * The DMA descriptor could have multiple format, which are 75691e581e5SChengwen Feng * distinguished by the opcode field. 75791e581e5SChengwen Feng */ 75891e581e5SChengwen Feng RTE_DMA_STATUS_INVALID_OPCODE, 75991e581e5SChengwen Feng /** The operation failed to complete due bus read error. */ 76091e581e5SChengwen Feng RTE_DMA_STATUS_BUS_READ_ERROR, 76191e581e5SChengwen Feng /** The operation failed to complete due bus write error. */ 76291e581e5SChengwen Feng RTE_DMA_STATUS_BUS_WRITE_ERROR, 76391e581e5SChengwen Feng /** The operation failed to complete due bus error, cover the case that 76491e581e5SChengwen Feng * only knows the bus error, but not sure which direction error. 76591e581e5SChengwen Feng */ 76691e581e5SChengwen Feng RTE_DMA_STATUS_BUS_ERROR, 76791e581e5SChengwen Feng /** The operation failed to complete due data poison. */ 76891e581e5SChengwen Feng RTE_DMA_STATUS_DATA_POISION, 76991e581e5SChengwen Feng /** The operation failed to complete due descriptor read error. */ 77091e581e5SChengwen Feng RTE_DMA_STATUS_DESCRIPTOR_READ_ERROR, 77191e581e5SChengwen Feng /** The operation failed to complete due device link error. 77291e581e5SChengwen Feng * Used to indicates that the link error in the memory-to-device/ 77391e581e5SChengwen Feng * device-to-memory/device-to-device transfer scenario. 77491e581e5SChengwen Feng */ 77591e581e5SChengwen Feng RTE_DMA_STATUS_DEV_LINK_ERROR, 77691e581e5SChengwen Feng /** The operation failed to complete due lookup page fault. */ 77791e581e5SChengwen Feng RTE_DMA_STATUS_PAGE_FAULT, 77891e581e5SChengwen Feng /** The operation failed to complete due unknown reason. 77991e581e5SChengwen Feng * The initial value is 256, which reserves space for future errors. 78091e581e5SChengwen Feng */ 78191e581e5SChengwen Feng RTE_DMA_STATUS_ERROR_UNKNOWN = 0x100, 78291e581e5SChengwen Feng }; 78391e581e5SChengwen Feng 78491e581e5SChengwen Feng /** 78591e581e5SChengwen Feng * A structure used to hold scatter-gather DMA operation request entry. 78691e581e5SChengwen Feng * 78791e581e5SChengwen Feng * @see rte_dma_copy_sg 78891e581e5SChengwen Feng */ 78991e581e5SChengwen Feng struct rte_dma_sge { 79091e581e5SChengwen Feng rte_iova_t addr; /**< The DMA operation address. */ 79191e581e5SChengwen Feng uint32_t length; /**< The DMA operation length. */ 79291e581e5SChengwen Feng }; 79391e581e5SChengwen Feng 794719834a6SMattias Rönnblom #ifdef __cplusplus 795719834a6SMattias Rönnblom } 796719834a6SMattias Rönnblom #endif 797719834a6SMattias Rönnblom 79891e581e5SChengwen Feng #include "rte_dmadev_core.h" 799112327c2SChengwen Feng #include "rte_dmadev_trace_fp.h" 80091e581e5SChengwen Feng 801719834a6SMattias Rönnblom #ifdef __cplusplus 802719834a6SMattias Rönnblom extern "C" { 803719834a6SMattias Rönnblom #endif 804719834a6SMattias Rönnblom 80591e581e5SChengwen Feng /**@{@name DMA operation flag 80691e581e5SChengwen Feng * @see rte_dma_copy() 80791e581e5SChengwen Feng * @see rte_dma_copy_sg() 80891e581e5SChengwen Feng * @see rte_dma_fill() 80991e581e5SChengwen Feng */ 81091e581e5SChengwen Feng /** Fence flag. 81191e581e5SChengwen Feng * It means the operation with this flag must be processed only after all 81291e581e5SChengwen Feng * previous operations are completed. 81391e581e5SChengwen Feng * If the specify DMA HW works in-order (it means it has default fence between 81491e581e5SChengwen Feng * operations), this flag could be NOP. 81591e581e5SChengwen Feng */ 81691e581e5SChengwen Feng #define RTE_DMA_OP_FLAG_FENCE RTE_BIT64(0) 81791e581e5SChengwen Feng /** Submit flag. 81891e581e5SChengwen Feng * It means the operation with this flag must issue doorbell to hardware after 81991e581e5SChengwen Feng * enqueued jobs. 82091e581e5SChengwen Feng */ 82191e581e5SChengwen Feng #define RTE_DMA_OP_FLAG_SUBMIT RTE_BIT64(1) 82291e581e5SChengwen Feng /** Write data to low level cache hint. 82391e581e5SChengwen Feng * Used for performance optimization, this is just a hint, and there is no 82491e581e5SChengwen Feng * capability bit for this, driver should not return error if this flag was set. 82591e581e5SChengwen Feng */ 82691e581e5SChengwen Feng #define RTE_DMA_OP_FLAG_LLC RTE_BIT64(2) 827877cb3e3SAmit Prakash Shukla /** Auto free buffer flag. 828877cb3e3SAmit Prakash Shukla * Operation with this flag must issue command to hardware to free the DMA 829877cb3e3SAmit Prakash Shukla * buffer after DMA transfer is completed. 830877cb3e3SAmit Prakash Shukla * 831877cb3e3SAmit Prakash Shukla * @see struct rte_dma_vchan_conf::auto_free 832877cb3e3SAmit Prakash Shukla */ 833877cb3e3SAmit Prakash Shukla #define RTE_DMA_OP_FLAG_AUTO_FREE RTE_BIT64(3) 83491e581e5SChengwen Feng /**@}*/ 83591e581e5SChengwen Feng 83691e581e5SChengwen Feng /** 83791e581e5SChengwen Feng * Enqueue a copy operation onto the virtual DMA channel. 83891e581e5SChengwen Feng * 83991e581e5SChengwen Feng * This queues up a copy operation to be performed by hardware, if the 'flags' 84091e581e5SChengwen Feng * parameter contains RTE_DMA_OP_FLAG_SUBMIT then trigger doorbell to begin 84191e581e5SChengwen Feng * this operation, otherwise do not trigger doorbell. 84291e581e5SChengwen Feng * 84391e581e5SChengwen Feng * @param dev_id 84491e581e5SChengwen Feng * The identifier of the device. 84591e581e5SChengwen Feng * @param vchan 84691e581e5SChengwen Feng * The identifier of virtual DMA channel. 84791e581e5SChengwen Feng * @param src 84891e581e5SChengwen Feng * The address of the source buffer. 84991e581e5SChengwen Feng * @param dst 85091e581e5SChengwen Feng * The address of the destination buffer. 85191e581e5SChengwen Feng * @param length 85291e581e5SChengwen Feng * The length of the data to be copied. 85391e581e5SChengwen Feng * @param flags 85491e581e5SChengwen Feng * An flags for this operation. 85591e581e5SChengwen Feng * @see RTE_DMA_OP_FLAG_* 85691e581e5SChengwen Feng * 85791e581e5SChengwen Feng * @return 85891e581e5SChengwen Feng * - 0..UINT16_MAX: index of enqueued job. 85991e581e5SChengwen Feng * - -ENOSPC: if no space left to enqueue. 86091e581e5SChengwen Feng * - other values < 0 on failure. 86191e581e5SChengwen Feng */ 86291e581e5SChengwen Feng static inline int 86391e581e5SChengwen Feng rte_dma_copy(int16_t dev_id, uint16_t vchan, rte_iova_t src, rte_iova_t dst, 86491e581e5SChengwen Feng uint32_t length, uint64_t flags) 86591e581e5SChengwen Feng { 86691e581e5SChengwen Feng struct rte_dma_fp_object *obj = &rte_dma_fp_objs[dev_id]; 867112327c2SChengwen Feng int ret; 86891e581e5SChengwen Feng 86991e581e5SChengwen Feng #ifdef RTE_DMADEV_DEBUG 87091e581e5SChengwen Feng if (!rte_dma_is_valid(dev_id) || length == 0) 87191e581e5SChengwen Feng return -EINVAL; 8728f1d23ecSDavid Marchand if (*obj->copy == NULL) 8738f1d23ecSDavid Marchand return -ENOTSUP; 87491e581e5SChengwen Feng #endif 87591e581e5SChengwen Feng 876112327c2SChengwen Feng ret = (*obj->copy)(obj->dev_private, vchan, src, dst, length, flags); 877112327c2SChengwen Feng rte_dma_trace_copy(dev_id, vchan, src, dst, length, flags, ret); 878112327c2SChengwen Feng 879112327c2SChengwen Feng return ret; 88091e581e5SChengwen Feng } 88191e581e5SChengwen Feng 88291e581e5SChengwen Feng /** 88391e581e5SChengwen Feng * Enqueue a scatter-gather list copy operation onto the virtual DMA channel. 88491e581e5SChengwen Feng * 88591e581e5SChengwen Feng * This queues up a scatter-gather list copy operation to be performed by 88691e581e5SChengwen Feng * hardware, if the 'flags' parameter contains RTE_DMA_OP_FLAG_SUBMIT then 88791e581e5SChengwen Feng * trigger doorbell to begin this operation, otherwise do not trigger doorbell. 88891e581e5SChengwen Feng * 88991e581e5SChengwen Feng * @param dev_id 89091e581e5SChengwen Feng * The identifier of the device. 89191e581e5SChengwen Feng * @param vchan 89291e581e5SChengwen Feng * The identifier of virtual DMA channel. 89391e581e5SChengwen Feng * @param src 89491e581e5SChengwen Feng * The pointer of source scatter-gather entry array. 89591e581e5SChengwen Feng * @param dst 89691e581e5SChengwen Feng * The pointer of destination scatter-gather entry array. 89791e581e5SChengwen Feng * @param nb_src 89891e581e5SChengwen Feng * The number of source scatter-gather entry. 89991e581e5SChengwen Feng * @see struct rte_dma_info::max_sges 90091e581e5SChengwen Feng * @param nb_dst 90191e581e5SChengwen Feng * The number of destination scatter-gather entry. 90291e581e5SChengwen Feng * @see struct rte_dma_info::max_sges 90391e581e5SChengwen Feng * @param flags 90491e581e5SChengwen Feng * An flags for this operation. 90591e581e5SChengwen Feng * @see RTE_DMA_OP_FLAG_* 90691e581e5SChengwen Feng * 90791e581e5SChengwen Feng * @return 90891e581e5SChengwen Feng * - 0..UINT16_MAX: index of enqueued job. 90991e581e5SChengwen Feng * - -ENOSPC: if no space left to enqueue. 91091e581e5SChengwen Feng * - other values < 0 on failure. 91191e581e5SChengwen Feng */ 91291e581e5SChengwen Feng static inline int 91391e581e5SChengwen Feng rte_dma_copy_sg(int16_t dev_id, uint16_t vchan, struct rte_dma_sge *src, 91491e581e5SChengwen Feng struct rte_dma_sge *dst, uint16_t nb_src, uint16_t nb_dst, 91591e581e5SChengwen Feng uint64_t flags) 91691e581e5SChengwen Feng { 91791e581e5SChengwen Feng struct rte_dma_fp_object *obj = &rte_dma_fp_objs[dev_id]; 918112327c2SChengwen Feng int ret; 91991e581e5SChengwen Feng 92091e581e5SChengwen Feng #ifdef RTE_DMADEV_DEBUG 92191e581e5SChengwen Feng if (!rte_dma_is_valid(dev_id) || src == NULL || dst == NULL || 92291e581e5SChengwen Feng nb_src == 0 || nb_dst == 0) 92391e581e5SChengwen Feng return -EINVAL; 9248f1d23ecSDavid Marchand if (*obj->copy_sg == NULL) 9258f1d23ecSDavid Marchand return -ENOTSUP; 92691e581e5SChengwen Feng #endif 92791e581e5SChengwen Feng 928112327c2SChengwen Feng ret = (*obj->copy_sg)(obj->dev_private, vchan, src, dst, nb_src, 92991e581e5SChengwen Feng nb_dst, flags); 930112327c2SChengwen Feng rte_dma_trace_copy_sg(dev_id, vchan, src, dst, nb_src, nb_dst, flags, 931112327c2SChengwen Feng ret); 932112327c2SChengwen Feng 933112327c2SChengwen Feng return ret; 93491e581e5SChengwen Feng } 93591e581e5SChengwen Feng 93691e581e5SChengwen Feng /** 93791e581e5SChengwen Feng * Enqueue a fill operation onto the virtual DMA channel. 93891e581e5SChengwen Feng * 93991e581e5SChengwen Feng * This queues up a fill operation to be performed by hardware, if the 'flags' 94091e581e5SChengwen Feng * parameter contains RTE_DMA_OP_FLAG_SUBMIT then trigger doorbell to begin 94191e581e5SChengwen Feng * this operation, otherwise do not trigger doorbell. 94291e581e5SChengwen Feng * 94391e581e5SChengwen Feng * @param dev_id 94491e581e5SChengwen Feng * The identifier of the device. 94591e581e5SChengwen Feng * @param vchan 94691e581e5SChengwen Feng * The identifier of virtual DMA channel. 94791e581e5SChengwen Feng * @param pattern 94891e581e5SChengwen Feng * The pattern to populate the destination buffer with. 94991e581e5SChengwen Feng * @param dst 95091e581e5SChengwen Feng * The address of the destination buffer. 95191e581e5SChengwen Feng * @param length 95291e581e5SChengwen Feng * The length of the destination buffer. 95391e581e5SChengwen Feng * @param flags 95491e581e5SChengwen Feng * An flags for this operation. 95591e581e5SChengwen Feng * @see RTE_DMA_OP_FLAG_* 95691e581e5SChengwen Feng * 95791e581e5SChengwen Feng * @return 95891e581e5SChengwen Feng * - 0..UINT16_MAX: index of enqueued job. 95991e581e5SChengwen Feng * - -ENOSPC: if no space left to enqueue. 96091e581e5SChengwen Feng * - other values < 0 on failure. 96191e581e5SChengwen Feng */ 96291e581e5SChengwen Feng static inline int 96391e581e5SChengwen Feng rte_dma_fill(int16_t dev_id, uint16_t vchan, uint64_t pattern, 96491e581e5SChengwen Feng rte_iova_t dst, uint32_t length, uint64_t flags) 96591e581e5SChengwen Feng { 96691e581e5SChengwen Feng struct rte_dma_fp_object *obj = &rte_dma_fp_objs[dev_id]; 967112327c2SChengwen Feng int ret; 96891e581e5SChengwen Feng 96991e581e5SChengwen Feng #ifdef RTE_DMADEV_DEBUG 97091e581e5SChengwen Feng if (!rte_dma_is_valid(dev_id) || length == 0) 97191e581e5SChengwen Feng return -EINVAL; 9728f1d23ecSDavid Marchand if (*obj->fill == NULL) 9738f1d23ecSDavid Marchand return -ENOTSUP; 97491e581e5SChengwen Feng #endif 97591e581e5SChengwen Feng 976112327c2SChengwen Feng ret = (*obj->fill)(obj->dev_private, vchan, pattern, dst, length, 97791e581e5SChengwen Feng flags); 978112327c2SChengwen Feng rte_dma_trace_fill(dev_id, vchan, pattern, dst, length, flags, ret); 979112327c2SChengwen Feng 980112327c2SChengwen Feng return ret; 98191e581e5SChengwen Feng } 98291e581e5SChengwen Feng 98391e581e5SChengwen Feng /** 98491e581e5SChengwen Feng * Trigger hardware to begin performing enqueued operations. 98591e581e5SChengwen Feng * 986cb68a563SStephen Hemminger * Writes the "doorbell" to the hardware to trigger it 98791e581e5SChengwen Feng * to begin the operations previously enqueued by rte_dma_copy/fill(). 98891e581e5SChengwen Feng * 98991e581e5SChengwen Feng * @param dev_id 99091e581e5SChengwen Feng * The identifier of the device. 99191e581e5SChengwen Feng * @param vchan 99291e581e5SChengwen Feng * The identifier of virtual DMA channel. 99391e581e5SChengwen Feng * 99491e581e5SChengwen Feng * @return 99591e581e5SChengwen Feng * 0 on success. Otherwise negative value is returned. 99691e581e5SChengwen Feng */ 99791e581e5SChengwen Feng static inline int 99891e581e5SChengwen Feng rte_dma_submit(int16_t dev_id, uint16_t vchan) 99991e581e5SChengwen Feng { 100091e581e5SChengwen Feng struct rte_dma_fp_object *obj = &rte_dma_fp_objs[dev_id]; 1001112327c2SChengwen Feng int ret; 100291e581e5SChengwen Feng 100391e581e5SChengwen Feng #ifdef RTE_DMADEV_DEBUG 100491e581e5SChengwen Feng if (!rte_dma_is_valid(dev_id)) 100591e581e5SChengwen Feng return -EINVAL; 10068f1d23ecSDavid Marchand if (*obj->submit == NULL) 10078f1d23ecSDavid Marchand return -ENOTSUP; 100891e581e5SChengwen Feng #endif 100991e581e5SChengwen Feng 1010112327c2SChengwen Feng ret = (*obj->submit)(obj->dev_private, vchan); 1011112327c2SChengwen Feng rte_dma_trace_submit(dev_id, vchan, ret); 1012112327c2SChengwen Feng 1013112327c2SChengwen Feng return ret; 101491e581e5SChengwen Feng } 101591e581e5SChengwen Feng 101691e581e5SChengwen Feng /** 101791e581e5SChengwen Feng * Return the number of operations that have been successfully completed. 1018e345594fSBruce Richardson * Once an operation has been reported as completed, the results of that 1019e345594fSBruce Richardson * operation will be visible to all cores on the system. 102091e581e5SChengwen Feng * 102191e581e5SChengwen Feng * @param dev_id 102291e581e5SChengwen Feng * The identifier of the device. 102391e581e5SChengwen Feng * @param vchan 102491e581e5SChengwen Feng * The identifier of virtual DMA channel. 102591e581e5SChengwen Feng * @param nb_cpls 102691e581e5SChengwen Feng * The maximum number of completed operations that can be processed. 102791e581e5SChengwen Feng * @param[out] last_idx 102891e581e5SChengwen Feng * The last completed operation's ring_idx. 102991e581e5SChengwen Feng * If not required, NULL can be passed in. 103091e581e5SChengwen Feng * @param[out] has_error 103191e581e5SChengwen Feng * Indicates if there are transfer error. 103291e581e5SChengwen Feng * If not required, NULL can be passed in. 103391e581e5SChengwen Feng * 103491e581e5SChengwen Feng * @return 103591e581e5SChengwen Feng * The number of operations that successfully completed. This return value 103691e581e5SChengwen Feng * must be less than or equal to the value of nb_cpls. 103791e581e5SChengwen Feng */ 103891e581e5SChengwen Feng static inline uint16_t 103991e581e5SChengwen Feng rte_dma_completed(int16_t dev_id, uint16_t vchan, const uint16_t nb_cpls, 104091e581e5SChengwen Feng uint16_t *last_idx, bool *has_error) 104191e581e5SChengwen Feng { 104291e581e5SChengwen Feng struct rte_dma_fp_object *obj = &rte_dma_fp_objs[dev_id]; 1043112327c2SChengwen Feng uint16_t idx, ret; 104491e581e5SChengwen Feng bool err; 104591e581e5SChengwen Feng 104691e581e5SChengwen Feng #ifdef RTE_DMADEV_DEBUG 104791e581e5SChengwen Feng if (!rte_dma_is_valid(dev_id) || nb_cpls == 0) 104891e581e5SChengwen Feng return 0; 10498f1d23ecSDavid Marchand if (*obj->completed == NULL) 10508f1d23ecSDavid Marchand return 0; 105191e581e5SChengwen Feng #endif 105291e581e5SChengwen Feng 105391e581e5SChengwen Feng /* Ensure the pointer values are non-null to simplify drivers. 105491e581e5SChengwen Feng * In most cases these should be compile time evaluated, since this is 105591e581e5SChengwen Feng * an inline function. 105691e581e5SChengwen Feng * - If NULL is explicitly passed as parameter, then compiler knows the 105791e581e5SChengwen Feng * value is NULL 105891e581e5SChengwen Feng * - If address of local variable is passed as parameter, then compiler 105991e581e5SChengwen Feng * can know it's non-NULL. 106091e581e5SChengwen Feng */ 106191e581e5SChengwen Feng if (last_idx == NULL) 106291e581e5SChengwen Feng last_idx = &idx; 106391e581e5SChengwen Feng if (has_error == NULL) 106491e581e5SChengwen Feng has_error = &err; 106591e581e5SChengwen Feng 106691e581e5SChengwen Feng *has_error = false; 1067112327c2SChengwen Feng ret = (*obj->completed)(obj->dev_private, vchan, nb_cpls, last_idx, 106891e581e5SChengwen Feng has_error); 1069112327c2SChengwen Feng rte_dma_trace_completed(dev_id, vchan, nb_cpls, last_idx, has_error, 1070112327c2SChengwen Feng ret); 1071112327c2SChengwen Feng 1072112327c2SChengwen Feng return ret; 107391e581e5SChengwen Feng } 107491e581e5SChengwen Feng 107591e581e5SChengwen Feng /** 107691e581e5SChengwen Feng * Return the number of operations that have been completed, and the operations 107791e581e5SChengwen Feng * result may succeed or fail. 1078e345594fSBruce Richardson * Once an operation has been reported as completed successfully, the results of that 1079e345594fSBruce Richardson * operation will be visible to all cores on the system. 108091e581e5SChengwen Feng * 108191e581e5SChengwen Feng * @param dev_id 108291e581e5SChengwen Feng * The identifier of the device. 108391e581e5SChengwen Feng * @param vchan 108491e581e5SChengwen Feng * The identifier of virtual DMA channel. 108591e581e5SChengwen Feng * @param nb_cpls 108691e581e5SChengwen Feng * Indicates the size of status array. 108791e581e5SChengwen Feng * @param[out] last_idx 108891e581e5SChengwen Feng * The last completed operation's ring_idx. 108991e581e5SChengwen Feng * If not required, NULL can be passed in. 109091e581e5SChengwen Feng * @param[out] status 109191e581e5SChengwen Feng * This is a pointer to an array of length 'nb_cpls' that holds the completion 109291e581e5SChengwen Feng * status code of each operation. 109391e581e5SChengwen Feng * @see enum rte_dma_status_code 109491e581e5SChengwen Feng * 109591e581e5SChengwen Feng * @return 109691e581e5SChengwen Feng * The number of operations that completed. This return value must be less 109791e581e5SChengwen Feng * than or equal to the value of nb_cpls. 109891e581e5SChengwen Feng * If this number is greater than zero (assuming n), then n values in the 109991e581e5SChengwen Feng * status array are also set. 110091e581e5SChengwen Feng */ 110191e581e5SChengwen Feng static inline uint16_t 110291e581e5SChengwen Feng rte_dma_completed_status(int16_t dev_id, uint16_t vchan, 110391e581e5SChengwen Feng const uint16_t nb_cpls, uint16_t *last_idx, 110491e581e5SChengwen Feng enum rte_dma_status_code *status) 110591e581e5SChengwen Feng { 110691e581e5SChengwen Feng struct rte_dma_fp_object *obj = &rte_dma_fp_objs[dev_id]; 1107112327c2SChengwen Feng uint16_t idx, ret; 110891e581e5SChengwen Feng 110991e581e5SChengwen Feng #ifdef RTE_DMADEV_DEBUG 111091e581e5SChengwen Feng if (!rte_dma_is_valid(dev_id) || nb_cpls == 0 || status == NULL) 111191e581e5SChengwen Feng return 0; 11128f1d23ecSDavid Marchand if (*obj->completed_status == NULL) 11138f1d23ecSDavid Marchand return 0; 111491e581e5SChengwen Feng #endif 111591e581e5SChengwen Feng 111691e581e5SChengwen Feng if (last_idx == NULL) 111791e581e5SChengwen Feng last_idx = &idx; 111891e581e5SChengwen Feng 1119112327c2SChengwen Feng ret = (*obj->completed_status)(obj->dev_private, vchan, nb_cpls, 112091e581e5SChengwen Feng last_idx, status); 1121112327c2SChengwen Feng rte_dma_trace_completed_status(dev_id, vchan, nb_cpls, last_idx, status, 1122112327c2SChengwen Feng ret); 1123112327c2SChengwen Feng 1124112327c2SChengwen Feng return ret; 112591e581e5SChengwen Feng } 112691e581e5SChengwen Feng 1127ea8cf0f8SKevin Laatz /** 1128ea8cf0f8SKevin Laatz * Check remaining capacity in descriptor ring for the current burst. 1129ea8cf0f8SKevin Laatz * 1130ea8cf0f8SKevin Laatz * @param dev_id 1131ea8cf0f8SKevin Laatz * The identifier of the device. 1132ea8cf0f8SKevin Laatz * @param vchan 1133ea8cf0f8SKevin Laatz * The identifier of virtual DMA channel. 1134ea8cf0f8SKevin Laatz * 1135ea8cf0f8SKevin Laatz * @return 1136ea8cf0f8SKevin Laatz * - Remaining space in the descriptor ring for the current burst. 1137ea8cf0f8SKevin Laatz * - 0 on error 1138ea8cf0f8SKevin Laatz */ 1139ea8cf0f8SKevin Laatz static inline uint16_t 1140ea8cf0f8SKevin Laatz rte_dma_burst_capacity(int16_t dev_id, uint16_t vchan) 1141ea8cf0f8SKevin Laatz { 1142ea8cf0f8SKevin Laatz struct rte_dma_fp_object *obj = &rte_dma_fp_objs[dev_id]; 1143112327c2SChengwen Feng uint16_t ret; 1144ea8cf0f8SKevin Laatz 1145ea8cf0f8SKevin Laatz #ifdef RTE_DMADEV_DEBUG 1146ea8cf0f8SKevin Laatz if (!rte_dma_is_valid(dev_id)) 1147ea8cf0f8SKevin Laatz return 0; 11488f1d23ecSDavid Marchand if (*obj->burst_capacity == NULL) 11498f1d23ecSDavid Marchand return 0; 1150ea8cf0f8SKevin Laatz #endif 1151112327c2SChengwen Feng ret = (*obj->burst_capacity)(obj->dev_private, vchan); 1152112327c2SChengwen Feng rte_dma_trace_burst_capacity(dev_id, vchan, ret); 1153112327c2SChengwen Feng 1154112327c2SChengwen Feng return ret; 1155ea8cf0f8SKevin Laatz } 1156ea8cf0f8SKevin Laatz 1157b36970f2SChengwen Feng #ifdef __cplusplus 1158b36970f2SChengwen Feng } 1159b36970f2SChengwen Feng #endif 1160b36970f2SChengwen Feng 1161b36970f2SChengwen Feng #endif /* RTE_DMADEV_H */ 1162