From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by yocto-www.yoctoproject.org (Postfix, from userid 118) id 6DDFEE00809; Thu, 7 Aug 2014 15:38:55 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on yocto-www.yoctoproject.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.3.1 X-Spam-HAM-Report: * -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% * [score: 0.0000] Received: from smtp.webfaction.com (mail6.webfaction.com [74.55.86.74]) by yocto-www.yoctoproject.org (Postfix) with ESMTP id BB208E0034B for ; Thu, 7 Aug 2014 15:38:45 -0700 (PDT) Received: from [192.168.1.10] (c-68-38-40-177.hsd1.nj.comcast.net [68.38.40.177]) by smtp.webfaction.com (Postfix) with ESMTP id EBEAC210D6C0 for ; Thu, 7 Aug 2014 22:38:43 +0000 (UTC) Message-ID: <53E3FFF2.5010207@mindchasers.com> Date: Thu, 07 Aug 2014 18:38:42 -0400 From: Bob Cochran User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.0 MIME-Version: 1.0 To: meta-freescale@yoctoproject.org References: <1406880342-35231-1-git-send-email-ting.liu@freescale.com> In-Reply-To: <1406880342-35231-1-git-send-email-ting.liu@freescale.com> Subject: Re: [meta-fsl-ppc][PATCH] ptpd: add 2.2.0 recipe to support etsec 1588 X-BeenThere: meta-freescale@yoctoproject.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Usage and development list for the meta-fsl-* layers List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 07 Aug 2014 22:38:55 -0000 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit On 08/01/2014 04:05 AM, ting.liu@freescale.com wrote: > From: Zhenhua Luo > > 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 > Signed-off-by: Ting Liu > --- > 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" Hi Ting, I can't find a patch where PREFERRED_VERSION_valgrind_e500v2 was added, and it's not currently in the master branch version of qoriq-default-versions.inc Therefore, patch failed when I tried to apply it to master. Bob > +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 > +Bug-Debian: http://bugs.debian.org/607583 > + > +Signed-off-by: Jackie Huang > +--- > + 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 // 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 > ++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 > ++/*************************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 > +} >