diff --git a/tests/drivers/ethernet/eth_ivshmem_queue/CMakeLists.txt b/tests/drivers/ethernet/eth_ivshmem_queue/CMakeLists.txt new file mode 100644 index 00000000000..fa26887c216 --- /dev/null +++ b/tests/drivers/ethernet/eth_ivshmem_queue/CMakeLists.txt @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(eth_ivshmem_queue) + +target_include_directories(app PRIVATE ${ZEPHYR_BASE}/drivers/ethernet) +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE + ${app_sources} + ${ZEPHYR_BASE}/drivers/ethernet/eth_ivshmem_queue.c) diff --git a/tests/drivers/ethernet/eth_ivshmem_queue/prj.conf b/tests/drivers/ethernet/eth_ivshmem_queue/prj.conf new file mode 100644 index 00000000000..ec2681e0763 --- /dev/null +++ b/tests/drivers/ethernet/eth_ivshmem_queue/prj.conf @@ -0,0 +1,4 @@ +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y + +CONFIG_OPENAMP=y diff --git a/tests/drivers/ethernet/eth_ivshmem_queue/src/main.c b/tests/drivers/ethernet/eth_ivshmem_queue/src/main.c new file mode 100644 index 00000000000..53c65e39e16 --- /dev/null +++ b/tests/drivers/ethernet/eth_ivshmem_queue/src/main.c @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2023 Enphase Energy + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include "eth_ivshmem_priv.h" + +#define SHMEM_SECTION_SIZE KB(4) + +#define VRING_DESC_LEN 32 +#define VRING_HEADER_SIZE 1792 +#define VRING_DATA_MAX_LEN 2304 + +static struct eth_ivshmem_queue q1, q2; +static uint8_t shmem_buff[SHMEM_SECTION_SIZE * 2]; +static const void *rx_message; +static size_t rx_len; + +static void test_init_queues(void) +{ + int res = eth_ivshmem_queue_init(&q1, (uintptr_t)shmem_buff, SHMEM_SECTION_SIZE, true); + + zassert_ok(res); + res = eth_ivshmem_queue_init(&q2, (uintptr_t)shmem_buff, SHMEM_SECTION_SIZE, false); + zassert_ok(res); +} + +static inline int queue_tx(struct eth_ivshmem_queue *q, const void *data, size_t len) +{ + void *dest; + int res = eth_ivshmem_queue_tx_get_buff(q, &dest, len); + + if (res == 0) { + memcpy(dest, data, len); + res = eth_ivshmem_queue_tx_commit_buff(q); + } + return res; +} + +static void test_setup(void *fixture) +{ + ARG_UNUSED(fixture); + rx_message = NULL; + rx_len = 0; + test_init_queues(); +} + + +ZTEST(eth_ivshmem_queue_tests, test_init) +{ + zassert_equal(q1.desc_max_len, VRING_DESC_LEN); + zassert_equal(q1.vring_header_size, VRING_HEADER_SIZE); + zassert_equal(q1.vring_data_max_len, VRING_DATA_MAX_LEN); + zassert_equal_ptr(q1.tx.shmem, shmem_buff); + zassert_equal_ptr(q1.rx.shmem, shmem_buff + SHMEM_SECTION_SIZE); + zassert_equal_ptr(q2.tx.shmem, shmem_buff + SHMEM_SECTION_SIZE); + zassert_equal_ptr(q2.rx.shmem, shmem_buff); +} + +ZTEST(eth_ivshmem_queue_tests, test_simple_send_receive) +{ + /* Send */ + int x = 42; + + zassert_ok(queue_tx(&q1, &x, sizeof(x))); + + /* Receive */ + zassert_ok(eth_ivshmem_queue_rx(&q2, &rx_message, &rx_len)); + zassert_equal(rx_len, sizeof(x)); + zassert_equal(*(int *)rx_message, x); + zassert_ok(eth_ivshmem_queue_rx_complete(&q2)); +} + +ZTEST(eth_ivshmem_queue_tests, test_send_receive_both_directions) +{ + /* Send q1 */ + int q1_tx_data = 42; + + zassert_ok(queue_tx(&q1, &q1_tx_data, sizeof(q1_tx_data))); + + /* Send q2 */ + int q2_tx_data = 21; + + zassert_ok(queue_tx(&q2, &q2_tx_data, sizeof(q2_tx_data))); + + /* Receive q2 */ + zassert_ok(eth_ivshmem_queue_rx(&q2, &rx_message, &rx_len)); + zassert_equal(rx_len, sizeof(q1_tx_data)); + zassert_equal(*(int *)rx_message, q1_tx_data); + zassert_ok(eth_ivshmem_queue_rx_complete(&q2)); + + /* Receive q1 */ + zassert_ok(eth_ivshmem_queue_rx(&q1, &rx_message, &rx_len)); + zassert_equal(rx_len, sizeof(q2_tx_data)); + zassert_equal(*(int *)rx_message, q2_tx_data); + zassert_ok(eth_ivshmem_queue_rx_complete(&q1)); +} + +ZTEST(eth_ivshmem_queue_tests, test_queue_empty) +{ + /* Read with empty queue */ + zassert_equal(eth_ivshmem_queue_rx(&q1, &rx_message, &rx_len), -EWOULDBLOCK); + + /* Complete with empty queue */ + zassert_equal(eth_ivshmem_queue_rx_complete(&q1), -EWOULDBLOCK); + + /* TX commit without getting buffer */ + zassert_equal(eth_ivshmem_queue_tx_commit_buff(&q1), -EINVAL); + + /* Getting a buffer (without committing) should not modify/overflow the queue */ + for (int i = 0; i < 100; i++) { + void *data; + + zassert_ok(eth_ivshmem_queue_tx_get_buff(&q1, &data, KB(1))); + } +} + +ZTEST(eth_ivshmem_queue_tests, test_queue_descriptors_full) +{ + /* Fill queue descriptors */ + for (int i = 0; i < VRING_DESC_LEN; i++) { + zassert_ok(queue_tx(&q1, &i, sizeof(i))); + } + + /* Fail to add another */ + int x = 0; + + zassert_equal(queue_tx(&q1, &x, sizeof(x)), -ENOBUFS); + + /* Read 3 */ + for (int i = 0; i < 3; i++) { + zassert_ok(eth_ivshmem_queue_rx(&q2, &rx_message, &rx_len)); + zassert_equal(rx_len, sizeof(i)); + zassert_equal(*(int *)rx_message, i); + zassert_ok(eth_ivshmem_queue_rx_complete(&q2)); + } + + /* Can now add 3 more */ + for (int i = 0; i < 3; i++) { + zassert_ok(queue_tx(&q1, &i, sizeof(i))); + } + + /* Fail to add another */ + zassert_equal(queue_tx(&q1, &x, sizeof(x)), -ENOBUFS); +} + +ZTEST(eth_ivshmem_queue_tests, test_queue_shmem_full) +{ + static uint8_t large_message[KB(1)]; + + /* Fill queue shmem */ + for (int i = 0; i < VRING_DATA_MAX_LEN / sizeof(large_message); i++) { + zassert_ok(queue_tx(&q1, large_message, sizeof(large_message))); + } + + /* Fail to add another */ + zassert_equal(queue_tx(&q1, large_message, sizeof(large_message)), -ENOBUFS); + + /* Read 1 */ + zassert_ok(eth_ivshmem_queue_rx(&q2, &rx_message, &rx_len)); + zassert_equal(rx_len, sizeof(large_message)); + zassert_ok(eth_ivshmem_queue_rx_complete(&q2)); + + /* Can now add 1 more */ + zassert_ok(queue_tx(&q1, large_message, sizeof(large_message))); + + /* Fail to add another */ + zassert_equal(queue_tx(&q1, large_message, sizeof(large_message)), -ENOBUFS); +} + +ZTEST_SUITE(eth_ivshmem_queue_tests, NULL, NULL, test_setup, NULL, NULL); diff --git a/tests/drivers/ethernet/eth_ivshmem_queue/testcase.yaml b/tests/drivers/ethernet/eth_ivshmem_queue/testcase.yaml new file mode 100644 index 00000000000..c4512d95326 --- /dev/null +++ b/tests/drivers/ethernet/eth_ivshmem_queue/testcase.yaml @@ -0,0 +1,3 @@ +tests: + net.eth_ivshmem_queue: + platform_allow: qemu_cortex_a53