Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2021 HiSilicon Limited
3 : : */
4 : :
5 : : #include <string.h>
6 : :
7 : : #include <rte_cycles.h>
8 : : #include <rte_malloc.h>
9 : : #include <rte_test.h>
10 : : #include <rte_dmadev.h>
11 : :
12 : : #include "test.h"
13 : : #include "test_dmadev_api.h"
14 : :
15 : : extern int test_dma_api(uint16_t dev_id);
16 : :
17 : : #define TEST_MEMCPY_SIZE 1024
18 : : #define TEST_WAIT_US_VAL 50000
19 : : #define TEST_SG_MAX 64
20 : :
21 : : static int16_t test_dev_id;
22 : : static int16_t invalid_dev_id;
23 : :
24 : : static char *src;
25 : : static char *dst;
26 : : static char *src_sg[TEST_SG_MAX];
27 : : static char *dst_sg[TEST_SG_MAX];
28 : :
29 : : static int
30 : 0 : testsuite_setup(void)
31 : : {
32 : 0 : invalid_dev_id = -1;
33 : : int i, rc = 0;
34 : :
35 [ # # ]: 0 : for (i = 0; i < TEST_SG_MAX; i++) {
36 : 0 : src_sg[i] = rte_malloc("dmadev_test_src", TEST_MEMCPY_SIZE, 0);
37 [ # # ]: 0 : if (src_sg[i] == NULL) {
38 : : rc = -ENOMEM;
39 : 0 : goto exit;
40 : : }
41 : :
42 : 0 : dst_sg[i] = rte_malloc("dmadev_test_dst", TEST_MEMCPY_SIZE, 0);
43 [ # # ]: 0 : if (dst_sg[i] == NULL) {
44 : 0 : rte_free(src_sg[i]);
45 : 0 : src_sg[i] = NULL;
46 : : rc = -ENOMEM;
47 : 0 : goto exit;
48 : : }
49 : : }
50 : :
51 : 0 : src = src_sg[0];
52 : 0 : dst = dst_sg[0];
53 : :
54 : : /* Set dmadev log level to critical to suppress unnecessary output
55 : : * during API tests.
56 : : */
57 : 0 : rte_log_set_level_pattern("lib.dmadev", RTE_LOG_CRIT);
58 : :
59 : 0 : return rc;
60 : : exit:
61 [ # # ]: 0 : while (--i >= 0) {
62 : 0 : rte_free(src_sg[i]);
63 : 0 : rte_free(dst_sg[i]);
64 : : }
65 : :
66 : : return rc;
67 : : }
68 : :
69 : : static void
70 : 0 : testsuite_teardown(void)
71 : : {
72 : : int i;
73 : :
74 [ # # ]: 0 : for (i = 0; i < TEST_SG_MAX; i++) {
75 : 0 : rte_free(src_sg[i]);
76 : 0 : src_sg[i] = NULL;
77 : 0 : rte_free(dst_sg[i]);
78 : 0 : dst_sg[i] = NULL;
79 : : }
80 : :
81 : 0 : src = NULL;
82 : 0 : dst = NULL;
83 : : /* Ensure the dmadev is stopped. */
84 : 0 : rte_dma_stop(test_dev_id);
85 : 0 : rte_dma_stats_reset(test_dev_id, RTE_DMA_ALL_VCHAN);
86 : :
87 : 0 : rte_log_set_level_pattern("lib.dmadev", RTE_LOG_INFO);
88 : 0 : }
89 : :
90 : : static int
91 : 0 : test_dma_get_dev_id_by_name(void)
92 : : {
93 : 0 : int ret = rte_dma_get_dev_id_by_name("invalid_dmadev_device");
94 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
95 : : return TEST_SUCCESS;
96 : : }
97 : :
98 : : static int
99 : 0 : test_dma_is_valid_dev(void)
100 : : {
101 : : int ret;
102 : 0 : ret = rte_dma_is_valid(invalid_dev_id);
103 [ # # ]: 0 : RTE_TEST_ASSERT(ret == false, "Expected false for invalid dev id");
104 : 0 : ret = rte_dma_is_valid(test_dev_id);
105 [ # # ]: 0 : RTE_TEST_ASSERT(ret == true, "Expected true for valid dev id");
106 : : return TEST_SUCCESS;
107 : : }
108 : :
109 : : static int
110 : 0 : test_dma_count(void)
111 : : {
112 : 0 : uint16_t count = rte_dma_count_avail();
113 [ # # ]: 0 : RTE_TEST_ASSERT(count > 0, "Invalid dmadev count %u", count);
114 : : return TEST_SUCCESS;
115 : : }
116 : :
117 : : static int
118 : 0 : test_dma_info_get(void)
119 : : {
120 : 0 : struct rte_dma_info info = { 0 };
121 : : int ret;
122 : :
123 : 0 : ret = rte_dma_info_get(invalid_dev_id, &info);
124 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
125 : 0 : ret = rte_dma_info_get(test_dev_id, NULL);
126 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
127 : 0 : ret = rte_dma_info_get(test_dev_id, &info);
128 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info");
129 : :
130 : : return TEST_SUCCESS;
131 : : }
132 : :
133 : : static int
134 : 0 : test_dma_configure(void)
135 : : {
136 : 0 : struct rte_dma_conf conf = { 0 };
137 : 0 : struct rte_dma_info info = { 0 };
138 : : int ret;
139 : :
140 : : /* Check for invalid parameters */
141 : 0 : ret = rte_dma_configure(invalid_dev_id, &conf);
142 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
143 : 0 : ret = rte_dma_configure(test_dev_id, NULL);
144 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
145 : :
146 : : /* Check for nb_vchans == 0 */
147 : : memset(&conf, 0, sizeof(conf));
148 : 0 : ret = rte_dma_configure(test_dev_id, &conf);
149 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
150 : :
151 : : /* Check for conf.nb_vchans > info.max_vchans */
152 : 0 : ret = rte_dma_info_get(test_dev_id, &info);
153 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info");
154 : : memset(&conf, 0, sizeof(conf));
155 : 0 : conf.nb_vchans = info.max_vchans + 1;
156 : 0 : ret = rte_dma_configure(test_dev_id, &conf);
157 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
158 : :
159 : : /* Check enable silent mode */
160 : : memset(&conf, 0, sizeof(conf));
161 : 0 : conf.nb_vchans = info.max_vchans;
162 : 0 : conf.flags = RTE_DMA_CFG_FLAG_SILENT;
163 : 0 : ret = rte_dma_configure(test_dev_id, &conf);
164 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
165 : :
166 : : /* Configure success */
167 : : memset(&conf, 0, sizeof(conf));
168 : 0 : conf.nb_vchans = info.max_vchans;
169 : 0 : ret = rte_dma_configure(test_dev_id, &conf);
170 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to configure dmadev, %d", ret);
171 : :
172 : : /* Check configure success */
173 : 0 : ret = rte_dma_info_get(test_dev_id, &info);
174 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info");
175 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(conf.nb_vchans, info.nb_vchans,
176 : : "Configure nb_vchans not match");
177 : :
178 : : return TEST_SUCCESS;
179 : : }
180 : :
181 : : static int
182 : 0 : check_direction(void)
183 : : {
184 : : struct rte_dma_vchan_conf vchan_conf;
185 : : int ret;
186 : :
187 : : /* Check for direction */
188 : : memset(&vchan_conf, 0, sizeof(vchan_conf));
189 : 0 : vchan_conf.direction = RTE_DMA_DIR_DEV_TO_DEV + 1;
190 : 0 : ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf);
191 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
192 : 0 : vchan_conf.direction = RTE_DMA_DIR_MEM_TO_MEM - 1;
193 : 0 : ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf);
194 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
195 : :
196 : : /* Check for direction and dev_capa combination */
197 : : memset(&vchan_conf, 0, sizeof(vchan_conf));
198 : 0 : vchan_conf.direction = RTE_DMA_DIR_MEM_TO_DEV;
199 : 0 : ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf);
200 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
201 : 0 : vchan_conf.direction = RTE_DMA_DIR_DEV_TO_MEM;
202 : 0 : ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf);
203 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
204 : 0 : vchan_conf.direction = RTE_DMA_DIR_DEV_TO_DEV;
205 : 0 : ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf);
206 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
207 : :
208 : : return 0;
209 : : }
210 : :
211 : : static int
212 : 0 : check_port_type(struct rte_dma_info *dev_info)
213 : : {
214 : : struct rte_dma_vchan_conf vchan_conf;
215 : : int ret;
216 : :
217 : : /* Check src port type validation */
218 : : memset(&vchan_conf, 0, sizeof(vchan_conf));
219 : : vchan_conf.direction = RTE_DMA_DIR_MEM_TO_MEM;
220 : 0 : vchan_conf.nb_desc = dev_info->min_desc;
221 : 0 : vchan_conf.src_port.port_type = RTE_DMA_PORT_PCIE;
222 : 0 : ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf);
223 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
224 : :
225 : : /* Check dst port type validation */
226 : : memset(&vchan_conf, 0, sizeof(vchan_conf));
227 : : vchan_conf.direction = RTE_DMA_DIR_MEM_TO_MEM;
228 : 0 : vchan_conf.nb_desc = dev_info->min_desc;
229 : 0 : vchan_conf.dst_port.port_type = RTE_DMA_PORT_PCIE;
230 : 0 : ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf);
231 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
232 : :
233 : : return 0;
234 : : }
235 : :
236 : : static int
237 : 0 : test_dma_vchan_setup(void)
238 : : {
239 : 0 : struct rte_dma_vchan_conf vchan_conf = { 0 };
240 : 0 : struct rte_dma_conf dev_conf = { 0 };
241 : 0 : struct rte_dma_info dev_info = { 0 };
242 : : int ret;
243 : :
244 : : /* Check for invalid parameters */
245 : 0 : ret = rte_dma_vchan_setup(invalid_dev_id, 0, &vchan_conf);
246 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
247 : 0 : ret = rte_dma_vchan_setup(test_dev_id, 0, NULL);
248 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
249 : 0 : ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf);
250 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
251 : :
252 : : /* Make sure configure success */
253 : 0 : ret = rte_dma_info_get(test_dev_id, &dev_info);
254 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info");
255 : 0 : dev_conf.nb_vchans = dev_info.max_vchans;
256 : 0 : ret = rte_dma_configure(test_dev_id, &dev_conf);
257 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to configure dmadev, %d", ret);
258 : :
259 : : /* Check for invalid vchan */
260 : 0 : ret = rte_dma_vchan_setup(test_dev_id, dev_conf.nb_vchans, &vchan_conf);
261 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
262 : :
263 : : /* Check for direction */
264 : 0 : ret = check_direction();
265 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to check direction");
266 : :
267 : : /* Check for nb_desc validation */
268 : : memset(&vchan_conf, 0, sizeof(vchan_conf));
269 : : vchan_conf.direction = RTE_DMA_DIR_MEM_TO_MEM;
270 : 0 : vchan_conf.nb_desc = dev_info.min_desc - 1;
271 : 0 : ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf);
272 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
273 : 0 : vchan_conf.nb_desc = dev_info.max_desc + 1;
274 : 0 : ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf);
275 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
276 : :
277 : : /* Check port type */
278 : 0 : ret = check_port_type(&dev_info);
279 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to check port type");
280 : :
281 : : /* Check vchan setup success */
282 : : memset(&vchan_conf, 0, sizeof(vchan_conf));
283 : : vchan_conf.direction = RTE_DMA_DIR_MEM_TO_MEM;
284 : 0 : vchan_conf.nb_desc = dev_info.min_desc;
285 : 0 : ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf);
286 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup vchan, %d", ret);
287 : :
288 : : return TEST_SUCCESS;
289 : : }
290 : :
291 : : static int
292 : 0 : setup_vchan(int nb_vchans, bool ena_enq_deq)
293 : : {
294 : 0 : struct rte_dma_vchan_conf vchan_conf = { 0 };
295 : 0 : struct rte_dma_info dev_info = { 0 };
296 : 0 : struct rte_dma_conf dev_conf = { 0 };
297 : : int ret;
298 : :
299 : 0 : ret = rte_dma_info_get(test_dev_id, &dev_info);
300 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
301 : 0 : dev_conf.nb_vchans = nb_vchans;
302 [ # # ]: 0 : dev_conf.flags = ena_enq_deq ? RTE_DMA_CFG_FLAG_ENQ_DEQ : 0;
303 : 0 : ret = rte_dma_configure(test_dev_id, &dev_conf);
304 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to configure, %d", ret);
305 : 0 : vchan_conf.direction = RTE_DMA_DIR_MEM_TO_MEM;
306 : 0 : vchan_conf.nb_desc = dev_info.min_desc;
307 [ # # ]: 0 : for (int i = 0; i < nb_vchans; i++) {
308 : 0 : ret = rte_dma_vchan_setup(test_dev_id, i, &vchan_conf);
309 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup vchan %d, %d", i, ret);
310 : : }
311 : :
312 : : return TEST_SUCCESS;
313 : : }
314 : :
315 : : static int
316 : 0 : test_dma_start_stop(void)
317 : : {
318 : 0 : struct rte_dma_vchan_conf vchan_conf = { 0 };
319 : 0 : struct rte_dma_conf dev_conf = { 0 };
320 : : int ret;
321 : :
322 : : /* Check for invalid parameters */
323 : 0 : ret = rte_dma_start(invalid_dev_id);
324 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
325 : 0 : ret = rte_dma_stop(invalid_dev_id);
326 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
327 : :
328 : : /* Setup one vchan for later test */
329 : 0 : ret = setup_vchan(1, 0);
330 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
331 : :
332 : 0 : ret = rte_dma_start(test_dev_id);
333 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start, %d", ret);
334 : :
335 : : /* Check reconfigure and vchan setup when device started */
336 : 0 : ret = rte_dma_configure(test_dev_id, &dev_conf);
337 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EBUSY, "Failed to configure, %d", ret);
338 : 0 : ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf);
339 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EBUSY, "Failed to setup vchan, %d", ret);
340 : :
341 : 0 : ret = rte_dma_stop(test_dev_id);
342 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to stop, %d", ret);
343 : :
344 : : return TEST_SUCCESS;
345 : : }
346 : :
347 : : static int
348 : 0 : test_dma_reconfigure(void)
349 : : {
350 : : struct rte_dma_conf dev_conf = { 0 };
351 : 0 : struct rte_dma_info dev_info = { 0 };
352 : : uint16_t cfg_vchans;
353 : : int ret;
354 : :
355 : 0 : ret = rte_dma_info_get(test_dev_id, &dev_info);
356 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
357 : :
358 : : /* At least two vchans required for the test */
359 [ # # ]: 0 : if (dev_info.max_vchans < 2)
360 : : return TEST_SKIPPED;
361 : :
362 : : /* Setup one vchan for later test */
363 : 0 : ret = setup_vchan(1, 0);
364 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
365 : :
366 : 0 : ret = rte_dma_start(test_dev_id);
367 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start, %d", ret);
368 : :
369 : 0 : ret = rte_dma_stop(test_dev_id);
370 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to stop, %d", ret);
371 : :
372 : : /* Check reconfigure and vchan setup after device stopped */
373 : 0 : cfg_vchans = dev_conf.nb_vchans = (dev_info.max_vchans - 1);
374 : :
375 : 0 : ret = setup_vchan(cfg_vchans, 0);
376 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
377 : :
378 : 0 : ret = rte_dma_start(test_dev_id);
379 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start, %d", ret);
380 : :
381 : 0 : ret = rte_dma_info_get(test_dev_id, &dev_info);
382 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
383 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(dev_info.nb_vchans, cfg_vchans, "incorrect reconfiguration");
384 : :
385 : 0 : ret = rte_dma_stop(test_dev_id);
386 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to stop, %d", ret);
387 : :
388 : : return TEST_SUCCESS;
389 : : }
390 : :
391 : : static int
392 : 0 : test_dma_stats(void)
393 : : {
394 : 0 : struct rte_dma_info dev_info = { 0 };
395 : 0 : struct rte_dma_stats stats = { 0 };
396 : : int ret;
397 : :
398 : : /* Check for invalid parameters */
399 : 0 : ret = rte_dma_stats_get(invalid_dev_id, 0, &stats);
400 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
401 : 0 : ret = rte_dma_stats_get(invalid_dev_id, 0, NULL);
402 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
403 : 0 : ret = rte_dma_stats_reset(invalid_dev_id, 0);
404 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
405 : :
406 : : /* Setup one vchan for later test */
407 : 0 : ret = setup_vchan(1, 0);
408 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
409 : :
410 : : /* Check for invalid vchan */
411 : 0 : ret = rte_dma_info_get(test_dev_id, &dev_info);
412 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
413 : 0 : ret = rte_dma_stats_get(test_dev_id, dev_info.max_vchans, &stats);
414 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
415 : 0 : ret = rte_dma_stats_reset(test_dev_id, dev_info.max_vchans);
416 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
417 : :
418 : : /* Check for valid vchan */
419 : 0 : ret = rte_dma_stats_get(test_dev_id, 0, &stats);
420 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to get stats, %d", ret);
421 : 0 : ret = rte_dma_stats_get(test_dev_id, RTE_DMA_ALL_VCHAN, &stats);
422 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to get all stats, %d", ret);
423 : 0 : ret = rte_dma_stats_reset(test_dev_id, 0);
424 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to reset stats, %d", ret);
425 : 0 : ret = rte_dma_stats_reset(test_dev_id, RTE_DMA_ALL_VCHAN);
426 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to reset all stats, %d", ret);
427 : :
428 : : return TEST_SUCCESS;
429 : : }
430 : :
431 : : static int
432 : 0 : test_dma_dump(void)
433 : : {
434 : : int ret;
435 : :
436 : : /* Check for invalid parameters */
437 : 0 : ret = rte_dma_dump(invalid_dev_id, stderr);
438 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Excepted -EINVAL, %d", ret);
439 : 0 : ret = rte_dma_dump(test_dev_id, NULL);
440 [ # # ]: 0 : RTE_TEST_ASSERT(ret == -EINVAL, "Excepted -EINVAL, %d", ret);
441 : :
442 : : return TEST_SUCCESS;
443 : : }
444 : :
445 : : static void
446 : 0 : setup_memory(void)
447 : : {
448 : : int i;
449 : :
450 [ # # ]: 0 : for (i = 0; i < TEST_MEMCPY_SIZE; i++)
451 : 0 : src[i] = (char)i;
452 : 0 : memset(dst, 0, TEST_MEMCPY_SIZE);
453 : 0 : }
454 : :
455 : : static int
456 : 0 : verify_memory(void)
457 : : {
458 : : int i;
459 : :
460 [ # # ]: 0 : for (i = 0; i < TEST_MEMCPY_SIZE; i++) {
461 [ # # ]: 0 : if (src[i] == dst[i])
462 : : continue;
463 : 0 : RTE_TEST_ASSERT_EQUAL(src[i], dst[i],
464 : : "Failed to copy memory, %d %d", src[i], dst[i]);
465 : : }
466 : :
467 : : return 0;
468 : : }
469 : :
470 : : static void
471 : 0 : sg_memory_setup(int n)
472 : : {
473 : : int i, j;
474 : :
475 [ # # ]: 0 : for (i = 0; i < n; i++) {
476 [ # # ]: 0 : for (j = 0; j < TEST_MEMCPY_SIZE; j++)
477 : 0 : src_sg[i][j] = (char)j;
478 : :
479 : 0 : memset(dst_sg[i], 0, TEST_MEMCPY_SIZE);
480 : : }
481 : 0 : }
482 : :
483 : : static int
484 : 0 : sg_memory_verify(int n)
485 : : {
486 : : int i, j;
487 : :
488 [ # # ]: 0 : for (i = 0; i < n; i++) {
489 [ # # ]: 0 : for (j = 0; j < TEST_MEMCPY_SIZE; j++) {
490 [ # # ]: 0 : if (src_sg[i][j] == dst_sg[i][j])
491 : : continue;
492 : :
493 : 0 : RTE_TEST_ASSERT_EQUAL(src_sg[i][j], dst_sg[i][j], "Failed to copy memory, %d %d",
494 : : src_sg[i][j], dst_sg[i][j]);
495 : : }
496 : : }
497 : :
498 : : return 0;
499 : : }
500 : :
501 : : static int
502 : 0 : test_dma_completed(void)
503 : : {
504 : 0 : uint16_t last_idx = 1;
505 : 0 : bool has_error = true;
506 : : uint16_t cpl_ret;
507 : : int ret;
508 : :
509 : : /* Setup one vchan for later test */
510 : 0 : ret = setup_vchan(1, 0);
511 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
512 : :
513 : 0 : ret = rte_dma_start(test_dev_id);
514 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start, %d", ret);
515 : :
516 : 0 : setup_memory();
517 : :
518 : : /* Check enqueue without submit */
519 : 0 : ret = rte_dma_copy(test_dev_id, 0,
520 : : rte_malloc_virt2iova(src),
521 : : rte_malloc_virt2iova(dst),
522 : : TEST_MEMCPY_SIZE, 0);
523 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(ret, 0, "Failed to enqueue copy, %d", ret);
524 : 0 : rte_delay_us_sleep(TEST_WAIT_US_VAL);
525 : 0 : cpl_ret = rte_dma_completed(test_dev_id, 0, 1, &last_idx, &has_error);
526 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(cpl_ret, 0, "Failed to get completed");
527 : :
528 : : /* Check add submit */
529 : 0 : ret = rte_dma_submit(test_dev_id, 0);
530 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to submit, %d", ret);
531 : 0 : rte_delay_us_sleep(TEST_WAIT_US_VAL);
532 : 0 : cpl_ret = rte_dma_completed(test_dev_id, 0, 1, &last_idx, &has_error);
533 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(cpl_ret, 1, "Failed to get completed");
534 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(last_idx, 0, "Last idx should be zero, %u",
535 : : last_idx);
536 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(has_error, false, "Should have no error");
537 : 0 : ret = verify_memory();
538 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to verify memory");
539 : :
540 : 0 : setup_memory();
541 : :
542 : : /* Check for enqueue with submit */
543 : 0 : ret = rte_dma_copy(test_dev_id, 0,
544 : : rte_malloc_virt2iova(src),
545 : : rte_malloc_virt2iova(dst),
546 : : TEST_MEMCPY_SIZE, RTE_DMA_OP_FLAG_SUBMIT);
547 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(ret, 1, "Failed to enqueue copy, %d", ret);
548 : 0 : rte_delay_us_sleep(TEST_WAIT_US_VAL);
549 : 0 : cpl_ret = rte_dma_completed(test_dev_id, 0, 1, &last_idx, &has_error);
550 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(cpl_ret, 1, "Failed to get completed");
551 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(last_idx, 1, "Last idx should be 1, %u",
552 : : last_idx);
553 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(has_error, false, "Should have no error");
554 : 0 : ret = verify_memory();
555 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to verify memory");
556 : :
557 : : /* Stop dmadev to make sure dmadev to a known state */
558 : 0 : ret = rte_dma_stop(test_dev_id);
559 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to stop, %d", ret);
560 : :
561 : : return TEST_SUCCESS;
562 : : }
563 : :
564 : : static int
565 : 0 : test_dma_completed_status(void)
566 : : {
567 : 0 : enum rte_dma_status_code status[1] = { 1 };
568 : 0 : uint16_t last_idx = 1;
569 : : uint16_t cpl_ret, i;
570 : : int ret;
571 : :
572 : : /* Setup one vchan for later test */
573 : 0 : ret = setup_vchan(1, 0);
574 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
575 : :
576 : 0 : ret = rte_dma_start(test_dev_id);
577 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start, %d", ret);
578 : :
579 : : /* Check for enqueue with submit */
580 : 0 : ret = rte_dma_copy(test_dev_id, 0,
581 : : rte_malloc_virt2iova(src),
582 : : rte_malloc_virt2iova(dst),
583 : : TEST_MEMCPY_SIZE, RTE_DMA_OP_FLAG_SUBMIT);
584 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(ret, 0, "Failed to enqueue copy, %d", ret);
585 : 0 : rte_delay_us_sleep(TEST_WAIT_US_VAL);
586 : 0 : cpl_ret = rte_dma_completed_status(test_dev_id, 0, 1, &last_idx,
587 : : status);
588 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(cpl_ret, 1, "Failed to completed status");
589 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(last_idx, 0, "Last idx should be zero, %u",
590 : : last_idx);
591 [ # # ]: 0 : for (i = 0; i < RTE_DIM(status); i++)
592 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(status[i], 0,
593 : : "Failed to completed status, %d", status[i]);
594 : :
595 : : /* Check do completed status again */
596 : 0 : cpl_ret = rte_dma_completed_status(test_dev_id, 0, 1, &last_idx,
597 : : status);
598 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(cpl_ret, 0, "Failed to completed status");
599 : :
600 : : /* Check for enqueue with submit again */
601 : 0 : ret = rte_dma_copy(test_dev_id, 0,
602 : : rte_malloc_virt2iova(src),
603 : : rte_malloc_virt2iova(dst),
604 : : TEST_MEMCPY_SIZE, RTE_DMA_OP_FLAG_SUBMIT);
605 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(ret, 1, "Failed to enqueue copy, %d", ret);
606 : 0 : rte_delay_us_sleep(TEST_WAIT_US_VAL);
607 : 0 : cpl_ret = rte_dma_completed_status(test_dev_id, 0, 1, &last_idx,
608 : : status);
609 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(cpl_ret, 1, "Failed to completed status");
610 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(last_idx, 1, "Last idx should be 1, %u",
611 : : last_idx);
612 [ # # ]: 0 : for (i = 0; i < RTE_DIM(status); i++)
613 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(status[i], 0,
614 : : "Failed to completed status, %d", status[i]);
615 : :
616 : : /* Stop dmadev to make sure dmadev to a known state */
617 : 0 : ret = rte_dma_stop(test_dev_id);
618 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to stop, %d", ret);
619 : :
620 : : return TEST_SUCCESS;
621 : : }
622 : :
623 : : static int
624 : 0 : test_dma_sg(void)
625 : : {
626 : : struct rte_dma_sge src_sge[TEST_SG_MAX], dst_sge[TEST_SG_MAX];
627 : 0 : struct rte_dma_info dev_info = { 0 };
628 : 0 : uint16_t last_idx = -1;
629 : 0 : bool has_error = true;
630 : : int n_sge, i, ret;
631 : : uint16_t cpl_ret;
632 : :
633 : 0 : ret = rte_dma_info_get(test_dev_id, &dev_info);
634 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
635 : :
636 [ # # ]: 0 : if ((dev_info.dev_capa & RTE_DMA_CAPA_OPS_COPY_SG) == 0)
637 : : return TEST_SKIPPED;
638 : :
639 : 0 : n_sge = RTE_MIN(dev_info.max_sges, TEST_SG_MAX);
640 : :
641 : 0 : ret = setup_vchan(1, 0);
642 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
643 : :
644 : 0 : ret = rte_dma_start(test_dev_id);
645 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start, %d", ret);
646 : :
647 [ # # ]: 0 : for (i = 0; i < n_sge; i++) {
648 : 0 : src_sge[i].addr = rte_malloc_virt2iova(src_sg[i]);
649 : 0 : src_sge[i].length = TEST_MEMCPY_SIZE;
650 : 0 : dst_sge[i].addr = rte_malloc_virt2iova(dst_sg[i]);
651 : 0 : dst_sge[i].length = TEST_MEMCPY_SIZE;
652 : : }
653 : :
654 : 0 : sg_memory_setup(n_sge);
655 : :
656 : : /* Check enqueue without submit */
657 : 0 : ret = rte_dma_copy_sg(test_dev_id, 0, src_sge, dst_sge, n_sge, n_sge, 0);
658 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(ret, 0, "Failed to enqueue copy, %d", ret);
659 : :
660 : 0 : rte_delay_us_sleep(TEST_WAIT_US_VAL);
661 : :
662 : 0 : cpl_ret = rte_dma_completed(test_dev_id, 0, 1, &last_idx, &has_error);
663 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(cpl_ret, 0, "Failed to get completed");
664 : :
665 : : /* Check DMA submit */
666 : 0 : ret = rte_dma_submit(test_dev_id, 0);
667 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to submit, %d", ret);
668 : :
669 : 0 : rte_delay_us_sleep(TEST_WAIT_US_VAL);
670 : :
671 : 0 : cpl_ret = rte_dma_completed(test_dev_id, 0, 1, &last_idx, &has_error);
672 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(cpl_ret, 1, "Failed to get completed");
673 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(last_idx, 0, "Last idx should be zero, %u", last_idx);
674 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(has_error, false, "Should have no error");
675 : :
676 : 0 : ret = sg_memory_verify(n_sge);
677 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to verify memory");
678 : :
679 : 0 : sg_memory_setup(n_sge);
680 : :
681 : : /* Check for enqueue with submit */
682 : 0 : ret = rte_dma_copy_sg(test_dev_id, 0, src_sge, dst_sge, n_sge, n_sge,
683 : : RTE_DMA_OP_FLAG_SUBMIT);
684 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(ret, 1, "Failed to enqueue copy, %d", ret);
685 : :
686 : 0 : rte_delay_us_sleep(TEST_WAIT_US_VAL);
687 : :
688 : 0 : cpl_ret = rte_dma_completed(test_dev_id, 0, 1, &last_idx, &has_error);
689 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(cpl_ret, 1, "Failed to get completed");
690 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(last_idx, 1, "Last idx should be 1, %u", last_idx);
691 [ # # ]: 0 : RTE_TEST_ASSERT_EQUAL(has_error, false, "Should have no error");
692 : :
693 : 0 : ret = sg_memory_verify(n_sge);
694 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to verify memory");
695 : :
696 : : /* Stop dmadev to make sure dmadev to a known state */
697 : 0 : ret = rte_dma_stop(test_dev_id);
698 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to stop, %d", ret);
699 : :
700 : : return TEST_SUCCESS;
701 : : }
702 : :
703 : : static int
704 : 0 : test_dma_ops_enq_deq(void)
705 : : {
706 : 0 : struct rte_dma_info dev_info = {0};
707 : : struct rte_dma_op *ops;
708 : : int n_sge, i, ret;
709 : :
710 : 0 : ret = rte_dma_info_get(test_dev_id, &dev_info);
711 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
712 [ # # ]: 0 : if ((dev_info.dev_capa & RTE_DMA_CAPA_OPS_ENQ_DEQ) == 0)
713 : : return TEST_SKIPPED;
714 : :
715 : 0 : n_sge = RTE_MIN(dev_info.max_sges, TEST_SG_MAX);
716 : :
717 : 0 : ret = setup_vchan(1, 1);
718 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
719 : :
720 : 0 : ret = rte_dma_start(test_dev_id);
721 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start, %d", ret);
722 : :
723 : 0 : ops = rte_zmalloc(
724 : 0 : "ops", sizeof(struct rte_dma_op) + ((2 * n_sge) * sizeof(struct rte_dma_sge)), 0);
725 : :
726 [ # # ]: 0 : for (i = 0; i < n_sge; i++) {
727 : 0 : ops->src_dst_seg[i].addr = rte_malloc_virt2iova(src_sg[i]);
728 : 0 : ops->src_dst_seg[i].length = TEST_MEMCPY_SIZE;
729 : 0 : ops->src_dst_seg[n_sge + i].addr = rte_malloc_virt2iova(dst_sg[i]);
730 : 0 : ops->src_dst_seg[n_sge + i].length = TEST_MEMCPY_SIZE;
731 : : }
732 : :
733 : 0 : ops->nb_src = n_sge;
734 : 0 : ops->nb_dst = n_sge;
735 : 0 : sg_memory_setup(n_sge);
736 : :
737 : : /* Enqueue operations */
738 : 0 : ret = rte_dma_enqueue_ops(test_dev_id, 0, &ops, 1);
739 [ # # ]: 0 : RTE_TEST_ASSERT(ret == 1, "Failed to enqueue DMA operations, %d", ret);
740 : :
741 : 0 : rte_delay_us_sleep(TEST_WAIT_US_VAL);
742 : :
743 : 0 : ops = NULL;
744 : : /* Dequeue operations */
745 : 0 : ret = rte_dma_dequeue_ops(test_dev_id, 0, &ops, 1);
746 [ # # ]: 0 : RTE_TEST_ASSERT(ret == 1, "Failed to dequeue DMA operations, %d", ret);
747 [ # # ]: 0 : RTE_TEST_ASSERT(ops != NULL, "Failed to dequeue DMA operations %p", ops);
748 : : /* Free allocated memory for ops */
749 : 0 : rte_free(ops);
750 : :
751 : 0 : ret = sg_memory_verify(n_sge);
752 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to verify memory");
753 : :
754 : : /* Stop dmadev to make sure dmadev to a known state */
755 : 0 : ret = rte_dma_stop(test_dev_id);
756 [ # # ]: 0 : RTE_TEST_ASSERT_SUCCESS(ret, "Failed to stop, %d", ret);
757 : :
758 : : return TEST_SUCCESS;
759 : : }
760 : :
761 : : static struct unit_test_suite dma_api_testsuite = {
762 : : .suite_name = "DMA API Test Suite",
763 : : .setup = testsuite_setup,
764 : : .teardown = testsuite_teardown,
765 : : .unit_test_cases = {
766 : : TEST_CASE(test_dma_get_dev_id_by_name),
767 : : TEST_CASE(test_dma_is_valid_dev),
768 : : TEST_CASE(test_dma_count),
769 : : TEST_CASE(test_dma_info_get),
770 : : TEST_CASE(test_dma_configure),
771 : : TEST_CASE(test_dma_vchan_setup),
772 : : TEST_CASE(test_dma_start_stop),
773 : : TEST_CASE(test_dma_reconfigure),
774 : : TEST_CASE(test_dma_stats),
775 : : TEST_CASE(test_dma_dump),
776 : : TEST_CASE(test_dma_completed),
777 : : TEST_CASE(test_dma_completed_status),
778 : : TEST_CASE(test_dma_sg),
779 : : TEST_CASE(test_dma_ops_enq_deq),
780 : : TEST_CASES_END()
781 : : }
782 : : };
783 : :
784 : : int
785 : 0 : test_dma_api(uint16_t dev_id)
786 : : {
787 : : struct rte_dma_info dev_info;
788 : :
789 [ # # ]: 0 : if (rte_dma_info_get(dev_id, &dev_info) < 0)
790 : : return TEST_SKIPPED;
791 : :
792 : 0 : printf("\n### Test dmadev infrastructure using %u [%s]\n", dev_id, dev_info.dev_name);
793 : 0 : test_dev_id = dev_id;
794 : 0 : return unit_test_suite_runner(&dma_api_testsuite);
795 : : };
|