Patchwork [meta-fsl-ppc] ptpd: add 2.2.0 recipe to support etsec 1588

login
register
mail settings
Submitter Ting Liu
Date Aug. 1, 2014, 8:05 a.m.
Message ID <1406880342-35231-1-git-send-email-ting.liu@freescale.com>
Download mbox | patch
Permalink /patch/77079/
State Rejected
Headers show

Comments

Ting Liu - Aug. 1, 2014, 8:05 a.m.
From: Zhenhua Luo <zhenhua.luo@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@freescale.com>
Signed-off-by: Ting Liu <ting.liu@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
Otavio Salvador - Aug. 1, 2014, 1:54 p.m.
This should go to meta-networking, not meta-fsl-ppc.

On Fri, Aug 1, 2014 at 5:05 AM,  <ting.liu@freescale.com> wrote:
> From: Zhenhua Luo <zhenhua.luo@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@freescale.com>
> Signed-off-by: Ting Liu <ting.liu@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@antcom.de>
> +Bug-Debian: http://bugs.debian.org/607583
> +
> +Signed-off-by: Jackie Huang <jackie.huang@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
>
> --
> _______________________________________________
> meta-freescale mailing list
> meta-freescale@yoctoproject.org
> https://lists.yoctoproject.org/listinfo/meta-freescale
Ting Liu - Aug. 4, 2014, 9:03 a.m.
> -----Original Message-----
> From: otavio.salvador@gmail.com [mailto:otavio.salvador@gmail.com] On Behalf
> Of Otavio Salvador
> Sent: Friday, August 01, 2014 9:55 PM
> To: Liu Ting-B28495
> Cc: meta-freescale@yoctoproject.org
> Subject: Re: [meta-freescale] [meta-fsl-ppc][PATCH] ptpd: add 2.2.0 recipe to
> support etsec 1588
> 
> This should go to meta-networking, not meta-fsl-ppc.

mete-openembedded/meta-networking has latest 2.3.0 ptpd. There is a patch which was based on 
2.2.0 for qoriq boards, so keep a copy in meta-fsl-ppc currently.

> 
> On Fri, Aug 1, 2014 at 5:05 AM,  <ting.liu@freescale.com> wrote:
> > From: Zhenhua Luo <zhenhua.luo@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@freescale.com>
> > Signed-off-by: Ting Liu <ting.liu@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@antcom.de>
> > +Bug-Debian: http://bugs.debian.org/607583
> > +
> > +Signed-off-by: Jackie Huang <jackie.huang@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
> >
> > --
> > _______________________________________________
> > meta-freescale mailing list
> > meta-freescale@yoctoproject.org
> > https://lists.yoctoproject.org/listinfo/meta-freescale
> 
> 
> 
> --
> Otavio Salvador                             O.S. Systems
> http://www.ossystems.com.br        http://code.ossystems.com.br
> Mobile: +55 (53) 9981-7854            Mobile: +1 (347) 903-9750
Otavio Salvador - Aug. 4, 2014, 12:16 p.m.
On Mon, Aug 4, 2014 at 6:03 AM, ting.liu@freescale.com
<ting.liu@freescale.com> wrote:
>> -----Original Message-----
>> From: otavio.salvador@gmail.com [mailto:otavio.salvador@gmail.com] On Behalf
>> Of Otavio Salvador
>> Sent: Friday, August 01, 2014 9:55 PM
>> To: Liu Ting-B28495
>> Cc: meta-freescale@yoctoproject.org
>> Subject: Re: [meta-freescale] [meta-fsl-ppc][PATCH] ptpd: add 2.2.0 recipe to
>> support etsec 1588
>>
>> This should go to meta-networking, not meta-fsl-ppc.
>
> mete-openembedded/meta-networking has latest 2.3.0 ptpd. There is a patch which was based on
> 2.2.0 for qoriq boards, so keep a copy in meta-fsl-ppc currently.

Why not use 2.3.0?
Ting Liu - Aug. 5, 2014, 1:42 a.m.
> -----Original Message-----
> From: otavio.salvador@gmail.com [mailto:otavio.salvador@gmail.com] On Behalf
> Of Otavio Salvador
> Sent: Monday, August 04, 2014 8:16 PM
> To: Liu Ting-B28495
> Cc: meta-freescale@yoctoproject.org
> Subject: Re: [meta-freescale] [meta-fsl-ppc][PATCH] ptpd: add 2.2.0 recipe to
> support etsec 1588
> 
> On Mon, Aug 4, 2014 at 6:03 AM, ting.liu@freescale.com <ting.liu@freescale.com>
> wrote:
> >> -----Original Message-----
> >> From: otavio.salvador@gmail.com [mailto:otavio.salvador@gmail.com] On
> >> Behalf Of Otavio Salvador
> >> Sent: Friday, August 01, 2014 9:55 PM
> >> To: Liu Ting-B28495
> >> Cc: meta-freescale@yoctoproject.org
> >> Subject: Re: [meta-freescale] [meta-fsl-ppc][PATCH] ptpd: add 2.2.0
> >> recipe to support etsec 1588
> >>
> >> This should go to meta-networking, not meta-fsl-ppc.
> >
> > mete-openembedded/meta-networking has latest 2.3.0 ptpd. There is a
> > patch which was based on
> > 2.2.0 for qoriq boards, so keep a copy in meta-fsl-ppc currently.
> 
> Why not use 2.3.0?

