From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4979DC433FE for ; Fri, 24 Sep 2021 10:58:46 +0000 (UTC) Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by mail.kernel.org (Postfix) with ESMTP id C3BB061107 for ; Fri, 24 Sep 2021 10:58:45 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org C3BB061107 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=huawei.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=dpdk.org Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id D232341325; Fri, 24 Sep 2021 12:58:21 +0200 (CEST) Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) by mails.dpdk.org (Postfix) with ESMTP id 4D21C412F6 for ; Fri, 24 Sep 2021 12:58:14 +0200 (CEST) Received: from dggemv703-chm.china.huawei.com (unknown [172.30.72.57]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4HG86H1TLKzbmk6; Fri, 24 Sep 2021 18:53:59 +0800 (CST) Received: from dggpeml500024.china.huawei.com (7.185.36.10) by dggemv703-chm.china.huawei.com (10.3.19.46) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.8; Fri, 24 Sep 2021 18:58:12 +0800 Received: from localhost.localdomain (10.67.165.24) by dggpeml500024.china.huawei.com (7.185.36.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.8; Fri, 24 Sep 2021 18:58:12 +0800 From: Chengwen Feng To: , , , , , CC: , , , , , , , , , , , Date: Fri, 24 Sep 2021 18:53:57 +0800 Message-ID: <20210924105357.15386-7-fengchengwen@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20210924105357.15386-1-fengchengwen@huawei.com> References: <1625231891-2963-1-git-send-email-fengchengwen@huawei.com> <20210924105357.15386-1-fengchengwen@huawei.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Originating-IP: [10.67.165.24] X-ClientProxiedBy: dggems703-chm.china.huawei.com (10.3.19.180) To dggpeml500024.china.huawei.com (7.185.36.10) X-CFilter-Loop: Reflected Subject: [dpdk-dev] [PATCH v23 6/6] app/test: add dmadev API test X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch add dmadev API test which based on 'dma_skeleton' vdev. The test cases could be executed using 'dmadev_autotest' command in test framework. Signed-off-by: Chengwen Feng Signed-off-by: Bruce Richardson Reviewed-by: Kevin Laatz Reviewed-by: Conor Walsh --- MAINTAINERS | 1 + app/test/meson.build | 4 + app/test/test_dmadev.c | 41 +++ app/test/test_dmadev_api.c | 574 +++++++++++++++++++++++++++++++++++++ app/test/test_dmadev_api.h | 5 + 5 files changed, 625 insertions(+) create mode 100644 app/test/test_dmadev.c create mode 100644 app/test/test_dmadev_api.c create mode 100644 app/test/test_dmadev_api.h diff --git a/MAINTAINERS b/MAINTAINERS index 85d4f83395..3258da194d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -458,6 +458,7 @@ DMA device API - EXPERIMENTAL M: Chengwen Feng F: lib/dmadev/ F: drivers/dma/skeleton/ +F: app/test/test_dmadev* F: doc/guides/prog_guide/dmadev.rst Eventdev API diff --git a/app/test/meson.build b/app/test/meson.build index a7611686ad..9027eba3a4 100644 --- a/app/test/meson.build +++ b/app/test/meson.build @@ -43,6 +43,8 @@ test_sources = files( 'test_debug.c', 'test_distributor.c', 'test_distributor_perf.c', + 'test_dmadev.c', + 'test_dmadev_api.c', 'test_eal_flags.c', 'test_eal_fs.c', 'test_efd.c', @@ -162,6 +164,7 @@ test_deps = [ 'cmdline', 'cryptodev', 'distributor', + 'dmadev', 'efd', 'ethdev', 'eventdev', @@ -333,6 +336,7 @@ driver_test_names = [ 'cryptodev_sw_mvsam_autotest', 'cryptodev_sw_snow3g_autotest', 'cryptodev_sw_zuc_autotest', + 'dmadev_autotest', 'eventdev_selftest_octeontx', 'eventdev_selftest_sw', 'rawdev_autotest', diff --git a/app/test/test_dmadev.c b/app/test/test_dmadev.c new file mode 100644 index 0000000000..75cc939158 --- /dev/null +++ b/app/test/test_dmadev.c @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2021 HiSilicon Limited + * Copyright(c) 2021 Intel Corporation + */ + +#include +#include + +#include "test.h" +#include "test_dmadev_api.h" + +static int +test_apis(void) +{ + const char *pmd = "dma_skeleton"; + int id; + int ret; + + if (rte_vdev_init(pmd, NULL) < 0) + return TEST_SKIPPED; + id = rte_dma_get_dev_id(pmd); + if (id < 0) + return TEST_SKIPPED; + printf("\n### Test dmadev infrastructure using skeleton driver\n"); + ret = test_dma_api(id); + rte_vdev_uninit(pmd); + + return ret; +} + +static int +test_dma(void) +{ + /* basic sanity on dmadev infrastructure */ + if (test_apis() < 0) + return -1; + + return 0; +} + +REGISTER_TEST_COMMAND(dmadev_autotest, test_dma); diff --git a/app/test/test_dmadev_api.c b/app/test/test_dmadev_api.c new file mode 100644 index 0000000000..90c317aae2 --- /dev/null +++ b/app/test/test_dmadev_api.c @@ -0,0 +1,574 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2021 HiSilicon Limited + */ + +#include + +#include +#include +#include +#include + +extern int test_dma_api(uint16_t dev_id); + +#define DMA_TEST_API_RUN(test) \ + testsuite_run_test(test, #test) + +#define TEST_MEMCPY_SIZE 1024 +#define TEST_WAIT_US_VAL 50000 + +#define TEST_SUCCESS 0 +#define TEST_FAILED -1 + +static int16_t test_dev_id; +static int16_t invalid_dev_id; + +static char *src; +static char *dst; + +static int total; +static int passed; +static int failed; + +static int +testsuite_setup(int16_t dev_id) +{ + test_dev_id = dev_id; + invalid_dev_id = -1; + + src = rte_malloc("dmadev_test_src", TEST_MEMCPY_SIZE, 0); + if (src == NULL) + return -ENOMEM; + dst = rte_malloc("dmadev_test_dst", TEST_MEMCPY_SIZE, 0); + if (dst == NULL) { + rte_free(src); + src = NULL; + return -ENOMEM; + } + + total = 0; + passed = 0; + failed = 0; + + /* Set dmadev log level to critical to suppress unnecessary output + * during API tests. + */ + rte_log_set_level_pattern("lib.dmadev", RTE_LOG_CRIT); + + return 0; +} + +static void +testsuite_teardown(void) +{ + rte_free(src); + src = NULL; + rte_free(dst); + dst = NULL; + /* Ensure the dmadev is stopped. */ + rte_dma_stop(test_dev_id); + + rte_log_set_level_pattern("lib.dmadev", RTE_LOG_INFO); +} + +static void +testsuite_run_test(int (*test)(void), const char *name) +{ + int ret = 0; + + if (test) { + ret = test(); + if (ret < 0) { + failed++; + printf("%s Failed\n", name); + } else { + passed++; + printf("%s Passed\n", name); + } + } + + total++; +} + +static int +test_dma_get_dev_id(void) +{ + int ret = rte_dma_get_dev_id("invalid_dmadev_device"); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + return TEST_SUCCESS; +} + +static int +test_dma_is_valid_dev(void) +{ + int ret; + ret = rte_dma_is_valid(invalid_dev_id); + RTE_TEST_ASSERT(ret == false, "Expected false for invalid dev id"); + ret = rte_dma_is_valid(test_dev_id); + RTE_TEST_ASSERT(ret == true, "Expected true for valid dev id"); + return TEST_SUCCESS; +} + +static int +test_dma_count(void) +{ + uint16_t count = rte_dma_count_avail(); + RTE_TEST_ASSERT(count > 0, "Invalid dmadev count %u", count); + return TEST_SUCCESS; +} + +static int +test_dma_info_get(void) +{ + struct rte_dma_info info = { 0 }; + int ret; + + ret = rte_dma_info_get(invalid_dev_id, &info); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + ret = rte_dma_info_get(test_dev_id, NULL); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + ret = rte_dma_info_get(test_dev_id, &info); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info"); + + return TEST_SUCCESS; +} + +static int +test_dma_configure(void) +{ + struct rte_dma_conf conf = { 0 }; + struct rte_dma_info info = { 0 }; + int ret; + + /* Check for invalid parameters */ + ret = rte_dma_configure(invalid_dev_id, &conf); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + ret = rte_dma_configure(test_dev_id, NULL); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + + /* Check for nb_vchans == 0 */ + memset(&conf, 0, sizeof(conf)); + ret = rte_dma_configure(test_dev_id, &conf); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + + /* Check for conf.nb_vchans > info.max_vchans */ + ret = rte_dma_info_get(test_dev_id, &info); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info"); + memset(&conf, 0, sizeof(conf)); + conf.nb_vchans = info.max_vchans + 1; + ret = rte_dma_configure(test_dev_id, &conf); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + + /* Check enable silent mode */ + memset(&conf, 0, sizeof(conf)); + conf.nb_vchans = info.max_vchans; + conf.enable_silent = true; + ret = rte_dma_configure(test_dev_id, &conf); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + + /* Configure success */ + memset(&conf, 0, sizeof(conf)); + conf.nb_vchans = info.max_vchans; + ret = rte_dma_configure(test_dev_id, &conf); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to configure dmadev, %d", ret); + + /* Check configure success */ + ret = rte_dma_info_get(test_dev_id, &info); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info"); + RTE_TEST_ASSERT_EQUAL(conf.nb_vchans, info.nb_vchans, + "Configure nb_vchans not match"); + + return TEST_SUCCESS; +} + +static int +check_direction(void) +{ + struct rte_dma_vchan_conf vchan_conf; + int ret; + + /* Check for direction */ + memset(&vchan_conf, 0, sizeof(vchan_conf)); + vchan_conf.direction = RTE_DMA_DIR_DEV_TO_DEV + 1; + ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + vchan_conf.direction = RTE_DMA_DIR_MEM_TO_MEM - 1; + ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + + /* Check for direction and dev_capa combination */ + memset(&vchan_conf, 0, sizeof(vchan_conf)); + vchan_conf.direction = RTE_DMA_DIR_MEM_TO_DEV; + ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + vchan_conf.direction = RTE_DMA_DIR_DEV_TO_MEM; + ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + vchan_conf.direction = RTE_DMA_DIR_DEV_TO_DEV; + ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + + return 0; +} + +static int +check_port_type(struct rte_dma_info *dev_info) +{ + struct rte_dma_vchan_conf vchan_conf; + int ret; + + /* Check src port type validation */ + memset(&vchan_conf, 0, sizeof(vchan_conf)); + vchan_conf.direction = RTE_DMA_DIR_MEM_TO_MEM; + vchan_conf.nb_desc = dev_info->min_desc; + vchan_conf.src_port.port_type = RTE_DMA_PORT_PCIE; + ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + + /* Check dst port type validation */ + memset(&vchan_conf, 0, sizeof(vchan_conf)); + vchan_conf.direction = RTE_DMA_DIR_MEM_TO_MEM; + vchan_conf.nb_desc = dev_info->min_desc; + vchan_conf.dst_port.port_type = RTE_DMA_PORT_PCIE; + ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + + return 0; +} + +static int +test_dma_vchan_setup(void) +{ + struct rte_dma_vchan_conf vchan_conf = { 0 }; + struct rte_dma_conf dev_conf = { 0 }; + struct rte_dma_info dev_info = { 0 }; + int ret; + + /* Check for invalid parameters */ + ret = rte_dma_vchan_setup(invalid_dev_id, 0, &vchan_conf); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + ret = rte_dma_vchan_setup(test_dev_id, 0, NULL); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + + /* Make sure configure success */ + ret = rte_dma_info_get(test_dev_id, &dev_info); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info"); + dev_conf.nb_vchans = dev_info.max_vchans; + ret = rte_dma_configure(test_dev_id, &dev_conf); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to configure dmadev, %d", ret); + + /* Check for invalid vchan */ + ret = rte_dma_vchan_setup(test_dev_id, dev_conf.nb_vchans, &vchan_conf); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + + /* Check for direction */ + ret = check_direction(); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to check direction"); + + /* Check for nb_desc validation */ + memset(&vchan_conf, 0, sizeof(vchan_conf)); + vchan_conf.direction = RTE_DMA_DIR_MEM_TO_MEM; + vchan_conf.nb_desc = dev_info.min_desc - 1; + ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + vchan_conf.nb_desc = dev_info.max_desc + 1; + ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + + /* Check port type */ + ret = check_port_type(&dev_info); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to check port type"); + + /* Check vchan setup success */ + memset(&vchan_conf, 0, sizeof(vchan_conf)); + vchan_conf.direction = RTE_DMA_DIR_MEM_TO_MEM; + vchan_conf.nb_desc = dev_info.min_desc; + ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup vchan, %d", ret); + + return TEST_SUCCESS; +} + +static int +setup_one_vchan(void) +{ + struct rte_dma_vchan_conf vchan_conf = { 0 }; + struct rte_dma_info dev_info = { 0 }; + struct rte_dma_conf dev_conf = { 0 }; + int ret; + + ret = rte_dma_info_get(test_dev_id, &dev_info); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret); + dev_conf.nb_vchans = dev_info.max_vchans; + ret = rte_dma_configure(test_dev_id, &dev_conf); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to configure, %d", ret); + vchan_conf.direction = RTE_DMA_DIR_MEM_TO_MEM; + vchan_conf.nb_desc = dev_info.min_desc; + ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup vchan, %d", ret); + + return TEST_SUCCESS; +} + +static int +test_dma_start_stop(void) +{ + struct rte_dma_vchan_conf vchan_conf = { 0 }; + struct rte_dma_conf dev_conf = { 0 }; + int ret; + + /* Check for invalid parameters */ + ret = rte_dma_start(invalid_dev_id); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + ret = rte_dma_stop(invalid_dev_id); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + + /* Setup one vchan for later test */ + ret = setup_one_vchan(); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret); + + ret = rte_dma_start(test_dev_id); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start, %d", ret); + + /* Check reconfigure and vchan setup when device started */ + ret = rte_dma_configure(test_dev_id, &dev_conf); + RTE_TEST_ASSERT(ret == -EBUSY, "Failed to configure, %d", ret); + ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf); + RTE_TEST_ASSERT(ret == -EBUSY, "Failed to setup vchan, %d", ret); + + ret = rte_dma_stop(test_dev_id); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to stop, %d", ret); + + return TEST_SUCCESS; +} + +static int +test_dma_stats(void) +{ + struct rte_dma_info dev_info = { 0 }; + struct rte_dma_stats stats = { 0 }; + int ret; + + /* Check for invalid parameters */ + ret = rte_dma_stats_get(invalid_dev_id, 0, &stats); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + ret = rte_dma_stats_get(invalid_dev_id, 0, NULL); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + ret = rte_dma_stats_reset(invalid_dev_id, 0); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + + /* Setup one vchan for later test */ + ret = setup_one_vchan(); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret); + + /* Check for invalid vchan */ + ret = rte_dma_info_get(test_dev_id, &dev_info); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret); + ret = rte_dma_stats_get(test_dev_id, dev_info.max_vchans, &stats); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + ret = rte_dma_stats_reset(test_dev_id, dev_info.max_vchans); + RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret); + + /* Check for valid vchan */ + ret = rte_dma_stats_get(test_dev_id, 0, &stats); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to get stats, %d", ret); + ret = rte_dma_stats_get(test_dev_id, RTE_DMA_ALL_VCHAN, &stats); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to get all stats, %d", ret); + ret = rte_dma_stats_reset(test_dev_id, 0); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to reset stats, %d", ret); + ret = rte_dma_stats_reset(test_dev_id, RTE_DMA_ALL_VCHAN); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to reset all stats, %d", ret); + + return TEST_SUCCESS; +} + +static int +test_dma_dump(void) +{ + int ret; + + /* Check for invalid parameters */ + ret = rte_dma_dump(invalid_dev_id, stderr); + RTE_TEST_ASSERT(ret == -EINVAL, "Excepted -EINVAL, %d", ret); + ret = rte_dma_dump(test_dev_id, NULL); + RTE_TEST_ASSERT(ret == -EINVAL, "Excepted -EINVAL, %d", ret); + + return TEST_SUCCESS; +} + +static void +setup_memory(void) +{ + int i; + + for (i = 0; i < TEST_MEMCPY_SIZE; i++) + src[i] = (char)i; + memset(dst, 0, TEST_MEMCPY_SIZE); +} + +static int +verify_memory(void) +{ + int i; + + for (i = 0; i < TEST_MEMCPY_SIZE; i++) { + if (src[i] == dst[i]) + continue; + RTE_TEST_ASSERT_EQUAL(src[i], dst[i], + "Failed to copy memory, %d %d", src[i], dst[i]); + } + + return 0; +} + +static int +test_dma_completed(void) +{ + uint16_t last_idx = 1; + bool has_error = true; + uint16_t cpl_ret; + int ret; + + /* Setup one vchan for later test */ + ret = setup_one_vchan(); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret); + + ret = rte_dma_start(test_dev_id); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start, %d", ret); + + setup_memory(); + + /* Check enqueue without submit */ + ret = rte_dma_copy(test_dev_id, 0, (rte_iova_t)src, (rte_iova_t)dst, + TEST_MEMCPY_SIZE, 0); + RTE_TEST_ASSERT_EQUAL(ret, 0, "Failed to enqueue copy, %d", ret); + rte_delay_us_sleep(TEST_WAIT_US_VAL); + cpl_ret = rte_dma_completed(test_dev_id, 0, 1, &last_idx, &has_error); + RTE_TEST_ASSERT_EQUAL(cpl_ret, 0, "Failed to get completed"); + + /* Check add submit */ + ret = rte_dma_submit(test_dev_id, 0); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to submit, %d", ret); + rte_delay_us_sleep(TEST_WAIT_US_VAL); + cpl_ret = rte_dma_completed(test_dev_id, 0, 1, &last_idx, &has_error); + RTE_TEST_ASSERT_EQUAL(cpl_ret, 1, "Failed to get completed"); + RTE_TEST_ASSERT_EQUAL(last_idx, 0, "Last idx should be zero, %u", + last_idx); + RTE_TEST_ASSERT_EQUAL(has_error, false, "Should have no error"); + ret = verify_memory(); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to verify memory"); + + setup_memory(); + + /* Check for enqueue with submit */ + ret = rte_dma_copy(test_dev_id, 0, (rte_iova_t)src, (rte_iova_t)dst, + TEST_MEMCPY_SIZE, RTE_DMA_OP_FLAG_SUBMIT); + RTE_TEST_ASSERT_EQUAL(ret, 1, "Failed to enqueue copy, %d", ret); + rte_delay_us_sleep(TEST_WAIT_US_VAL); + cpl_ret = rte_dma_completed(test_dev_id, 0, 1, &last_idx, &has_error); + RTE_TEST_ASSERT_EQUAL(cpl_ret, 1, "Failed to get completed"); + RTE_TEST_ASSERT_EQUAL(last_idx, 1, "Last idx should be 1, %u", + last_idx); + RTE_TEST_ASSERT_EQUAL(has_error, false, "Should have no error"); + ret = verify_memory(); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to verify memory"); + + /* Stop dmadev to make sure dmadev to a known state */ + ret = rte_dma_stop(test_dev_id); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to stop, %d", ret); + + return TEST_SUCCESS; +} + +static int +test_dma_completed_status(void) +{ + enum rte_dma_status_code status[1] = { 1 }; + uint16_t last_idx = 1; + uint16_t cpl_ret, i; + int ret; + + /* Setup one vchan for later test */ + ret = setup_one_vchan(); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret); + + ret = rte_dma_start(test_dev_id); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start, %d", ret); + + /* Check for enqueue with submit */ + ret = rte_dma_copy(test_dev_id, 0, (rte_iova_t)src, (rte_iova_t)dst, + TEST_MEMCPY_SIZE, RTE_DMA_OP_FLAG_SUBMIT); + RTE_TEST_ASSERT_EQUAL(ret, 0, "Failed to enqueue copy, %d", ret); + rte_delay_us_sleep(TEST_WAIT_US_VAL); + cpl_ret = rte_dma_completed_status(test_dev_id, 0, 1, &last_idx, + status); + RTE_TEST_ASSERT_EQUAL(cpl_ret, 1, "Failed to completed status"); + RTE_TEST_ASSERT_EQUAL(last_idx, 0, "Last idx should be zero, %u", + last_idx); + for (i = 0; i < RTE_DIM(status); i++) + RTE_TEST_ASSERT_EQUAL(status[i], 0, + "Failed to completed status, %d", status[i]); + + /* Check do completed status again */ + cpl_ret = rte_dma_completed_status(test_dev_id, 0, 1, &last_idx, + status); + RTE_TEST_ASSERT_EQUAL(cpl_ret, 0, "Failed to completed status"); + + /* Check for enqueue with submit again */ + ret = rte_dma_copy(test_dev_id, 0, (rte_iova_t)src, (rte_iova_t)dst, + TEST_MEMCPY_SIZE, RTE_DMA_OP_FLAG_SUBMIT); + RTE_TEST_ASSERT_EQUAL(ret, 1, "Failed to enqueue copy, %d", ret); + rte_delay_us_sleep(TEST_WAIT_US_VAL); + cpl_ret = rte_dma_completed_status(test_dev_id, 0, 1, &last_idx, + status); + RTE_TEST_ASSERT_EQUAL(cpl_ret, 1, "Failed to completed status"); + RTE_TEST_ASSERT_EQUAL(last_idx, 1, "Last idx should be 1, %u", + last_idx); + for (i = 0; i < RTE_DIM(status); i++) + RTE_TEST_ASSERT_EQUAL(status[i], 0, + "Failed to completed status, %d", status[i]); + + /* Stop dmadev to make sure dmadev to a known state */ + ret = rte_dma_stop(test_dev_id); + RTE_TEST_ASSERT_SUCCESS(ret, "Failed to stop, %d", ret); + + return TEST_SUCCESS; +} + +int +test_dma_api(uint16_t dev_id) +{ + int ret = testsuite_setup(dev_id); + if (ret) { + printf("testsuite setup fail!\n"); + return -1; + } + + /* If the testcase exit successfully, ensure that the test dmadev exist + * and the dmadev is in the stopped state. + */ + DMA_TEST_API_RUN(test_dma_get_dev_id); + DMA_TEST_API_RUN(test_dma_is_valid_dev); + DMA_TEST_API_RUN(test_dma_count); + DMA_TEST_API_RUN(test_dma_info_get); + DMA_TEST_API_RUN(test_dma_configure); + DMA_TEST_API_RUN(test_dma_vchan_setup); + DMA_TEST_API_RUN(test_dma_start_stop); + DMA_TEST_API_RUN(test_dma_stats); + DMA_TEST_API_RUN(test_dma_dump); + DMA_TEST_API_RUN(test_dma_completed); + DMA_TEST_API_RUN(test_dma_completed_status); + + testsuite_teardown(); + + printf("Total tests : %d\n", total); + printf("Passed : %d\n", passed); + printf("Failed : %d\n", failed); + + if (failed) + return -1; + + return 0; +}; diff --git a/app/test/test_dmadev_api.h b/app/test/test_dmadev_api.h new file mode 100644 index 0000000000..33fbc5bd41 --- /dev/null +++ b/app/test/test_dmadev_api.h @@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2021 HiSilicon Limited + */ + +int test_dma_api(uint16_t dev_id); -- 2.33.0