From c9aaab74dba8bcc60e00219da4439ed9fd33d597 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Mon, 27 May 2019 16:01:49 +0800 Subject: [PATCH] net: ptp: clock: Add usermode support to ptp_clock_get() It is useful that the ptp_clock_get() function can be called from the userspace. Create also unit test for calling that function from userspace. Signed-off-by: Jukka Rissanen --- drivers/CMakeLists.txt | 1 + drivers/ptp_clock/CMakeLists.txt | 3 ++ drivers/ptp_clock/ptp_clock.c | 30 +++++++++++++++++ include/ptp_clock.h | 8 ++++- scripts/gen_kobject_list.py | 1 + tests/net/ptp/clock/src/main.c | 53 ++++++++++++++++++++++++++++++- tests/net/ptp/clock/testcase.yaml | 1 - 7 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 drivers/ptp_clock/CMakeLists.txt create mode 100644 drivers/ptp_clock/ptp_clock.c diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt index aa770c1049c..57acca6826c 100644 --- a/drivers/CMakeLists.txt +++ b/drivers/CMakeLists.txt @@ -43,3 +43,4 @@ add_subdirectory_ifdef(CONFIG_NET_L2_ETHERNET ethernet) add_subdirectory_ifdef(CONFIG_ENTROPY_HAS_DRIVER entropy) add_subdirectory_ifdef(CONFIG_SYS_CLOCK_EXISTS timer) add_subdirectory_ifdef(CONFIG_NEURAL_NET_ACCEL neural_net) +add_subdirectory_ifdef(CONFIG_PTP_CLOCK ptp_clock) diff --git a/drivers/ptp_clock/CMakeLists.txt b/drivers/ptp_clock/CMakeLists.txt new file mode 100644 index 00000000000..6ece3042a45 --- /dev/null +++ b/drivers/ptp_clock/CMakeLists.txt @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources_ifdef(CONFIG_PTP_CLOCK ptp_clock.c) diff --git a/drivers/ptp_clock/ptp_clock.c b/drivers/ptp_clock/ptp_clock.c new file mode 100644 index 00000000000..ce9ce02561b --- /dev/null +++ b/drivers/ptp_clock/ptp_clock.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2019 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#ifdef CONFIG_USERSPACE +Z_SYSCALL_HANDLER(ptp_clock_get, dev, tm) +{ + struct net_ptp_time ptp_time; + int ret; + + Z_OOPS(Z_SYSCALL_DRIVER_PTP_CLOCK(dev, get)); + Z_OOPS(Z_SYSCALL_MEMORY_WRITE(tm, sizeof(struct net_ptp_time))); + + ret = z_impl_ptp_clock_get((struct device *)dev, &ptp_time); + if (ret != 0) { + return 0; + } + + if (z_user_to_copy((void *)tm, &ptp_time, sizeof(ptp_time)) != 0) { + return 0; + } + + return (u32_t)ret; +} +#endif /* CONFIG_USERSPACE */ diff --git a/include/ptp_clock.h b/include/ptp_clock.h index 68120b97039..edb908485b7 100644 --- a/include/ptp_clock.h +++ b/include/ptp_clock.h @@ -7,6 +7,7 @@ #ifndef ZEPHYR_INCLUDE_PTP_CLOCK_H_ #define ZEPHYR_INCLUDE_PTP_CLOCK_H_ +#include #include #include #include @@ -51,7 +52,10 @@ static inline int ptp_clock_set(struct device *dev, struct net_ptp_time *tm) * * @return 0 if ok, <0 if error */ -static inline int ptp_clock_get(struct device *dev, struct net_ptp_time *tm) +__syscall int ptp_clock_get(struct device *dev, struct net_ptp_time *tm); + +static inline int z_impl_ptp_clock_get(struct device *dev, + struct net_ptp_time *tm) { const struct ptp_clock_driver_api *api = dev->driver_api; @@ -88,6 +92,8 @@ static inline int ptp_clock_rate_adjust(struct device *dev, float rate) return api->rate_adjust(dev, rate); } +#include + #ifdef __cplusplus } #endif diff --git a/scripts/gen_kobject_list.py b/scripts/gen_kobject_list.py index d4aa54d7915..8cf04ab9baa 100755 --- a/scripts/gen_kobject_list.py +++ b/scripts/gen_kobject_list.py @@ -112,6 +112,7 @@ subsystems = [ "spi_driver_api", "uart_driver_api", "can_driver_api", + "ptp_clock_driver_api", ] diff --git a/tests/net/ptp/clock/src/main.c b/tests/net/ptp/clock/src/main.c index 1ca2d0657a9..88e45d3a78c 100644 --- a/tests/net/ptp/clock/src/main.c +++ b/tests/net/ptp/clock/src/main.c @@ -394,6 +394,7 @@ static void address_setup(void) static void test_ptp_clock_interfaces(void) { + struct device *clk_by_index; struct device *clk; int idx; @@ -410,6 +411,11 @@ static void test_ptp_clock_interfaces(void) clk = net_eth_get_ptp_clock(eth_interfaces[non_ptp_interface]); zassert_is_null(clk, "Clock found for interface %p\n", eth_interfaces[non_ptp_interface]); + + clk_by_index = net_eth_get_ptp_clock_by_index(ptp_clocks[0]); + zassert_not_null(clk_by_index, + "Clock not found for interface index %d\n", + ptp_clocks[0]); } static void test_ptp_clock_iface(int idx) @@ -504,8 +510,51 @@ static void test_ptp_clock_get_by_index_user(void) zassert_equal(clk1, clk_by_index, "Invalid PTP clock 1"); } +static ZTEST_BMEM struct net_ptp_time tm; +static ZTEST_BMEM struct net_ptp_time empty; + +static void test_ptp_clock_get_by_xxx(const char *who) +{ + struct device *clk_by_index; + int ret; + + clk_by_index = net_eth_get_ptp_clock_by_index(ptp_clocks[0]); + zassert_not_null(clk_by_index, "PTP 0 not found (%s)", who); + zassert_equal(clk0, clk_by_index, "Invalid PTP clock 0 (%s)", who); + + (void)memset(&tm, 0, sizeof(tm)); + ptp_clock_get(clk_by_index, &tm); + + ret = memcmp(&tm, &empty, sizeof(tm)); + zassert_not_equal(ret, 0, "ptp_clock_get() failed in %s mode", who); +} + +static void test_ptp_clock_get_kernel(void) +{ + struct device *clk; + + /* Make sure that this function is really run in kernel mode by + * calling a function that will not work in user mode. + */ + clk = net_eth_get_ptp_clock(eth_interfaces[0]); + + test_ptp_clock_get_by_xxx("kernel"); +} + +static void test_ptp_clock_get_user(void) +{ + test_ptp_clock_get_by_xxx("user"); +} + void test_main(void) { + struct device *clk; + + clk = device_get_binding(PTP_CLOCK_NAME); + if (clk != NULL) { + k_object_access_grant(clk, k_current_get()); + } + ztest_test_suite(ptp_clock_test, ztest_unit_test(check_interfaces), ztest_unit_test(address_setup), @@ -513,7 +562,9 @@ void test_main(void) ztest_unit_test(test_ptp_clock_iface_1), ztest_unit_test(test_ptp_clock_iface_2), ztest_unit_test(test_ptp_clock_get_by_index), - ztest_user_unit_test(test_ptp_clock_get_by_index_user) + ztest_user_unit_test(test_ptp_clock_get_by_index_user), + ztest_unit_test(test_ptp_clock_get_kernel), + ztest_user_unit_test(test_ptp_clock_get_user) ); ztest_run_test_suite(ptp_clock_test); diff --git a/tests/net/ptp/clock/testcase.yaml b/tests/net/ptp/clock/testcase.yaml index fa33ec5e115..c0eb38cf014 100644 --- a/tests/net/ptp/clock/testcase.yaml +++ b/tests/net/ptp/clock/testcase.yaml @@ -1,6 +1,5 @@ common: depends_on: netif - platform_whitelist: native_posix qemu_x86 qemu_cortex_m3 tests: net.ptp.clock: min_ram: 32