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 <jukka.rissanen@linux.intel.com>
This commit is contained in:
parent
95e8498c27
commit
c9aaab74db
7 changed files with 94 additions and 3 deletions
|
@ -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)
|
||||
|
|
3
drivers/ptp_clock/CMakeLists.txt
Normal file
3
drivers/ptp_clock/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_sources_ifdef(CONFIG_PTP_CLOCK ptp_clock.c)
|
30
drivers/ptp_clock/ptp_clock.c
Normal file
30
drivers/ptp_clock/ptp_clock.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Intel Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <syscall_handler.h>
|
||||
#include <ptp_clock.h>
|
||||
|
||||
#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 */
|
|
@ -7,6 +7,7 @@
|
|||
#ifndef ZEPHYR_INCLUDE_PTP_CLOCK_H_
|
||||
#define ZEPHYR_INCLUDE_PTP_CLOCK_H_
|
||||
|
||||
#include <kernel.h>
|
||||
#include <stdint.h>
|
||||
#include <device.h>
|
||||
#include <misc/util.h>
|
||||
|
@ -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 <syscalls/ptp_clock.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -112,6 +112,7 @@ subsystems = [
|
|||
"spi_driver_api",
|
||||
"uart_driver_api",
|
||||
"can_driver_api",
|
||||
"ptp_clock_driver_api",
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
common:
|
||||
depends_on: netif
|
||||
platform_whitelist: native_posix qemu_x86 qemu_cortex_m3
|
||||
tests:
|
||||
net.ptp.clock:
|
||||
min_ram: 32
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue