Skip to content
Permalink
Browse files

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>
  • Loading branch information...
jukkar committed May 27, 2019
1 parent 95e8498 commit c9aaab74dba8bcc60e00219da4439ed9fd33d597
@@ -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)
@@ -0,0 +1,3 @@
# SPDX-License-Identifier: Apache-2.0

zephyr_sources_ifdef(CONFIG_PTP_CLOCK ptp_clock.c)
@@ -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 @@
"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,16 +510,61 @@ 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),
ztest_unit_test(test_ptp_clock_interfaces),
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

0 comments on commit c9aaab7

Please sign in to comment.
You can’t perform that action at this time.