[meta-freescale] [meta-fsl-ppc][PATCH] ptpd: add 2.2.0 recipe to support etsec 1588
ting.liu at freescale.com
ting.liu at freescale.com
Fri Aug 1 01:05:42 PDT 2014
From: Zhenhua Luo <zhenhua.luo at freescale.com>
In sdk 1.6, ptpd was based on 2.2.0. There is a patch that can't
be applied on latest 2.3.0. Developers are trying to upstream it.
Signed-off-by: Zhenhua Luo <zhenhua.luo at freescale.com>
Signed-off-by: Ting Liu <ting.liu at freescale.com>
---
conf/machine/include/qoriq-default-versions.inc | 1 +
recipes-daemons/ptpd/ptpd-2.2.0/ld-as-needed.patch | 37 +
.../ptpd/ptpd-2.2.0/ptpd-2.2.0-etsec.patch | 778 +++++++++++++++++++++
recipes-daemons/ptpd/ptpd_2.2.0.bb | 27 +
4 files changed, 843 insertions(+)
create mode 100644 recipes-daemons/ptpd/ptpd-2.2.0/ld-as-needed.patch
create mode 100644 recipes-daemons/ptpd/ptpd-2.2.0/ptpd-2.2.0-etsec.patch
create mode 100644 recipes-daemons/ptpd/ptpd_2.2.0.bb
diff --git a/conf/machine/include/qoriq-default-versions.inc b/conf/machine/include/qoriq-default-versions.inc
index 2e05c8a..ca52255 100644
--- a/conf/machine/include/qoriq-default-versions.inc
+++ b/conf/machine/include/qoriq-default-versions.inc
@@ -1,4 +1,5 @@
PREFERRED_VERSION_qemu = "1.7+fsl"
PREFERRED_VERSION_openssl = "1.0.1g"
PREFERRED_VERSION_valgrind_e500v2 = "3.8.1+fsl"
+PREFERRED_VERSION_ptpd = "2.2.0"
diff --git a/recipes-daemons/ptpd/ptpd-2.2.0/ld-as-needed.patch b/recipes-daemons/ptpd/ptpd-2.2.0/ld-as-needed.patch
new file mode 100644
index 0000000..7d5251b
--- /dev/null
+++ b/recipes-daemons/ptpd/ptpd-2.2.0/ld-as-needed.patch
@@ -0,0 +1,37 @@
+Patch from http://patch-tracker.debian.org/package/ptpd
+
+Description: Fix ld --as-needed
+ This patch fixes the order of gcc arguments to fix ld --as-needed
+Author: Roland Stigge <stigge at antcom.de>
+Bug-Debian: http://bugs.debian.org/607583
+
+Signed-off-by: Jackie Huang <jackie.huang at windriver.com>
+---
+ src/Makefile | 4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/Makefile b/src/Makefile
+index a672625..88a2fc8 100644
+--- a/src/Makefile
++++ b/src/Makefile
+@@ -40,7 +40,7 @@ CFLAGS += -DDBG_SIGUSR2_CHANGE_DEBUG
+
+ CFLAGS += -DPTP_EXPERIMENTAL
+
+-LDFLAGS+= -lm -lrt
++LIBS += -lm -lrt
+
+ PROG = ptpd
+ SRCS = ptpd.c arith.c bmc.c protocol.c display.c\
+@@ -63,7 +63,7 @@ TAGFILES = GPATH GRTAGS GSYMS GTAGS cscope.in.out cscope.out cscope.po.out
+ all: $(PROG)
+
+ $(PROG): $(OBJS)
+- $(CC) -o $@ $(OBJS) $(LDFLAGS)
++ $(CC) -o $@ $(OBJS) $(LDFLAGS) $(LIBS)
+
+ $(OBJS): $(HDRS)
+
+--
+1.7.4
+
diff --git a/recipes-daemons/ptpd/ptpd-2.2.0/ptpd-2.2.0-etsec.patch b/recipes-daemons/ptpd/ptpd-2.2.0/ptpd-2.2.0-etsec.patch
new file mode 100644
index 0000000..9a3cf42
--- /dev/null
+++ b/recipes-daemons/ptpd/ptpd-2.2.0/ptpd-2.2.0-etsec.patch
@@ -0,0 +1,778 @@
+Upstream-status: Pending
+
+diff --git a/src/Makefile b/src/Makefile
+index dbbe525..befc278 100644
+--- a/src/Makefile
++++ b/src/Makefile
+@@ -46,6 +46,12 @@ PROG = ptpd2
+ SRCS = ptpd.c arith.c bmc.c protocol.c display.c\
+ dep/msg.c dep/net.c dep/servo.c dep/startup.c dep/sys.c dep/timer.c
+
++#FSL_1588
++CFLAGS += -DFSL_1588
++SRCS += fsl_1588.o
++HDRS = fsl_1588.h
++#FSL_1588
++
+ OBJS = $(SRCS:.c=.o)
+
+ HDRS = ptpd.h constants.h datatypes.h \
+diff --git a/src/dep/net.c b/src/dep/net.c
+index ddd7866..c1497ae 100644
+--- a/src/dep/net.c
++++ b/src/dep/net.c
+@@ -38,6 +38,9 @@
+ */
+
+ #include "../ptpd.h"
++#if defined(FSL_1588)
++#include "../fsl_1588.h"
++#endif
+
+ /* choose kernel-level nanoseconds or microseconds resolution on the client-side */
+ #if !defined(SO_TIMESTAMPNS) && !defined(SO_TIMESTAMP) && !defined(SO_BINTIME)
+@@ -257,6 +260,9 @@ findIface(Octet * ifaceName, UInteger8 * communicationTechnology,
+ PERROR("failed to get ip address");
+ return 0;
+ }
++#if defined(FSL_1588)
++ memcpy(fsl_1588_if_name, ifaceName, IFACE_NAME_LENGTH);
++#endif
+ return ((struct sockaddr_in *)&device[i].ifr_addr)->sin_addr.s_addr;
+
+ #else /* usually *BSD */
+@@ -418,6 +424,17 @@ netInitTimestamping(NetPath * netPath)
+ int val = 1;
+ Boolean result = TRUE;
+
++#if defined(FSL_1588)
++ int so_timestamping_flags = 0;
++
++ so_timestamping_flags = SOF_TIMESTAMPING_RX_HARDWARE | SOF_TIMESTAMPING_RAW_HARDWARE;
++ if (setsockopt(netPath->eventSock, SOL_SOCKET, SO_TIMESTAMPING, &so_timestamping_flags, sizeof(so_timestamping_flags)) < 0
++ || setsockopt(netPath->generalSock, SOL_SOCKET, SO_TIMESTAMPING, &so_timestamping_flags, sizeof(so_timestamping_flags)) < 0) {
++ printf("netInitTimestamping: failed to enable SO_TIMESTAMPING");
++ result = FALSE;
++ }
++
++#else /* FSL_1588 */
+ #if defined(SO_TIMESTAMPNS) /* Linux, Apple */
+ DBG("netInitTimestamping: trying to use SO_TIMESTAMPNS\n");
+
+@@ -437,6 +454,7 @@ netInitTimestamping(NetPath * netPath)
+ #else
+ result = FALSE;
+ #endif
++#endif /* FSL_1588 */
+
+ /* fallback method */
+ #if defined(SO_TIMESTAMP) /* Linux, Apple, FreeBSD */
+@@ -494,6 +512,9 @@ netInit(NetPath * netPath, RunTimeOpts * rtOpts, PtpClock * ptpClock)
+ netPath->interfaceAddr = interfaceAddr;
+
+ DBG("Local IP address used : %s \n", inet_ntoa(interfaceAddr));
++#if defined(FSL_1588)
++ hwtstamp_tx_ctl(&ptpClock->netPath, FALSE);//HWTSTAMP_TX_OFF
++#endif
+
+ temp = 1; /* allow address reuse */
+ if (setsockopt(netPath->eventSock, SOL_SOCKET, SO_REUSEADDR,
+@@ -591,7 +612,11 @@ netInit(NetPath * netPath, RunTimeOpts * rtOpts, PtpClock * ptpClock)
+ }
+
+ /* enable loopback */
++#if defined(FSL_1588)
++ temp = 0;
++#else
+ temp = 1;
++#endif
+
+ DBG("Going to set IP_MULTICAST_LOOP with %d \n", temp);
+
+@@ -677,17 +702,25 @@ netRecvEvent(Octet * buf, TimeInternal * time, NetPath * netPath)
+
+ union {
+ struct cmsghdr cm;
++#if defined(FSL_1588)
++ char control[3*CMSG_SPACE(sizeof(struct timeval))];
++#else
+ char control[CMSG_SPACE(sizeof(struct timeval))];
++#endif
+ } cmsg_un;
+
+ struct cmsghdr *cmsg;
+
++#if defined(FSL_1588)
++ struct timespec * ts;
++#else /*FSL_1588 */
+ #if defined(SO_TIMESTAMPNS)
+ struct timespec * ts;
+ #elif defined(SO_BINTIME)
+ struct bintime * bt;
+ struct timespec ts;
+ #endif
++#endif /*FSL_1588 */
+
+ #if defined(SO_TIMESTAMP)
+ struct timeval * tv;
+@@ -747,6 +780,27 @@ netRecvEvent(Octet * buf, TimeInternal * time, NetPath * netPath)
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
+ cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ if (cmsg->cmsg_level == SOL_SOCKET) {
++#if defined(FSL_1588)
++ if(cmsg->cmsg_type == SCM_TIMESTAMPING) {
++ ts = (struct timespec *)CMSG_DATA(cmsg);
++ //printf("SO_TIMESTAMPING ");
++ //printf("SW %ld.%09ld ",
++ // (long)ts->tv_sec,
++ // (long)ts->tv_nsec);
++ ts++;
++ //printf("HW transformed %ld.%09ld ",
++ // (long)ts->tv_sec,
++ // (long)ts->tv_nsec);
++ ts++;
++ //printf("HW raw %ld.%09ld\n",
++ // (long)ts->tv_sec,
++ // (long)ts->tv_nsec);
++ time->seconds = ts->tv_sec;
++ time->nanoseconds = ts->tv_nsec;
++ timestampValid = TRUE;
++ break;
++ }
++#else /* FSL_1588 */
+ #if defined(SO_TIMESTAMPNS)
+ if(cmsg->cmsg_type == SCM_TIMESTAMPNS) {
+ ts = (struct timespec *)CMSG_DATA(cmsg);
+@@ -769,6 +823,7 @@ netRecvEvent(Octet * buf, TimeInternal * time, NetPath * netPath)
+ break;
+ }
+ #endif
++#endif /* FSL_1588 */
+
+ #if defined(SO_TIMESTAMP)
+ if(cmsg->cmsg_type == SCM_TIMESTAMP) {
+@@ -821,17 +876,25 @@ netRecvGeneral(Octet * buf, TimeInternal * time, NetPath * netPath)
+
+ union {
+ struct cmsghdr cm;
++#if defined(FSL_1588)
++ char control[3*CMSG_SPACE(sizeof(struct timeval))];
++#else
+ char control[CMSG_SPACE(sizeof(struct timeval))];
++#endif
+ } cmsg_un;
+
+ struct cmsghdr *cmsg;
+
++#if defined(FSL_1588)
++ struct timespec * ts;
++#else /* FSL_1588 */
+ #if defined(SO_TIMESTAMPNS)
+ struct timespec * ts;
+ #elif defined(SO_BINTIME)
+ struct bintime * bt;
+ struct timespec ts;
+ #endif
++#endif /* FSL_1588 */
+
+ #if defined(SO_TIMESTAMP)
+ struct timeval * tv;
+@@ -893,6 +956,27 @@ netRecvGeneral(Octet * buf, TimeInternal * time, NetPath * netPath)
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
+ cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ if (cmsg->cmsg_level == SOL_SOCKET) {
++#if defined(FSL_1588)
++ if(cmsg->cmsg_type == SCM_TIMESTAMPING) {
++ ts = (struct timespec *)CMSG_DATA(cmsg);
++ //printf("SO_TIMESTAMPING ");
++ //printf("SW %ld.%09ld ",
++ // (long)ts->tv_sec,
++ // (long)ts->tv_nsec);
++ ts++;
++ //printf("HW transformed %ld.%09ld ",
++ // (long)ts->tv_sec,
++ // (long)ts->tv_nsec);
++ ts++;
++ //printf("HW raw %ld.%09ld\n",
++ // (long)ts->tv_sec,
++ // (long)ts->tv_nsec);
++ time->seconds = ts->tv_sec;
++ time->nanoseconds = ts->tv_nsec;
++ timestampValid = TRUE;
++ break;
++ }
++#else /* FSL_1588 */
+ #if defined(SO_TIMESTAMPNS)
+ if(cmsg->cmsg_type == SCM_TIMESTAMPNS) {
+ ts = (struct timespec *)CMSG_DATA(cmsg);
+@@ -915,6 +999,7 @@ netRecvGeneral(Octet * buf, TimeInternal * time, NetPath * netPath)
+ break;
+ }
+ #endif
++#endif /* FSL_1588 */
+
+ #if defined(SO_TIMESTAMP)
+ if(cmsg->cmsg_type == SCM_TIMESTAMP) {
+@@ -960,6 +1045,9 @@ netSendEvent(Octet * buf, UInteger16 length, NetPath * netPath, Integer32 alt_ds
+ {
+ ssize_t ret;
+ struct sockaddr_in addr;
++#if defined(FSL_1588)
++ hwtstamp_tx_ctl(netPath, TRUE);//HWTSTAMP_TX_ON
++#endif
+
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(PTP_EVENT_PORT);
+@@ -1006,6 +1094,9 @@ netSendGeneral(Octet * buf, UInteger16 length, NetPath * netPath, Integer32 alt_
+ {
+ ssize_t ret;
+ struct sockaddr_in addr;
++#if defined(FSL_1588)
++ hwtstamp_tx_ctl(netPath, TRUE);//HWTSTAMP_TX_ON
++#endif
+
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(PTP_GENERAL_PORT);
+@@ -1041,6 +1132,9 @@ netSendPeerGeneral(Octet * buf, UInteger16 length, NetPath * netPath)
+
+ ssize_t ret;
+ struct sockaddr_in addr;
++#if defined(FSL_1588)
++ hwtstamp_tx_ctl(netPath, TRUE);//HWTSTAMP_TX_ON
++#endif
+
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(PTP_GENERAL_PORT);
+@@ -1072,6 +1166,9 @@ netSendPeerEvent(Octet * buf, UInteger16 length, NetPath * netPath)
+ {
+ ssize_t ret;
+ struct sockaddr_in addr;
++#if defined(FSL_1588)
++ hwtstamp_tx_ctl(netPath, TRUE);//HWTSTAMP_TX_ON
++#endif
+
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(PTP_EVENT_PORT);
+diff --git a/src/dep/servo.c b/src/dep/servo.c
+index efbf815..2ec7692 100644
+--- a/src/dep/servo.c
++++ b/src/dep/servo.c
+@@ -565,8 +565,13 @@ updateClock(RunTimeOpts * rtOpts, PtpClock * ptpClock)
+
+ /* the accumulator for the I component */
+ // original PI servo
++#if defined(FSL_1588)
++ ptpClock->observed_drift +=
++ ptpClock->offsetFromMaster.nanoseconds * 0.05;
++#else
+ ptpClock->observed_drift +=
+ ptpClock->offsetFromMaster.nanoseconds / ai;
++#endif
+
+ // ADJ_FREQ_MAX: 512 000
+
+@@ -576,8 +581,13 @@ updateClock(RunTimeOpts * rtOpts, PtpClock * ptpClock)
+ else if (ptpClock->observed_drift < -ADJ_FREQ_MAX)
+ ptpClock->observed_drift = -ADJ_FREQ_MAX;
+
++#if defined(FSL_1588)
++ adj = ptpClock->offsetFromMaster.nanoseconds * 0.32 +
++ ptpClock->observed_drift;
++#else
+ adj = ptpClock->offsetFromMaster.nanoseconds / ap +
+ ptpClock->observed_drift;
++#endif
+
+ DBG(" Observed_drift with AI component: %d\n",
+ ptpClock->observed_drift );
+diff --git a/src/dep/sys.c b/src/dep/sys.c
+index 9f275d4..8555012 100644
+--- a/src/dep/sys.c
++++ b/src/dep/sys.c
+@@ -51,6 +51,10 @@
+ # include <some ether header> // force build error
+ #endif
+
++#if defined(FSL_1588)
++#include "../fsl_1588.h"
++#endif
++
+
+ /* only C99 has the round function built-in */
+ double round (double __x);
+@@ -376,7 +380,14 @@ message(int priority, const char * format, ...)
+ * it also can cause problems in nested debug statements (which are solved by turning the signal
+ * handling synchronous, and not calling this function inside assycnhonous signal processing)
+ */
++#if defined(FSL_1588)
++ struct timespec tp;
++ clock_gettime(clkid,&tp);
++ now.tv_sec = tp.tv_sec;
++ now.tv_usec = tp.tv_nsec / 1000;
++#else
+ gettimeofday(&now, 0);
++#endif
+ strftime(time_str, MAXTIMESTR, "%X", localtime(&now.tv_sec));
+ fprintf(stderr, "%s.%06d ", time_str, (int)now.tv_usec );
+ fprintf(stderr, " (%s) ", G_ptpClock ?
+@@ -586,10 +597,20 @@ getTime(TimeInternal * time)
+ {
+ #if defined(linux) || defined(__APPLE__)
+
++#if defined(FSL_1588)
++ struct timespec tp;
++ if (clock_gettime(clkid, &tp)){
++ perror("clock_gettime");
++ exit(0);
++ }
++ time->seconds = tp.tv_sec;
++ time->nanoseconds = tp.tv_nsec;
++#else
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ time->seconds = tv.tv_sec;
+ time->nanoseconds = tv.tv_usec * 1000;
++#endif/* FSL_1588 */
+ #else
+ struct timespec tp;
+ if (clock_gettime(CLOCK_REALTIME, &tp) < 0) {
+@@ -604,6 +625,13 @@ getTime(TimeInternal * time)
+ void
+ setTime(TimeInternal * time)
+ {
++#if defined(FSL_1588)
++ struct timespec tp;
++ tp.tv_sec = time->seconds;
++ tp.tv_nsec = time->nanoseconds;
++ if (clock_settime(clkid, &tp))
++ perror("clock_settime");
++#else
+ struct timeval tv;
+
+ tv.tv_sec = time->seconds;
+@@ -613,6 +641,7 @@ setTime(TimeInternal * time)
+ settimeofday(&tv, 0);
+ WARNING("Finished stepping the system clock to %ds %dns\n",
+ time->seconds, time->nanoseconds);
++#endif
+ }
+
+
+@@ -660,7 +689,11 @@ adjFreq(Integer32 adj)
+
+ DBG2(" adj is %d; t freq is %d (float: %f Integer32: %d)\n", adj, t.freq, f, t1);
+
++#if defined(FSL_1588)
++ return !clock_adjtime(clkid, &t);
++#else
+ return !adjtimex(&t);
++#endif
+ }
+
+ #else
+diff --git a/src/fsl_1588.c b/src/fsl_1588.c
+new file mode 100644
+index 0000000..75937e8
+--- /dev/null
++++ b/src/fsl_1588.c
+@@ -0,0 +1,130 @@
++#include "fsl_1588.h"
++
++/*************************PTP Clock*************************/
++clockid_t get_clockid(int fd)
++{
++#define CLOCKFD 3
++#define FD_TO_CLOCKID(fd) ((~(clockid_t) (fd) << 3) | CLOCKFD)
++ return FD_TO_CLOCKID(fd);
++}
++
++/* When glibc offers the syscall, this will go away. */
++#include <sys/syscall.h>
++int clock_adjtime(clockid_t id, struct timex *tx)
++{
++ return syscall(__NR_clock_adjtime, id, tx);
++}
++
++
++
++
++
++/*************************HW Timestamp*************************/
++//select HWTSTAMP_TX_ON or HWTSTAMP_TX_OFF
++void hwtstamp_tx_ctl(NetPath * netPath, Boolean enable)
++{
++ struct ifreq hwtstamp;
++ struct hwtstamp_config hwconfig;
++
++ memset(&hwtstamp, 0, sizeof(hwtstamp));
++ strncpy(hwtstamp.ifr_name, fsl_1588_if_name, sizeof(hwtstamp.ifr_name));
++ hwtstamp.ifr_data = (void *)&hwconfig;
++ memset(&hwconfig, 0, sizeof(hwconfig));
++ hwconfig.tx_type =
++ enable ?
++ HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
++ hwconfig.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_SYNC;
++ if (ioctl(netPath->eventSock, SIOCSHWTSTAMP, &hwtstamp) < 0
++ || ioctl(netPath->generalSock, SIOCSHWTSTAMP, &hwtstamp) < 0)
++ printf("error:hwtstamp_tx_ctl\n");
++}
++
++//select SOF_TIMESTAMPING_RX_HARDWARE or SOF_TIMESTAMPING_TX_HARDWARE
++void hwtstamp_rx_init(NetPath * netPath, Boolean isRecv)
++{
++ int so_timestamping_flags = 0;
++
++ so_timestamping_flags = isRecv ? SOF_TIMESTAMPING_RX_HARDWARE : SOF_TIMESTAMPING_TX_HARDWARE;
++ so_timestamping_flags = so_timestamping_flags | SOF_TIMESTAMPING_RAW_HARDWARE;
++
++ if (setsockopt(netPath->eventSock, SOL_SOCKET, SO_TIMESTAMPING, &so_timestamping_flags, sizeof(so_timestamping_flags)) < 0
++ || setsockopt(netPath->generalSock, SOL_SOCKET, SO_TIMESTAMPING, &so_timestamping_flags, sizeof(so_timestamping_flags)) < 0) {
++ printf("error:hwtstamp_rx_init\n");
++ }
++}
++
++ssize_t
++hwtstamp_tx_get(Octet * buf, TimeInternal * time, NetPath * netPath)
++{
++ ssize_t ret;
++ struct msghdr msg;
++ struct iovec vec[1];
++ struct sockaddr_in from_addr;
++
++ union {
++ struct cmsghdr cm;
++ char control[3*CMSG_SPACE(sizeof(struct timeval))];
++ } cmsg_un;
++
++ struct cmsghdr *cmsg;
++ struct timespec * ts;
++
++ vec[0].iov_base = buf;
++ vec[0].iov_len = PACKET_SIZE;
++
++ memset(&msg, 0, sizeof(msg));
++ memset(&from_addr, 0, sizeof(from_addr));
++ memset(buf, 0, PACKET_SIZE);
++ memset(&cmsg_un, 0, sizeof(cmsg_un));
++
++ msg.msg_name = (caddr_t)&from_addr;
++ msg.msg_namelen = sizeof(from_addr);
++ msg.msg_iov = vec;
++ msg.msg_iovlen = 1;
++ msg.msg_control = cmsg_un.control;
++ msg.msg_controllen = sizeof(cmsg_un.control);
++ msg.msg_flags = 0;
++
++ if (netSelect(0, netPath) <= 0)
++ return 0;
++
++ ret = recvmsg(netPath->eventSock, &msg, MSG_ERRQUEUE);
++
++ if (ret <= 0) {
++ printf("error:hwtstamp_tx_get\n");
++ if (errno == EAGAIN || errno == EINTR)
++ return 0;
++ return ret;
++ }
++
++ if (msg.msg_controllen <= 0) {
++ ERROR("received short ancillary data (%ld/%ld)\n",
++ (long)msg.msg_controllen, (long)sizeof(cmsg_un.control));
++ return 0;
++ }
++
++ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
++ cmsg = CMSG_NXTHDR(&msg, cmsg)) {
++ if (cmsg->cmsg_level == SOL_SOCKET) {
++ if(cmsg->cmsg_type == SCM_TIMESTAMPING) {
++ ts = (struct timespec *)CMSG_DATA(cmsg);
++ //printf("SO_TIMESTAMPING ");
++ //printf("SW %ld.%09ld ",
++ // (long)ts->tv_sec,
++ // (long)ts->tv_nsec);
++ ts++;
++ //printf("HW transformed %ld.%09ld ",
++ // (long)ts->tv_sec,
++ // (long)ts->tv_nsec);
++ ts++;
++ //printf("HW raw %ld.%09ld\n",
++ // (long)ts->tv_sec,
++ // (long)ts->tv_nsec);
++ time->seconds = ts->tv_sec;
++ time->nanoseconds = ts->tv_nsec;
++ break;
++ }
++ }
++ }
++ return ret;
++}
+diff --git a/src/fsl_1588.h b/src/fsl_1588.h
+new file mode 100644
+index 0000000..6524930
+--- /dev/null
++++ b/src/fsl_1588.h
+@@ -0,0 +1,34 @@
++#include "ptpd.h"
++#include <linux/net_tstamp.h>
++/*************************MACROS*************************/
++#ifndef SO_TIMESTAMPING
++# define SO_TIMESTAMPING 37
++# define SCM_TIMESTAMPING SO_TIMESTAMPING
++#endif
++
++#ifndef SIOCSHWTSTAMP
++# define SIOCSHWTSTAMP 0x89b0
++#endif
++
++#ifndef CLOCK_INVALID
++#define CLOCK_INVALID -1
++#endif
++
++
++
++/*************************VARIABLES*************************/
++clockid_t clkid;
++char fsl_1588_if_name[IFACE_NAME_LENGTH];
++
++
++
++
++
++
++/*************************FUNCTIONS*************************/
++clockid_t get_clockid(int fd);
++int clock_adjtime(clockid_t id, struct timex *tx);
++
++void hwtstamp_tx_ctl(NetPath * netPath, Boolean enable);
++void hwtstamp_rx_init(NetPath * netPath, Boolean isRecv);
++ssize_t hwtstamp_tx_get(Octet * buf, TimeInternal * time, NetPath * netPath);
+diff --git a/src/protocol.c b/src/protocol.c
+index 81be48f..5ac0109 100644
+--- a/src/protocol.c
++++ b/src/protocol.c
+@@ -37,6 +37,9 @@
+ */
+
+ #include "ptpd.h"
++#if defined(FSL_1588)
++#include "fsl_1588.h"
++#endif
+
+ Boolean doInit(RunTimeOpts*,PtpClock*);
+ void doState(RunTimeOpts*,PtpClock*);
+@@ -76,6 +79,22 @@ void addForeign(Octet*,MsgHeader*,PtpClock*);
+ void
+ protocol(RunTimeOpts *rtOpts, PtpClock *ptpClock)
+ {
++#if defined(FSL_1588)
++ char device[]="/dev/ptp0";
++ int fd;
++ fd = open(device, O_RDWR);
++ if (fd < 0) {
++ fprintf(stderr, "opening %s: %s\n", device, strerror(errno));
++ return;
++ }
++
++ clkid = get_clockid(fd);
++
++ if (CLOCK_INVALID == clkid) {
++ fprintf(stderr, "failed to read clock id\n");
++ return;
++ }
++#endif
+ DBG("event POWERUP\n");
+
+ toState(PTP_INITIALIZING, rtOpts, ptpClock);
+@@ -309,9 +328,23 @@ doInit(RunTimeOpts *rtOpts, PtpClock *ptpClock)
+ }
+
+ /* handle actions and events for 'port_state' */
++#if defined(FSL_1588)
++TimeInternal issueSyncTime = { 0, 0 };
++TimeInternal issueDelayReqTime = { 0, 0 };
++TimeInternal issuePDelayReqTime = { 0, 0 };
++TimeInternal issuePDelayRespTime = { 0, 0 };
++int issueSyncFlag = 0;
++int issueDelayReqFlag = 0;
++int issuePDelayReqFlag = 0;
++int issuePDelayRespFlag = 0;
++#endif
++
+ void
+ doState(RunTimeOpts *rtOpts, PtpClock *ptpClock)
+ {
++#if defined(FSL_1588)
++ ssize_t length = 0;
++#endif
+ UInteger8 state;
+
+ ptpClock->message_activity = FALSE;
+@@ -354,6 +387,29 @@ doState(RunTimeOpts *rtOpts, PtpClock *ptpClock)
+ case PTP_SLAVE:
+ // passive mode behaves like the SLAVE state, in order to wait for the announce timeout of the current active master
+ case PTP_PASSIVE:
++#if defined(FSL_1588)
++ if (issueDelayReqFlag == 1)
++ {
++ issueDelayReqFlag = 0;
++ ptpClock->waitingForDelayResp = TRUE;
++ ptpClock->delay_req_send_time.seconds =
++ issueDelayReqTime.seconds;
++ ptpClock->delay_req_send_time.nanoseconds =
++ issueDelayReqTime.nanoseconds;
++ }
++ if (issuePDelayReqFlag == 1)
++ {
++ issuePDelayReqFlag = 0;
++ ptpClock->pdelay_req_send_time.seconds =
++ issuePDelayReqTime.seconds;
++ ptpClock->pdelay_req_send_time.nanoseconds =
++ issuePDelayReqTime.nanoseconds;
++ }
++ if (ptpClock->twoStepFlag && issuePDelayRespFlag == 1) {
++ issuePDelayRespFlag = 0;
++ issuePDelayRespFollowUp(&issuePDelayRespTime, &ptpClock->PdelayReqHeader, rtOpts, ptpClock);
++ }
++#endif
+ handle(rtOpts, ptpClock);
+
+ /*
+@@ -390,13 +446,37 @@ doState(RunTimeOpts *rtOpts, PtpClock *ptpClock)
+ if(timerExpired(DELAYREQ_INTERVAL_TIMER,
+ ptpClock->itimer)) {
+ DBG2("event DELAYREQ_INTERVAL_TIMEOUT_EXPIRES\n");
++#if defined(FSL_1588)
++ hwtstamp_rx_init(&ptpClock->netPath, FALSE);//SOF_TIMESTAMPING_TX_HARDWARE
+ issueDelayReq(rtOpts,ptpClock);
++ usleep(1);
++ length = hwtstamp_tx_get(ptpClock->msgIbuf, &issueDelayReqTime, &ptpClock->netPath);
++ hwtstamp_rx_init(&ptpClock->netPath, TRUE);//SOF_TIMESTAMPING_RX_HARDWARE
++ if(length > 0)
++ issueDelayReqFlag = 1;
++ else
++ toState(PTP_FAULTY, rtOpts, ptpClock);
++#else
++ issueDelayReq(rtOpts,ptpClock);
++#endif
+ }
+ } else if (ptpClock->delayMechanism == P2P) {
+ if (timerExpired(PDELAYREQ_INTERVAL_TIMER,
+ ptpClock->itimer)) {
+ DBGV("event PDELAYREQ_INTERVAL_TIMEOUT_EXPIRES\n");
++#if defined(FSL_1588)
++ hwtstamp_rx_init(&ptpClock->netPath, FALSE);//SOF_TIMESTAMPING_TX_HARDWARE
+ issuePDelayReq(rtOpts,ptpClock);
++ usleep(1);
++ length = hwtstamp_tx_get(ptpClock->msgIbuf, &issuePDelayReqTime, &ptpClock->netPath);
++ hwtstamp_rx_init(&ptpClock->netPath, TRUE);//SOF_TIMESTAMPING_RX_HARDWARE
++ if(length > 0)
++ issuePDelayReqFlag = 1;
++ else
++ toState(PTP_FAULTY, rtOpts, ptpClock);
++#else
++ issuePDelayReq(rtOpts,ptpClock);
++#endif
+ }
+
+ /* FIXME: Path delay should also rearm its timer with the value received from the Master */
+@@ -414,7 +494,19 @@ doState(RunTimeOpts *rtOpts, PtpClock *ptpClock)
+
+ if (timerExpired(SYNC_INTERVAL_TIMER, ptpClock->itimer)) {
+ DBGV("event SYNC_INTERVAL_TIMEOUT_EXPIRES\n");
++#if defined(FSL_1588)
++ hwtstamp_rx_init(&ptpClock->netPath, FALSE);//SOF_TIMESTAMPING_TX_HARDWARE
+ issueSync(rtOpts, ptpClock);
++ usleep(1);
++ length = hwtstamp_tx_get(ptpClock->msgIbuf, &issueSyncTime, &ptpClock->netPath);
++ hwtstamp_rx_init(&ptpClock->netPath, TRUE);//SOF_TIMESTAMPING_RX_HARDWARE
++ if(length > 0)
++ issueSyncFlag = 1;
++ else
++ toState(PTP_FAULTY, rtOpts, ptpClock);
++#else
++ issueSync(rtOpts, ptpClock);
++#endif
+ }
+
+ if (timerExpired(ANNOUNCE_INTERVAL_TIMER, ptpClock->itimer)) {
+@@ -426,9 +518,39 @@ doState(RunTimeOpts *rtOpts, PtpClock *ptpClock)
+ if (timerExpired(PDELAYREQ_INTERVAL_TIMER,
+ ptpClock->itimer)) {
+ DBGV("event PDELAYREQ_INTERVAL_TIMEOUT_EXPIRES\n");
++#if defined(FSL_1588)
++ hwtstamp_rx_init(&ptpClock->netPath, FALSE);//SOF_TIMESTAMPING_TX_HARDWARE
+ issuePDelayReq(rtOpts,ptpClock);
++ usleep(1);
++ length = hwtstamp_tx_get(ptpClock->msgIbuf, &issuePDelayReqTime, &ptpClock->netPath);
++ hwtstamp_rx_init(&ptpClock->netPath, TRUE);//SOF_TIMESTAMPING_RX_HARDWARE
++ if(length > 0)
++ issuePDelayReqFlag = 1;
++ else
++ toState(PTP_FAULTY, rtOpts, ptpClock);
++#else
++ issuePDelayReq(rtOpts,ptpClock);
++#endif
+ }
+ }
++#if defined(FSL_1588)
++ if(issueSyncFlag == 1 && ptpClock->twoStepFlag){
++ issueSyncFlag = 0;
++ issueFollowup(&issueSyncTime,rtOpts,ptpClock);
++ }
++ if (issuePDelayReqFlag == 1)
++ {
++ issuePDelayReqFlag = 0;
++ ptpClock->pdelay_req_send_time.seconds =
++ issuePDelayReqTime.seconds;
++ ptpClock->pdelay_req_send_time.nanoseconds =
++ issuePDelayReqTime.nanoseconds;
++ }
++ if (ptpClock->twoStepFlag && issuePDelayRespFlag == 1) {
++ issuePDelayRespFlag = 0;
++ issuePDelayRespFollowUp(&issuePDelayRespTime, &ptpClock->PdelayReqHeader, rtOpts, ptpClock);
++ }
++#endif
+
+ // TODO: why is handle() below expiretimer, while in slave is the opposite
+ handle(rtOpts, ptpClock);
+@@ -458,6 +580,9 @@ handle(RunTimeOpts *rtOpts, PtpClock *ptpClock)
+ Boolean isFromSelf;
+ TimeInternal time = { 0, 0 };
+
++#if defined(FSL_1588)
++ hwtstamp_tx_ctl(&ptpClock->netPath, FALSE);//HWTSTAMP_TX_OFF
++#endif
+ if (!ptpClock->message_activity) {
+ ret = netSelect(0, &ptpClock->netPath);
+ if (ret < 0) {
+@@ -1192,6 +1317,9 @@ handlePDelayReq(MsgHeader *header, Octet *msgIbuf, ssize_t length,
+ TimeInternal *time, Boolean isFromSelf,
+ RunTimeOpts *rtOpts, PtpClock *ptpClock)
+ {
++#if defined(FSL_1588)
++ ssize_t length1 = 0;
++#endif
+ if (ptpClock->delayMechanism == P2P) {
+ DBGV("PdelayReq message received : \n");
+
+@@ -1231,8 +1359,20 @@ handlePDelayReq(MsgHeader *header, Octet *msgIbuf, ssize_t length,
+ } else {
+ msgUnpackHeader(ptpClock->msgIbuf,
+ &ptpClock->PdelayReqHeader);
++#if defined(FSL_1588)
++ hwtstamp_rx_init(&ptpClock->netPath, FALSE);//SOF_TIMESTAMPING_TX_HARDWARE
++ issuePDelayResp(time, header, rtOpts, ptpClock);
++ usleep(1);//important
++ length1 = hwtstamp_tx_get(ptpClock->msgIbuf, &issuePDelayRespTime, &ptpClock->netPath);
++ hwtstamp_rx_init(&ptpClock->netPath, TRUE);//SOF_TIMESTAMPING_RX_HARDWARE
++ if(length1 > 0)
++ issuePDelayRespFlag = 1;
++ else
++ toState(PTP_FAULTY, rtOpts, ptpClock);
++#else
+ issuePDelayResp(time, header, rtOpts,
+ ptpClock);
++#endif
+ break;
+ }
+ default:
diff --git a/recipes-daemons/ptpd/ptpd_2.2.0.bb b/recipes-daemons/ptpd/ptpd_2.2.0.bb
new file mode 100644
index 0000000..f47caed
--- /dev/null
+++ b/recipes-daemons/ptpd/ptpd_2.2.0.bb
@@ -0,0 +1,27 @@
+SUMMARY = "The PTP daemon (PTPd)"
+DESCRIPTION = "The PTP daemon (PTPd) implements the Precision Time protocol (PTP) as \
+defined by the relevant IEEE 1588 standard. PTP Version 1 implements IEEE-1588-2002, \
+and PTP Version 2 implements IEEE-1588-2008. PTP was developed to provide very precise \
+time coordination of LAN connected computers."
+HOMEPAGE = "http://sourceforge.net/projects/ptpd"
+SECTION = "network"
+LICENSE = "BSD"
+LIC_FILES_CHKSUM = "file://../COPYRIGHT;md5=3d8ac2c46c116bce2d2ad838b6cf3491"
+
+SRC_URI = "http://downloads.sourceforge.net/project/ptpd/ptpd/${PV}/ptpd-${PV}.tar.gz \
+ file://ld-as-needed.patch;striplevel=2 \
+ file://ptpd-2.2.0-etsec.patch;striplevel=2 \
+"
+
+SRC_URI[md5sum] = "c63a3a149d30c710773ccb02df5782a3"
+SRC_URI[sha256sum] = "f2266a22db84318d8b9ce266ea83772c03438c31f4993fa9643fa675a07c26b4"
+
+S = "${WORKDIR}/ptpd-${PV}/src"
+
+EXTRA_OEMAKE = ""
+
+do_install() {
+ install -d ${D}${bindir} ${D}${mandir}/man8
+ install -m 0755 ptpd2 ${D}${bindir}
+ install -m 0644 ptpd2.8 ${D}${mandir}/man8
+}
--
1.8.3.2
More information about the meta-freescale
mailing list