What was tested in sdk 1.6 is 2.2.0, and there is a patch that can't be 
applied on latest 2.3.0. . Developers are trying to upstream it.

> 
> --
> Otavio Salvador                             O.S. Systems
> http://www.ossystems.com.br        http://code.ossystems.com.br
> Mobile: +55 (53) 9981-7854            Mobile: +1 (347) 903-9750
Otavio Salvador - Aug. 5, 2014, 1:09 p.m.
Hello Ting,

On Mon, Aug 4, 2014 at 10:42 PM, ting.liu@freescale.com
<ting.liu@freescale.com> wrote:
>> -----Original Message-----
>> From: otavio.salvador@gmail.com [mailto:otavio.salvador@gmail.com] On Behalf
>> Of Otavio Salvador
>> Sent: Monday, August 04, 2014 8:16 PM
>> To: Liu Ting-B28495
>> Cc: meta-freescale@yoctoproject.org
>> Subject: Re: [meta-freescale] [meta-fsl-ppc][PATCH] ptpd: add 2.2.0 recipe to
>> support etsec 1588
>>
>> On Mon, Aug 4, 2014 at 6:03 AM, ting.liu@freescale.com <ting.liu@freescale.com>
>> wrote:
>> >> -----Original Message-----
>> >> From: otavio.salvador@gmail.com [mailto:otavio.salvador@gmail.com] On
>> >> Behalf Of Otavio Salvador
>> >> Sent: Friday, August 01, 2014 9:55 PM
>> >> To: Liu Ting-B28495
>> >> Cc: meta-freescale@yoctoproject.org
>> >> Subject: Re: [meta-freescale] [meta-fsl-ppc][PATCH] ptpd: add 2.2.0
>> >> recipe to support etsec 1588
>> >>
>> >> This should go to meta-networking, not meta-fsl-ppc.
>> >
>> > mete-openembedded/meta-networking has latest 2.3.0 ptpd. There is a
>> > patch which was based on
>> > 2.2.0 for qoriq boards, so keep a copy in meta-fsl-ppc currently.
>>
>> Why not use 2.3.0?
>
> What was tested in sdk 1.6 is 2.2.0, and there is a patch that can't be
> applied on latest 2.3.0. . Developers are trying to upstream it.

I think the best is to get the patch working with 2.3.0 and use this
one. We shouldn't put non-BSP stuff in meta-fsl-ppc.

In fact the patch shouldn't even be here as a bbappend, except if it
has machine specific code, but in the original recipe.
Bob Cochran - Aug. 7, 2014, 10:38 p.m.
On 08/01/2014 04:05 AM, ting.liu@freescale.com wrote:
> From: Zhenhua Luo <zhenhua.luo@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@freescale.com>
> Signed-off-by: Ting Liu <ting.liu@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"

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 <stigge@antcom.de>
> +Bug-Debian: http://bugs.debian.org/607583
> +
> +Signed-off-by: Jackie Huang <jackie.huang@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
> +}
>
Ting Liu - Aug. 8, 2014, 2:29 a.m.
> -----Original Message-----
> From: meta-freescale-bounces@yoctoproject.org [mailto:meta-freescale-
> bounces@yoctoproject.org] On Behalf Of Bob Cochran
> Sent: Friday, August 08, 2014 6:39 AM
> To: meta-freescale@yoctoproject.org
> Subject: Re: [meta-freescale] [meta-fsl-ppc][PATCH] ptpd: add 2.2.0 recipe to
> support etsec 1588
> 
> On 08/01/2014 04:05 AM, ting.liu@freescale.com wrote:
> > From: Zhenhua Luo <zhenhua.luo@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@freescale.com>
> > Signed-off-by: Ting Liu <ting.liu@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"
> 
> 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.

My fault. I generated the patch based on internal test git tree. please ignore this line.

> 
> 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 <stigge@antcom.de>
> > +Bug-Debian: http://bugs.debian.org/607583
> > +
> > +Signed-off-by: Jackie Huang <jackie.huang@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
> > +}
> >
> 
> --
> _______________________________________________
> meta-freescale mailing list
> meta-freescale@yoctoproject.org
> https://lists.yoctoproject.org/listinfo/meta-freescale

Patch

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@antcom.de>
+Bug-Debian: http://bugs.debian.org/607583
+
+Signed-off-by: Jackie Huang <jackie.huang@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
+}