[Linuxptp-devel] [PATCH v4 1/4] [Interface Rate TLV] function to support get interface speed via ethtool

2022-12-28 Thread SyncMonk Technologies
When master and slave instance interacting with each other operating
at different interface speed, delay assymetry needs to be compensated
as described in G.8271 appendix V.

In this patch we are adding changes to get the interface speed using
ethtool.

v1: initial commit.
v2: updating comments and data types.
v3: updating Boolean data type to bool from 
v4: updating iface_if_info.speed data type to uint32_t from int.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 sk.c | 71 
 sk.h | 19 
 2 files changed, 90 insertions(+)

diff --git a/sk.c b/sk.c
index d27abff..1c14ca3 100644
--- a/sk.c
+++ b/sk.c
@@ -205,6 +205,77 @@ failed:
return -1;
 }
 
+int sk_get_if_info(const char *name, struct sk_if_info *if_info)
+{
+#ifdef ETHTOOL_GLINKSETTINGS
+   struct ifreq ifr;
+   int fd, err;
+
+   struct {
+   struct ethtool_link_settings req;
+   /*
+* link_mode_data consists of supported[], advertising[],
+* lp_advertising[] with size up to 127 each.
+* The actual size is provided by the kernel.
+*/
+   __u32 link_mode_data[3 * 127];
+   } ecmd;
+
+   memset(, 0, sizeof(ifr));
+   memset(, 0, sizeof(ecmd));
+
+   fd = socket(AF_INET, SOCK_DGRAM, 0);
+   if (fd < 0) {
+   goto failed;
+   }
+
+   ecmd.req.cmd = ETHTOOL_GLINKSETTINGS;
+
+   strncpy(ifr.ifr_name, name, IFNAMSIZ - 1);
+   ifr.ifr_data = (char *) 
+
+   /* Handshake with kernel to determine number of words for link
+* mode bitmaps. When requested number of bitmap words is not
+* the one expected by kernel, the latter returns the integer
+* opposite of what it is expecting. We request length 0 below
+* (aka. invalid bitmap length) to get this info.
+*/
+   err = ioctl(fd, SIOCETHTOOL, );
+   if (err < 0) {
+   pr_err("ioctl SIOCETHTOOL failed: %m");
+   close(fd);
+   goto failed;
+   }
+
+   if (ecmd.req.link_mode_masks_nwords >= 0 ||
+   ecmd.req.cmd != ETHTOOL_GLINKSETTINGS) {
+   return 1;
+   }
+   ecmd.req.link_mode_masks_nwords = -ecmd.req.link_mode_masks_nwords;
+
+   err = ioctl(fd, SIOCETHTOOL, );
+   if (err < 0) {
+   pr_err("ioctl SIOCETHTOOL failed: %m");
+   close(fd);
+   goto failed;
+   }
+
+   close(fd);
+
+   /* copy the necessary data to sk_info */
+   memset(if_info, 0, sizeof(struct sk_if_info));
+   if_info->valid = 1;
+   if_info->speed = ecmd.req.speed;
+
+   return 0;
+failed:
+#endif
+   /* clear data and ensure it is not marked valid */
+   memset(if_info, 0, sizeof(struct sk_if_info));
+   return -1;
+}
+
+
 static int sk_interface_guidaddr(const char *name, unsigned char *guid)
 {
char file_name[64], buf[64], addr[8];
diff --git a/sk.h b/sk.h
index 486dbc4..7a9058a 100644
--- a/sk.h
+++ b/sk.h
@@ -20,6 +20,7 @@
 #ifndef HAVE_SK_H
 #define HAVE_SK_H
 
+#include 
 #include "address.h"
 #include "transport.h"
 
@@ -49,6 +50,16 @@ struct sk_ts_info {
unsigned int rx_filters;
 };
 
+/**
+ * Contains interface information returned by the GLINKSETTINGS ioctl.
+ * @valid:set to non-zero when the info struct contains valid data.
+ * @speed:interface speed.
+ */
+struct sk_if_info {
+   bool valid;
+   uint32_t speed;
+};
+
 /**
  * Obtains a socket suitable for use with sk_interface_index().
  * @return  An open socket on success, -1 otherwise.
@@ -78,6 +89,14 @@ int sk_general_init(int fd);
  */
 int sk_get_ts_info(const char *name, struct sk_ts_info *sk_info);
 
+/**
+ * Obtain supporte interface information
+ * @param name The name of the interface
+ * @param info  Struct containing obtained interface information.
+ * @return  zero on success, negative on failure.
+ */
+int sk_get_if_info(const char *name, struct sk_if_info *sk_info);
+
 /**
  * Obtain the MAC address of a network interface.
  * @param name  The name of the interface
-- 
2.34.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH v4 4/4] [Interface Rate TLV] adding delay asymmetry calculation

2022-12-28 Thread SyncMonk Technologies
Delay asymmetry calculation based on the PTP port interface speed of
master obtained from TLV and the slave interface rate obtained by ethtool.

The calculation is done in attoseconds to accomodate interface bit period
less than 1ns. (ITU-T G.8275.2(06/2021) annex D).

v4: removing bit period calculation on every signalling message and updating
the bit-period when link update happens
v3: updating network/host byte order handling.
v1: initial commit

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 interface.c   |  5 +
 interface.h   |  7 +++
 port_private.h|  1 +
 port_signaling.c  | 39 ---
 ptp4l.8   |  7 +++
 tlv.c | 29 +
 unicast_service.c | 32 
 7 files changed, 117 insertions(+), 3 deletions(-)

diff --git a/interface.c b/interface.c
index 8524719..29229ad 100644
--- a/interface.c
+++ b/interface.c
@@ -94,3 +94,8 @@ int interface_get_vclock(struct interface *iface)
 {
return iface->vclock;
 }
+
+uint64_t interface_bitperiod(struct interface *iface)
+{
+   return iface->if_info.iface_bit_period;
+}
diff --git a/interface.h b/interface.h
index 5289a7f..0873bba 100644
--- a/interface.h
+++ b/interface.h
@@ -113,4 +113,11 @@ void interface_set_vclock(struct interface *iface, int 
vclock);
  */
 int interface_get_vclock(struct interface *iface);
 
+/**
+ * Obtains the interface bit period based on the speed.
+ * @param iface  The interface of interest.
+ * @return   return interface bitperiod in atto seconds.
+ */
+uint64_t interface_bitperiod(struct interface *iface);
+
 #endif
diff --git a/port_private.h b/port_private.h
index d6487eb..6ad4af8 100644
--- a/port_private.h
+++ b/port_private.h
@@ -146,6 +146,7 @@ struct port {
UInteger8   delay_response_counter;
UInteger8   delay_response_timeout;
booliface_rate_tlv;
+   Integer64   portAsymmetry;
struct PortStatsstats;
struct PortServiceStatsservice_stats;
/* foreignMasterDS */
diff --git a/port_signaling.c b/port_signaling.c
index ed217c0..5a764d6 100644
--- a/port_signaling.c
+++ b/port_signaling.c
@@ -103,10 +103,37 @@ static int process_interval_request(struct port *p,
return 0;
 }
 
+static int process_interface_rate(struct port *p,
+ struct msg_interface_rate_tlv *r)
+{
+   Integer64 delayAsymmetry;
+   doublensDelay;
+   Integer64 slaveBitPeriod;
+   Integer64 masterBitPeriod;
+
+   if (p->iface_rate_tlv && interface_ifinfo_valid(p->iface)) {
+   slaveBitPeriod = interface_bitperiod(p->iface);
+   masterBitPeriod = r->interfaceBitPeriod;
+
+   /* Delay Asymmetry Calculation */
+   nsDelay = (double)(masterBitPeriod - slaveBitPeriod) / (2 * 
1.0e9);
+   delayAsymmetry =
+   (r->numberOfBitsAfterTimestamp - 
r->numberOfBitsBeforeTimestamp)  * nsDelay;
+
+   if (delayAsymmetry != p->portAsymmetry) {
+   p->asymmetry += ((delayAsymmetry - p->portAsymmetry) << 
16);
+   p->portAsymmetry = delayAsymmetry;
+   }
+   }
+   return 0;
+}
+
 int process_signaling(struct port *p, struct ptp_message *m)
 {
struct tlv_extra *extra;
+   struct organization_tlv *org;
struct msg_interval_req_tlv *r;
+   struct msg_interface_rate_tlv *rate;
int err = 0, result;
 
switch (p->state) {
@@ -160,11 +187,17 @@ int process_signaling(struct port *p, struct ptp_message 
*m)
break;
 
case TLV_ORGANIZATION_EXTENSION:
-   r = (struct msg_interval_req_tlv *) extra->tlv;
+   org = (struct organization_tlv *)extra->tlv;
 
-   if (0 == memcmp(r->id, ieee8021_id, 
sizeof(ieee8021_id)) &&
-   r->subtype[0] == 0 && r->subtype[1] == 0 && 
r->subtype[2] == 2)
+   if (0 == memcmp(org->id, ieee8021_id, 
sizeof(ieee8021_id)) &&
+   org->subtype[0] == 0 && org->subtype[1] == 0 && 
org->subtype[2] == 2) {
+   r = (struct msg_interval_req_tlv *) extra->tlv;
err = process_interval_request(p, r);
+   } else if (0 == memcmp(org->id, itu_t_id, 
sizeof(itu_t_id)) &&
+  org->subtype[0] == 0 && org->subtype[1] == 0 
&& org->subtype[2] == 2) {
+   rate = (struct msg_interface_rate_tlv *) 
extra->tlv;
+   err = process_interface_rate(p, rate);
+   }
break;
}
}
diff --git a/ptp4l.8 b/ptp4l.8
index cd6299f..e96d090 100644
--- 

[Linuxptp-devel] [PATCH v4 3/4] [Interface Rate TLV] organization TLV support for interface rate

2022-12-28 Thread SyncMonk Technologies
adding interface rate TLV as defined by ITU-T G.8275.2 Annex D to
enable master to communicate PTP port interface rate to slave.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 

v4: Updating comments for UInteger64 introduced in pdt.h as per ITU-T G.8275.2
---
 config.c   |  1 +
 pdt.h  |  1 +
 port.c |  1 +
 port_private.h |  1 +
 tlv.c  |  1 +
 tlv.h  | 14 ++
 6 files changed, 19 insertions(+)

diff --git a/config.c b/config.c
index 08e3346..2fa95fc 100644
--- a/config.c
+++ b/config.c
@@ -267,6 +267,7 @@ struct config_item config_tab[] = {
PORT_ITEM_INT("inhibit_delay_req", 0, 0, 1),
PORT_ITEM_INT("inhibit_multicast_service", 0, 0, 1),
GLOB_ITEM_INT("initial_delay", 0, 0, INT_MAX),
+   PORT_ITEM_INT("interface_rate_tlv", 0, 0, 1),
GLOB_ITEM_INT("kernel_leap", 1, 0, 1),
GLOB_ITEM_STR("leapfile", NULL),
PORT_ITEM_INT("logAnnounceInterval", 1, INT8_MIN, INT8_MAX),
diff --git a/pdt.h b/pdt.h
index e46b218..eaad58b 100644
--- a/pdt.h
+++ b/pdt.h
@@ -39,6 +39,7 @@ typedef uint16_t  UInteger16;
 typedef int32_t   Integer32;
 typedef uint32_t  UInteger32;
 typedef int64_t   Integer64;
+typedef uint64_t  UInteger64; /* ITU-T G.8275.2 */
 typedef uint8_t   Octet;
 
 #endif
diff --git a/port.c b/port.c
index 2a96c40..8a1c42a 100644
--- a/port.c
+++ b/port.c
@@ -1854,6 +1854,7 @@ int port_initialize(struct port *p)
p->neighborPropDelayThresh = config_get_int(cfg, p->name, 
"neighborPropDelayThresh");
p->min_neighbor_prop_delay = config_get_int(cfg, p->name, 
"min_neighbor_prop_delay");
p->delay_response_timeout  = config_get_int(cfg, p->name, 
"delay_response_timeout");
+   p->iface_rate_tlv  = config_get_int(cfg, p->name, 
"interface_rate_tlv");
 
if (config_get_int(cfg, p->name, "asCapable") == AS_CAPABLE_TRUE) {
p->asCapable = ALWAYS_CAPABLE;
diff --git a/port_private.h b/port_private.h
index d27dceb..d6487eb 100644
--- a/port_private.h
+++ b/port_private.h
@@ -145,6 +145,7 @@ struct port {
UInteger8   versionNumber; /* UInteger4 */
UInteger8   delay_response_counter;
UInteger8   delay_response_timeout;
+   booliface_rate_tlv;
struct PortStatsstats;
struct PortServiceStatsservice_stats;
/* foreignMasterDS */
diff --git a/tlv.c b/tlv.c
index 1c13460..35bee4f 100644
--- a/tlv.c
+++ b/tlv.c
@@ -35,6 +35,7 @@
(tlv->length < sizeof(struct type) - sizeof(struct TLV))
 
 uint8_t ieee8021_id[3] = { IEEE_802_1_COMMITTEE };
+uint8_t itu_t_id[3] = { ITU_T_COMMITTEE };
 
 static TAILQ_HEAD(tlv_pool, tlv_extra) tlv_pool =
TAILQ_HEAD_INITIALIZER(tlv_pool);
diff --git a/tlv.h b/tlv.h
index 8966696..ec22e2f 100644
--- a/tlv.h
+++ b/tlv.h
@@ -395,6 +395,20 @@ struct tlv_extra {
};
 };
 
+/* Organizationally Unique Identifiers */
+#define ITU_T_COMMITTEE 0x00, 0x19, 0xA7
+extern uint8_t itu_t_id[3];
+
+struct msg_interface_rate_tlv {
+   Enumeration16 type;
+   UInteger16length;
+   Octet id[3];
+   Octet subtype[3];
+   UInteger64interfaceBitPeriod;
+   UInteger16numberOfBitsBeforeTimestamp;
+   UInteger16numberOfBitsAfterTimestamp;
+} PACKED;
+
 /**
  * Allocates a new tlv_extra structure.
  * @return  Pointer to a new structure on success or NULL otherwise.
-- 
2.34.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH v4 2/4] [Interface Rate TLV] adding speed field information for interface

2022-12-28 Thread SyncMonk Technologies
Get the interface speed related information using ethtool and
convert interface speed to bit rate in attoseconds per bit.

v4: adding interface bit period in iface_if_info. This bit period
is updated during init time and whenever there are port events
like link up and down and speed updates.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 clock.c |  6 --
 interface.c | 12 
 interface.h | 14 ++
 port.c  |  5 +
 sk.c|  2 ++
 sk.h|  2 ++
 6 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/clock.c b/clock.c
index 134c7c3..94da41b 100644
--- a/clock.c
+++ b/clock.c
@@ -1005,11 +1005,13 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
memset(ts_label, 0, sizeof(ts_label));
if (!rtnl_get_ts_device(interface_name(iface), ts_label))
interface_set_label(iface, ts_label);
+   /* Interface speed information */
+   interface_get_ifinfo(iface);
interface_get_tsinfo(iface);
if (interface_tsinfo_valid(iface) &&
-   !interface_tsmodes_supported(iface, required_modes)) {
+   !interface_tsmodes_supported(iface, 
required_modes)) {
pr_err("interface '%s' does not support requested 
timestamping mode",
-  interface_name(iface));
+   interface_name(iface));
return NULL;
}
}
diff --git a/interface.c b/interface.c
index 6c2630c..8524719 100644
--- a/interface.c
+++ b/interface.c
@@ -12,6 +12,7 @@ struct interface {
char name[MAX_IFNAME_SIZE + 1];
char ts_label[MAX_IFNAME_SIZE + 1];
struct sk_ts_info ts_info;
+   struct sk_if_info if_info;
int vclock;
 };
 
@@ -40,11 +41,22 @@ int interface_get_tsinfo(struct interface *iface)
return sk_get_ts_info(iface->ts_label, >ts_info);
 }
 
+int interface_get_ifinfo(struct interface *iface)
+{
+   return sk_get_if_info(iface->ts_label, >if_info);
+}
+
 const char *interface_label(struct interface *iface)
 {
return iface->ts_label;
 }
 
+bool interface_ifinfo_valid(struct interface *iface)
+{
+   return iface->if_info.valid ? true : false;
+}
+
+
 const char *interface_name(struct interface *iface)
 {
return iface->name;
diff --git a/interface.h b/interface.h
index 5fc7836..5289a7f 100644
--- a/interface.h
+++ b/interface.h
@@ -40,6 +40,13 @@ void interface_destroy(struct interface *iface);
  */
 int interface_get_tsinfo(struct interface *iface);
 
+/**
+ * Populate the time stamping information of a given interface.
+ * @param iface  The interface of interest.
+ * @return   zero on success, negative on failure.
+ */
+int interface_get_ifinfo(struct interface *iface);
+
 /**
  * Obtain the time stamping label of a network interface.  This can be
  * different from the name of the interface when bonding is in effect.
@@ -77,6 +84,13 @@ void interface_set_label(struct interface *iface, const char 
*label);
  */
 bool interface_tsinfo_valid(struct interface *iface);
 
+/**
+ * Tests whether an interface's interface information is valid or not.
+ * @param iface  The interface of interest.
+ * @return   True if the interface information is valid, false otherwise.
+ */
+bool interface_ifinfo_valid(struct interface *iface);
+
 /**
  * Tests whether an interface supports a set of given time stamping modes.
  * @param iface  The interface of interest.
diff --git a/port.c b/port.c
index 6baf5c8..2a96c40 100644
--- a/port.c
+++ b/port.c
@@ -2741,6 +2741,11 @@ void port_link_status(void *ctx, int linkup, int 
ts_index)
p->link_status = link_state;
} else {
p->link_status = link_state | LINK_STATE_CHANGED;
+   /* Update Interface speed information on Link up*/
+   if (linkup) {
+   interface_get_ifinfo(p->iface);
+   }
+
pr_notice("%s: link %s", p->log_name, linkup ? "up" : "down");
}
 
diff --git a/sk.c b/sk.c
index 1c14ca3..2e4ef2c 100644
--- a/sk.c
+++ b/sk.c
@@ -267,6 +267,8 @@ int sk_get_if_info(const char *name, struct sk_if_info 
*if_info)
if_info->valid = 1;
if_info->speed = ecmd.req.speed;
 
+   /* Megabits per second converted to attoseconds per bit */
+   if_info->iface_bit_period = (1ULL/if_info->speed);
return 0;
 failed:
 #endif
diff --git a/sk.h b/sk.h
index 7a9058a..df105d6 100644
--- a/sk.h
+++ b/sk.h
@@ -54,10 +54,12 @@ struct sk_ts_info {
  * Contains interface information returned by the GLINKSETTINGS ioctl.
  * @valid:set to non-zero when the info struct contains valid data.
  * @speed:interface speed.
+ * @iface_bit_period  interface bit period in attoseconds 

[Linuxptp-devel] [PATCH v3 2/4] [Interface Rate TLV] adding speed field information for interface

2022-12-07 Thread SyncMonk Technologies
Get the interface speed related information using ethtool

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 clock.c |  2 ++
 interface.c | 12 
 interface.h | 14 ++
 port.c  |  5 +
 4 files changed, 33 insertions(+)

diff --git a/clock.c b/clock.c
index 5186010..7323636 100644
--- a/clock.c
+++ b/clock.c
@@ -1005,6 +1005,8 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
memset(ts_label, 0, sizeof(ts_label));
if (!rtnl_get_ts_device(interface_name(iface), ts_label))
interface_set_label(iface, ts_label);
+/* Interface speed information */
+interface_get_ifinfo(iface);
interface_get_tsinfo(iface);
if (interface_tsinfo_valid(iface) &&
!interface_tsmodes_supported(iface, required_modes)) {
diff --git a/interface.c b/interface.c
index 6c2630c..3157e8c 100644
--- a/interface.c
+++ b/interface.c
@@ -12,6 +12,7 @@ struct interface {
char name[MAX_IFNAME_SIZE + 1];
char ts_label[MAX_IFNAME_SIZE + 1];
struct sk_ts_info ts_info;
+struct sk_if_info if_info;
int vclock;
 };
 
@@ -40,11 +41,22 @@ int interface_get_tsinfo(struct interface *iface)
return sk_get_ts_info(iface->ts_label, >ts_info);
 }
 
+int interface_get_ifinfo(struct interface *iface)
+{
+   return sk_get_if_info(iface->ts_label, >if_info);
+}
+
 const char *interface_label(struct interface *iface)
 {
return iface->ts_label;
 }
 
+bool interface_ifinfo_valid(struct interface *iface)
+{
+   return iface->if_info.valid ? true : false;
+}
+
+
 const char *interface_name(struct interface *iface)
 {
return iface->name;
diff --git a/interface.h b/interface.h
index 5fc7836..f4b9545 100644
--- a/interface.h
+++ b/interface.h
@@ -40,6 +40,13 @@ void interface_destroy(struct interface *iface);
  */
 int interface_get_tsinfo(struct interface *iface);
 
+/**
+ * Populate the time stamping information of a given interface.
+ * @param iface  The interface of interest.
+ * @return   zero on success, negative on failure.
+ */
+int interface_get_ifinfo(struct interface *iface);
+
 /**
  * Obtain the time stamping label of a network interface.  This can be
  * different from the name of the interface when bonding is in effect.
@@ -77,6 +84,13 @@ void interface_set_label(struct interface *iface, const char 
*label);
  */
 bool interface_tsinfo_valid(struct interface *iface);
 
+/**
+ * Tests whether an interface's interface information is valid or not.
+ * @param iface  The interface of interest.
+ * @return   True if the interface information is valid, false otherwise.
+ */
+bool interface_ifinfo_valid(struct interface *iface);
+ 
 /**
  * Tests whether an interface supports a set of given time stamping modes.
  * @param iface  The interface of interest.
diff --git a/port.c b/port.c
index 1866a20..7fd50dd 100644
--- a/port.c
+++ b/port.c
@@ -2738,6 +2738,11 @@ void port_link_status(void *ctx, int linkup, int 
ts_index)
p->link_status = link_state;
} else {
p->link_status = link_state | LINK_STATE_CHANGED;
+/* Update Interface speed information on Link up*/
+if (linkup) {
+interface_get_ifinfo(p->iface);
+}
+
pr_notice("%s: link %s", p->log_name, linkup ? "up" : "down");
}
 
-- 
2.34.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH v3 3/4] [Interface Rate TLV] organization TLV support for interface rate

2022-12-07 Thread SyncMonk Technologies
adding interface rate TLV as defined by ITU-T G.8275.2 Annex D to
enable master to communicate PTP port interface rate to slave.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 config.c   |  1 +
 pdt.h  |  1 +
 port.c |  1 +
 port_private.h |  1 +
 tlv.c  |  1 +
 tlv.h  | 14 ++
 6 files changed, 19 insertions(+)

diff --git a/config.c b/config.c
index 08e3346..2fa95fc 100644
--- a/config.c
+++ b/config.c
@@ -267,6 +267,7 @@ struct config_item config_tab[] = {
PORT_ITEM_INT("inhibit_delay_req", 0, 0, 1),
PORT_ITEM_INT("inhibit_multicast_service", 0, 0, 1),
GLOB_ITEM_INT("initial_delay", 0, 0, INT_MAX),
+   PORT_ITEM_INT("interface_rate_tlv", 0, 0, 1),
GLOB_ITEM_INT("kernel_leap", 1, 0, 1),
GLOB_ITEM_STR("leapfile", NULL),
PORT_ITEM_INT("logAnnounceInterval", 1, INT8_MIN, INT8_MAX),
diff --git a/pdt.h b/pdt.h
index e46b218..1ad23d4 100644
--- a/pdt.h
+++ b/pdt.h
@@ -39,6 +39,7 @@ typedef uint16_t  UInteger16;
 typedef int32_t   Integer32;
 typedef uint32_t  UInteger32;
 typedef int64_t   Integer64;
+typedef uint64_t  UInteger64;
 typedef uint8_t   Octet;
 
 #endif
diff --git a/port.c b/port.c
index 7fd50dd..85cfa4a 100644
--- a/port.c
+++ b/port.c
@@ -1854,6 +1854,7 @@ int port_initialize(struct port *p)
p->neighborPropDelayThresh = config_get_int(cfg, p->name, 
"neighborPropDelayThresh");
p->min_neighbor_prop_delay = config_get_int(cfg, p->name, 
"min_neighbor_prop_delay");
p->delay_response_timeout  = config_get_int(cfg, p->name, 
"delay_response_timeout");
+   p->iface_rate_tlv  = config_get_int(cfg, p->name, 
"interface_rate_tlv");
 
if (config_get_int(cfg, p->name, "asCapable") == AS_CAPABLE_TRUE) {
p->asCapable = ALWAYS_CAPABLE;
diff --git a/port_private.h b/port_private.h
index d27dceb..d6487eb 100644
--- a/port_private.h
+++ b/port_private.h
@@ -145,6 +145,7 @@ struct port {
UInteger8   versionNumber; /* UInteger4 */
UInteger8   delay_response_counter;
UInteger8   delay_response_timeout;
+   booliface_rate_tlv;
struct PortStatsstats;
struct PortServiceStatsservice_stats;
/* foreignMasterDS */
diff --git a/tlv.c b/tlv.c
index 1c13460..35bee4f 100644
--- a/tlv.c
+++ b/tlv.c
@@ -35,6 +35,7 @@
(tlv->length < sizeof(struct type) - sizeof(struct TLV))
 
 uint8_t ieee8021_id[3] = { IEEE_802_1_COMMITTEE };
+uint8_t itu_t_id[3] = { ITU_T_COMMITTEE };
 
 static TAILQ_HEAD(tlv_pool, tlv_extra) tlv_pool =
TAILQ_HEAD_INITIALIZER(tlv_pool);
diff --git a/tlv.h b/tlv.h
index 8966696..ec22e2f 100644
--- a/tlv.h
+++ b/tlv.h
@@ -395,6 +395,20 @@ struct tlv_extra {
};
 };
 
+/* Organizationally Unique Identifiers */
+#define ITU_T_COMMITTEE 0x00, 0x19, 0xA7
+extern uint8_t itu_t_id[3];
+
+struct msg_interface_rate_tlv {
+   Enumeration16 type;
+   UInteger16length;
+   Octet id[3];
+   Octet subtype[3];
+   UInteger64interfaceBitPeriod;
+   UInteger16numberOfBitsBeforeTimestamp;
+   UInteger16numberOfBitsAfterTimestamp;
+} PACKED;
+
 /**
  * Allocates a new tlv_extra structure.
  * @return  Pointer to a new structure on success or NULL otherwise.
-- 
2.34.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH v3 4/4] [Interface Rate TLV] adding delay asymmetry calculation

2022-12-07 Thread SyncMonk Technologies
Delay asymmetry calculation based on the PTP port interface speed of
master obtained from TLV and the slave interface rate obtained by ethtool.

v3: updating network/host byte order handling.
v1: initial commit

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 interface.c   | 10 ++
 interface.h   |  7 +++
 port_private.h|  1 +
 port_signaling.c  | 39 ---
 ptp4l.8   |  7 +++
 tlv.c | 29 +
 unicast_service.c | 32 
 7 files changed, 122 insertions(+), 3 deletions(-)

diff --git a/interface.c b/interface.c
index 3157e8c..02d530e 100644
--- a/interface.c
+++ b/interface.c
@@ -94,3 +94,13 @@ int interface_get_vclock(struct interface *iface)
 {
return iface->vclock;
 }
+
+uint64_t interface_bitperiod(struct interface *iface)
+{
+   if (!iface->if_info.valid)
+   return 0;
+
+   /* Megabits per secon converted to attoseconds per bit. */
+   return 1ULL/ iface->if_info.speed;
+}
+
diff --git a/interface.h b/interface.h
index f4b9545..7c9a6bd 100644
--- a/interface.h
+++ b/interface.h
@@ -113,4 +113,11 @@ void interface_set_vclock(struct interface *iface, int 
vclock);
  */
 int interface_get_vclock(struct interface *iface);
 
+/**
+ * Obtains the interface bit period based on the speed.
+ * @param iface  The interface of interest.
+ * @return   if valid speed return interface bitperiod in atto seconds.
+ */
+uint64_t interface_bitperiod(struct interface *iface);
+
 #endif
diff --git a/port_private.h b/port_private.h
index d6487eb..6ad4af8 100644
--- a/port_private.h
+++ b/port_private.h
@@ -146,6 +146,7 @@ struct port {
UInteger8   delay_response_counter;
UInteger8   delay_response_timeout;
booliface_rate_tlv;
+   Integer64   portAsymmetry;
struct PortStatsstats;
struct PortServiceStatsservice_stats;
/* foreignMasterDS */
diff --git a/port_signaling.c b/port_signaling.c
index ed217c0..75a0689 100644
--- a/port_signaling.c
+++ b/port_signaling.c
@@ -103,10 +103,37 @@ static int process_interval_request(struct port *p,
return 0;
 }
 
+static int process_interface_rate(struct port *p,
+ struct msg_interface_rate_tlv *r)
+{
+   Integer64 delayAsymmetry;
+   doublensDelay;
+   Integer64 slaveBitPeriod;
+   Integer64 masterBitPeriod;
+
+   if (p->iface_rate_tlv && interface_ifinfo_valid(p->iface)) {
+   slaveBitPeriod = interface_bitperiod(p->iface);
+   masterBitPeriod = r->interfaceBitPeriod;
+
+   /* Delay Asymmetry Calculation */
+   nsDelay = (masterBitPeriod - slaveBitPeriod) / (2 * 1.0e9);
+   delayAsymmetry =
+   (r->numberOfBitsAfterTimestamp - 
r->numberOfBitsBeforeTimestamp)  * nsDelay;
+
+   if (delayAsymmetry != p->portAsymmetry) {
+   p->asymmetry += ((delayAsymmetry - p->portAsymmetry) << 
16);
+   p->portAsymmetry = delayAsymmetry;
+   }
+   }
+   return 0;
+}
+
 int process_signaling(struct port *p, struct ptp_message *m)
 {
struct tlv_extra *extra;
+   struct organization_tlv *org;
struct msg_interval_req_tlv *r;
+   struct msg_interface_rate_tlv *rate;
int err = 0, result;
 
switch (p->state) {
@@ -160,11 +187,17 @@ int process_signaling(struct port *p, struct ptp_message 
*m)
break;
 
case TLV_ORGANIZATION_EXTENSION:
-   r = (struct msg_interval_req_tlv *) extra->tlv;
+   org = (struct organization_tlv *)extra->tlv;
 
-   if (0 == memcmp(r->id, ieee8021_id, 
sizeof(ieee8021_id)) &&
-   r->subtype[0] == 0 && r->subtype[1] == 0 && 
r->subtype[2] == 2)
+   if (0 == memcmp(org->id, ieee8021_id, 
sizeof(ieee8021_id)) &&
+   org->subtype[0] == 0 && org->subtype[1] == 0 && 
org->subtype[2] == 2) {
+   r = (struct msg_interval_req_tlv *) extra->tlv;
err = process_interval_request(p, r);
+   } else if (0 == memcmp(org->id, itu_t_id, 
sizeof(itu_t_id)) &&
+  org->subtype[0] == 0 && org->subtype[1] == 0 
&& org->subtype[2] == 2) {
+   rate = (struct msg_interface_rate_tlv *) 
extra->tlv;
+   err = process_interface_rate(p, rate);
+   }
break;
}
}
diff --git a/ptp4l.8 b/ptp4l.8
index cd6299f..e96d090 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -697,6 +697,13 @@ The default is 0 (disabled).
 Print messages to the 

[Linuxptp-devel] [PATCH v3 1/4] [Interface Rate TLV] function to support get interface speed via ethtool

2022-12-07 Thread SyncMonk Technologies
When master and slave instance interacting with each other operating
at different interface speed, delay assymetry needs to be compensated
as described in G.8271 appendix V.

In this patch we are adding changes to get the interface speed using
ethtool.

v1: initial commit.
v2: updating comments and data types.
v3: updating Boolean data type to bool from 
---
 sk.c | 71 
 sk.h | 19 
 2 files changed, 90 insertions(+)

diff --git a/sk.c b/sk.c
index d27abff..1d1a656 100644
--- a/sk.c
+++ b/sk.c
@@ -205,6 +205,77 @@ failed:
return -1;
 }
 
+int sk_get_if_info(const char *name, struct sk_if_info *if_info)
+{
+#ifdef ETHTOOL_GLINKSETTINGS
+   struct ifreq ifr;
+   int fd, err;
+
+   struct {
+   struct ethtool_link_settings req;
+   /*
+* link_mode_data consists of supported[], advertising[],
+* lp_advertising[] with size up to 127 each.
+* The actual size is provided by the kernel.
+*/
+   __u32 link_mode_data[3 * 127];
+   } ecmd;
+
+   memset(, 0, sizeof(ifr));
+   memset(, 0, sizeof(ecmd));
+
+   fd = socket(AF_INET, SOCK_DGRAM, 0);
+   if (fd < 0) {
+   goto failed;
+   }
+
+   ecmd.req.cmd = ETHTOOL_GLINKSETTINGS;
+
+   strncpy(ifr.ifr_name, name, IFNAMSIZ - 1);
+   ifr.ifr_data = (char *) 
+
+   /* Handshake with kernel to determine number of words for link
+* mode bitmaps. When requested number of bitmap words is not
+* the one expected by kernel, the latter returns the integer
+* opposite of what it is expecting. We request length 0 below
+* (aka. invalid bitmap length) to get this info.
+*/
+   err = ioctl(fd, SIOCETHTOOL, );
+   if (err < 0) {
+   pr_err("ioctl SIOCETHTOOL failed: %m");
+   close(fd);
+   goto failed;
+   }
+
+   if (ecmd.req.link_mode_masks_nwords >= 0 ||
+   ecmd.req.cmd != ETHTOOL_GLINKSETTINGS) {
+   return 1;
+   }
+   ecmd.req.link_mode_masks_nwords = -ecmd.req.link_mode_masks_nwords;
+
+   err = ioctl(fd, SIOCETHTOOL, );
+   if (err < 0) {
+   pr_err("ioctl SIOCETHTOOL failed: %m");
+   close(fd);
+   goto failed;
+   }
+
+   close(fd);
+
+   /* copy the necessary data to sk_info */
+   memset(if_info, 0, sizeof(struct sk_if_info));
+   if_info->valid = 1;
+   if_info->speed = ecmd.req.speed;
+
+   return 0;
+failed:
+#endif
+   /* clear data and ensure it is not marked valid */
+   memset(if_info, 0, sizeof(struct sk_if_info));
+   return -1;
+}
+
+
 static int sk_interface_guidaddr(const char *name, unsigned char *guid)
 {
char file_name[64], buf[64], addr[8];
diff --git a/sk.h b/sk.h
index 486dbc4..4cee3d7 100644
--- a/sk.h
+++ b/sk.h
@@ -20,6 +20,7 @@
 #ifndef HAVE_SK_H
 #define HAVE_SK_H
 
+#include 
 #include "address.h"
 #include "transport.h"
 
@@ -49,6 +50,16 @@ struct sk_ts_info {
unsigned int rx_filters;
 };
 
+/**
+ * Contains interface information returned by theGLINKSETTINGS ioctl.
+ * @valid:set to non-zero when the info struct contains valid data.
+ * @speed:interface speed.
+ */
+struct sk_if_info {
+   bool valid;
+   int speed;
+};
+
 /**
  * Obtains a socket suitable for use with sk_interface_index().
  * @return  An open socket on success, -1 otherwise.
@@ -78,6 +89,14 @@ int sk_general_init(int fd);
  */
 int sk_get_ts_info(const char *name, struct sk_ts_info *sk_info);
 
+/**
+ * Obtain supporte interface information
+ * @param name The name of the interface
+ * @param info  Struct containing obtained interface information.
+ * @return  zero on success, negative on failure.
+ */
+int sk_get_if_info(const char *name, struct sk_if_info *sk_info);
+
 /**
  * Obtain the MAC address of a network interface.
  * @param name  The name of the interface
-- 
2.34.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 4/4] [Interface Rate TLV] adding delay asymmetry calculation

2022-10-10 Thread SyncMonk Technologies
From: devasishsyncmonk 

Delay asymmetry calculation based on the PTP port interface speed of
master obtained from TLV and the slave interface rate obtained by ethtool.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 interface.c   |  9 +
 interface.h   |  7 +++
 port_private.h|  1 +
 port_signaling.c  | 32 
 ptp4l.8   |  7 +++
 unicast_service.c | 35 +++
 6 files changed, 91 insertions(+)

diff --git a/interface.c b/interface.c
index 9c30499..6237e88 100644
--- a/interface.c
+++ b/interface.c
@@ -93,3 +93,12 @@ int interface_get_vclock(struct interface *iface)
 {
return iface->vclock;
 }
+
+uint64_t interface_bitperiod(struct interface *iface)
+{
+   if (!iface->if_info.valid)
+   return 0;
+
+   /* Megabits per secon converted to attoseconds per bit. */
+   return 1ULL/ iface->if_info.speed;
+}
diff --git a/interface.h b/interface.h
index 5289a7f..e1dc0e8 100644
--- a/interface.h
+++ b/interface.h
@@ -113,4 +113,11 @@ void interface_set_vclock(struct interface *iface, int 
vclock);
  */
 int interface_get_vclock(struct interface *iface);
 
+/**
+ * Obtains the interface bit period based on the speed.
+ * @param iface  The interface of interest.
+ * @return   if valid speed return interface bitperiod in atto seconds.
+ */
+uint64_t interface_bitperiod(struct interface *iface);
+
 #endif
diff --git a/port_private.h b/port_private.h
index d27dceb..d1a1e76 100644
--- a/port_private.h
+++ b/port_private.h
@@ -145,6 +145,7 @@ struct port {
UInteger8   versionNumber; /* UInteger4 */
UInteger8   delay_response_counter;
UInteger8   delay_response_timeout;
+   Integer64   portAsymmetry;
struct PortStatsstats;
struct PortServiceStatsservice_stats;
/* foreignMasterDS */
diff --git a/port_signaling.c b/port_signaling.c
index ed217c0..d78acb6 100644
--- a/port_signaling.c
+++ b/port_signaling.c
@@ -103,10 +103,38 @@ static int process_interval_request(struct port *p,
return 0;
 }
 
+static int process_interface_rate(struct port *p,
+ struct msg_interface_rate_tlv *r)
+{
+   Integer64 delayAsymmetry;
+   doublensDelay;
+   Integer64 slaveBitPeriod;
+   Integer64 masterBitPeriod;
+
+   if (clock_interface_rate_tlv (p->clock) &&
+   interface_ifinfo_valid(p->iface)) {
+   slaveBitPeriod = interface_bitperiod(p->iface);
+   masterBitPeriod = r->interfaceBitPeriod;
+
+   /* Delay Asymmetry Calculation */
+   nsDelay = (masterBitPeriod - slaveBitPeriod) / (2 * 1.0e9);
+   delayAsymmetry =
+   (r->numberOfBitsAfterTimestamp - 
r->numberOfBitsBeforeTimestamp)  * nsDelay;
+
+   if (delayAsymmetry != p->portAsymmetry) {
+   p->asymmetry += ((delayAsymmetry - p->portAsymmetry) << 
16);
+   p->portAsymmetry = delayAsymmetry;
+   }
+   }
+   return 0;
+}
+
+
 int process_signaling(struct port *p, struct ptp_message *m)
 {
struct tlv_extra *extra;
struct msg_interval_req_tlv *r;
+   struct msg_interface_rate_tlv *rate;
int err = 0, result;
 
switch (p->state) {
@@ -161,10 +189,14 @@ int process_signaling(struct port *p, struct ptp_message 
*m)
 
case TLV_ORGANIZATION_EXTENSION:
r = (struct msg_interval_req_tlv *) extra->tlv;
+   rate = (struct msg_interface_rate_tlv *) extra->tlv;
 
if (0 == memcmp(r->id, ieee8021_id, 
sizeof(ieee8021_id)) &&
r->subtype[0] == 0 && r->subtype[1] == 0 && 
r->subtype[2] == 2)
err = process_interval_request(p, r);
+   else if (0 == memcmp(r->id, itu_t_id, sizeof(itu_t_id)) 
&&
+   r->subtype[0] == 0 && r->subtype[1] == 0 && 
r->subtype[2] == 2)
+   err = process_interface_rate(p, rate);
break;
}
}
diff --git a/ptp4l.8 b/ptp4l.8
index 1268802..eab4b47 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -695,6 +695,13 @@ The default is 0 (disabled).
 Print messages to the system log if enabled.
 The default is 1 (enabled).
 .TP
+.B interface_rate_tlv
+When the client and server are operating are operating at different interface 
rate,
+delay asymmetry caused due to different interface rate needs to be compensated.
+The server sends its interface rate using interface rate TLV
+as per G.8275.2 Annex D.
+The default is 0 (does not support interface rate tlv).
+
 .B summary_interval
 The time interval in which are printed summary statistics of the clock. It is
 specified as a power 

[Linuxptp-devel] [PATCH 2/4] [Interface Rate TLV] adding speed field information for interface

2022-10-10 Thread SyncMonk Technologies
From: devasishsyncmonk 

Get the interface speed related information using ethtool

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 clock.c |  2 ++
 interface.c | 11 +++
 interface.h | 14 ++
 port.c  |  4 
 4 files changed, 31 insertions(+)

diff --git a/clock.c b/clock.c
index d37bb87..086b1a8 100644
--- a/clock.c
+++ b/clock.c
@@ -1004,6 +1004,8 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
memset(ts_label, 0, sizeof(ts_label));
if (!rtnl_get_ts_device(interface_name(iface), ts_label))
interface_set_label(iface, ts_label);
+/* Interface speed information */
+interface_get_ifinfo(iface);
interface_get_tsinfo(iface);
if (interface_tsinfo_valid(iface) &&
!interface_tsmodes_supported(iface, required_modes)) {
diff --git a/interface.c b/interface.c
index 6c2630c..9c30499 100644
--- a/interface.c
+++ b/interface.c
@@ -12,6 +12,7 @@ struct interface {
char name[MAX_IFNAME_SIZE + 1];
char ts_label[MAX_IFNAME_SIZE + 1];
struct sk_ts_info ts_info;
+struct sk_if_info if_info;
int vclock;
 };
 
@@ -40,11 +41,21 @@ int interface_get_tsinfo(struct interface *iface)
return sk_get_ts_info(iface->ts_label, >ts_info);
 }
 
+int interface_get_ifinfo(struct interface *iface)
+{
+   return sk_get_if_info(iface->ts_label, >if_info);
+}
+
 const char *interface_label(struct interface *iface)
 {
return iface->ts_label;
 }
 
+bool interface_ifinfo_valid(struct interface *iface)
+{
+   return iface->if_info.valid ? true : false;
+}
+
 const char *interface_name(struct interface *iface)
 {
return iface->name;
diff --git a/interface.h b/interface.h
index 5fc7836..5289a7f 100644
--- a/interface.h
+++ b/interface.h
@@ -40,6 +40,13 @@ void interface_destroy(struct interface *iface);
  */
 int interface_get_tsinfo(struct interface *iface);
 
+/**
+ * Populate the time stamping information of a given interface.
+ * @param iface  The interface of interest.
+ * @return   zero on success, negative on failure.
+ */
+int interface_get_ifinfo(struct interface *iface);
+
 /**
  * Obtain the time stamping label of a network interface.  This can be
  * different from the name of the interface when bonding is in effect.
@@ -77,6 +84,13 @@ void interface_set_label(struct interface *iface, const char 
*label);
  */
 bool interface_tsinfo_valid(struct interface *iface);
 
+/**
+ * Tests whether an interface's interface information is valid or not.
+ * @param iface  The interface of interest.
+ * @return   True if the interface information is valid, false otherwise.
+ */
+bool interface_ifinfo_valid(struct interface *iface);
+
 /**
  * Tests whether an interface supports a set of given time stamping modes.
  * @param iface  The interface of interest.
diff --git a/port.c b/port.c
index 871ad68..ca508a6 100644
--- a/port.c
+++ b/port.c
@@ -2726,6 +2726,10 @@ void port_link_status(void *ctx, int linkup, int 
ts_index)
p->link_status = link_state;
} else {
p->link_status = link_state | LINK_STATE_CHANGED;
+   /* Update Interface speed information on Link up*/
+if (linkup) {
+interface_get_ifinfo(p->iface);
+}
pr_notice("%s: link %s", p->log_name, linkup ? "up" : "down");
}
 
-- 
2.34.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 1/4] [Interface Rate TLV] function to support get interface speed via ethtool

2022-10-10 Thread SyncMonk Technologies
From: devasishsyncmonk 

When master and slave instance interacting with each other operating
at different interface speed, delay assymetry needs to be compensated
as described in G.8271 appendix V.

In this patch we are adding changes to get the interface speed using
ethtool.

v1: initial commit.
v2: updating comments and data types.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 sk.c | 71 
 sk.h | 20 +
 2 files changed, 91 insertions(+)

diff --git a/sk.c b/sk.c
index 80075be..8525603 100644
--- a/sk.c
+++ b/sk.c
@@ -205,6 +205,77 @@ failed:
return -1;
 }
 
+int sk_get_if_info(const char *name, struct sk_if_info *if_info)
+{
+#ifdef ETHTOOL_GLINKSETTINGS
+   struct ifreq ifr;
+   int fd, err;
+
+   struct {
+   struct ethtool_link_settings req;
+   /*
+* link_mode_data consists of supported[], advertising[],
+* lp_advertising[] with size up to 127 each.
+* The actual size is provided by the kernel.
+*/
+   __u32 link_mode_data[3 * 127];
+   } ecmd;
+
+   memset(, 0, sizeof(ifr));
+   memset(, 0, sizeof(ecmd));
+
+   fd = socket(AF_INET, SOCK_DGRAM, 0);
+   if (fd < 0) {
+   goto failed;
+   }
+
+   ecmd.req.cmd = ETHTOOL_GLINKSETTINGS;
+
+   strncpy(ifr.ifr_name, name, IFNAMSIZ - 1);
+   ifr.ifr_data = (char *) 
+
+   /* Handshake with kernel to determine number of words for link
+* mode bitmaps. When requested number of bitmap words is not
+* the one expected by kernel, the latter returns the integer
+* opposite of what it is expecting. We request length 0 below
+* (aka. invalid bitmap length) to get this info.
+*/
+   err = ioctl(fd, SIOCETHTOOL, );
+   if (err < 0) {
+   pr_err("ioctl SIOCETHTOOL failed: %m");
+   close(fd);
+   goto failed;
+   }
+
+   if (ecmd.req.link_mode_masks_nwords >= 0 ||
+   ecmd.req.cmd != ETHTOOL_GLINKSETTINGS) {
+   return 1;
+   }
+   ecmd.req.link_mode_masks_nwords = -ecmd.req.link_mode_masks_nwords;
+
+   err = ioctl(fd, SIOCETHTOOL, );
+   if (err < 0) {
+   pr_err("ioctl SIOCETHTOOL failed: %m");
+   close(fd);
+   goto failed;
+   }
+
+   close(fd);
+
+   /* copy the necessary data to sk_info */
+   memset(if_info, 0, sizeof(struct sk_if_info));
+   if_info->valid = 1;
+   if_info->speed = ecmd.req.speed;
+
+   return 0;
+failed:
+#endif
+   /* clear data and ensure it is not marked valid */
+   memset(if_info, 0, sizeof(struct sk_if_info));
+   return -1;
+}
+
+
 static int sk_interface_guidaddr(const char *name, unsigned char *guid)
 {
char file_name[64], buf[64], addr[8];
diff --git a/sk.h b/sk.h
index 486dbc4..ea19a8e 100644
--- a/sk.h
+++ b/sk.h
@@ -49,6 +49,17 @@ struct sk_ts_info {
unsigned int rx_filters;
 };
 
+/**
+ * Contains interface information returned by theGLINKSETTINGS ioctl.
+ * @valid:set to non-zero when the info struct contains valid data.
+ * @speed:interface speed.
+ */
+struct sk_if_info {
+   Boolean valid;
+   int speed;
+};
+
+
 /**
  * Obtains a socket suitable for use with sk_interface_index().
  * @return  An open socket on success, -1 otherwise.
@@ -78,6 +89,15 @@ int sk_general_init(int fd);
  */
 int sk_get_ts_info(const char *name, struct sk_ts_info *sk_info);
 
+/**
+ * Obtain supporte interface information
+ * @param name The name of the interface
+ * @param info  Struct containing obtained interface information.
+ * @return  zero on success, negative on failure.
+ */
+int sk_get_if_info(const char *name, struct sk_if_info *sk_info);
+
+
 /**
  * Obtain the MAC address of a network interface.
  * @param name  The name of the interface
-- 
2.34.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 3/4] [Interface Rate TLV] organization TLV support for interface rate

2022-10-10 Thread SyncMonk Technologies
From: devasishsyncmonk 

adding interface rate TLV as defined by ITU-T G.8275.2 Annex D to
enable master to communicate PTP port interface rate to slave.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 

-v1: initial commit
-v2: maintaining alphabetical sequence for the config.
---
 clock.c  |  7 +++
 clock.h  |  7 +++
 config.c |  1 +
 pdt.h|  1 +
 tlv.c|  1 +
 tlv.h| 15 +++
 6 files changed, 32 insertions(+)

diff --git a/clock.c b/clock.c
index 086b1a8..c6708e0 100644
--- a/clock.c
+++ b/clock.c
@@ -137,6 +137,7 @@ struct clock {
struct monitor *slave_event_monitor;
int step_window_counter;
int step_window;
+   bool iface_rate_tlv;
 };
 
 struct clock the_clock;
@@ -1106,6 +1107,7 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
c->utc_offset = config_get_int(config, NULL, "utc_offset");
c->time_source = config_get_int(config, NULL, "timeSource");
c->step_window = config_get_int(config, NULL, "step_window");
+   c->iface_rate_tlv = config_get_int(config, NULL, "interface_rate_tlv");
 
if (c->free_running) {
c->clkid = CLOCK_INVALID;
@@ -2083,6 +2085,11 @@ struct servo *clock_servo(struct clock *c)
return c->servo;
 }
 
+bool clock_interface_rate_tlv (struct clock *c)
+{
+   return c->iface_rate_tlv;
+}
+
 enum servo_state clock_servo_state(struct clock *c)
 {
return c->servo_state;
diff --git a/clock.h b/clock.h
index 0534f21..b393c3e 100644
--- a/clock.h
+++ b/clock.h
@@ -388,4 +388,11 @@ void clock_check_ts(struct clock *c, uint64_t ts);
  */
 double clock_rate_ratio(struct clock *c);
 
+/**
+ * Obtain interface rate tlv support configuration.
+ * @param c  The clock instance.
+ * @return   The interface_rate_supoort config true if supported, else false.
+ */
+bool clock_interface_rate_tlv(struct clock *c);
+
 #endif
diff --git a/config.c b/config.c
index e454c91..be19143 100644
--- a/config.c
+++ b/config.c
@@ -267,6 +267,7 @@ struct config_item config_tab[] = {
PORT_ITEM_INT("inhibit_delay_req", 0, 0, 1),
PORT_ITEM_INT("inhibit_multicast_service", 0, 0, 1),
GLOB_ITEM_INT("initial_delay", 0, 0, INT_MAX),
+   PORT_ITEM_INT("interface_rate_tlv", 0, 0, 1),
GLOB_ITEM_INT("kernel_leap", 1, 0, 1),
GLOB_ITEM_STR("leapfile", NULL),
PORT_ITEM_INT("logAnnounceInterval", 1, INT8_MIN, INT8_MAX),
diff --git a/pdt.h b/pdt.h
index e46b218..1ad23d4 100644
--- a/pdt.h
+++ b/pdt.h
@@ -39,6 +39,7 @@ typedef uint16_t  UInteger16;
 typedef int32_t   Integer32;
 typedef uint32_t  UInteger32;
 typedef int64_t   Integer64;
+typedef uint64_t  UInteger64;
 typedef uint8_t   Octet;
 
 #endif
diff --git a/tlv.c b/tlv.c
index 1c13460..35bee4f 100644
--- a/tlv.c
+++ b/tlv.c
@@ -35,6 +35,7 @@
(tlv->length < sizeof(struct type) - sizeof(struct TLV))
 
 uint8_t ieee8021_id[3] = { IEEE_802_1_COMMITTEE };
+uint8_t itu_t_id[3] = { ITU_T_COMMITTEE };
 
 static TAILQ_HEAD(tlv_pool, tlv_extra) tlv_pool =
TAILQ_HEAD_INITIALIZER(tlv_pool);
diff --git a/tlv.h b/tlv.h
index 8966696..1dfaac8 100644
--- a/tlv.h
+++ b/tlv.h
@@ -395,6 +395,21 @@ struct tlv_extra {
};
 };
 
+/* Organizationally Unique Identifiers */
+#define ITU_T_COMMITTEE 0x00, 0x19, 0xA7
+extern uint8_t itu_t_id[3];
+
+struct msg_interface_rate_tlv {
+   Enumeration16 type;
+   UInteger16length;
+   Octet id[3];
+   Octet subtype[3];
+   UInteger64interfaceBitPeriod;
+   UInteger16numberOfBitsBeforeTimestamp;
+   UInteger16numberOfBitsAfterTimestamp;
+} PACKED;
+
+
 /**
  * Allocates a new tlv_extra structure.
  * @return  Pointer to a new structure on success or NULL otherwise.
-- 
2.34.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH v3 3/3] Adding support for passing announce message from external source

2022-09-02 Thread SyncMonk Technologies
The announce message from the External source is passed by virtual port
for BMCA participation so that it becomes a selection source
along with other ports for linuxPTP.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Vipin Sharma 
Signed-off-by: Devasish Dey 

v2->v3:
 - no change.
v1->v2:
- amended commit message
---
 ts2phc_phc_pps_source.c | 23 +++
 ts2phc_phc_pps_source.h |  2 ++
 ts2phc_pps_sink.c   |  6 +-
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/ts2phc_phc_pps_source.c b/ts2phc_phc_pps_source.c
index 5f15e8e..0546913 100644
--- a/ts2phc_phc_pps_source.c
+++ b/ts2phc_phc_pps_source.c
@@ -14,10 +14,12 @@
 #include "print.h"
 #include "ts2phc_phc_pps_source.h"
 #include "ts2phc_pps_source_private.h"
+#include "ts2phc_vport.h"
 #include "util.h"
 
 struct ts2phc_phc_pps_source {
struct ts2phc_pps_source pps_source;
+   struct ts2phc_vport *vport;
clockid_t clkid;
int channel;
int fd;
@@ -71,6 +73,9 @@ static void ts2phc_phc_pps_source_destroy(struct 
ts2phc_pps_source *src)
pr_err(PTP_PEROUT_REQUEST_FAILED);
}
posix_clock_close(m->clkid);
+   if (m->vport) {
+   free(m->vport);
+   }
free(m);
 }
 
@@ -82,11 +87,21 @@ static int ts2phc_phc_pps_source_getppstime(struct 
ts2phc_pps_source *src,
return clock_gettime(s->clkid, ts);
 }
 
+int ts2phc_phc_pps_source_vport_transmit(struct ts2phc_pps_source *src,
+   struct timespec *ts)
+{
+   struct ts2phc_phc_pps_source *s =
+   container_of(src, struct ts2phc_phc_pps_source, pps_source);
+   return ts2phc_vport_tx_announce(s->vport);
+}
+
+
 struct ts2phc_pps_source *ts2phc_phc_pps_source_create(struct config *cfg,
   const char *dev)
 {
struct ts2phc_phc_pps_source *s;
int junk;
+   const char *iface_name;
 
s = calloc(1, sizeof(*s));
if (!s) {
@@ -95,6 +110,14 @@ struct ts2phc_pps_source 
*ts2phc_phc_pps_source_create(struct config *cfg,
s->pps_source.destroy = ts2phc_phc_pps_source_destroy;
s->pps_source.getppstime = ts2phc_phc_pps_source_getppstime;
 
+   iface_name = config_get_string(cfg, NULL, "vport_address");
+   if (iface_name && iface_name[0]) {
+   s->vport = ts2phc_vport_create(cfg);
+   if (!s->vport) {
+   pr_warning("Error in vport creation: %s\n", iface_name);
+   }
+   }
+
s->clkid = posix_clock_open(dev, );
if (s->clkid == CLOCK_INVALID) {
free(s);
diff --git a/ts2phc_phc_pps_source.h b/ts2phc_phc_pps_source.h
index c9ab54e..01c1d8d 100644
--- a/ts2phc_phc_pps_source.h
+++ b/ts2phc_phc_pps_source.h
@@ -11,4 +11,6 @@
 struct ts2phc_pps_source *ts2phc_phc_pps_source_create(struct config *cfg,
   const char *dev);
 
+int ts2phc_phc_pps_source_vport_transmit(struct ts2phc_pps_source *src,
+struct timespec *ts);
 #endif
diff --git a/ts2phc_pps_sink.c b/ts2phc_pps_sink.c
index 91bd7c9..6e6acc0 100644
--- a/ts2phc_pps_sink.c
+++ b/ts2phc_pps_sink.c
@@ -23,6 +23,7 @@
 #include "servo.h"
 #include "ts2phc_pps_sink.h"
 #include "ts2phc_pps_source.h"
+#include "ts2phc_phc_pps_source.h"
 #include "util.h"
 
 #define NS_PER_SEC 10LL
@@ -426,7 +427,10 @@ int ts2phc_pps_sink_poll(struct ts2phc_pps_source *src)
 
err = ts2phc_pps_source_getppstime(src, _ts.ts);
source_ts.valid = err ? false : true;
-
+   if (source_ts.valid) {
+   /* Send Announce and Sync Message on Virtual Port  */
+   ts2phc_phc_pps_source_vport_transmit(src, _ts.ts);
+   }
for (i = 0; i < ts2phc_n_sinks; i++) {
if (polling_array.pfd[i].revents & (POLLIN|POLLPRI)) {
ts2phc_pps_sink_event(polling_array.sink[i], source_ts);
-- 
2.25.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH v3 2/3] adding virtual port support for ts2phc

2022-09-02 Thread SyncMonk Technologies
Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Vipin Sharma 
Signed-off-by: Devasish Dey 

v2->v3:
- Using UDS interface for virtual PTP port support.
v1->v2:
- amended commit message
- updated ts2phc.8
---
 makefile   |   7 +-
 ts2phc.8   |  70 
 ts2phc_vport.c | 281 +
 ts2phc_vport.h |  28 +
 4 files changed, 383 insertions(+), 3 deletions(-)
 create mode 100644 ts2phc_vport.c
 create mode 100644 ts2phc_vport.h

diff --git a/makefile b/makefile
index 5295b60..cd15559 100644
--- a/makefile
+++ b/makefile
@@ -27,7 +27,8 @@ FILTERS   = filter.o mave.o mmedian.o
 SERVOS = linreg.o ntpshm.o nullf.o pi.o servo.o
 TRANSP = raw.o transport.o udp.o udp6.o uds.o
 TS2PHC = ts2phc.o lstab.o nmea.o serial.o sock.o ts2phc_generic_pps_source.o \
- ts2phc_nmea_pps_source.o ts2phc_phc_pps_source.o ts2phc_pps_sink.o 
ts2phc_pps_source.o
+ ts2phc_nmea_pps_source.o ts2phc_phc_pps_source.o ts2phc_pps_sink.o \
+ ts2phc_pps_source.o ts2phc_vport.o
 OBJ= bmc.o clock.o clockadj.o clockcheck.o config.o designated_fsm.o \
  e2e_tc.o fault.o $(FILTERS) fsm.o hash.o interface.o monitor.o msg.o phc.o \
  port.o port_signaling.o pqueue.o print.o ptp4l.o p2p_tc.o rtnl.o $(SERVOS) \
@@ -68,8 +69,8 @@ phc_ctl: phc_ctl.o phc.o sk.o util.o clockadj.o sysoff.o 
print.o version.o
 
 timemaster: phc.o print.o rtnl.o sk.o timemaster.o util.o version.o
 
-ts2phc: config.o clockadj.o hash.o interface.o phc.o print.o $(SERVOS) sk.o \
- $(TS2PHC) util.o version.o
+ts2phc: config.o clockadj.o hash.o msg.o tlv.o interface.o phc.o print.o 
$(SERVOS) sk.o \
+ $(TS2PHC) $(TRANSP) util.o version.o
 
 version.o: .version version.sh $(filter-out version.d,$(DEPEND))
 
diff --git a/ts2phc.8 b/ts2phc.8
index 690c462..4166766 100644
--- a/ts2phc.8
+++ b/ts2phc.8
@@ -145,6 +145,76 @@ by changing the clock frequency instead of stepping the 
clock. When
 set to 0.0, the servo will never step the clock except on start.
 The default is 0.0.
 .TP
+.B vport_address
+Specifies the address of the UNIX domain socket for communicating with the
+virtual PTP port to a PTP clock as defined in the G.8275 Annex B. The default
+is NULL
+.TP
+.B utc_offset
+The current offset between TAI and UTC.
+The default is 37.
+.TP
+.B transportSpecific
+The transport specific field. Must be in the range 0 to 255.
+The default is 0.
+.TP
+.B domainNumber
+The domain attribute of the local clock.
+The default is 0.
+.TP
+.B logSyncInterval
+The mean time interval between Sync messages. A shorter interval may improve
+accuracy of the local clock. It's specified as a power of two in seconds.
+The default is 0 (1 second).
+.TP
+.B logAnnounceInterval
+The mean time interval between Announce messages. A shorter interval makes
+ptp4l react faster to the changes in the client/server hierarchy. The interval
+should be the same in the whole domain. It's specified as a power of two in
+seconds.
+.TP
+.B priorty1
+The priority1 attribute of the local clock. It is used in the PTP server
+selection algorithm, lower values take precedence. Must be in the range 0 to
+255.
+The default is 128.
+.TP
+.B priorty2
+The priority2 attribute of the local clock. It is used in the PTP server
+selection algorithm, lower values take precedence. Must be in the range 0 to
+255.
+The default is 128.
+.TP
+.B timeSource
+The time source is a single byte code that gives an idea of the kind
+of local clock in use. The value is purely informational, having no
+effect on the outcome of the Best Master Clock algorithm, and is
+advertised when the clock becomes grand master.
+.TP
+.B clockClass
+The clockClass attribute of the local clock. It denotes the traceability of the
+time distributed by the grandmaster clock.
+The default is 248.
+.TP
+.B clockAccuracy
+The clockAccuracy attribute of the local clock. It is used in the PTP server
+selection algorithm.
+The default is 0xFE.
+.TP
+.B clockIdenitity
+The clockIdentity attribute of the local clock.
+The clockIdentity is an 8-octet array and should in this configuration be
+written in textual form, see default. It should be unique since it is used to
+identify the specific clock.
+If default is used or if not set at all, the clockIdentity will be automtically
+generated.
+The default is "00..00"
+.TP
+.B offsetScaledLogVariance
+The offsetScaledLogVariance attribute of the local clock. It characterizes the
+stability of the clock.
+The default is 0x.
+.TP
 .B ts2phc.nmea_remote_host, ts2phc.nmea_remote_port
 Specifies the remote host providing ToD information when using the
 "nmea" PPS signal source.  Note that if these two options are both
diff --git a/ts2phc_vport.c b/ts2phc_vport.c
new file mode 100644
index 000..539c48f
--- /dev/null
+++ b/ts2phc_vport.c
@@ -0,0 +1,281 @@
+/**
+ * @file ts2phc_vport.c
+ * @note Copyright (C) 2022 SyncMonk Technologies 
+ * @note SPDX-License-Identifier: GPL-2.0+
+ *

[Linuxptp-devel] [PATCH v3 1/3] Adding virtual PTP port support

2022-09-02 Thread SyncMonk Technologies
Virtual PTP port is for unidirectional tranfer of phase/time interface
on a PTP clock.
When associated with an external input signal, a virtual PTP port allows
this external interface to participate in the PTP protocol.
As an input, this external port can participate in the source selection
with an associated virtual Erbest using the associated virtual PTP port.

As per G.8275 (Annex-B) including virtual PTP ports on a PTP clock. This
virtual port will be used to support Assisted Partial Timing Support
(APTS), Inter Working Function (IWF)  between different clock_domains.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Vipin Sharma 
Signed-off-by: Devasish Dey 

v2->v3:
- Using UDS sockets for virtual PTP ports.
v1->v2:
- Amended the commit message.
---
 clock.c | 58 -
 config.c|  2 ++
 configs/default.cfg |  2 +-
 port.c  | 10 ++--
 ptp4l.8 |  5 
 sk.c|  1 +
 transport.c |  1 +
 transport.h |  1 +
 uds.c   | 33 +++---
 util.c  |  2 ++
 10 files changed, 102 insertions(+), 13 deletions(-)

diff --git a/clock.c b/clock.c
index d37bb87..eba0833 100644
--- a/clock.c
+++ b/clock.c
@@ -97,9 +97,10 @@ struct clock {
LIST_HEAD(ports_head, port) ports;
struct port *uds_rw_port;
struct port *uds_ro_port;
+   struct port *vport_port;
struct pollfd *pollfd;
int pollfd_valid;
-   int nports; /* does not include the two UDS ports */
+   int nports; /* does not include the two UDS ports + 1 Virtual Port */
int last_port_number;
int sde;
int free_running;
@@ -133,6 +134,7 @@ struct clock {
struct clockcheck *sanity_check;
struct interface *uds_rw_if;
struct interface *uds_ro_if;
+   struct interface *vport_if;
LIST_HEAD(clock_subscribers_head, clock_subscriber) subscribers;
struct monitor *slave_event_monitor;
int step_window_counter;
@@ -272,6 +274,7 @@ void clock_destroy(struct clock *c)
 
interface_destroy(c->uds_rw_if);
interface_destroy(c->uds_ro_if);
+   interface_destroy(c->vport_if);
clock_flush_subscriptions(c);
LIST_FOREACH_SAFE(p, >ports, list, tmp) {
clock_remove_port(c, p);
@@ -901,6 +904,7 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
int phc_index, conf_phc_index, required_modes = 0;
struct clock *c = _clock;
const char *uds_ifname;
+   const char *vport_ifname;
struct port *p;
unsigned char oui[OUI_LEN];
struct interface *iface;
@@ -1094,6 +1098,32 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
return NULL;
}
 
+   /* Configure the Virtual Port. */
+   vport_ifname = config_get_string(config, NULL, "vport_address");
+   if (vport_ifname && vport_ifname[0]) {
+   c->vport_if = interface_create(vport_ifname);
+   if (config_set_section_int(config, interface_name(c->vport_if),
+  "announceReceiptTimeout", 2)) {
+   return NULL;
+   }
+   if (config_set_section_int(config,
+  interface_name(c->vport_if),
+  "delay_mechanism",
+  DM_NO_MECHANISM)) {
+   return NULL;
+   }
+   if (config_set_section_int(config,
+  interface_name(c->vport_if),
+  "network_transport",
+  TRANS_VPORT)) {
+   return NULL;
+   }
+   if (config_set_section_int(config, interface_name(c->vport_if),
+  "delay_filter_length", 1)) {
+   return NULL;
+   }
+   }
+
c->config = config;
c->free_running = config_get_int(config, NULL, "free_running");
c->freq_est_interval = config_get_int(config, NULL, 
"freq_est_interval");
@@ -1231,6 +1261,17 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
pr_err("failed to open the UDS-RO port");
return NULL;
}
+
+   if (c->vport_if) {
+   c->vport_port = port_open(phc_device, phc_index, timestamping, 
0,
+  c->vport_if, c);
+   if (!c->vport_port) {
+   pr_err("failed to open the Virtual port");
+   return NULL;
+   }
+   LIST_INSERT_HEAD(>ports, c->vport_port, list);
+   c->nports++;
+   }
clock_fda_changed(c);
 

[Linuxptp-devel] [PATCH v2 1/4] Adding virtual PTP port support

2022-09-01 Thread SyncMonk Technologies
Virtual PTP port is for unidirectional tranfer of phase/time interface
on a PTP clock.
When associated with an external input signal, a virtual PTP port allows
this external interface to participate in the PTP protocol.
As an input, this external port can participate in the source selection
with an associated virtual Erbest using the associated virtual PTP port.

As per G.8275 (Annex-B) including virtual PTP ports on a PTP clock. This
virtual port will be used to support Assisted Partial Timing Support
(APTS), Inter Working Function (IWF)  between different clock_domains.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Vipin Sharma 
Signed-off-by: Devasish Dey 

v1->v2:
- Amended the commit message.
---
 makefile |   2 +-
 vport.c  | 140 +++
 vport.h  |  20 
 3 files changed, 161 insertions(+), 1 deletion(-)
 create mode 100644 vport.c
 create mode 100644 vport.h

diff --git a/makefile b/makefile
index 5295b60..7d8c0d3 100644
--- a/makefile
+++ b/makefile
@@ -25,7 +25,7 @@ LDLIBS= -lm -lrt -pthread $(EXTRA_LDFLAGS)
 PRG= ptp4l hwstamp_ctl nsm phc2sys phc_ctl pmc timemaster ts2phc
 FILTERS= filter.o mave.o mmedian.o
 SERVOS = linreg.o ntpshm.o nullf.o pi.o servo.o
-TRANSP = raw.o transport.o udp.o udp6.o uds.o
+TRANSP = raw.o transport.o udp.o udp6.o uds.o vport.o
 TS2PHC = ts2phc.o lstab.o nmea.o serial.o sock.o ts2phc_generic_pps_source.o \
  ts2phc_nmea_pps_source.o ts2phc_phc_pps_source.o ts2phc_pps_sink.o 
ts2phc_pps_source.o
 OBJ= bmc.o clock.o clockadj.o clockcheck.o config.o designated_fsm.o \
diff --git a/vport.c b/vport.c
new file mode 100644
index 000..89d4105
--- /dev/null
+++ b/vport.c
@@ -0,0 +1,140 @@
+/**
+ * @file vport.c
+ * @note Copyright (C) 2022 SyncMonk Technologies 
+ * @note SPDX-License-Identifier: GPL-2.0+
+ *
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "address.h"
+#include "contain.h"
+#include "print.h"
+#include "transport_private.h"
+#include "vport.h"
+
+#define VPORT_FILEMODE (0660) /*0660*/
+
+struct vport {
+   struct transport t;
+   struct address address;
+};
+
+static int vport_close(struct transport *t, struct fdarray *fda)
+{
+   struct sockaddr_un sa;
+   socklen_t len = sizeof(sa);
+
+   if (!getsockname(fda->fd[FD_GENERAL],
+   (struct sockaddr *) , ) &&
+   sa.sun_family == AF_LOCAL) {
+   unlink(sa.sun_path);
+   }
+
+   close(fda->fd[FD_GENERAL]);
+   return 0;
+}
+
+static int vport_open(struct transport *t,
+ struct interface *iface,
+ struct fdarray *fda,
+ enum timestamp_type tt)
+{
+   char *vport_path = config_get_string(t->cfg, NULL, "vport_address");
+   struct vport *vport = container_of(t, struct vport, t);
+   const char *name = interface_name(iface);
+   struct sockaddr_un sa;
+   int fd, err;
+
+   fd = socket(AF_LOCAL, SOCK_DGRAM, 0);
+   if (fd < 0) {
+   pr_err("vport: failed to create socket: %m");
+   return -1;
+   }
+   memset(, 0, sizeof(sa));
+   sa.sun_family = AF_LOCAL;
+   strncpy(sa.sun_path, name, sizeof(sa.sun_path) - 1);
+
+   unlink(name);
+
+   err = bind(fd, (struct sockaddr *) , sizeof(sa));
+   if (err < 0) {
+   pr_err("vport: bind failed: %m");
+   close(fd);
+   return -1;
+   }
+
+   /* For client use, pre load the server path. */
+   memset(, 0, sizeof(sa));
+   sa.sun_family = AF_LOCAL;
+   strncpy(sa.sun_path, vport_path, sizeof(sa.sun_path) - 1);
+   vport->address.sun = sa;
+   vport->address.len = sizeof(sa);
+
+   chmod(name, VPORT_FILEMODE);
+   fda->fd[FD_EVENT] = -1;
+   fda->fd[FD_GENERAL] = fd;
+   return 0;
+}
+
+static int vport_recv(struct transport *t, int fd, void *buf, int buflen,
+ struct address *addr, struct hw_timestamp *hwts)
+{
+   int cnt;
+   struct vport *vport = container_of(t, struct vport, t);
+
+   addr->len = sizeof(addr->sun);
+   cnt = recvfrom(fd, buf, buflen, 0, >sa, >len);
+   if (cnt <= 0) {
+   pr_err("vport: recvfrom failed: %m");
+   return cnt;
+   }
+   vport->address = *addr;
+   return cnt;
+}
+
+static int vport_send(struct transport *t, struct fdarray *fda,
+ enum transport_event event, int peer, void *buf,
+ int buflen, struct address *addr,
+ struct hw_timestamp *hwts)
+{
+   int cnt, fd = fda->fd[FD_GENERAL];
+   struct vport *vport = container_of(t, struct vport, t);
+
+   if (!addr)
+   addr = >

[Linuxptp-devel] [PATCH v2 2/4] Integrating virtual PTP ports with ptp4l

2022-09-01 Thread SyncMonk Technologies
When associated with an external input signal,
a virtual PTP port allows this external interface to participate
in the PTP protocol.
As an input, this external port can participate in the source selection
with an associated virtual Erbest using the associated virtual PTP port.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Vipin Sharma 
Signed-off-by: Devasish Dey 

v1->v2:
- updated ptp4l.8
- amended commit message.
---
 clock.c | 59 -
 config.c|  2 ++
 interface.c |  7 +++
 interface.h |  6 ++
 port.c  | 10 +++--
 ptp4l.8 |  5 +
 sk.c|  1 +
 transport.c |  4 
 transport.h |  1 +
 util.c  |  2 ++
 10 files changed, 94 insertions(+), 3 deletions(-)

diff --git a/clock.c b/clock.c
index d37bb87..314eebf 100644
--- a/clock.c
+++ b/clock.c
@@ -43,6 +43,7 @@
 #include "tlv.h"
 #include "tsproc.h"
 #include "uds.h"
+#include "vport.h"
 #include "util.h"
 
 #define N_CLOCK_PFD (N_POLLFD + 1) /* one extra per port, for the fault timer 
*/
@@ -97,9 +98,10 @@ struct clock {
LIST_HEAD(ports_head, port) ports;
struct port *uds_rw_port;
struct port *uds_ro_port;
+   struct port *vport_port;
struct pollfd *pollfd;
int pollfd_valid;
-   int nports; /* does not include the two UDS ports */
+   int nports; /* does not include the two UDS ports + 1 Virtual Port */
int last_port_number;
int sde;
int free_running;
@@ -133,6 +135,7 @@ struct clock {
struct clockcheck *sanity_check;
struct interface *uds_rw_if;
struct interface *uds_ro_if;
+   struct interface *vport_if;
LIST_HEAD(clock_subscribers_head, clock_subscriber) subscribers;
struct monitor *slave_event_monitor;
int step_window_counter;
@@ -272,6 +275,7 @@ void clock_destroy(struct clock *c)
 
interface_destroy(c->uds_rw_if);
interface_destroy(c->uds_ro_if);
+   interface_destroy(c->vport_if);
clock_flush_subscriptions(c);
LIST_FOREACH_SAFE(p, >ports, list, tmp) {
clock_remove_port(c, p);
@@ -901,6 +905,7 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
int phc_index, conf_phc_index, required_modes = 0;
struct clock *c = _clock;
const char *uds_ifname;
+   const char *vport_ifname;
struct port *p;
unsigned char oui[OUI_LEN];
struct interface *iface;
@@ -1094,6 +1099,32 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
return NULL;
}
 
+   /* Configure the Virtual Port. */
+   vport_ifname = config_get_string(config, NULL, "vport_address");
+   if (vport_ifname && vport_ifname[0]) {
+   c->vport_if = interface_create(vport_ifname);
+   if (config_set_section_int(config, interface_name(c->vport_if),
+  "announceReceiptTimeout", 2)) {
+   return NULL;
+   }
+   if (config_set_section_int(config,
+  interface_name(c->vport_if),
+  "delay_mechanism",
+  DM_NO_MECHANISM)) {
+   return NULL;
+   }
+   if (config_set_section_int(config,
+  interface_name(c->vport_if),
+  "network_transport",
+  TRANS_VPORT)) {
+   return NULL;
+   }
+   if (config_set_section_int(config, interface_name(c->vport_if),
+  "delay_filter_length", 1)) {
+   return NULL;
+   }
+   }
+
c->config = config;
c->free_running = config_get_int(config, NULL, "free_running");
c->freq_est_interval = config_get_int(config, NULL, 
"freq_est_interval");
@@ -1231,6 +1262,17 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
pr_err("failed to open the UDS-RO port");
return NULL;
}
+
+   if (c->vport_if) {
+   c->vport_port = port_open(phc_device, phc_index, timestamping, 
0,
+  c->vport_if, c);
+   if (!c->vport_port) {
+   pr_err("failed to open the Virtual port");
+   return NULL;
+   }
+   LIST_INSERT_HEAD(>ports, c->vport_port, list);
+   c->nports++;
+   }
clock_fda_changed(c);
 
c->slave_event_monitor = monitor_create(config, c->uds_rw_port);
@@ -1254,6 +1296,9 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
}
port_dispatch(c->uds_rw_port, EV_INITIALIZE, 0);

[Linuxptp-devel] [PATCH v2 4/4] Adding support for passing announce message from external source

2022-09-01 Thread SyncMonk Technologies
The announce message from the External source is passed by virtual port
for BMCA participation so that it becomes a selection source
along with other ports for linuxPTP.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Vipin Sharma 
Signed-off-by: Devasish Dey 

v1->v2:
- amended commit message
---
 ts2phc_phc_pps_source.c | 23 +++
 ts2phc_phc_pps_source.h |  2 ++
 ts2phc_pps_sink.c   |  6 +-
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/ts2phc_phc_pps_source.c b/ts2phc_phc_pps_source.c
index 5f15e8e..0546913 100644
--- a/ts2phc_phc_pps_source.c
+++ b/ts2phc_phc_pps_source.c
@@ -14,10 +14,12 @@
 #include "print.h"
 #include "ts2phc_phc_pps_source.h"
 #include "ts2phc_pps_source_private.h"
+#include "ts2phc_vport.h"
 #include "util.h"
 
 struct ts2phc_phc_pps_source {
struct ts2phc_pps_source pps_source;
+   struct ts2phc_vport *vport;
clockid_t clkid;
int channel;
int fd;
@@ -71,6 +73,9 @@ static void ts2phc_phc_pps_source_destroy(struct 
ts2phc_pps_source *src)
pr_err(PTP_PEROUT_REQUEST_FAILED);
}
posix_clock_close(m->clkid);
+   if (m->vport) {
+   free(m->vport);
+   }
free(m);
 }
 
@@ -82,11 +87,21 @@ static int ts2phc_phc_pps_source_getppstime(struct 
ts2phc_pps_source *src,
return clock_gettime(s->clkid, ts);
 }
 
+int ts2phc_phc_pps_source_vport_transmit(struct ts2phc_pps_source *src,
+   struct timespec *ts)
+{
+   struct ts2phc_phc_pps_source *s =
+   container_of(src, struct ts2phc_phc_pps_source, pps_source);
+   return ts2phc_vport_tx_announce(s->vport);
+}
+
+
 struct ts2phc_pps_source *ts2phc_phc_pps_source_create(struct config *cfg,
   const char *dev)
 {
struct ts2phc_phc_pps_source *s;
int junk;
+   const char *iface_name;
 
s = calloc(1, sizeof(*s));
if (!s) {
@@ -95,6 +110,14 @@ struct ts2phc_pps_source 
*ts2phc_phc_pps_source_create(struct config *cfg,
s->pps_source.destroy = ts2phc_phc_pps_source_destroy;
s->pps_source.getppstime = ts2phc_phc_pps_source_getppstime;
 
+   iface_name = config_get_string(cfg, NULL, "vport_address");
+   if (iface_name && iface_name[0]) {
+   s->vport = ts2phc_vport_create(cfg);
+   if (!s->vport) {
+   pr_warning("Error in vport creation: %s\n", iface_name);
+   }
+   }
+
s->clkid = posix_clock_open(dev, );
if (s->clkid == CLOCK_INVALID) {
free(s);
diff --git a/ts2phc_phc_pps_source.h b/ts2phc_phc_pps_source.h
index c9ab54e..01c1d8d 100644
--- a/ts2phc_phc_pps_source.h
+++ b/ts2phc_phc_pps_source.h
@@ -11,4 +11,6 @@
 struct ts2phc_pps_source *ts2phc_phc_pps_source_create(struct config *cfg,
   const char *dev);
 
+int ts2phc_phc_pps_source_vport_transmit(struct ts2phc_pps_source *src,
+struct timespec *ts);
 #endif
diff --git a/ts2phc_pps_sink.c b/ts2phc_pps_sink.c
index 91bd7c9..6e6acc0 100644
--- a/ts2phc_pps_sink.c
+++ b/ts2phc_pps_sink.c
@@ -23,6 +23,7 @@
 #include "servo.h"
 #include "ts2phc_pps_sink.h"
 #include "ts2phc_pps_source.h"
+#include "ts2phc_phc_pps_source.h"
 #include "util.h"
 
 #define NS_PER_SEC 10LL
@@ -426,7 +427,10 @@ int ts2phc_pps_sink_poll(struct ts2phc_pps_source *src)
 
err = ts2phc_pps_source_getppstime(src, _ts.ts);
source_ts.valid = err ? false : true;
-
+   if (source_ts.valid) {
+   /* Send Announce and Sync Message on Virtual Port  */
+   ts2phc_phc_pps_source_vport_transmit(src, _ts.ts);
+   }
for (i = 0; i < ts2phc_n_sinks; i++) {
if (polling_array.pfd[i].revents & (POLLIN|POLLPRI)) {
ts2phc_pps_sink_event(polling_array.sink[i], source_ts);
-- 
2.25.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH v2 3/4] adding virtual port support to ts2phc

2022-09-01 Thread SyncMonk Technologies
Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Vipin Sharma 
Signed-off-by: Devasish Dey 

v1->v2:
- amended commit message
- updated ts2phc.8
---
 makefile   |   6 +-
 ts2phc.8   |  70 
 ts2phc_vport.c | 282 +
 ts2phc_vport.h |  28 +
 4 files changed, 383 insertions(+), 3 deletions(-)
 create mode 100644 ts2phc_vport.c
 create mode 100644 ts2phc_vport.h

diff --git a/makefile b/makefile
index 7d8c0d3..3631f1d 100644
--- a/makefile
+++ b/makefile
@@ -27,7 +27,7 @@ FILTERS   = filter.o mave.o mmedian.o
 SERVOS = linreg.o ntpshm.o nullf.o pi.o servo.o
 TRANSP = raw.o transport.o udp.o udp6.o uds.o vport.o
 TS2PHC = ts2phc.o lstab.o nmea.o serial.o sock.o ts2phc_generic_pps_source.o \
- ts2phc_nmea_pps_source.o ts2phc_phc_pps_source.o ts2phc_pps_sink.o 
ts2phc_pps_source.o
+ ts2phc_nmea_pps_source.o ts2phc_phc_pps_source.o ts2phc_pps_sink.o 
ts2phc_pps_source.o ts2phc_vport.o
 OBJ= bmc.o clock.o clockadj.o clockcheck.o config.o designated_fsm.o \
  e2e_tc.o fault.o $(FILTERS) fsm.o hash.o interface.o monitor.o msg.o phc.o \
  port.o port_signaling.o pqueue.o print.o ptp4l.o p2p_tc.o rtnl.o $(SERVOS) \
@@ -68,8 +68,8 @@ phc_ctl: phc_ctl.o phc.o sk.o util.o clockadj.o sysoff.o 
print.o version.o
 
 timemaster: phc.o print.o rtnl.o sk.o timemaster.o util.o version.o
 
-ts2phc: config.o clockadj.o hash.o interface.o phc.o print.o $(SERVOS) sk.o \
- $(TS2PHC) util.o version.o
+ts2phc: config.o clockadj.o hash.o msg.o tlv.o interface.o phc.o print.o 
$(SERVOS) sk.o \
+ $(TS2PHC) $(TRANSP) util.o version.o
 
 version.o: .version version.sh $(filter-out version.d,$(DEPEND))
 
diff --git a/ts2phc.8 b/ts2phc.8
index 690c462..4166766 100644
--- a/ts2phc.8
+++ b/ts2phc.8
@@ -145,6 +145,76 @@ by changing the clock frequency instead of stepping the 
clock. When
 set to 0.0, the servo will never step the clock except on start.
 The default is 0.0.
 .TP
+.B vport_address
+Specifies the address of the UNIX domain socket for communicating with the
+virtual PTP port to a PTP clock as defined in the G.8275 Annex B. The default
+is NULL
+.TP
+.B utc_offset
+The current offset between TAI and UTC.
+The default is 37.
+.TP
+.B transportSpecific
+The transport specific field. Must be in the range 0 to 255.
+The default is 0.
+.TP
+.B domainNumber
+The domain attribute of the local clock.
+The default is 0.
+.TP
+.B logSyncInterval
+The mean time interval between Sync messages. A shorter interval may improve
+accuracy of the local clock. It's specified as a power of two in seconds.
+The default is 0 (1 second).
+.TP
+.B logAnnounceInterval
+The mean time interval between Announce messages. A shorter interval makes
+ptp4l react faster to the changes in the client/server hierarchy. The interval
+should be the same in the whole domain. It's specified as a power of two in
+seconds.
+.TP
+.B priorty1
+The priority1 attribute of the local clock. It is used in the PTP server
+selection algorithm, lower values take precedence. Must be in the range 0 to
+255.
+The default is 128.
+.TP
+.B priorty2
+The priority2 attribute of the local clock. It is used in the PTP server
+selection algorithm, lower values take precedence. Must be in the range 0 to
+255.
+The default is 128.
+.TP
+.B timeSource
+The time source is a single byte code that gives an idea of the kind
+of local clock in use. The value is purely informational, having no
+effect on the outcome of the Best Master Clock algorithm, and is
+advertised when the clock becomes grand master.
+.TP
+.B clockClass
+The clockClass attribute of the local clock. It denotes the traceability of the
+time distributed by the grandmaster clock.
+The default is 248.
+.TP
+.B clockAccuracy
+The clockAccuracy attribute of the local clock. It is used in the PTP server
+selection algorithm.
+The default is 0xFE.
+.TP
+.B clockIdenitity
+The clockIdentity attribute of the local clock.
+The clockIdentity is an 8-octet array and should in this configuration be
+written in textual form, see default. It should be unique since it is used to
+identify the specific clock.
+If default is used or if not set at all, the clockIdentity will be automtically
+generated.
+The default is "00..00"
+.TP
+.B offsetScaledLogVariance
+The offsetScaledLogVariance attribute of the local clock. It characterizes the
+stability of the clock.
+The default is 0x.
+.TP
 .B ts2phc.nmea_remote_host, ts2phc.nmea_remote_port
 Specifies the remote host providing ToD information when using the
 "nmea" PPS signal source.  Note that if these two options are both
diff --git a/ts2phc_vport.c b/ts2phc_vport.c
new file mode 100644
index 000..ae9cbe9
--- /dev/null
+++ b/ts2phc_vport.c
@@ -0,0 +1,282 @@
+/**
+ * @file ts2phc_vport.c
+ * @note Copyright (C) 2022 SyncMonk Technologies 
+ * @note SPDX-License-Identifier: GPL-2.0+
+ *
+ */
+#include 
+#include 
+
+#include "address.h"
+#include &q

[Linuxptp-devel] [PATCH 3/4] APTS support

2022-08-24 Thread SyncMonk Technologies
Adding virtual port support for ts2phc.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Vipin Sharma 
Signed-off-by: Devasish Dey 
---
 makefile   |   6 +-
 ts2phc_vport.c | 282 +
 ts2phc_vport.h |  28 +
 3 files changed, 313 insertions(+), 3 deletions(-)
 create mode 100644 ts2phc_vport.c
 create mode 100644 ts2phc_vport.h

diff --git a/makefile b/makefile
index 7d8c0d3..3631f1d 100644
--- a/makefile
+++ b/makefile
@@ -27,7 +27,7 @@ FILTERS   = filter.o mave.o mmedian.o
 SERVOS = linreg.o ntpshm.o nullf.o pi.o servo.o
 TRANSP = raw.o transport.o udp.o udp6.o uds.o vport.o
 TS2PHC = ts2phc.o lstab.o nmea.o serial.o sock.o ts2phc_generic_pps_source.o \
- ts2phc_nmea_pps_source.o ts2phc_phc_pps_source.o ts2phc_pps_sink.o 
ts2phc_pps_source.o
+ ts2phc_nmea_pps_source.o ts2phc_phc_pps_source.o ts2phc_pps_sink.o 
ts2phc_pps_source.o ts2phc_vport.o
 OBJ= bmc.o clock.o clockadj.o clockcheck.o config.o designated_fsm.o \
  e2e_tc.o fault.o $(FILTERS) fsm.o hash.o interface.o monitor.o msg.o phc.o \
  port.o port_signaling.o pqueue.o print.o ptp4l.o p2p_tc.o rtnl.o $(SERVOS) \
@@ -68,8 +68,8 @@ phc_ctl: phc_ctl.o phc.o sk.o util.o clockadj.o sysoff.o 
print.o version.o
 
 timemaster: phc.o print.o rtnl.o sk.o timemaster.o util.o version.o
 
-ts2phc: config.o clockadj.o hash.o interface.o phc.o print.o $(SERVOS) sk.o \
- $(TS2PHC) util.o version.o
+ts2phc: config.o clockadj.o hash.o msg.o tlv.o interface.o phc.o print.o 
$(SERVOS) sk.o \
+ $(TS2PHC) $(TRANSP) util.o version.o
 
 version.o: .version version.sh $(filter-out version.d,$(DEPEND))
 
diff --git a/ts2phc_vport.c b/ts2phc_vport.c
new file mode 100644
index 000..ae9cbe9
--- /dev/null
+++ b/ts2phc_vport.c
@@ -0,0 +1,282 @@
+/**
+ * @file ts2phc_vport.c
+ * @note Copyright (C) 2022 SyncMonk Technologies 
+ * @note SPDX-License-Identifier: GPL-2.0+
+ *
+ */
+#include 
+#include 
+
+#include "address.h"
+#include "ts2phc_vport.h"
+#include "print.h"
+#include "port.h"
+#include "transport.h"
+
+#define RECORDS_PER_MESSAGE 1
+
+struct ts2phc_vport_message {
+   struct ptp_message *msg;
+   int records_per_msg;
+   int count;
+};
+
+struct ts2phc_vport {
+   struct fdarray fda;
+   struct transport *trp;
+   struct interface *iface;
+   struct ts2phc_vport_message announce;
+   struct ts2phc_vport_message sync;
+   struct {
+   UInteger16 announce;
+   UInteger16 sync;
+   } seqnum;
+   struct PortIdentity portIdentity;
+   Integer16 utcOffset;
+   UInteger8 priority1;
+   struct ClockQuality clockQuality;
+   UInteger8 priority2;
+   struct ClockIdentity clockIdentity;
+   UInteger8 transportSpecific;
+   UInteger8 domainNumber;
+   UInteger8 flags;
+   Integer8 logAnnounceInterval;
+   Integer8 logSyncInterval;
+   Enumeration8 timeSource;
+};
+
+static bool ts2phc_vport_active(struct ts2phc_vport *ts2phc_vport)
+{
+   return ts2phc_vport->trp ? true : false;
+}
+
+static int ts2phc_vport_forward(struct ts2phc_vport *port, struct ptp_message 
*msg)
+{
+   int cnt;
+   if (msg_pre_send(msg)) {
+   return -1;
+   }
+   cnt = transport_sendto(port->trp, >fda, TRANS_GENERAL, msg);
+   if (cnt <= 0) {
+   pr_debug("failed to send message to ts2phc_vport: ");
+   }
+
+   msg->header.sequenceId++;
+   return 0;
+}
+
+static int ts2phc_vport_init_announce(struct ts2phc_vport *p,
+ struct address address)
+{
+
+   struct ptp_message *msg;
+
+   msg = msg_allocate();
+   if (!msg) {
+   return -1;
+   }
+
+   msg->hwts.type = TS_ONESTEP;
+   msg->header.tsmt   = ANNOUNCE | p->transportSpecific;
+   msg->header.ver= PTP_VERSION;
+   msg->header.messageLength  = sizeof(struct announce_msg);
+   msg->header.domainNumber   = p->domainNumber;
+   msg->header.sourcePortIdentity = p->portIdentity;
+   msg->header.sequenceId = p->seqnum.announce++;
+   msg->header.control= CTL_OTHER;
+   msg->header.logMessageInterval = p->logAnnounceInterval;
+   msg->header.flagField[1]   = p->flags | PTP_TIMESCALE;
+
+   msg->announce.currentUtcOffset= p->utcOffset;
+   msg->announce.grandmasterPriority1= p->priority1;
+   msg->announce.grandmasterClockQuality = p->clockQuality;
+   msg->announce.grandmasterPriority2= p->priority2;
+   msg->announce.grandmasterIdentity = p->clockIdentity;
+   msg->announce.stepsRemoved= 0;
+   msg->announce.timeSource  = p->timeSource;
+   msg->address = address;
+
+   p->announce.msg 

[Linuxptp-devel] [PATCH 2/4] APTS support

2022-08-24 Thread SyncMonk Technologies
Adding virtual port support to ptp4l

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Vipin Sharma 
Signed-off-by: Devasish Dey 
---
 clock.c | 59 -
 config.c|  2 ++
 interface.c |  7 +++
 interface.h |  6 ++
 port.c  | 10 +++--
 ptp4l.8 |  4 
 sk.c|  1 +
 transport.c |  4 
 transport.h |  1 +
 util.c  |  2 ++
 10 files changed, 93 insertions(+), 3 deletions(-)

diff --git a/clock.c b/clock.c
index d37bb87..314eebf 100644
--- a/clock.c
+++ b/clock.c
@@ -43,6 +43,7 @@
 #include "tlv.h"
 #include "tsproc.h"
 #include "uds.h"
+#include "vport.h"
 #include "util.h"
 
 #define N_CLOCK_PFD (N_POLLFD + 1) /* one extra per port, for the fault timer 
*/
@@ -97,9 +98,10 @@ struct clock {
LIST_HEAD(ports_head, port) ports;
struct port *uds_rw_port;
struct port *uds_ro_port;
+   struct port *vport_port;
struct pollfd *pollfd;
int pollfd_valid;
-   int nports; /* does not include the two UDS ports */
+   int nports; /* does not include the two UDS ports + 1 Virtual Port */
int last_port_number;
int sde;
int free_running;
@@ -133,6 +135,7 @@ struct clock {
struct clockcheck *sanity_check;
struct interface *uds_rw_if;
struct interface *uds_ro_if;
+   struct interface *vport_if;
LIST_HEAD(clock_subscribers_head, clock_subscriber) subscribers;
struct monitor *slave_event_monitor;
int step_window_counter;
@@ -272,6 +275,7 @@ void clock_destroy(struct clock *c)
 
interface_destroy(c->uds_rw_if);
interface_destroy(c->uds_ro_if);
+   interface_destroy(c->vport_if);
clock_flush_subscriptions(c);
LIST_FOREACH_SAFE(p, >ports, list, tmp) {
clock_remove_port(c, p);
@@ -901,6 +905,7 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
int phc_index, conf_phc_index, required_modes = 0;
struct clock *c = _clock;
const char *uds_ifname;
+   const char *vport_ifname;
struct port *p;
unsigned char oui[OUI_LEN];
struct interface *iface;
@@ -1094,6 +1099,32 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
return NULL;
}
 
+   /* Configure the Virtual Port. */
+   vport_ifname = config_get_string(config, NULL, "vport_address");
+   if (vport_ifname && vport_ifname[0]) {
+   c->vport_if = interface_create(vport_ifname);
+   if (config_set_section_int(config, interface_name(c->vport_if),
+  "announceReceiptTimeout", 2)) {
+   return NULL;
+   }
+   if (config_set_section_int(config,
+  interface_name(c->vport_if),
+  "delay_mechanism",
+  DM_NO_MECHANISM)) {
+   return NULL;
+   }
+   if (config_set_section_int(config,
+  interface_name(c->vport_if),
+  "network_transport",
+  TRANS_VPORT)) {
+   return NULL;
+   }
+   if (config_set_section_int(config, interface_name(c->vport_if),
+  "delay_filter_length", 1)) {
+   return NULL;
+   }
+   }
+
c->config = config;
c->free_running = config_get_int(config, NULL, "free_running");
c->freq_est_interval = config_get_int(config, NULL, 
"freq_est_interval");
@@ -1231,6 +1262,17 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
pr_err("failed to open the UDS-RO port");
return NULL;
}
+
+   if (c->vport_if) {
+   c->vport_port = port_open(phc_device, phc_index, timestamping, 
0,
+  c->vport_if, c);
+   if (!c->vport_port) {
+   pr_err("failed to open the Virtual port");
+   return NULL;
+   }
+   LIST_INSERT_HEAD(>ports, c->vport_port, list);
+   c->nports++;
+   }
clock_fda_changed(c);
 
c->slave_event_monitor = monitor_create(config, c->uds_rw_port);
@@ -1254,6 +1296,9 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
}
port_dispatch(c->uds_rw_port, EV_INITIALIZE, 0);
port_dispatch(c->uds_ro_port, EV_INITIALIZE, 0);
+   if (c->vport_port) {
+   port_dispatch(c->vport_port, EV_INITIALIZE, 0);
+   }
 
return c;
 }
@@ -1670,6 +1715,18 @@ int clock_poll(struct clock *c)
/* sde is not expected on the UDS-RO port */

[Linuxptp-devel] [PATCH 4/4] APTS support

2022-08-24 Thread SyncMonk Technologies
adding APTS to participate in BMCA

Passing the announce message for external source to ptp4l using virtual
port to avoid selection of master from PTP source.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Vipin Sharma 
Signed-off-by: Devasish Dey 
---
 ts2phc_phc_pps_source.c | 16 
 ts2phc_phc_pps_source.h |  2 ++
 ts2phc_pps_sink.c   |  6 +-
 3 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/ts2phc_phc_pps_source.c b/ts2phc_phc_pps_source.c
index 5f15e8e..fa9d286 100644
--- a/ts2phc_phc_pps_source.c
+++ b/ts2phc_phc_pps_source.c
@@ -14,10 +14,12 @@
 #include "print.h"
 #include "ts2phc_phc_pps_source.h"
 #include "ts2phc_pps_source_private.h"
+#include "ts2phc_vport.h"
 #include "util.h"
 
 struct ts2phc_phc_pps_source {
struct ts2phc_pps_source pps_source;
+   struct ts2phc_vport *vport;
clockid_t clkid;
int channel;
int fd;
@@ -82,6 +84,15 @@ static int ts2phc_phc_pps_source_getppstime(struct 
ts2phc_pps_source *src,
return clock_gettime(s->clkid, ts);
 }
 
+int ts2phc_phc_pps_source_vport_transmit(struct ts2phc_pps_source *src,
+   struct timespec *ts)
+{
+   struct ts2phc_phc_pps_source *s =
+   container_of(src, struct ts2phc_phc_pps_source, pps_source);
+   return ts2phc_vport_tx_announce(s->vport);
+}
+
+
 struct ts2phc_pps_source *ts2phc_phc_pps_source_create(struct config *cfg,
   const char *dev)
 {
@@ -94,6 +105,11 @@ struct ts2phc_pps_source 
*ts2phc_phc_pps_source_create(struct config *cfg,
}
s->pps_source.destroy = ts2phc_phc_pps_source_destroy;
s->pps_source.getppstime = ts2phc_phc_pps_source_getppstime;
+   s->vport = ts2phc_vport_create(cfg);
+   if (!s->vport) {
+   free(s);
+   return NULL;
+   }
 
s->clkid = posix_clock_open(dev, );
if (s->clkid == CLOCK_INVALID) {
diff --git a/ts2phc_phc_pps_source.h b/ts2phc_phc_pps_source.h
index c9ab54e..01c1d8d 100644
--- a/ts2phc_phc_pps_source.h
+++ b/ts2phc_phc_pps_source.h
@@ -11,4 +11,6 @@
 struct ts2phc_pps_source *ts2phc_phc_pps_source_create(struct config *cfg,
   const char *dev);
 
+int ts2phc_phc_pps_source_vport_transmit(struct ts2phc_pps_source *src,
+struct timespec *ts);
 #endif
diff --git a/ts2phc_pps_sink.c b/ts2phc_pps_sink.c
index 91bd7c9..6e6acc0 100644
--- a/ts2phc_pps_sink.c
+++ b/ts2phc_pps_sink.c
@@ -23,6 +23,7 @@
 #include "servo.h"
 #include "ts2phc_pps_sink.h"
 #include "ts2phc_pps_source.h"
+#include "ts2phc_phc_pps_source.h"
 #include "util.h"
 
 #define NS_PER_SEC 10LL
@@ -426,7 +427,10 @@ int ts2phc_pps_sink_poll(struct ts2phc_pps_source *src)
 
err = ts2phc_pps_source_getppstime(src, _ts.ts);
source_ts.valid = err ? false : true;
-
+   if (source_ts.valid) {
+   /* Send Announce and Sync Message on Virtual Port  */
+   ts2phc_phc_pps_source_vport_transmit(src, _ts.ts);
+   }
for (i = 0; i < ts2phc_n_sinks; i++) {
if (polling_array.pfd[i].revents & (POLLIN|POLLPRI)) {
ts2phc_pps_sink_event(polling_array.sink[i], source_ts);
-- 
2.25.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 1/4] APTS support

2022-08-24 Thread SyncMonk Technologies
Adding virtual PTP port support
As per G.8275 (Annex-B) including virtual PTP ports on a PTP clock. This
virtual port will be used to support APTS, IWF between different
clock_domains.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Vipin Sharma 
Signed-off-by: Devasish Dey 
---
 makefile |   2 +-
 vport.c  | 140 +++
 vport.h  |  20 
 3 files changed, 161 insertions(+), 1 deletion(-)
 create mode 100644 vport.c
 create mode 100644 vport.h

diff --git a/makefile b/makefile
index 5295b60..7d8c0d3 100644
--- a/makefile
+++ b/makefile
@@ -25,7 +25,7 @@ LDLIBS= -lm -lrt -pthread $(EXTRA_LDFLAGS)
 PRG= ptp4l hwstamp_ctl nsm phc2sys phc_ctl pmc timemaster ts2phc
 FILTERS= filter.o mave.o mmedian.o
 SERVOS = linreg.o ntpshm.o nullf.o pi.o servo.o
-TRANSP = raw.o transport.o udp.o udp6.o uds.o
+TRANSP = raw.o transport.o udp.o udp6.o uds.o vport.o
 TS2PHC = ts2phc.o lstab.o nmea.o serial.o sock.o ts2phc_generic_pps_source.o \
  ts2phc_nmea_pps_source.o ts2phc_phc_pps_source.o ts2phc_pps_sink.o 
ts2phc_pps_source.o
 OBJ= bmc.o clock.o clockadj.o clockcheck.o config.o designated_fsm.o \
diff --git a/vport.c b/vport.c
new file mode 100644
index 000..89d4105
--- /dev/null
+++ b/vport.c
@@ -0,0 +1,140 @@
+/**
+ * @file vport.c
+ * @note Copyright (C) 2022 SyncMonk Technologies 
+ * @note SPDX-License-Identifier: GPL-2.0+
+ *
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "address.h"
+#include "contain.h"
+#include "print.h"
+#include "transport_private.h"
+#include "vport.h"
+
+#define VPORT_FILEMODE (0660) /*0660*/
+
+struct vport {
+   struct transport t;
+   struct address address;
+};
+
+static int vport_close(struct transport *t, struct fdarray *fda)
+{
+   struct sockaddr_un sa;
+   socklen_t len = sizeof(sa);
+
+   if (!getsockname(fda->fd[FD_GENERAL],
+   (struct sockaddr *) , ) &&
+   sa.sun_family == AF_LOCAL) {
+   unlink(sa.sun_path);
+   }
+
+   close(fda->fd[FD_GENERAL]);
+   return 0;
+}
+
+static int vport_open(struct transport *t,
+ struct interface *iface,
+ struct fdarray *fda,
+ enum timestamp_type tt)
+{
+   char *vport_path = config_get_string(t->cfg, NULL, "vport_address");
+   struct vport *vport = container_of(t, struct vport, t);
+   const char *name = interface_name(iface);
+   struct sockaddr_un sa;
+   int fd, err;
+
+   fd = socket(AF_LOCAL, SOCK_DGRAM, 0);
+   if (fd < 0) {
+   pr_err("vport: failed to create socket: %m");
+   return -1;
+   }
+   memset(, 0, sizeof(sa));
+   sa.sun_family = AF_LOCAL;
+   strncpy(sa.sun_path, name, sizeof(sa.sun_path) - 1);
+
+   unlink(name);
+
+   err = bind(fd, (struct sockaddr *) , sizeof(sa));
+   if (err < 0) {
+   pr_err("vport: bind failed: %m");
+   close(fd);
+   return -1;
+   }
+
+   /* For client use, pre load the server path. */
+   memset(, 0, sizeof(sa));
+   sa.sun_family = AF_LOCAL;
+   strncpy(sa.sun_path, vport_path, sizeof(sa.sun_path) - 1);
+   vport->address.sun = sa;
+   vport->address.len = sizeof(sa);
+
+   chmod(name, VPORT_FILEMODE);
+   fda->fd[FD_EVENT] = -1;
+   fda->fd[FD_GENERAL] = fd;
+   return 0;
+}
+
+static int vport_recv(struct transport *t, int fd, void *buf, int buflen,
+ struct address *addr, struct hw_timestamp *hwts)
+{
+   int cnt;
+   struct vport *vport = container_of(t, struct vport, t);
+
+   addr->len = sizeof(addr->sun);
+   cnt = recvfrom(fd, buf, buflen, 0, >sa, >len);
+   if (cnt <= 0) {
+   pr_err("vport: recvfrom failed: %m");
+   return cnt;
+   }
+   vport->address = *addr;
+   return cnt;
+}
+
+static int vport_send(struct transport *t, struct fdarray *fda,
+ enum transport_event event, int peer, void *buf,
+ int buflen, struct address *addr,
+ struct hw_timestamp *hwts)
+{
+   int cnt, fd = fda->fd[FD_GENERAL];
+   struct vport *vport = container_of(t, struct vport, t);
+
+   if (!addr)
+   addr = >address;
+
+   cnt = sendto(fd, buf, buflen, 0, >sa, addr->len);
+   if (cnt < 1) {
+   return -errno;
+   }
+   return cnt;
+}
+
+static void vport_release(struct transport *t)
+{
+   struct vport *vport = container_of(t, struct vport, t);
+
+   free(vport);
+}
+
+struct transport *vport_transport_create(void)
+{
+   struct vport *vport;
+
+   vport = calloc(1, sizeof(*

[Linuxptp-devel] [PATCH 3/3] Packet Timing Signal Fail (PTSF)(G.8275.2 Section 6.7.11)

2022-08-24 Thread SyncMonk Technologies
adding TLV support for PORT_PTSF_UNUSABLE

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 pmc.c|  6 ++
 pmc_common.c | 23 +++
 port.c   | 23 +++
 tlv.c| 12 
 tlv.h|  6 ++
 5 files changed, 70 insertions(+)

diff --git a/pmc.c b/pmc.c
index 34c9609..35300b4 100644
--- a/pmc.c
+++ b/pmc.c
@@ -176,6 +176,7 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
struct currentDS *cds;
struct parentDS *pds;
struct portDS *p;
+   struct port_ptsf_unusable_np *ptsf;
struct port_ptsf_data_np *ptsf_data;
struct TLV *tlv;
uint8_t *buf;
@@ -608,6 +609,11 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
fprintf(fp, "LOG_MIN_PDELAY_REQ_INTERVAL "
IFMT "logMinPdelayReqInterval %hhd", mtd->val);
break;
+   case MID_PORT_PTSF_UNUSABLE_NP:
+   ptsf = (struct port_ptsf_unusable_np *) mgt->data;
+   fprintf(fp, "PORT_PTSF_UNUSABLE_NP "
+   IFMT "unusable %hu", ptsf->ptsf_unusable);
+   break;
case MID_PORT_PTSF_DATA_NP:
ptsf_data = (struct port_ptsf_data_np *) mgt->data;
fprintf(fp, "PORT_PTSF_DATA_NP "
diff --git a/pmc_common.c b/pmc_common.c
index 9570841..528bd43 100644
--- a/pmc_common.c
+++ b/pmc_common.c
@@ -154,6 +154,7 @@ struct management_id idtab[] = {
{ "PORT_SERVICE_STATS_NP", MID_PORT_SERVICE_STATS_NP, do_get_action },
{ "UNICAST_MASTER_TABLE_NP", MID_UNICAST_MASTER_TABLE_NP, do_get_action 
},
{ "PORT_HWCLOCK_NP", MID_PORT_HWCLOCK_NP, do_get_action },
+   { "PORT_PTSF_UNUSABLE_NP", MID_PORT_PTSF_UNUSABLE_NP, do_set_action },
{ "PORT_PTSF_DATA_NP", MID_PORT_PTSF_DATA_NP, do_get_action },
 };
 
@@ -173,6 +174,7 @@ static void do_set_action(struct pmc *pmc, int action, int 
index, char *str)
struct management_tlv_datum mtd;
struct subscribe_events_np sen;
struct port_ds_np pnp;
+   struct port_ptsf_unusable_np ptsf;
char onoff_port_state[4] = "off";
char onoff_time_status[4] = "off";
 
@@ -303,6 +305,27 @@ static void do_set_action(struct pmc *pmc, int action, int 
index, char *str)
}
pmc_send_set_action(pmc, code, , sizeof(pnp));
break;
+   case MID_PORT_PTSF_UNUSABLE_NP:
+   cnt = sscanf(str, " %*s %*s %hu %hu",
+_unusable,
+);
+   if (cnt != 2) {
+   fprintf(stderr, "%s SET needs 2 value\n",
+   idtab[index].name);
+   break;
+   }
+   switch (ptsf.ptsf_unusable) {
+   case TRUE:
+   case FALSE:
+   pmc_send_set_action(pmc, code, , sizeof(ptsf));
+   break;
+   default:
+   fprintf(stderr, "\nusage:"
+   "set PORT_PTSF_UNUSABLE_NP%hhu (false) or"
+   "%hhu (true) \n\n",
+   FALSE, TRUE);
+   }
+   break;
}
 }
 
diff --git a/port.c b/port.c
index ff00e46..d0997f8 100644
--- a/port.c
+++ b/port.c
@@ -852,6 +852,7 @@ static int port_management_fill_response(struct port 
*target,
struct PortIdentity pid;
const char *ts_label;
struct portDS *pds;
+   struct port_ptsf_unusable_np *ptsf;
struct port_ptsf_data_np *ptsf_data;
uint16_t u16;
uint8_t *buf;
@@ -1075,6 +1076,13 @@ static int port_management_fill_response(struct port 
*target,
PORT_HWCLOCK_VCLOCK : 0;
datalen = sizeof(*phn);
break;
+   case MID_PORT_PTSF_UNUSABLE_NP:
+   ptsf = (struct port_ptsf_unusable_np *)tlv->data;
+   ptsf->portIdentity = target->portIdentity;
+   ptsf->ptsf_unusable =
+   (target->signalFail & PDS_PTSF_UNUSABLE) ? 1 : 0;
+   datalen = sizeof(*ptsf);
+   break;
case MID_PORT_PTSF_DATA_NP:
ptsf_data = (struct port_ptsf_data_np *)tlv->data;
ptsf_data->portIdentity = target->portIdentity;
@@ -1125,6 +1133,8 @@ static int port_management_set(struct port *target,
int respond = 0;
struct management_tlv *tlv;
struct port_ds_np *pdsnp;
+   struct port_ptsf_unusable_np *ptsf;
+   UInteger16 signalFail;
 
tlv = (struct management_tlv *) req->management.suffix;
 
@@ -1134,6 +1144,19 @@ static int port_management_set(struct port *target,
target->neighborPropDelayThresh = 
pdsnp->neighborPropDelayThresh;
respond = 1;
break;
+   case 

[Linuxptp-devel] [PATCH 1/3] Packet Timing Signal Fail (PTSF)(G.8275.2 Section 6.7.11)

2022-08-24 Thread SyncMonk Technologies
- adding sync receipt timeout, delay response timeout and signal fail
  support to portDS as per G.8275.2.
- This also sets the signal fail condition for timeout.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 ds.h   |  9 +
 pmc.c  |  9 +++--
 port.c | 16 +++-
 port_private.h |  1 +
 4 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/ds.h b/ds.h
index dff6d5e..5136bb2 100644
--- a/ds.h
+++ b/ds.h
@@ -95,6 +95,11 @@ struct timePropertiesDS {
Enumeration8 timeSource;
 } PACKED;
 
+
+#define PDS_PTSF_LOSS_SYNC(1<<0)
+#define PDS_PTSF_UNUSABLE (1<<1)
+#define PDS_PTSF_LOSS_DELAY_RESP  (1<<2)
+
 struct portDS {
struct PortIdentity portIdentity;
Enumeration8portState;
@@ -106,6 +111,10 @@ struct portDS {
Enumeration8delayMechanism;
Integer8logMinPdelayReqInterval;
UInteger8   versionNumber;
+   UInteger8   localPriority;
+   UInteger8   signalFail;
+   UInteger8   syncReceiptTimeout;
+   UInteger8   delayRespReceiptTimeout;
 } PACKED;
 
 #define FRI_ASAP (-128)
diff --git a/pmc.c b/pmc.c
index e218ca4..cdc76c8 100644
--- a/pmc.c
+++ b/pmc.c
@@ -438,16 +438,21 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
IFMT "peerMeanPathDelay   %" PRId64
IFMT "logAnnounceInterval %hhd"
IFMT "announceReceiptTimeout  %hhu"
+   IFMT "syncReceiptTimeout  %hhu"
+   IFMT "delayRespReceiptTimeout %hhu"
IFMT "logSyncInterval %hhd"
IFMT "delayMechanism  %hhu"
IFMT "logMinPdelayReqInterval %hhd"
-   IFMT "versionNumber   %u",
+   IFMT "versionNumber   %u"
+   IFMT "signalFail  %d",
pid2str(>portIdentity), ps_str[p->portState],
p->logMinDelayReqInterval, p->peerMeanPathDelay >> 16,
p->logAnnounceInterval, p->announceReceiptTimeout,
+   p->syncReceiptTimeout, p->delayRespReceiptTimeout,
p->logSyncInterval, p->delayMechanism,
p->logMinPdelayReqInterval,
-   p->versionNumber & MAJOR_VERSION_MASK);
+   p->versionNumber & MAJOR_VERSION_MASK,
+   p->signalFail ? 1 : 0);
break;
case MID_PORT_DATA_SET_NP:
pnp = (struct port_ds_np *) mgt->data;
diff --git a/port.c b/port.c
index 871ad68..8075896 100644
--- a/port.c
+++ b/port.c
@@ -951,6 +951,9 @@ static int port_management_fill_response(struct port 
*target,
}
pds->logMinPdelayReqInterval = target->logMinPdelayReqInterval;
pds->versionNumber   = target->versionNumber;
+   pds->syncReceiptTimeout  = target->syncReceiptTimeout;
+   pds->delayRespReceiptTimeout = target->delay_response_timeout;
+   pds->signalFail  = target->signalFail;
datalen = sizeof(*pds);
break;
case MID_LOG_ANNOUNCE_INTERVAL:
@@ -1115,7 +1118,6 @@ static int port_management_set(struct port *target,
int respond = 0;
struct management_tlv *tlv;
struct port_ds_np *pdsnp;
-
tlv = (struct management_tlv *) req->management.suffix;
 
switch (id) {
@@ -1284,6 +1286,7 @@ static void port_synchronize(struct port *p,
enum servo_state state, last_state;
tmv_t t1, t1c, t2, c1, c2;
 
+   p->signalFail &= ~PDS_PTSF_LOSS_SYNC;
port_set_sync_rx_tmo(p);
 
t1 = timestamp_to_tmv(origin_ts);
@@ -1995,6 +1998,12 @@ int process_announce(struct port *p, struct ptp_message 
*m)
return result;
}
 
+   if (p->signalFail) {
+   pr_debug("%s: Announce message ignored for signal fail\n",
+   p->name);
+   return result;
+   }
+
if (m->announce.grandmasterClockQuality.clockClass >
clock_get_clock_class_threshold(p->clock)) {
pl_err(60, "%s: Master clock quality received is "
@@ -2089,6 +2098,9 @@ void process_delay_resp(struct port *p, struct 
ptp_message *m)
struct ptp_message *req;
tmv_t c3, t3, t4, t4c;
 
+   /* clear delay response time out. */
+   p->signalFail &= ~PDS_PTSF_LOSS_DELAY_RESP;
+
if (p->state != PS_UNCALIBRATED && p->state != PS_SLAVE) {
return;
}
@@ -2780,6 +2792,7 @@ static enum fsm_event bc_event(struct port *p, int 
fd_index)
 
if (fd_index == FD_SYNC_RX_TIMER) {

[Linuxptp-devel] [PATCH 2/3] Packet Timing Signal Fail (PTSF)(G.8275.2 Section 6.7.11)

2022-08-24 Thread SyncMonk Technologies
adding TLV support for MID_PORT_PTSF_DATA_NP

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 pmc.c| 16 
 pmc_common.c |  1 +
 port.c   |  8 
 tlv.c| 11 +++
 tlv.h|  5 +
 5 files changed, 41 insertions(+)

diff --git a/pmc.c b/pmc.c
index cdc76c8..34c9609 100644
--- a/pmc.c
+++ b/pmc.c
@@ -176,6 +176,7 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
struct currentDS *cds;
struct parentDS *pds;
struct portDS *p;
+   struct port_ptsf_data_np *ptsf_data;
struct TLV *tlv;
uint8_t *buf;
int action;
@@ -607,6 +608,21 @@ static void pmc_show(struct ptp_message *msg, FILE *fp)
fprintf(fp, "LOG_MIN_PDELAY_REQ_INTERVAL "
IFMT "logMinPdelayReqInterval %hhd", mtd->val);
break;
+   case MID_PORT_PTSF_DATA_NP:
+   ptsf_data = (struct port_ptsf_data_np *) mgt->data;
+   fprintf(fp, "PORT_PTSF_DATA_NP "
+   IFMT "signalFail%hu"
+   IFMT "PTSF.lossSync %d"
+   IFMT "PTSF.syncMsgLoss  %d"
+   IFMT "PTSF.delayRespMsgLoss %d"
+   IFMT "PTSF.unusable %d",
+   ptsf_data->signalFail  ? 1 : 0,
+   ((ptsf_data->signalFail & PDS_PTSF_LOSS_SYNC) |
+(ptsf_data->signalFail & PDS_PTSF_LOSS_DELAY_RESP)) ? 
1 : 0,
+   ptsf_data->signalFail & PDS_PTSF_LOSS_SYNC ? 1 : 0,
+   ptsf_data->signalFail & PDS_PTSF_LOSS_DELAY_RESP ? 1 : 
0,
+   ptsf_data->signalFail & PDS_PTSF_UNUSABLE ? 1 : 0);
+   break;
}
 out:
fprintf(fp, "\n");
diff --git a/pmc_common.c b/pmc_common.c
index 1dd89f6..9570841 100644
--- a/pmc_common.c
+++ b/pmc_common.c
@@ -154,6 +154,7 @@ struct management_id idtab[] = {
{ "PORT_SERVICE_STATS_NP", MID_PORT_SERVICE_STATS_NP, do_get_action },
{ "UNICAST_MASTER_TABLE_NP", MID_UNICAST_MASTER_TABLE_NP, do_get_action 
},
{ "PORT_HWCLOCK_NP", MID_PORT_HWCLOCK_NP, do_get_action },
+   { "PORT_PTSF_DATA_NP", MID_PORT_PTSF_DATA_NP, do_get_action },
 };
 
 static void do_get_action(struct pmc *pmc, int action, int index, char *str)
diff --git a/port.c b/port.c
index 8075896..ff00e46 100644
--- a/port.c
+++ b/port.c
@@ -852,6 +852,7 @@ static int port_management_fill_response(struct port 
*target,
struct PortIdentity pid;
const char *ts_label;
struct portDS *pds;
+   struct port_ptsf_data_np *ptsf_data;
uint16_t u16;
uint8_t *buf;
int datalen;
@@ -1074,6 +1075,12 @@ static int port_management_fill_response(struct port 
*target,
PORT_HWCLOCK_VCLOCK : 0;
datalen = sizeof(*phn);
break;
+   case MID_PORT_PTSF_DATA_NP:
+   ptsf_data = (struct port_ptsf_data_np *)tlv->data;
+   ptsf_data->portIdentity = target->portIdentity;
+   ptsf_data->signalFail = target->signalFail;
+   datalen = sizeof(*ptsf_data);
+   break;
default:
/* The caller should *not* respond to this message. */
tlv_extra_recycle(extra);
@@ -1118,6 +1125,7 @@ static int port_management_set(struct port *target,
int respond = 0;
struct management_tlv *tlv;
struct port_ds_np *pdsnp;
+
tlv = (struct management_tlv *) req->management.suffix;
 
switch (id) {
diff --git a/tlv.c b/tlv.c
index 1c13460..745c96a 100644
--- a/tlv.c
+++ b/tlv.c
@@ -130,6 +130,7 @@ static int mgt_post_recv(struct management_tlv *m, uint16_t 
data_len,
struct defaultDS *dds;
struct parentDS *pds;
struct portDS *p;
+   struct port_ptsf_data_np *ptsf_data;
uint8_t *buf;
uint16_t u16;
 
@@ -407,6 +408,10 @@ static int mgt_post_recv(struct management_tlv *m, 
uint16_t data_len,
if (data_len != 0)
goto bad_length;
break;
+   case MID_PORT_PTSF_DATA_NP:
+   ptsf_data = (struct port_ptsf_data_np *) m->data;
+   ptsf_data->portIdentity.portNumber = 
ntohs(ptsf_data->portIdentity.portNumber);
+   break;
}
if (extra_len) {
if (extra_len % 2)
@@ -437,6 +442,7 @@ static void mgt_pre_send(struct management_tlv *m, struct 
tlv_extra *extra)
struct currentDS *cds;
struct parentDS *pds;
struct portDS *p;
+   struct port_ptsf_data_np *ptsf_data;
uint8_t *buf;
int i;
 
@@ -569,6 +575,11 @@ static void mgt_pre_send(struct management_tlv *m, struct 
tlv_extra *extra)
phn->portIdentity.portNumber = 
htons(phn->portIdentity.portNumber);
  

[Linuxptp-devel] [PATCH 2/2] Alternate master support

2022-08-24 Thread SyncMonk Technologies
adding alternate master support for linuxptp

A PTP Master Clock, which is not the Best Master,
may act as a master with the Alternate Master flag
set on the messages it sends.
Need to support Alternate Master, including using
Slave Event Monitoring channel for the
alternate connections (to pass along timestamps to external servo).
See ITU-T G.8275.2 Appendix III & V.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 clock.c|   5 +++
 clock.h|   7 
 config.c   |   1 +
 msg.h  |  10 +
 port.c | 100 -
 port_private.h |   1 +
 6 files changed, 107 insertions(+), 17 deletions(-)

diff --git a/clock.c b/clock.c
index d37bb87..428a1e5 100644
--- a/clock.c
+++ b/clock.c
@@ -1715,6 +1715,11 @@ int clock_slave_only(struct clock *c)
return c->dds.flags & DDS_SLAVE_ONLY;
 }
 
+bool clock_telecom_profile(struct clock *c)
+{
+   return (c->dscmp == telecom_dscmp);
+}
+
 UInteger8 clock_max_steps_removed(struct clock *c)
 {
return c->max_steps_removed;
diff --git a/clock.h b/clock.h
index 0534f21..a869fae 100644
--- a/clock.h
+++ b/clock.h
@@ -289,6 +289,13 @@ int clock_slave_only(struct clock *c);
  */
 UInteger8 clock_max_steps_removed(struct clock *c);
 
+/**
+ * Obtain the clock is set for telecom profile .
+ * @param c  The clock instance.
+ * @return   True if the profile is telecom, false otherwise.
+ */
+bool clock_telecom_profile(struct clock *c);
+
 /**
  * Obtain the clock class threshold field from a clock's default data set.
  * @param c  The clock instance.
diff --git a/config.c b/config.c
index b5cf397..ce8a3ae 100644
--- a/config.c
+++ b/config.c
@@ -226,6 +226,7 @@ static struct config_enum bmca_enu[] = {
 };
 
 struct config_item config_tab[] = {
+   PORT_ITEM_INT("altMaster", 0, 1, 1),
PORT_ITEM_INT("announceReceiptTimeout", 3, 2, UINT8_MAX),
PORT_ITEM_ENU("asCapable", AS_CAPABLE_AUTO, as_capable_enu),
GLOB_ITEM_INT("assume_two_step", 0, 0, 1),
diff --git a/msg.h b/msg.h
index b7423ee..22dfbeb 100644
--- a/msg.h
+++ b/msg.h
@@ -461,6 +461,16 @@ static inline Boolean one_step(struct ptp_message *m)
return !field_is_set(m, 0, TWO_STEP);
 }
 
+/**
+ * Test whether a message from ALTERNATE Master.
+ * @param m  Message to test.
+ * @return   One if the alt_master flag in message is set, zero otherwise.
+ */
+static inline Boolean alt_master(struct ptp_message *m)
+{
+   return field_is_set(m, 0, ALT_MASTER);
+}
+
 /**
  * Convert a 64 bit word into network byte order.
  */
diff --git a/port.c b/port.c
index 871ad68..4ff3ab8 100644
--- a/port.c
+++ b/port.c
@@ -1293,11 +1293,16 @@ static void port_synchronize(struct port *p,
t1c = tmv_add(t1, tmv_add(c1, c2));
 
switch (p->state) {
+   case PS_MASTER:
+   return;
case PS_UNCALIBRATED:
case PS_SLAVE:
monitor_sync(p->slave_event_monitor,
 clock_parent_identity(p->clock), seqid,
 t1, tmv_add(c1, c2), t2);
+   monitor_computed(p->slave_event_monitor,
+clock_parent_identity(p->clock), seqid,
+tmv_sub(t2, t1c), tmv_sub(t2, t1c), 0, 1);
break;
default:
break;
@@ -1509,6 +1514,7 @@ out:
 int port_delay_request(struct port *p)
 {
struct ptp_message *msg;
+   struct ptp_message *dst;
 
/* Time to send a new request, forget current pdelay resp and fup */
if (p->peer_delay_resp) {
@@ -1541,10 +1547,20 @@ int port_delay_request(struct port *p)
msg->header.control= CTL_DELAY_REQ;
msg->header.logMessageInterval = 0x7f;
 
-   if (p->hybrid_e2e) {
-   struct ptp_message *dst = TAILQ_FIRST(>best->messages);
+   if (p->hybrid_e2e && p->state != PS_MASTER) {
+   dst = TAILQ_FIRST(>best->messages);
msg->address = dst->address;
msg->header.flagField[0] |= UNICAST;
+   } else if (p->altMaster) {
+   struct foreign_clock *fc;
+   fc = LIST_FIRST(>foreign_masters);
+   if (fc) {
+   dst = TAILQ_FIRST(>messages);
+   if (dst) {
+   msg->address = dst->address;
+   msg->header.flagField[0] |= UNICAST;
+   }
+   }
}
 
if (port_prepare_and_send(p, msg, TRANS_EVENT)) {
@@ -1595,6 +1611,10 @@ int port_tx_announce(struct port *p, struct address 
*dst, uint16_t sequence_id)
 
msg->header.flagField[1] = tp.flags;
 
+   if (p->state != PS_MASTER && clock_telecom_profile(p->clock)) {
+   msg->header.flagField[0] |= ALT_MASTER;
+   }
+
if (dst) {
msg->address = *dst;

[Linuxptp-devel] [PATCH 1/2] Alternate master support

2022-08-24 Thread SyncMonk Technologies
Slave Event Monitoring channel for the alternate connections

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 monitor.c | 63 +++
 monitor.h |  3 +++
 pmc.c | 31 +++
 tlv.h | 21 +++
 4 files changed, 118 insertions(+)

diff --git a/monitor.c b/monitor.c
index ed451ac..1965a89 100644
--- a/monitor.c
+++ b/monitor.c
@@ -21,8 +21,10 @@ struct monitor_message {
 struct monitor {
struct port *dst_port;
struct slave_rx_sync_timing_data_tlv *sync_tlv;
+   struct slave_rx_sync_computed_data_tlv *computed_tlv;
struct slave_delay_timing_data_tlv *delay_tlv;
struct monitor_message delay;
+   struct monitor_message computed;
struct monitor_message sync;
 };
 
@@ -115,6 +117,23 @@ static int monitor_init_sync(struct monitor *monitor, 
struct address address)
return 0;
 }
 
+static int monitor_init_computed(struct monitor *monitor, struct address 
address)
+{
+   const size_t tlv_size = sizeof(struct slave_rx_sync_computed_data_tlv) +
+   sizeof(struct slave_rx_sync_computed_record) * 
RECORDS_PER_MESSAGE;
+   struct tlv_extra *extra;
+
+   extra = monitor_init_message(>computed, monitor->dst_port,
+TLV_SLAVE_RX_SYNC_COMPUTED_DATA, tlv_size,
+address);
+   if (!extra) {
+   return -1;
+   }
+   monitor->computed_tlv = (struct slave_rx_sync_computed_data_tlv *) 
extra->tlv;
+
+   return 0;
+}
+
 struct monitor *monitor_create(struct config *config, struct port *dst)
 {
struct monitor *monitor;
@@ -148,6 +167,12 @@ struct monitor *monitor_create(struct config *config, 
struct port *dst)
free(monitor);
return NULL;
}
+   if (monitor_init_computed(monitor, address)) {
+   msg_put(monitor->sync.msg);
+   msg_put(monitor->delay.msg);
+   free(monitor);
+   return NULL;
+   }
 
return monitor;
 }
@@ -193,6 +218,9 @@ void monitor_destroy(struct monitor *monitor)
if (monitor->sync.msg) {
msg_put(monitor->sync.msg);
}
+   if (monitor->computed.msg) {
+   msg_put(monitor->computed.msg);
+   }
free(monitor);
 }
 
@@ -229,3 +257,38 @@ int monitor_sync(struct monitor *monitor, struct 
PortIdentity source_pid,
}
return 0;
 }
+
+int monitor_computed(struct monitor *monitor, struct PortIdentity source_pid,
+uint16_t seqid, tmv_t offset, tmv_t pathdelay, int32_t ratio,
+uint8_t best_master)
+{
+   struct slave_rx_sync_computed_record *record;
+   struct ptp_message *msg;
+
+   if (!monitor_active(monitor)) {
+   return 0;
+   }
+
+   msg = monitor->computed.msg;
+
+   if (!pid_eq(>computed_tlv->sourcePortIdentity, _pid)) {
+   /* There was a change in remote master. Drop stale records. */
+   memcpy(>computed_tlv->sourcePortIdentity, _pid,
+  sizeof(monitor->computed_tlv->sourcePortIdentity));
+   monitor->computed.count = 0;
+   }
+
+   record = monitor->computed_tlv->record + monitor->computed.count;
+   monitor->computed_tlv->reserved= 0;
+   record->sequenceId = seqid;
+   record->offsetFromMaster   = tmv_to_TimeInterval(offset);
+   record->meanPathDelay  = tmv_to_TimeInterval(pathdelay);
+   record->scaledNeighborRateRatio= ratio;
+
+   monitor->computed.count++;
+   if (monitor->computed.count == monitor->computed.records_per_msg) {
+   monitor->computed.count = 0;
+   return monitor_forward(monitor->dst_port, msg);
+   }
+   return 0;
+}
diff --git a/monitor.h b/monitor.h
index c489aa9..9beb57e 100644
--- a/monitor.h
+++ b/monitor.h
@@ -22,4 +22,7 @@ void monitor_destroy(struct monitor *monitor);
 int monitor_sync(struct monitor *monitor, struct PortIdentity source_pid,
 uint16_t seqid, tmv_t t1, tmv_t corr, tmv_t t2);
 
+int monitor_computed(struct monitor *monitor, struct PortIdentity source_pid,
+uint16_t seqid, tmv_t offset, tmv_t pathdelay, int32_t ratio,
+uint8_t best_master);
 #endif
diff --git a/pmc.c b/pmc.c
index e218ca4..b6227dd 100644
--- a/pmc.c
+++ b/pmc.c
@@ -88,6 +88,19 @@ static void pmc_show_rx_sync_timing(struct 
slave_rx_sync_timing_record *record,
SHOW_TIMESTAMP(record->syncEventIngressTimestamp));
 }
 
+static void pmc_show_rx_sync_computed_data(struct 
slave_rx_sync_computed_record *record,
+ FILE *fp)
+{
+   fprintf(fp,
+   IFMT "sequenceId %hu"
+   IFMT "offsetFromMaster   %" PRId64
+  

[Linuxptp-devel] [PATCH 2/2] adding alternate master support for linuxptp

2022-08-24 Thread SyncMonk Technologies
A PTP Master Clock, which is not the Best Master,
may act as a master with the Alternate Master flag
set on the messages it sends.
Need to support Alternate Master, including using
Slave Event Monitoring channel for the
alternate connections (to pass along timestamps to external servo).
See ITU-T G.8275.2 Appendix III & V.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 clock.c|   5 +++
 clock.h|   7 
 config.c   |   1 +
 msg.h  |  10 +
 port.c | 100 -
 port_private.h |   1 +
 6 files changed, 107 insertions(+), 17 deletions(-)

diff --git a/clock.c b/clock.c
index d37bb87..428a1e5 100644
--- a/clock.c
+++ b/clock.c
@@ -1715,6 +1715,11 @@ int clock_slave_only(struct clock *c)
return c->dds.flags & DDS_SLAVE_ONLY;
 }
 
+bool clock_telecom_profile(struct clock *c)
+{
+   return (c->dscmp == telecom_dscmp);
+}
+
 UInteger8 clock_max_steps_removed(struct clock *c)
 {
return c->max_steps_removed;
diff --git a/clock.h b/clock.h
index 0534f21..a869fae 100644
--- a/clock.h
+++ b/clock.h
@@ -289,6 +289,13 @@ int clock_slave_only(struct clock *c);
  */
 UInteger8 clock_max_steps_removed(struct clock *c);
 
+/**
+ * Obtain the clock is set for telecom profile .
+ * @param c  The clock instance.
+ * @return   True if the profile is telecom, false otherwise.
+ */
+bool clock_telecom_profile(struct clock *c);
+
 /**
  * Obtain the clock class threshold field from a clock's default data set.
  * @param c  The clock instance.
diff --git a/config.c b/config.c
index b5cf397..ce8a3ae 100644
--- a/config.c
+++ b/config.c
@@ -226,6 +226,7 @@ static struct config_enum bmca_enu[] = {
 };
 
 struct config_item config_tab[] = {
+   PORT_ITEM_INT("altMaster", 0, 1, 1),
PORT_ITEM_INT("announceReceiptTimeout", 3, 2, UINT8_MAX),
PORT_ITEM_ENU("asCapable", AS_CAPABLE_AUTO, as_capable_enu),
GLOB_ITEM_INT("assume_two_step", 0, 0, 1),
diff --git a/msg.h b/msg.h
index b7423ee..22dfbeb 100644
--- a/msg.h
+++ b/msg.h
@@ -461,6 +461,16 @@ static inline Boolean one_step(struct ptp_message *m)
return !field_is_set(m, 0, TWO_STEP);
 }
 
+/**
+ * Test whether a message from ALTERNATE Master.
+ * @param m  Message to test.
+ * @return   One if the alt_master flag in message is set, zero otherwise.
+ */
+static inline Boolean alt_master(struct ptp_message *m)
+{
+   return field_is_set(m, 0, ALT_MASTER);
+}
+
 /**
  * Convert a 64 bit word into network byte order.
  */
diff --git a/port.c b/port.c
index 871ad68..4ff3ab8 100644
--- a/port.c
+++ b/port.c
@@ -1293,11 +1293,16 @@ static void port_synchronize(struct port *p,
t1c = tmv_add(t1, tmv_add(c1, c2));
 
switch (p->state) {
+   case PS_MASTER:
+   return;
case PS_UNCALIBRATED:
case PS_SLAVE:
monitor_sync(p->slave_event_monitor,
 clock_parent_identity(p->clock), seqid,
 t1, tmv_add(c1, c2), t2);
+   monitor_computed(p->slave_event_monitor,
+clock_parent_identity(p->clock), seqid,
+tmv_sub(t2, t1c), tmv_sub(t2, t1c), 0, 1);
break;
default:
break;
@@ -1509,6 +1514,7 @@ out:
 int port_delay_request(struct port *p)
 {
struct ptp_message *msg;
+   struct ptp_message *dst;
 
/* Time to send a new request, forget current pdelay resp and fup */
if (p->peer_delay_resp) {
@@ -1541,10 +1547,20 @@ int port_delay_request(struct port *p)
msg->header.control= CTL_DELAY_REQ;
msg->header.logMessageInterval = 0x7f;
 
-   if (p->hybrid_e2e) {
-   struct ptp_message *dst = TAILQ_FIRST(>best->messages);
+   if (p->hybrid_e2e && p->state != PS_MASTER) {
+   dst = TAILQ_FIRST(>best->messages);
msg->address = dst->address;
msg->header.flagField[0] |= UNICAST;
+   } else if (p->altMaster) {
+   struct foreign_clock *fc;
+   fc = LIST_FIRST(>foreign_masters);
+   if (fc) {
+   dst = TAILQ_FIRST(>messages);
+   if (dst) {
+   msg->address = dst->address;
+   msg->header.flagField[0] |= UNICAST;
+   }
+   }
}
 
if (port_prepare_and_send(p, msg, TRANS_EVENT)) {
@@ -1595,6 +1611,10 @@ int port_tx_announce(struct port *p, struct address 
*dst, uint16_t sequence_id)
 
msg->header.flagField[1] = tp.flags;
 
+   if (p->state != PS_MASTER && clock_telecom_profile(p->clock)) {
+   msg->header.flagField[0] |= ALT_MASTER;
+   }
+
if (dst) {
msg->address = *dst;
msg->header.flagField[0] |= UNICAST;
@@ -1674,6 +1694,10 @@ 

[Linuxptp-devel] [PATCH 1/2] Slave Event Monitoring channel for the alternate connections

2022-08-24 Thread SyncMonk Technologies
A PTP Master Clock, which is not the Best Master,
may act as a master with the Alternate Master flag
set on the messages it sends.
Need to support Alternate Master, including using
Slave Event Monitoring channel for the
alternate connections (to pass along timestamps to external servo).
See ITU-T G.8275.2 Appendix III & V.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 monitor.c | 63 +++
 monitor.h |  3 +++
 pmc.c | 31 +++
 tlv.h | 21 +++
 4 files changed, 118 insertions(+)

diff --git a/monitor.c b/monitor.c
index ed451ac..1965a89 100644
--- a/monitor.c
+++ b/monitor.c
@@ -21,8 +21,10 @@ struct monitor_message {
 struct monitor {
struct port *dst_port;
struct slave_rx_sync_timing_data_tlv *sync_tlv;
+   struct slave_rx_sync_computed_data_tlv *computed_tlv;
struct slave_delay_timing_data_tlv *delay_tlv;
struct monitor_message delay;
+   struct monitor_message computed;
struct monitor_message sync;
 };
 
@@ -115,6 +117,23 @@ static int monitor_init_sync(struct monitor *monitor, 
struct address address)
return 0;
 }
 
+static int monitor_init_computed(struct monitor *monitor, struct address 
address)
+{
+   const size_t tlv_size = sizeof(struct slave_rx_sync_computed_data_tlv) +
+   sizeof(struct slave_rx_sync_computed_record) * 
RECORDS_PER_MESSAGE;
+   struct tlv_extra *extra;
+
+   extra = monitor_init_message(>computed, monitor->dst_port,
+TLV_SLAVE_RX_SYNC_COMPUTED_DATA, tlv_size,
+address);
+   if (!extra) {
+   return -1;
+   }
+   monitor->computed_tlv = (struct slave_rx_sync_computed_data_tlv *) 
extra->tlv;
+
+   return 0;
+}
+
 struct monitor *monitor_create(struct config *config, struct port *dst)
 {
struct monitor *monitor;
@@ -148,6 +167,12 @@ struct monitor *monitor_create(struct config *config, 
struct port *dst)
free(monitor);
return NULL;
}
+   if (monitor_init_computed(monitor, address)) {
+   msg_put(monitor->sync.msg);
+   msg_put(monitor->delay.msg);
+   free(monitor);
+   return NULL;
+   }
 
return monitor;
 }
@@ -193,6 +218,9 @@ void monitor_destroy(struct monitor *monitor)
if (monitor->sync.msg) {
msg_put(monitor->sync.msg);
}
+   if (monitor->computed.msg) {
+   msg_put(monitor->computed.msg);
+   }
free(monitor);
 }
 
@@ -229,3 +257,38 @@ int monitor_sync(struct monitor *monitor, struct 
PortIdentity source_pid,
}
return 0;
 }
+
+int monitor_computed(struct monitor *monitor, struct PortIdentity source_pid,
+uint16_t seqid, tmv_t offset, tmv_t pathdelay, int32_t ratio,
+uint8_t best_master)
+{
+   struct slave_rx_sync_computed_record *record;
+   struct ptp_message *msg;
+
+   if (!monitor_active(monitor)) {
+   return 0;
+   }
+
+   msg = monitor->computed.msg;
+
+   if (!pid_eq(>computed_tlv->sourcePortIdentity, _pid)) {
+   /* There was a change in remote master. Drop stale records. */
+   memcpy(>computed_tlv->sourcePortIdentity, _pid,
+  sizeof(monitor->computed_tlv->sourcePortIdentity));
+   monitor->computed.count = 0;
+   }
+
+   record = monitor->computed_tlv->record + monitor->computed.count;
+   monitor->computed_tlv->reserved= 0;
+   record->sequenceId = seqid;
+   record->offsetFromMaster   = tmv_to_TimeInterval(offset);
+   record->meanPathDelay  = tmv_to_TimeInterval(pathdelay);
+   record->scaledNeighborRateRatio= ratio;
+
+   monitor->computed.count++;
+   if (monitor->computed.count == monitor->computed.records_per_msg) {
+   monitor->computed.count = 0;
+   return monitor_forward(monitor->dst_port, msg);
+   }
+   return 0;
+}
diff --git a/monitor.h b/monitor.h
index c489aa9..9beb57e 100644
--- a/monitor.h
+++ b/monitor.h
@@ -22,4 +22,7 @@ void monitor_destroy(struct monitor *monitor);
 int monitor_sync(struct monitor *monitor, struct PortIdentity source_pid,
 uint16_t seqid, tmv_t t1, tmv_t corr, tmv_t t2);
 
+int monitor_computed(struct monitor *monitor, struct PortIdentity source_pid,
+uint16_t seqid, tmv_t offset, tmv_t pathdelay, int32_t ratio,
+uint8_t best_master);
 #endif
diff --git a/pmc.c b/pmc.c
index e218ca4..b6227dd 100644
--- a/pmc.c
+++ b/pmc.c
@@ -88,6 +88,19 @@ static void pmc_show_rx_sync_timing(struct 
slave_rx_sync_timing_record *record,
SHOW_TIMESTAMP(record->syncEventIngressTimestamp));
 }
 
+static void 

[Linuxptp-devel] [PATCH 1/4] [Interface Rate TLV] function to support get interface speed via ethtool

2022-07-27 Thread SyncMonk Technologies
When master and slave instance interacting with each other operating
at different interface speed, delay assymetry needs to be compensated
as described in G.8271 appendix V.

In this patch we are adding changes to get the interface speed using
ethtool.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 sk.c | 69 
 sk.h | 18 
 2 files changed, 87 insertions(+)

diff --git a/sk.c b/sk.c
index 80075be..d372fef 100644
--- a/sk.c
+++ b/sk.c
@@ -205,6 +205,75 @@ failed:
return -1;
 }
 
+int sk_get_if_info(const char *name, struct sk_if_info *if_info)
+{
+#ifdef ETHTOOL_GLINKSETTINGS
+   struct ifreq ifr;
+   int fd, err;
+
+   struct {
+   struct ethtool_link_settings req;
+   /* link_mode_data consists of supported[], advertising[]
+* and lp_advertising[] with size up to 127 each.
+* The actual size is provided by the kernel.
+*/
+   __u32 link_mode_data[3 * 127];
+   } ecmd;
+
+   memset(, 0, sizeof(ifr));
+   memset(, 0, sizeof(ecmd));
+
+   fd = socket(AF_INET, SOCK_DGRAM, 0);
+   if (fd < 0) {
+   goto failed;
+   }
+
+   ecmd.req.cmd = ETHTOOL_GLINKSETTINGS;
+
+   strncpy(ifr.ifr_name, name, IFNAMSIZ - 1);
+   ifr.ifr_data = (char *) 
+
+   /* Handshake with kernel to determine number of words for link
+* mode bitmaps. When requested number of bitmap words is not
+* the one expected by kernel, the latter returns the integer
+* opposite of what it is expecting. We request length 0 below
+* (aka. invalid bitmap length) to get this info.
+*/
+   err = ioctl(fd, SIOCETHTOOL, );
+   if (err < 0) {
+   pr_err("ioctl SIOCETHTOOL failed: %m");
+   close(fd);
+   goto failed;
+   }
+
+   if (ecmd.req.link_mode_masks_nwords >= 0 ||
+   ecmd.req.cmd != ETHTOOL_GLINKSETTINGS) {
+   return 1;
+   }
+   ecmd.req.link_mode_masks_nwords = -ecmd.req.link_mode_masks_nwords;
+
+   err = ioctl(fd, SIOCETHTOOL, );
+   if (err < 0) {
+   pr_err("ioctl SIOCETHTOOL failed: %m");
+   close(fd);
+   goto failed;
+   }
+
+   close(fd);
+
+   /* copy the necessary data to sk_info */
+   memset(if_info, 0, sizeof(struct sk_if_info));
+   if_info->valid = 1;
+   if_info->speed = ecmd.req.speed;
+
+   return 0;
+failed:
+#endif
+   /* clear data and ensure it is not marked valid */
+   memset(if_info, 0, sizeof(struct sk_if_info));
+   return -1;
+}
+
 static int sk_interface_guidaddr(const char *name, unsigned char *guid)
 {
char file_name[64], buf[64], addr[8];
diff --git a/sk.h b/sk.h
index 486dbc4..853aadf 100644
--- a/sk.h
+++ b/sk.h
@@ -49,6 +49,16 @@ struct sk_ts_info {
unsigned int rx_filters;
 };
 
+/**
+ * Contains interface information returned by theGLINKSETTINGS ioctl.
+ * @valid:set to non-zero when the info struct contains valid data.
+ * @speed:interface speed.
+ */
+struct sk_if_info {
+   int valid;
+   int speed;
+};
+
 /**
  * Obtains a socket suitable for use with sk_interface_index().
  * @return  An open socket on success, -1 otherwise.
@@ -78,6 +88,14 @@ int sk_general_init(int fd);
  */
 int sk_get_ts_info(const char *name, struct sk_ts_info *sk_info);
 
+/**
+ * Obtain supporte interface information
+ * @param name The name of the interface
+ * @param info  Struct containing obtained interface information.
+ * @return  zero on success, negative on failure.
+ */
+int sk_get_if_info(const char *name, struct sk_if_info *sk_info);
+
 /**
  * Obtain the MAC address of a network interface.
  * @param name  The name of the interface
-- 
2.17.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 4/4] [Interface Rate TLV] adding delay asymmetry calculation

2022-07-27 Thread SyncMonk Technologies
Delay asymmetry calculation based on the PTP port interface speed of
master obtained from TLV and the slave interface rate obtained by ethtool.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 interface.c   |  9 +
 interface.h   |  7 +++
 port_private.h|  1 +
 port_signaling.c  | 33 -
 ptp4l.8   |  6 ++
 unicast_service.c | 34 ++
 6 files changed, 89 insertions(+), 1 deletion(-)

diff --git a/interface.c b/interface.c
index 9bcb343..ec8964c 100644
--- a/interface.c
+++ b/interface.c
@@ -93,3 +93,12 @@ int interface_get_vclock(struct interface *iface)
 {
return iface->vclock;
 }
+
+uint64_t interface_bitperiod(struct interface *iface)
+{
+   if (!iface->if_info.valid)
+   return 0;
+
+   /* Megabits per secon converted to attoseconds per bit. */
+   return 1/ iface->if_info.speed;
+}
diff --git a/interface.h b/interface.h
index 5289a7f..e1dc0e8 100644
--- a/interface.h
+++ b/interface.h
@@ -113,4 +113,11 @@ void interface_set_vclock(struct interface *iface, int 
vclock);
  */
 int interface_get_vclock(struct interface *iface);
 
+/**
+ * Obtains the interface bit period based on the speed.
+ * @param iface  The interface of interest.
+ * @return   if valid speed return interface bitperiod in atto seconds.
+ */
+uint64_t interface_bitperiod(struct interface *iface);
+
 #endif
diff --git a/port_private.h b/port_private.h
index d27dceb..d1a1e76 100644
--- a/port_private.h
+++ b/port_private.h
@@ -145,6 +145,7 @@ struct port {
UInteger8   versionNumber; /* UInteger4 */
UInteger8   delay_response_counter;
UInteger8   delay_response_timeout;
+   Integer64   portAsymmetry;
struct PortStatsstats;
struct PortServiceStatsservice_stats;
/* foreignMasterDS */
diff --git a/port_signaling.c b/port_signaling.c
index ed217c0..4b86b7e 100644
--- a/port_signaling.c
+++ b/port_signaling.c
@@ -103,10 +103,38 @@ static int process_interval_request(struct port *p,
return 0;
 }
 
+static int process_interface_rate(struct port *p,
+ struct msg_interface_rate_tlv *r)
+{
+   Integer64 delayAsymmetry;
+   doublensDelay;
+   Integer64 slaveBitPeriod;
+   Integer64 masterBitPeriod;
+
+   if (clock_interface_rate_tlv (p->clock) &&
+   interface_ifinfo_valid(p->iface)) {
+   slaveBitPeriod = interface_bitperiod(p->iface);
+   masterBitPeriod = r->interfaceBitPeriod;
+
+   /* Delay Asymmetry Calculation */
+   nsDelay = (masterBitPeriod - slaveBitPeriod) / (2 * 1.0e9);
+   delayAsymmetry =
+   (r->numberOfBitsAfterTimestamp - 
r->numberOfBitsBeforeTimestamp)  * nsDelay;
+
+   if (delayAsymmetry != p->portAsymmetry) {
+   p->asymmetry += ((delayAsymmetry - p->portAsymmetry) << 
16);
+   p->portAsymmetry = delayAsymmetry;
+   }
+   }
+   return 0;
+}
+
+
 int process_signaling(struct port *p, struct ptp_message *m)
 {
struct tlv_extra *extra;
struct msg_interval_req_tlv *r;
+   struct msg_interface_rate_tlv *rate;
int err = 0, result;
 
switch (p->state) {
@@ -161,10 +189,13 @@ int process_signaling(struct port *p, struct ptp_message 
*m)
 
case TLV_ORGANIZATION_EXTENSION:
r = (struct msg_interval_req_tlv *) extra->tlv;
-
+   rate = (struct msg_interface_rate_tlv *) extra->tlv;
if (0 == memcmp(r->id, ieee8021_id, 
sizeof(ieee8021_id)) &&
r->subtype[0] == 0 && r->subtype[1] == 0 && 
r->subtype[2] == 2)
err = process_interval_request(p, r);
+   else if (0 == memcmp(r->id, itu_t_id, sizeof(itu_t_id)) 
&&
+   r->subtype[0] == 0 && r->subtype[1] == 0 && 
r->subtype[2] == 2)
+   err = process_interface_rate(p, rate);
break;
}
}
diff --git a/ptp4l.8 b/ptp4l.8
index 1268802..140523c 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -705,6 +705,12 @@ the interval, the sample will be printed instead of the 
statistics. The
 messages are printed at the LOG_INFO level.
 The default is 0 (1 second).
 .TP
+.B interface_rate_tlv
+When master and slave instances are operating at different interface rate,
+delay asymmetry caused due to different interface rate needs to be compensated.
+The master and slave exhanges their interface rate based on interface rate TLV
+as per G.8275.2 Annex D.
+The default is 0 (does not support interface rate tlv).
 .B time_stamping
 The time stamping method to be used.  The allowed values are hardware,
 software, 

[Linuxptp-devel] [PATCH 3/4] [Interface Rate TLV] organization TLV support for interface rate

2022-07-27 Thread SyncMonk Technologies
adding interface rate TLV as defined by ITU-T G.8275.2 Annex D to
enable master to communicate PTP port interface rate to slave.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 clock.c  |  7 +++
 clock.h  |  7 +++
 config.c |  1 +
 pdt.h|  1 +
 tlv.c|  1 +
 tlv.h| 14 ++
 6 files changed, 31 insertions(+)

diff --git a/clock.c b/clock.c
index de69c52..cee469b 100644
--- a/clock.c
+++ b/clock.c
@@ -137,6 +137,7 @@ struct clock {
struct monitor *slave_event_monitor;
int step_window_counter;
int step_window;
+   bool iface_rate_tlv;
 };
 
 struct clock the_clock;
@@ -1106,6 +1107,7 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
c->utc_offset = config_get_int(config, NULL, "utc_offset");
c->time_source = config_get_int(config, NULL, "timeSource");
c->step_window = config_get_int(config, NULL, "step_window");
+   c->iface_rate_tlv = config_get_int(config, NULL, "interface_rate_tlv");
 
if (c->free_running) {
c->clkid = CLOCK_INVALID;
@@ -2087,3 +2089,8 @@ enum servo_state clock_servo_state(struct clock *c)
 {
return c->servo_state;
 }
+
+bool clock_interface_rate_tlv (struct clock *c)
+{
+   return c->iface_rate_tlv;
+}
diff --git a/clock.h b/clock.h
index 0534f21..b393c3e 100644
--- a/clock.h
+++ b/clock.h
@@ -388,4 +388,11 @@ void clock_check_ts(struct clock *c, uint64_t ts);
  */
 double clock_rate_ratio(struct clock *c);
 
+/**
+ * Obtain interface rate tlv support configuration.
+ * @param c  The clock instance.
+ * @return   The interface_rate_supoort config true if supported, else false.
+ */
+bool clock_interface_rate_tlv(struct clock *c);
+
 #endif
diff --git a/config.c b/config.c
index b5cf397..76dd755 100644
--- a/config.c
+++ b/config.c
@@ -241,6 +241,7 @@ struct config_item config_tab[] = {
GLOB_ITEM_ENU("clock_type", CLOCK_TYPE_ORDINARY, clock_type_enu),
GLOB_ITEM_ENU("dataset_comparison", DS_CMP_IEEE1588, dataset_comp_enu),
PORT_ITEM_INT("delayAsymmetry", 0, INT_MIN, INT_MAX),
+   GLOB_ITEM_INT("interface_rate_tlv", 0, 0, 1),
PORT_ITEM_ENU("delay_filter", FILTER_MOVING_MEDIAN, delay_filter_enu),
PORT_ITEM_INT("delay_filter_length", 10, 1, INT_MAX),
PORT_ITEM_ENU("delay_mechanism", DM_E2E, delay_mech_enu),
diff --git a/pdt.h b/pdt.h
index e46b218..1ad23d4 100644
--- a/pdt.h
+++ b/pdt.h
@@ -39,6 +39,7 @@ typedef uint16_t  UInteger16;
 typedef int32_t   Integer32;
 typedef uint32_t  UInteger32;
 typedef int64_t   Integer64;
+typedef uint64_t  UInteger64;
 typedef uint8_t   Octet;
 
 #endif
diff --git a/tlv.c b/tlv.c
index 1c13460..35bee4f 100644
--- a/tlv.c
+++ b/tlv.c
@@ -35,6 +35,7 @@
(tlv->length < sizeof(struct type) - sizeof(struct TLV))
 
 uint8_t ieee8021_id[3] = { IEEE_802_1_COMMITTEE };
+uint8_t itu_t_id[3] = { ITU_T_COMMITTEE };
 
 static TAILQ_HEAD(tlv_pool, tlv_extra) tlv_pool =
TAILQ_HEAD_INITIALIZER(tlv_pool);
diff --git a/tlv.h b/tlv.h
index 8966696..ec22e2f 100644
--- a/tlv.h
+++ b/tlv.h
@@ -395,6 +395,20 @@ struct tlv_extra {
};
 };
 
+/* Organizationally Unique Identifiers */
+#define ITU_T_COMMITTEE 0x00, 0x19, 0xA7
+extern uint8_t itu_t_id[3];
+
+struct msg_interface_rate_tlv {
+   Enumeration16 type;
+   UInteger16length;
+   Octet id[3];
+   Octet subtype[3];
+   UInteger64interfaceBitPeriod;
+   UInteger16numberOfBitsBeforeTimestamp;
+   UInteger16numberOfBitsAfterTimestamp;
+} PACKED;
+
 /**
  * Allocates a new tlv_extra structure.
  * @return  Pointer to a new structure on success or NULL otherwise.
-- 
2.17.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 2/4] [Interface Rate TLV] adding speed field information for interface

2022-07-27 Thread SyncMonk Technologies
Get the interface speed related information using ethtool

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 clock.c |  2 ++
 interface.c | 11 +++
 interface.h | 14 ++
 port.c  |  5 +
 4 files changed, 32 insertions(+)

diff --git a/clock.c b/clock.c
index d37bb87..de69c52 100644
--- a/clock.c
+++ b/clock.c
@@ -1004,6 +1004,8 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
memset(ts_label, 0, sizeof(ts_label));
if (!rtnl_get_ts_device(interface_name(iface), ts_label))
interface_set_label(iface, ts_label);
+   /* Interface speed information */
+   interface_get_ifinfo(iface);
interface_get_tsinfo(iface);
if (interface_tsinfo_valid(iface) &&
!interface_tsmodes_supported(iface, required_modes)) {
diff --git a/interface.c b/interface.c
index 6c2630c..9bcb343 100644
--- a/interface.c
+++ b/interface.c
@@ -12,6 +12,7 @@ struct interface {
char name[MAX_IFNAME_SIZE + 1];
char ts_label[MAX_IFNAME_SIZE + 1];
struct sk_ts_info ts_info;
+   struct sk_if_info if_info;
int vclock;
 };
 
@@ -40,6 +41,11 @@ int interface_get_tsinfo(struct interface *iface)
return sk_get_ts_info(iface->ts_label, >ts_info);
 }
 
+int interface_get_ifinfo(struct interface *iface)
+{
+   return sk_get_if_info(iface->ts_label, >if_info);
+}
+
 const char *interface_label(struct interface *iface)
 {
return iface->ts_label;
@@ -65,6 +71,11 @@ bool interface_tsinfo_valid(struct interface *iface)
return iface->ts_info.valid ? true : false;
 }
 
+bool interface_ifinfo_valid(struct interface *iface)
+{
+   return iface->if_info.valid ? true : false;
+}
+
 bool interface_tsmodes_supported(struct interface *iface, int modes)
 {
if ((iface->ts_info.so_timestamping & modes) == modes) {
diff --git a/interface.h b/interface.h
index 5fc7836..5289a7f 100644
--- a/interface.h
+++ b/interface.h
@@ -40,6 +40,13 @@ void interface_destroy(struct interface *iface);
  */
 int interface_get_tsinfo(struct interface *iface);
 
+/**
+ * Populate the time stamping information of a given interface.
+ * @param iface  The interface of interest.
+ * @return   zero on success, negative on failure.
+ */
+int interface_get_ifinfo(struct interface *iface);
+
 /**
  * Obtain the time stamping label of a network interface.  This can be
  * different from the name of the interface when bonding is in effect.
@@ -77,6 +84,13 @@ void interface_set_label(struct interface *iface, const char 
*label);
  */
 bool interface_tsinfo_valid(struct interface *iface);
 
+/**
+ * Tests whether an interface's interface information is valid or not.
+ * @param iface  The interface of interest.
+ * @return   True if the interface information is valid, false otherwise.
+ */
+bool interface_ifinfo_valid(struct interface *iface);
+
 /**
  * Tests whether an interface supports a set of given time stamping modes.
  * @param iface  The interface of interest.
diff --git a/port.c b/port.c
index 871ad68..2232b69 100644
--- a/port.c
+++ b/port.c
@@ -2726,6 +2726,11 @@ void port_link_status(void *ctx, int linkup, int 
ts_index)
p->link_status = link_state;
} else {
p->link_status = link_state | LINK_STATE_CHANGED;
+   /* Update Interface speed information on Link up*/
+   if (linkup) {
+   interface_get_ifinfo(p->iface);
+   }
+
pr_notice("%s: link %s", p->log_name, linkup ? "up" : "down");
}
 
-- 
2.17.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 3/4] [Interface Rate TLV] organization TLV support for interface rate

2022-07-26 Thread SyncMonk Technologies
adding interface rate TLV as defined by ITU-T G.8275.2 Annex D to
enable master to communicate PTP port interface rate to slave.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 clock.c  |  7 +++
 clock.h  |  7 +++
 config.c |  1 +
 pdt.h|  1 +
 tlv.c|  1 +
 tlv.h| 14 ++
 6 files changed, 31 insertions(+)

diff --git a/clock.c b/clock.c
index de69c52..cee469b 100644
--- a/clock.c
+++ b/clock.c
@@ -137,6 +137,7 @@ struct clock {
struct monitor *slave_event_monitor;
int step_window_counter;
int step_window;
+   bool iface_rate_tlv;
 };
 
 struct clock the_clock;
@@ -1106,6 +1107,7 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
c->utc_offset = config_get_int(config, NULL, "utc_offset");
c->time_source = config_get_int(config, NULL, "timeSource");
c->step_window = config_get_int(config, NULL, "step_window");
+   c->iface_rate_tlv = config_get_int(config, NULL, "interface_rate_tlv");
 
if (c->free_running) {
c->clkid = CLOCK_INVALID;
@@ -2087,3 +2089,8 @@ enum servo_state clock_servo_state(struct clock *c)
 {
return c->servo_state;
 }
+
+bool clock_interface_rate_tlv (struct clock *c)
+{
+   return c->iface_rate_tlv;
+}
diff --git a/clock.h b/clock.h
index 0534f21..b393c3e 100644
--- a/clock.h
+++ b/clock.h
@@ -388,4 +388,11 @@ void clock_check_ts(struct clock *c, uint64_t ts);
  */
 double clock_rate_ratio(struct clock *c);
 
+/**
+ * Obtain interface rate tlv support configuration.
+ * @param c  The clock instance.
+ * @return   The interface_rate_supoort config true if supported, else false.
+ */
+bool clock_interface_rate_tlv(struct clock *c);
+
 #endif
diff --git a/config.c b/config.c
index b5cf397..76dd755 100644
--- a/config.c
+++ b/config.c
@@ -241,6 +241,7 @@ struct config_item config_tab[] = {
GLOB_ITEM_ENU("clock_type", CLOCK_TYPE_ORDINARY, clock_type_enu),
GLOB_ITEM_ENU("dataset_comparison", DS_CMP_IEEE1588, dataset_comp_enu),
PORT_ITEM_INT("delayAsymmetry", 0, INT_MIN, INT_MAX),
+   GLOB_ITEM_INT("interface_rate_tlv", 0, 0, 1),
PORT_ITEM_ENU("delay_filter", FILTER_MOVING_MEDIAN, delay_filter_enu),
PORT_ITEM_INT("delay_filter_length", 10, 1, INT_MAX),
PORT_ITEM_ENU("delay_mechanism", DM_E2E, delay_mech_enu),
diff --git a/pdt.h b/pdt.h
index e46b218..1ad23d4 100644
--- a/pdt.h
+++ b/pdt.h
@@ -39,6 +39,7 @@ typedef uint16_t  UInteger16;
 typedef int32_t   Integer32;
 typedef uint32_t  UInteger32;
 typedef int64_t   Integer64;
+typedef uint64_t  UInteger64;
 typedef uint8_t   Octet;
 
 #endif
diff --git a/tlv.c b/tlv.c
index 1c13460..35bee4f 100644
--- a/tlv.c
+++ b/tlv.c
@@ -35,6 +35,7 @@
(tlv->length < sizeof(struct type) - sizeof(struct TLV))
 
 uint8_t ieee8021_id[3] = { IEEE_802_1_COMMITTEE };
+uint8_t itu_t_id[3] = { ITU_T_COMMITTEE };
 
 static TAILQ_HEAD(tlv_pool, tlv_extra) tlv_pool =
TAILQ_HEAD_INITIALIZER(tlv_pool);
diff --git a/tlv.h b/tlv.h
index 8966696..ec22e2f 100644
--- a/tlv.h
+++ b/tlv.h
@@ -395,6 +395,20 @@ struct tlv_extra {
};
 };
 
+/* Organizationally Unique Identifiers */
+#define ITU_T_COMMITTEE 0x00, 0x19, 0xA7
+extern uint8_t itu_t_id[3];
+
+struct msg_interface_rate_tlv {
+   Enumeration16 type;
+   UInteger16length;
+   Octet id[3];
+   Octet subtype[3];
+   UInteger64interfaceBitPeriod;
+   UInteger16numberOfBitsBeforeTimestamp;
+   UInteger16numberOfBitsAfterTimestamp;
+} PACKED;
+
 /**
  * Allocates a new tlv_extra structure.
  * @return  Pointer to a new structure on success or NULL otherwise.
-- 
2.17.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 4/4] [Interface Rate TLV] adding delay asymmetry calculation

2022-07-26 Thread SyncMonk Technologies
Delay asymmetry calculation based on the PTP port interface speed of
master obtained from TLV and the slave interface rate obtained by ethtool.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 interface.c   |  9 +
 interface.h   |  7 +++
 port_private.h|  1 +
 port_signaling.c  | 33 -
 ptp4l.8   |  6 ++
 unicast_service.c | 34 ++
 6 files changed, 89 insertions(+), 1 deletion(-)

diff --git a/interface.c b/interface.c
index 9bcb343..ec8964c 100644
--- a/interface.c
+++ b/interface.c
@@ -93,3 +93,12 @@ int interface_get_vclock(struct interface *iface)
 {
return iface->vclock;
 }
+
+uint64_t interface_bitperiod(struct interface *iface)
+{
+   if (!iface->if_info.valid)
+   return 0;
+
+   /* Megabits per secon converted to attoseconds per bit. */
+   return 1/ iface->if_info.speed;
+}
diff --git a/interface.h b/interface.h
index 5289a7f..e1dc0e8 100644
--- a/interface.h
+++ b/interface.h
@@ -113,4 +113,11 @@ void interface_set_vclock(struct interface *iface, int 
vclock);
  */
 int interface_get_vclock(struct interface *iface);
 
+/**
+ * Obtains the interface bit period based on the speed.
+ * @param iface  The interface of interest.
+ * @return   if valid speed return interface bitperiod in atto seconds.
+ */
+uint64_t interface_bitperiod(struct interface *iface);
+
 #endif
diff --git a/port_private.h b/port_private.h
index d27dceb..d1a1e76 100644
--- a/port_private.h
+++ b/port_private.h
@@ -145,6 +145,7 @@ struct port {
UInteger8   versionNumber; /* UInteger4 */
UInteger8   delay_response_counter;
UInteger8   delay_response_timeout;
+   Integer64   portAsymmetry;
struct PortStatsstats;
struct PortServiceStatsservice_stats;
/* foreignMasterDS */
diff --git a/port_signaling.c b/port_signaling.c
index ed217c0..4b86b7e 100644
--- a/port_signaling.c
+++ b/port_signaling.c
@@ -103,10 +103,38 @@ static int process_interval_request(struct port *p,
return 0;
 }
 
+static int process_interface_rate(struct port *p,
+ struct msg_interface_rate_tlv *r)
+{
+   Integer64 delayAsymmetry;
+   doublensDelay;
+   Integer64 slaveBitPeriod;
+   Integer64 masterBitPeriod;
+
+   if (clock_interface_rate_tlv (p->clock) &&
+   interface_ifinfo_valid(p->iface)) {
+   slaveBitPeriod = interface_bitperiod(p->iface);
+   masterBitPeriod = r->interfaceBitPeriod;
+
+   /* Delay Asymmetry Calculation */
+   nsDelay = (masterBitPeriod - slaveBitPeriod) / (2 * 1.0e9);
+   delayAsymmetry =
+   (r->numberOfBitsAfterTimestamp - 
r->numberOfBitsBeforeTimestamp)  * nsDelay;
+
+   if (delayAsymmetry != p->portAsymmetry) {
+   p->asymmetry += ((delayAsymmetry - p->portAsymmetry) << 
16);
+   p->portAsymmetry = delayAsymmetry;
+   }
+   }
+   return 0;
+}
+
+
 int process_signaling(struct port *p, struct ptp_message *m)
 {
struct tlv_extra *extra;
struct msg_interval_req_tlv *r;
+   struct msg_interface_rate_tlv *rate;
int err = 0, result;
 
switch (p->state) {
@@ -161,10 +189,13 @@ int process_signaling(struct port *p, struct ptp_message 
*m)
 
case TLV_ORGANIZATION_EXTENSION:
r = (struct msg_interval_req_tlv *) extra->tlv;
-
+   rate = (struct msg_interface_rate_tlv *) extra->tlv;
if (0 == memcmp(r->id, ieee8021_id, 
sizeof(ieee8021_id)) &&
r->subtype[0] == 0 && r->subtype[1] == 0 && 
r->subtype[2] == 2)
err = process_interval_request(p, r);
+   else if (0 == memcmp(r->id, itu_t_id, sizeof(itu_t_id)) 
&&
+   r->subtype[0] == 0 && r->subtype[1] == 0 && 
r->subtype[2] == 2)
+   err = process_interface_rate(p, rate);
break;
}
}
diff --git a/ptp4l.8 b/ptp4l.8
index 1268802..140523c 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -705,6 +705,12 @@ the interval, the sample will be printed instead of the 
statistics. The
 messages are printed at the LOG_INFO level.
 The default is 0 (1 second).
 .TP
+.B interface_rate_tlv
+When master and slave instances are operating at different interface rate,
+delay asymmetry caused due to different interface rate needs to be compensated.
+The master and slave exhanges their interface rate based on interface rate TLV
+as per G.8275.2 Annex D.
+The default is 0 (does not support interface rate tlv).
 .B time_stamping
 The time stamping method to be used.  The allowed values are hardware,
 software, 

[Linuxptp-devel] [PATCH 1/4] [Interface Rate TLV] function to support get interface speed via ethtool

2022-07-26 Thread SyncMonk Technologies
When master and slave instance interacting with each other operating
at different interface speed, delay assymetry needs to be compensated
as described in G.8271 appendix V.

In this patch we are adding changes to get the interface speed using
ethtool.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 sk.c | 65 
 sk.h | 18 +
 2 files changed, 83 insertions(+)

diff --git a/sk.c b/sk.c
index 80075be..7df14db 100644
--- a/sk.c
+++ b/sk.c
@@ -205,6 +205,71 @@ failed:
return -1;
 }
 
+int sk_get_if_info(const char *name, struct sk_if_info *if_info)
+{
+#ifdef ETHTOOL_GLINKSETTINGS
+   struct ifreq ifr;
+   int fd, err;
+
+   struct {
+   struct ethtool_link_settings req;
+   __u32 link_mode_data[3 * 127];
+   } ecmd;
+
+   memset(, 0, sizeof(ifr));
+   memset(, 0, sizeof(ecmd));
+
+   fd = socket(AF_INET, SOCK_DGRAM, 0);
+   if (fd < 0) {
+   goto failed;
+   }
+
+   ecmd.req.cmd = ETHTOOL_GLINKSETTINGS;
+
+   strncpy(ifr.ifr_name, name, IFNAMSIZ - 1);
+   ifr.ifr_data = (char *) 
+
+   /* Handshake with kernel to determine number of words for link
+* mode bitmaps. When requested number of bitmap words is not
+* the one expected by kernel, the latter returns the integer
+* opposite of what it is expecting. We request length 0 below
+* (aka. invalid bitmap length) to get this info.
+*/
+   err = ioctl(fd, SIOCETHTOOL, );
+   if (err < 0) {
+   pr_err("ioctl SIOCETHTOOL failed: %m");
+   close(fd);
+   goto failed;
+   }
+
+   if (ecmd.req.link_mode_masks_nwords >= 0 ||
+   ecmd.req.cmd != ETHTOOL_GLINKSETTINGS) {
+   return 1;
+   }
+   ecmd.req.link_mode_masks_nwords = -ecmd.req.link_mode_masks_nwords;
+
+   err = ioctl(fd, SIOCETHTOOL, );
+   if (err < 0) {
+   pr_err("ioctl SIOCETHTOOL failed: %m");
+   close(fd);
+   goto failed;
+   }
+
+   close(fd);
+
+   /* copy the necessary data to sk_info */
+   memset(if_info, 0, sizeof(struct sk_if_info));
+   if_info->valid = 1;
+   if_info->speed = ecmd.req.speed;
+
+   return 0;
+failed:
+#endif
+   /* clear data and ensure it is not marked valid */
+   memset(if_info, 0, sizeof(struct sk_if_info));
+   return -1;
+}
+
 static int sk_interface_guidaddr(const char *name, unsigned char *guid)
 {
char file_name[64], buf[64], addr[8];
diff --git a/sk.h b/sk.h
index 486dbc4..853aadf 100644
--- a/sk.h
+++ b/sk.h
@@ -49,6 +49,16 @@ struct sk_ts_info {
unsigned int rx_filters;
 };
 
+/**
+ * Contains interface information returned by theGLINKSETTINGS ioctl.
+ * @valid:set to non-zero when the info struct contains valid data.
+ * @speed:interface speed.
+ */
+struct sk_if_info {
+   int valid;
+   int speed;
+};
+
 /**
  * Obtains a socket suitable for use with sk_interface_index().
  * @return  An open socket on success, -1 otherwise.
@@ -78,6 +88,14 @@ int sk_general_init(int fd);
  */
 int sk_get_ts_info(const char *name, struct sk_ts_info *sk_info);
 
+/**
+ * Obtain supporte interface information
+ * @param name The name of the interface
+ * @param info  Struct containing obtained interface information.
+ * @return  zero on success, negative on failure.
+ */
+int sk_get_if_info(const char *name, struct sk_if_info *sk_info);
+
 /**
  * Obtain the MAC address of a network interface.
  * @param name  The name of the interface
-- 
2.17.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 2/4] [Interface Rate TLV] adding speed field information for interface

2022-07-26 Thread SyncMonk Technologies
Get the interface speed related information using ethtool

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 clock.c |  2 ++
 interface.c | 11 +++
 interface.h | 14 ++
 port.c  |  5 +
 4 files changed, 32 insertions(+)

diff --git a/clock.c b/clock.c
index d37bb87..de69c52 100644
--- a/clock.c
+++ b/clock.c
@@ -1004,6 +1004,8 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
memset(ts_label, 0, sizeof(ts_label));
if (!rtnl_get_ts_device(interface_name(iface), ts_label))
interface_set_label(iface, ts_label);
+   /* Interface speed information */
+   interface_get_ifinfo(iface);
interface_get_tsinfo(iface);
if (interface_tsinfo_valid(iface) &&
!interface_tsmodes_supported(iface, required_modes)) {
diff --git a/interface.c b/interface.c
index 6c2630c..9bcb343 100644
--- a/interface.c
+++ b/interface.c
@@ -12,6 +12,7 @@ struct interface {
char name[MAX_IFNAME_SIZE + 1];
char ts_label[MAX_IFNAME_SIZE + 1];
struct sk_ts_info ts_info;
+   struct sk_if_info if_info;
int vclock;
 };
 
@@ -40,6 +41,11 @@ int interface_get_tsinfo(struct interface *iface)
return sk_get_ts_info(iface->ts_label, >ts_info);
 }
 
+int interface_get_ifinfo(struct interface *iface)
+{
+   return sk_get_if_info(iface->ts_label, >if_info);
+}
+
 const char *interface_label(struct interface *iface)
 {
return iface->ts_label;
@@ -65,6 +71,11 @@ bool interface_tsinfo_valid(struct interface *iface)
return iface->ts_info.valid ? true : false;
 }
 
+bool interface_ifinfo_valid(struct interface *iface)
+{
+   return iface->if_info.valid ? true : false;
+}
+
 bool interface_tsmodes_supported(struct interface *iface, int modes)
 {
if ((iface->ts_info.so_timestamping & modes) == modes) {
diff --git a/interface.h b/interface.h
index 5fc7836..5289a7f 100644
--- a/interface.h
+++ b/interface.h
@@ -40,6 +40,13 @@ void interface_destroy(struct interface *iface);
  */
 int interface_get_tsinfo(struct interface *iface);
 
+/**
+ * Populate the time stamping information of a given interface.
+ * @param iface  The interface of interest.
+ * @return   zero on success, negative on failure.
+ */
+int interface_get_ifinfo(struct interface *iface);
+
 /**
  * Obtain the time stamping label of a network interface.  This can be
  * different from the name of the interface when bonding is in effect.
@@ -77,6 +84,13 @@ void interface_set_label(struct interface *iface, const char 
*label);
  */
 bool interface_tsinfo_valid(struct interface *iface);
 
+/**
+ * Tests whether an interface's interface information is valid or not.
+ * @param iface  The interface of interest.
+ * @return   True if the interface information is valid, false otherwise.
+ */
+bool interface_ifinfo_valid(struct interface *iface);
+
 /**
  * Tests whether an interface supports a set of given time stamping modes.
  * @param iface  The interface of interest.
diff --git a/port.c b/port.c
index 871ad68..2232b69 100644
--- a/port.c
+++ b/port.c
@@ -2726,6 +2726,11 @@ void port_link_status(void *ctx, int linkup, int 
ts_index)
p->link_status = link_state;
} else {
p->link_status = link_state | LINK_STATE_CHANGED;
+   /* Update Interface speed information on Link up*/
+   if (linkup) {
+   interface_get_ifinfo(p->iface);
+   }
+
pr_notice("%s: link %s", p->log_name, linkup ? "up" : "down");
}
 
-- 
2.17.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH] G.8275.2 support for delay_mechanism NO_MECHANISM

2022-07-25 Thread SyncMonk Technologies
As per IEEE1588-2019, Table 21 adding NO_MECHANISM support. In this
case port does not implement the delay mechanism.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 clock.c  |  4 +++-
 config.c |  1 +
 dm.h |  3 +++
 port.c   |  8 
 port.h   |  7 +++
 ptp4l.8  |  2 +-
 unicast_client.c | 11 ---
 7 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/clock.c b/clock.c
index 16ca6ed..d37bb87 100644
--- a/clock.c
+++ b/clock.c
@@ -1998,8 +1998,10 @@ static void handle_state_decision_event(struct clock *c)
if (c->sanity_check)
clockcheck_reset(c->sanity_check);
tsproc_reset(c->tsproc, 1);
-   if (!tmv_is_zero(c->initial_delay))
+   if (!tmv_is_zero(c->initial_delay) || (best &&
+   port_delay_mechanism(best->port) == DM_NO_MECHANISM)) {
tsproc_set_delay(c->tsproc, c->initial_delay);
+   }
c->ingress_ts = tmv_zero();
c->path_delay = c->initial_delay;
c->master_local_rr = 1.0;
diff --git a/config.c b/config.c
index 6ba9996..b5cf397 100644
--- a/config.c
+++ b/config.c
@@ -171,6 +171,7 @@ static struct config_enum delay_mech_enu[] = {
{ "Auto", DM_AUTO },
{ "E2E",  DM_E2E },
{ "P2P",  DM_P2P },
+   { "NONE", DM_NO_MECHANISM },
{ NULL, 0 },
 };
 
diff --git a/dm.h b/dm.h
index 2491c63..47bd847 100644
--- a/dm.h
+++ b/dm.h
@@ -33,6 +33,9 @@ enum delay_mechanism {
 
/** Peer delay mechanism. */
DM_P2P,
+
+   /** No Delay Mechanism. */
+   DM_NO_MECHANISM = 0xFE,
 };
 
 #endif
diff --git a/port.c b/port.c
index ce1ff33..15af41a 100644
--- a/port.c
+++ b/port.c
@@ -1854,6 +1854,9 @@ int port_initialize(struct port *p)
pr_err("inhibit_delay_req can only be set when asCapable == 
'true'.");
return -1;
}
+   if (port_delay_mechanism(p) == DM_NO_MECHANISM) {
+   p->inhibit_delay_req = 1;
+   }
 
for (i = 0; i < N_TIMER_FDS; i++) {
fd[i] = -1;
@@ -3396,6 +3399,11 @@ enum port_state port_state(struct port *port)
return port->state;
 }
 
+enum delay_mechanism port_delay_mechanism(struct port *port)
+{
+   return port->delayMechanism;
+}
+
 int port_state_update(struct port *p, enum fsm_event event, int mdiff)
 {
enum port_state next = p->state_machine(p->state, event, mdiff);
diff --git a/port.h b/port.h
index 37a4e19..4854698 100644
--- a/port.h
+++ b/port.h
@@ -227,6 +227,13 @@ struct ptp_message *port_signaling_construct(struct port 
*p,
  */
 enum port_state port_state(struct port *port);
 
+/**
+ * Return  port's delay mechanism method.
+ * @param port A port instance.
+ * @return one of the @ref delay_mechanism values.
+ */
+enum delay_mechanism port_delay_mechanism(struct port *port);
+
 /**
  * Update a port's current state based on a given event.
  * @param pA pointer previously obtained via port_open().
diff --git a/ptp4l.8 b/ptp4l.8
index e33454a..1268802 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -245,7 +245,7 @@ the fault be reset immediately.
 The default is 16 seconds.
 .TP
 .B delay_mechanism
-Select the delay mechanism. Possible values are E2E, P2P and Auto.
+Select the delay mechanism. Possible values are E2E, P2P, NONE and Auto.
 The default is E2E.
 .TP
 .B hybrid_e2e
diff --git a/unicast_client.c b/unicast_client.c
index 8ebe06f..20f9558 100644
--- a/unicast_client.c
+++ b/unicast_client.c
@@ -26,6 +26,7 @@
 
 #define E2E_SYDY_MASK  (1 << ANNOUNCE | 1 << SYNC | 1 << DELAY_RESP)
 #define P2P_SYDY_MASK  (1 << ANNOUNCE | 1 << SYNC)
+#define E2E_SY_MASK (1 << ANNOUNCE | 1 << SYNC)
 
 static int attach_ack(struct ptp_message *msg, uint8_t message_type_flags)
 {
@@ -200,7 +201,8 @@ static int unicast_client_renew(struct port *p,
if (err) {
goto out;
}
-   if (p->delayMechanism != DM_P2P) {
+   if (p->delayMechanism != DM_P2P &&
+   p->delayMechanism != DM_NO_MECHANISM) {
err = attach_request(msg, p->logMinDelayReqInterval,
 DELAY_RESP,
 p->unicast_req_duration);
@@ -253,9 +255,10 @@ static int unicast_client_sydy(struct port *p,
if (err) {
goto out;
}
-   if (p->delayMechanism != DM_P2P) {
+   if (p->delayMechanism != DM_P2P &&
+   p->delayMechanism != DM_NO_MECHANISM) {
err = attach_request(msg, p->logMinDelayReqInterval, DELAY_RESP,
-p->unicast_req_duration);
+   p->unicast_req_duration);
if (err) {
goto out;

[Linuxptp-devel] [PATCH 3/3] [Interface Rate TLV] adding TLV support

2022-06-22 Thread SyncMonk Technologies
- adding organizational TLV support for interface rate
- delay asymmetry calculation for master and slave

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 clock.c   | 12 
 clock.h   | 14 ++
 config.c  |  1 +
 interface.c   | 15 +++
 interface.h   |  7 +++
 pdt.h |  1 +
 port_private.h|  1 +
 port_signaling.c  | 33 -
 ptp4l.8   |  6 ++
 tlv.c |  1 +
 tlv.h | 14 ++
 unicast_service.c | 35 +++
 12 files changed, 139 insertions(+), 1 deletion(-)

diff --git a/clock.c b/clock.c
index 8f328e5..e271f5a 100644
--- a/clock.c
+++ b/clock.c
@@ -137,6 +137,7 @@ struct clock {
struct monitor *slave_event_monitor;
int step_window_counter;
int step_window;
+   bool iface_rate_tlv;
 };
 
 struct clock the_clock;
@@ -1107,6 +1108,7 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
c->utc_offset = config_get_int(config, NULL, "utc_offset");
c->time_source = config_get_int(config, NULL, "timeSource");
c->step_window = config_get_int(config, NULL, "step_window");
+   c->iface_rate_tlv = config_get_int(config, NULL, "interface_rate_tlv");
 
if (c->free_running) {
c->clkid = CLOCK_INVALID;
@@ -1718,6 +1720,11 @@ int clock_slave_only(struct clock *c)
return c->dds.flags & DDS_SLAVE_ONLY;
 }
 
+bool clock_telecom_profile(struct clock *c)
+{
+   return (c->dscmp == telecom_dscmp);
+}
+
 UInteger8 clock_max_steps_removed(struct clock *c)
 {
return c->max_steps_removed;
@@ -2083,3 +2090,8 @@ enum servo_state clock_servo_state(struct clock *c)
 {
return c->servo_state;
 }
+
+bool clock_interface_rate_tlv (struct clock *c)
+{
+   return c->iface_rate_tlv;
+}
diff --git a/clock.h b/clock.h
index 0534f21..d38ef6a 100644
--- a/clock.h
+++ b/clock.h
@@ -388,4 +388,18 @@ void clock_check_ts(struct clock *c, uint64_t ts);
  */
 double clock_rate_ratio(struct clock *c);
 
+/**
+ * Obtain interface rate tlv support configuration.
+ * @param c  The clock instance.
+ * @return   The interface_rate_supoort config true if supported, else false.
+ */
+bool clock_interface_rate_tlv(struct clock *c);
+
+/**
+ * Obtain the clock is set for telecom profile .
+ * @param c  The clock instance.
+ * @return   True if the profile is telecom, false otherwise.
+ */
+bool clock_telecom_profile(struct clock *c);
+
 #endif
diff --git a/config.c b/config.c
index 6ba9996..90040de 100644
--- a/config.c
+++ b/config.c
@@ -240,6 +240,7 @@ struct config_item config_tab[] = {
GLOB_ITEM_ENU("clock_type", CLOCK_TYPE_ORDINARY, clock_type_enu),
GLOB_ITEM_ENU("dataset_comparison", DS_CMP_IEEE1588, dataset_comp_enu),
PORT_ITEM_INT("delayAsymmetry", 0, INT_MIN, INT_MAX),
+   GLOB_ITEM_INT("interface_rate_tlv", 0, 0, 1),
PORT_ITEM_ENU("delay_filter", FILTER_MOVING_MEDIAN, delay_filter_enu),
PORT_ITEM_INT("delay_filter_length", 10, 1, INT_MAX),
PORT_ITEM_ENU("delay_mechanism", DM_E2E, delay_mech_enu),
diff --git a/interface.c b/interface.c
index 44d6588..d186455 100644
--- a/interface.c
+++ b/interface.c
@@ -99,3 +99,18 @@ int interface_get_vclock(struct interface *iface)
 {
return iface->vclock;
 }
+
+uint64_t interface_bitperiod(struct interface *iface)
+{
+   /* 10^18 atto-sec per bit*/
+   uint64_t if_atto_sec_bit_period = 0x0DE0B6B3A764;
+
+   if (!iface->if_info.valid) {
+   return 0;
+   }
+
+   if_atto_sec_bit_period /= iface->if_info.speed;
+   if_atto_sec_bit_period /= 100; /* 1 Mb = 10^6 */
+   return if_atto_sec_bit_period;
+
+}
diff --git a/interface.h b/interface.h
index fbbe919..4303568 100644
--- a/interface.h
+++ b/interface.h
@@ -119,4 +119,11 @@ void interface_set_vclock(struct interface *iface, int 
vclock);
  */
 int interface_get_vclock(struct interface *iface);
 
+/**
+ * Obtains the interface bit period based on the speed.
+ * @param iface  The interface of interest.
+ * @return   if valid speed return interface bitperiod in atto seconds.
+ */
+uint64_t interface_bitperiod(struct interface *iface);
+
 #endif
diff --git a/pdt.h b/pdt.h
index e46b218..1ad23d4 100644
--- a/pdt.h
+++ b/pdt.h
@@ -39,6 +39,7 @@ typedef uint16_t  UInteger16;
 typedef int32_t   Integer32;
 typedef uint32_t  UInteger32;
 typedef int64_t   Integer64;
+typedef uint64_t  UInteger64;
 typedef uint8_t   Octet;
 
 #endif
diff --git a/port_private.h b/port_private.h
index d27dceb..d1a1e76 100644
--- a/port_private.h
+++ b/port_private.h
@@ -145,6 +145,7 @@ struct port {
UInteger8   versionNumber; /* UInteger4 */
UInteger8   delay_response_counter;
UInteger8   delay_response_timeout;
+   Integer64   

[Linuxptp-devel] [PATCH 2/3] [Interface Rate TLV] adding speed field information for interface

2022-06-22 Thread SyncMonk Technologies
Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 clock.c |  2 ++
 interface.c | 11 +++
 interface.h | 14 ++
 port.c  |  5 +
 4 files changed, 32 insertions(+)

diff --git a/clock.c b/clock.c
index f808b35..8f328e5 100644
--- a/clock.c
+++ b/clock.c
@@ -1005,6 +1005,8 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
rtnl_get_ts_device(interface_name(iface), ts_label);
interface_set_label(iface, ts_label);
interface_ensure_tslabel(iface);
+   /* Interface speed information */
+   interface_get_ifinfo(iface);
interface_get_tsinfo(iface);
if (interface_tsinfo_valid(iface) &&
!interface_tsmodes_supported(iface, required_modes)) {
diff --git a/interface.c b/interface.c
index 445a270..44d6588 100644
--- a/interface.c
+++ b/interface.c
@@ -12,6 +12,7 @@ struct interface {
char name[MAX_IFNAME_SIZE + 1];
char ts_label[MAX_IFNAME_SIZE + 1];
struct sk_ts_info ts_info;
+   struct sk_if_info if_info;
int vclock;
 };
 
@@ -46,6 +47,11 @@ int interface_get_tsinfo(struct interface *iface)
return sk_get_ts_info(iface->ts_label, >ts_info);
 }
 
+int interface_get_ifinfo(struct interface *iface)
+{
+   return sk_get_if_info(iface->ts_label, >if_info);
+}
+
 const char *interface_label(struct interface *iface)
 {
return iface->ts_label;
@@ -71,6 +77,11 @@ bool interface_tsinfo_valid(struct interface *iface)
return iface->ts_info.valid ? true : false;
 }
 
+bool interface_ifinfo_valid(struct interface *iface)
+{
+   return iface->if_info.valid ? true : false;
+}
+
 bool interface_tsmodes_supported(struct interface *iface, int modes)
 {
if ((iface->ts_info.so_timestamping & modes) == modes) {
diff --git a/interface.h b/interface.h
index 752f4f1..fbbe919 100644
--- a/interface.h
+++ b/interface.h
@@ -46,6 +46,13 @@ void interface_ensure_tslabel(struct interface *iface);
  */
 int interface_get_tsinfo(struct interface *iface);
 
+/**
+ * Populate the time stamping information of a given interface.
+ * @param iface  The interface of interest.
+ * @return   zero on success, negative on failure.
+ */
+int interface_get_ifinfo(struct interface *iface);
+
 /**
  * Obtain the time stamping label of a network interface.  This can be
  * different from the name of the interface when bonding is in effect.
@@ -83,6 +90,13 @@ void interface_set_label(struct interface *iface, const char 
*label);
  */
 bool interface_tsinfo_valid(struct interface *iface);
 
+/**
+ * Tests whether an interface's interface information is valid or not.
+ * @param iface  The interface of interest.
+ * @return   True if the interface information is valid, false otherwise.
+ */
+bool interface_ifinfo_valid(struct interface *iface);
+
 /**
  * Tests whether an interface supports a set of given time stamping modes.
  * @param iface  The interface of interest.
diff --git a/port.c b/port.c
index d9dac38..b93225b 100644
--- a/port.c
+++ b/port.c
@@ -2690,6 +2690,11 @@ void port_link_status(void *ctx, int linkup, int 
ts_index)
p->link_status = link_state;
} else {
p->link_status = link_state | LINK_STATE_CHANGED;
+   /* Update Interface speed information on Link up*/
+   if (linkup) {
+   interface_get_ifinfo(p->iface);
+   }
+
pr_notice("%s: link %s", p->log_name, linkup ? "up" : "down");
}
 
-- 
2.17.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 1/3] [Interface Rate TLV] function to support get interface speed via ethtool

2022-06-22 Thread SyncMonk Technologies
When master and slave instance interacting with each other operating
at different interface speed, delay assymetry needs to be compensated
as described in G.8271 appendix V.

In this patch we are adding changes to get the interface speed using
ethtool.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 sk.c | 65 
 sk.h | 18 +
 2 files changed, 83 insertions(+)

diff --git a/sk.c b/sk.c
index b55d6b5..6a0fc5e 100644
--- a/sk.c
+++ b/sk.c
@@ -200,6 +200,71 @@ failed:
return -1;
 }
 
+int sk_get_if_info(const char *name, struct sk_if_info *if_info)
+{
+#ifdef ETHTOOL_GLINKSETTINGS
+   struct ifreq ifr;
+   int fd, err;
+
+   struct {
+   struct ethtool_link_settings req;
+   __u32 link_mode_data[3 * 127];
+   } ecmd;
+
+   memset(, 0, sizeof(ifr));
+   memset(, 0, sizeof(ecmd));
+
+   fd = socket(AF_INET, SOCK_DGRAM, 0);
+   if (fd < 0) {
+   goto failed;
+   }
+
+   ecmd.req.cmd = ETHTOOL_GLINKSETTINGS;
+
+   strncpy(ifr.ifr_name, name, IFNAMSIZ - 1);
+   ifr.ifr_data = (char *) 
+
+   /* Handshake with kernel to determine number of words for link
+* mode bitmaps. When requested number of bitmap words is not
+* the one expected by kernel, the latter returns the integer
+* opposite of what it is expecting. We request length 0 below
+* (aka. invalid bitmap length) to get this info.
+*/
+   err = ioctl(fd, SIOCETHTOOL, );
+   if (err < 0) {
+   pr_err("ioctl SIOCETHTOOL failed: %m");
+   close(fd);
+   goto failed;
+   }
+
+   if (ecmd.req.link_mode_masks_nwords >= 0 ||
+   ecmd.req.cmd != ETHTOOL_GLINKSETTINGS) {
+   return 1;
+   }
+   ecmd.req.link_mode_masks_nwords = -ecmd.req.link_mode_masks_nwords;
+
+   err = ioctl(fd, SIOCETHTOOL, );
+   if (err < 0) {
+   pr_err("ioctl SIOCETHTOOL failed: %m");
+   close(fd);
+   goto failed;
+   }
+
+   close(fd);
+
+   /* copy the necessary data to sk_info */
+   memset(if_info, 0, sizeof(struct sk_if_info));
+   if_info->valid = 1;
+   if_info->speed = ecmd.req.speed;
+
+   return 0;
+failed:
+#endif
+   /* clear data and ensure it is not marked valid */
+   memset(if_info, 0, sizeof(struct sk_if_info));
+   return -1;
+}
+
 static int sk_interface_guidaddr(const char *name, unsigned char *guid)
 {
char file_name[64], buf[64], addr[8];
diff --git a/sk.h b/sk.h
index 486dbc4..853aadf 100644
--- a/sk.h
+++ b/sk.h
@@ -49,6 +49,16 @@ struct sk_ts_info {
unsigned int rx_filters;
 };
 
+/**
+ * Contains interface information returned by theGLINKSETTINGS ioctl.
+ * @valid:set to non-zero when the info struct contains valid data.
+ * @speed:interface speed.
+ */
+struct sk_if_info {
+   int valid;
+   int speed;
+};
+
 /**
  * Obtains a socket suitable for use with sk_interface_index().
  * @return  An open socket on success, -1 otherwise.
@@ -78,6 +88,14 @@ int sk_general_init(int fd);
  */
 int sk_get_ts_info(const char *name, struct sk_ts_info *sk_info);
 
+/**
+ * Obtain supporte interface information
+ * @param name The name of the interface
+ * @param info  Struct containing obtained interface information.
+ * @return  zero on success, negative on failure.
+ */
+int sk_get_if_info(const char *name, struct sk_if_info *sk_info);
+
 /**
  * Obtain the MAC address of a network interface.
  * @param name  The name of the interface
-- 
2.17.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH 1/3] [Interface Rate TLV] function to support get interface speed via ethtool

2022-06-22 Thread SyncMonk Technologies
When master and slave instance interacting with each other operating
at different interface speed, delay assymetry needs to be compensated
as described in G.8271 appendix V.

In this patch we are adding changes to get the interface speed using
ethtool.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 sk.c | 65 
 sk.h | 18 +
 2 files changed, 83 insertions(+)

diff --git a/sk.c b/sk.c
index b55d6b5..6a0fc5e 100644
--- a/sk.c
+++ b/sk.c
@@ -200,6 +200,71 @@ failed:
return -1;
 }
 
+int sk_get_if_info(const char *name, struct sk_if_info *if_info)
+{
+#ifdef ETHTOOL_GLINKSETTINGS
+   struct ifreq ifr;
+   int fd, err;
+
+   struct {
+   struct ethtool_link_settings req;
+   __u32 link_mode_data[3 * 127];
+   } ecmd;
+
+   memset(, 0, sizeof(ifr));
+   memset(, 0, sizeof(ecmd));
+
+   fd = socket(AF_INET, SOCK_DGRAM, 0);
+   if (fd < 0) {
+   goto failed;
+   }
+
+   ecmd.req.cmd = ETHTOOL_GLINKSETTINGS;
+
+   strncpy(ifr.ifr_name, name, IFNAMSIZ - 1);
+   ifr.ifr_data = (char *) 
+
+   /* Handshake with kernel to determine number of words for link
+* mode bitmaps. When requested number of bitmap words is not
+* the one expected by kernel, the latter returns the integer
+* opposite of what it is expecting. We request length 0 below
+* (aka. invalid bitmap length) to get this info.
+*/
+   err = ioctl(fd, SIOCETHTOOL, );
+   if (err < 0) {
+   pr_err("ioctl SIOCETHTOOL failed: %m");
+   close(fd);
+   goto failed;
+   }
+
+   if (ecmd.req.link_mode_masks_nwords >= 0 ||
+   ecmd.req.cmd != ETHTOOL_GLINKSETTINGS) {
+   return 1;
+   }
+   ecmd.req.link_mode_masks_nwords = -ecmd.req.link_mode_masks_nwords;
+
+   err = ioctl(fd, SIOCETHTOOL, );
+   if (err < 0) {
+   pr_err("ioctl SIOCETHTOOL failed: %m");
+   close(fd);
+   goto failed;
+   }
+
+   close(fd);
+
+   /* copy the necessary data to sk_info */
+   memset(if_info, 0, sizeof(struct sk_if_info));
+   if_info->valid = 1;
+   if_info->speed = ecmd.req.speed;
+
+   return 0;
+failed:
+#endif
+   /* clear data and ensure it is not marked valid */
+   memset(if_info, 0, sizeof(struct sk_if_info));
+   return -1;
+}
+
 static int sk_interface_guidaddr(const char *name, unsigned char *guid)
 {
char file_name[64], buf[64], addr[8];
diff --git a/sk.h b/sk.h
index 486dbc4..853aadf 100644
--- a/sk.h
+++ b/sk.h
@@ -49,6 +49,16 @@ struct sk_ts_info {
unsigned int rx_filters;
 };
 
+/**
+ * Contains interface information returned by theGLINKSETTINGS ioctl.
+ * @valid:set to non-zero when the info struct contains valid data.
+ * @speed:interface speed.
+ */
+struct sk_if_info {
+   int valid;
+   int speed;
+};
+
 /**
  * Obtains a socket suitable for use with sk_interface_index().
  * @return  An open socket on success, -1 otherwise.
@@ -78,6 +88,14 @@ int sk_general_init(int fd);
  */
 int sk_get_ts_info(const char *name, struct sk_ts_info *sk_info);
 
+/**
+ * Obtain supporte interface information
+ * @param name The name of the interface
+ * @param info  Struct containing obtained interface information.
+ * @return  zero on success, negative on failure.
+ */
+int sk_get_if_info(const char *name, struct sk_if_info *sk_info);
+
 /**
  * Obtain the MAC address of a network interface.
  * @param name  The name of the interface
-- 
2.17.1



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


[Linuxptp-devel] [PATCH] Inclusion of a virtual PTP port on a PTP clock

2022-06-17 Thread SyncMonk Technologies
As per G.8275 (Annex-B) including virtual PTP ports on a PTP clock. This
virtual port will be used to support APTS, IWF between different
clock_domains.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Vipin Sharma 
Signed-off-by: Devasish Dey 
---
 makefile |   6 +--
 vport.c  | 136 +++
 vport.h  |  20 
 3 files changed, 159 insertions(+), 3 deletions(-)
 create mode 100644 vport.c
 create mode 100644 vport.h

diff --git a/makefile b/makefile
index 5295b60..cd1f3ef 100644
--- a/makefile
+++ b/makefile
@@ -25,7 +25,7 @@ LDLIBS= -lm -lrt -pthread $(EXTRA_LDFLAGS)
 PRG= ptp4l hwstamp_ctl nsm phc2sys phc_ctl pmc timemaster ts2phc
 FILTERS= filter.o mave.o mmedian.o
 SERVOS = linreg.o ntpshm.o nullf.o pi.o servo.o
-TRANSP = raw.o transport.o udp.o udp6.o uds.o
+TRANSP = raw.o transport.o udp.o udp6.o uds.o vport.o
 TS2PHC = ts2phc.o lstab.o nmea.o serial.o sock.o ts2phc_generic_pps_source.o \
  ts2phc_nmea_pps_source.o ts2phc_phc_pps_source.o ts2phc_pps_sink.o 
ts2phc_pps_source.o
 OBJ= bmc.o clock.o clockadj.o clockcheck.o config.o designated_fsm.o \
@@ -68,8 +68,8 @@ phc_ctl: phc_ctl.o phc.o sk.o util.o clockadj.o sysoff.o 
print.o version.o
 
 timemaster: phc.o print.o rtnl.o sk.o timemaster.o util.o version.o
 
-ts2phc: config.o clockadj.o hash.o interface.o phc.o print.o $(SERVOS) sk.o \
- $(TS2PHC) util.o version.o
+ts2phc: config.o clockadj.o hash.o msg.o tlv.o interface.o phc.o print.o 
$(SERVOS) sk.o \
+ $(TS2PHC) $(TRANSP) util.o version.o
 
 version.o: .version version.sh $(filter-out version.d,$(DEPEND))
 
diff --git a/vport.c b/vport.c
new file mode 100644
index 000..58241ea
--- /dev/null
+++ b/vport.c
@@ -0,0 +1,136 @@
+/**
+ * @file vport.c
+ * @note Copyright (C) 2022 SyncMonk Technologies 
+ * @note SPDX-License-Identifier: GPL-2.0+
+ *
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "address.h"
+#include "contain.h"
+#include "print.h"
+#include "transport_private.h"
+#include "vport.h"
+
+#define VPORT_FILEMODE (0660) /*0660*/
+
+struct vport {
+   struct transport t;
+   struct address address;
+};
+
+static int vport_close(struct transport *t, struct fdarray *fda)
+{
+   struct sockaddr_un sa;
+   socklen_t len = sizeof(sa);
+
+   if (!getsockname(fda->fd[FD_GENERAL], (struct sockaddr *) , ) &&
+   sa.sun_family == AF_LOCAL) {
+   unlink(sa.sun_path);
+   }
+
+   close(fda->fd[FD_GENERAL]);
+   return 0;
+}
+
+static int vport_open(struct transport *t, struct interface *iface, struct 
fdarray *fda,
+   enum timestamp_type tt)
+{
+   char *vport_path = config_get_string(t->cfg, NULL, "vport_address");
+   struct vport *vport = container_of(t, struct vport, t);
+   const char *name = interface_name(iface);
+   struct sockaddr_un sa;
+   int fd, err;
+
+   fd = socket(AF_LOCAL, SOCK_DGRAM, 0);
+   if (fd < 0) {
+   pr_err("vport: failed to create socket: %m");
+   return -1;
+   }
+   memset(, 0, sizeof(sa));
+   sa.sun_family = AF_LOCAL;
+   strncpy(sa.sun_path, name, sizeof(sa.sun_path) - 1);
+
+   unlink(name);
+
+   err = bind(fd, (struct sockaddr *) , sizeof(sa));
+   if (err < 0) {
+   pr_err("vport: bind failed: %m");
+   close(fd);
+   return -1;
+   }
+
+   /* For client use, pre load the server path. */
+   memset(, 0, sizeof(sa));
+   sa.sun_family = AF_LOCAL;
+   strncpy(sa.sun_path, vport_path, sizeof(sa.sun_path) - 1);
+   vport->address.sun = sa;
+   vport->address.len = sizeof(sa);
+
+   chmod(name, VPORT_FILEMODE);
+   fda->fd[FD_EVENT] = -1;
+   fda->fd[FD_GENERAL] = fd;
+   return 0;
+}
+
+static int vport_recv(struct transport *t, int fd, void *buf, int buflen,
+   struct address *addr, struct hw_timestamp *hwts)
+{
+   int cnt;
+   struct vport *vport = container_of(t, struct vport, t);
+
+   addr->len = sizeof(addr->sun);
+   cnt = recvfrom(fd, buf, buflen, 0, >sa, >len);
+   if (cnt <= 0) {
+   pr_err("vport: recvfrom failed: %m");
+   return cnt;
+   }
+   vport->address = *addr;
+   return cnt;
+}
+
+static int vport_send(struct transport *t, struct fdarray *fda,
+   enum transport_event event, int peer, void *buf, int buflen,
+   struct address *addr, struct hw_timestamp *hwts)
+{
+   int cnt, fd = fda->fd[FD_GENERAL];
+   struct vport *vport = container_of(t, struct vport, t);
+
+   if (!addr)
+   addr = >address;
+
+   cnt = sendto(fd, buf, buflen, 0, >sa, addr->len);
+   if (

[Linuxptp-devel] [PATCH] (G.8275.2 Annex D) TLV support for interface rate

2022-06-10 Thread SyncMonk Technologies
When master and slave instance interacting with each other operating
at different interface speed, delay assymetry needs to be compensated
as described in G.8271 appendix V.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 clock.c | 14 ++
 clock.h | 14 ++
 config.c|  1 +
 configs/default.cfg |  1 +
 interface.c | 50 ++
 interface.h | 21 +++
 pdt.h   |  1 +
 port.c  |  5 
 port_private.h  |  1 +
 port_signaling.c| 34 
 sk.c| 65 +
 sk.h| 18 +
 tlv.c   |  1 +
 tlv.h   | 16 +++
 unicast_service.c   | 33 +++
 15 files changed, 275 insertions(+)

diff --git a/clock.c b/clock.c
index f808b35..695f818 100644
--- a/clock.c
+++ b/clock.c
@@ -137,6 +137,7 @@ struct clock {
struct monitor *slave_event_monitor;
int step_window_counter;
int step_window;
+   bool iface_rate_tlv;
 };
 
 struct clock the_clock;
@@ -1005,6 +1006,8 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
rtnl_get_ts_device(interface_name(iface), ts_label);
interface_set_label(iface, ts_label);
interface_ensure_tslabel(iface);
+   /* Interface speed information */
+   interface_get_ifinfo(iface);
interface_get_tsinfo(iface);
if (interface_tsinfo_valid(iface) &&
!interface_tsmodes_supported(iface, required_modes)) {
@@ -1105,6 +1108,7 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
c->utc_offset = config_get_int(config, NULL, "utc_offset");
c->time_source = config_get_int(config, NULL, "timeSource");
c->step_window = config_get_int(config, NULL, "step_window");
+   c->iface_rate_tlv = config_get_int(config, NULL, "interface_rate_tlv");
 
if (c->free_running) {
c->clkid = CLOCK_INVALID;
@@ -1716,6 +1720,11 @@ int clock_slave_only(struct clock *c)
return c->dds.flags & DDS_SLAVE_ONLY;
 }
 
+bool clock_telecom_profile(struct clock *c)
+{
+   return (c->dscmp == telecom_dscmp);
+}
+
 UInteger8 clock_max_steps_removed(struct clock *c)
 {
return c->max_steps_removed;
@@ -2081,3 +2090,8 @@ enum servo_state clock_servo_state(struct clock *c)
 {
return c->servo_state;
 }
+
+bool clock_interface_rate_tlv (struct clock *c)
+{
+   return c->iface_rate_tlv;
+}
diff --git a/clock.h b/clock.h
index 0534f21..9b2738a 100644
--- a/clock.h
+++ b/clock.h
@@ -289,6 +289,13 @@ int clock_slave_only(struct clock *c);
  */
 UInteger8 clock_max_steps_removed(struct clock *c);
 
+/**
+ * Obtain the clock is set for telecom profile .
+ * @param c  The clock instance.
+ * @return   True if the profile is telecom, false otherwise.
+ */
+bool clock_telecom_profile(struct clock *c);
+
 /**
  * Obtain the clock class threshold field from a clock's default data set.
  * @param c  The clock instance.
@@ -388,4 +395,11 @@ void clock_check_ts(struct clock *c, uint64_t ts);
  */
 double clock_rate_ratio(struct clock *c);
 
+/**
+ * Obtain interface rate tlv support configuration.
+ * @param c  The clock instance.
+ * @return   The interface_rate_supoort config true if supported, else false.
+ */
+bool clock_interface_rate_tlv (struct clock *c);
+
 #endif
diff --git a/config.c b/config.c
index 6ba9996..0419423 100644
--- a/config.c
+++ b/config.c
@@ -266,6 +266,7 @@ struct config_item config_tab[] = {
PORT_ITEM_INT("inhibit_delay_req", 0, 0, 1),
PORT_ITEM_INT("inhibit_multicast_service", 0, 0, 1),
GLOB_ITEM_INT("initial_delay", 0, 0, INT_MAX),
+   GLOB_ITEM_INT("interface_rate_tlv", 0, 0, 1),
GLOB_ITEM_INT("kernel_leap", 1, 0, 1),
GLOB_ITEM_STR("leapfile", NULL),
PORT_ITEM_INT("logAnnounceInterval", 1, INT8_MIN, INT8_MAX),
diff --git a/configs/default.cfg b/configs/default.cfg
index 1b5b806..4c40a03 100644
--- a/configs/default.cfg
+++ b/configs/default.cfg
@@ -19,6 +19,7 @@ dscp_general  0
 dataset_comparison ieee1588
 G.8275.defaultDS.localPriority 128
 maxStepsRemoved255
+interface_rate_tlv 0
 #
 # Port Data Set
 #
diff --git a/interface.c b/interface.c
index 445a270..8559f62 100644
--- a/interface.c
+++ b/interface.c
@@ -12,6 +12,7 @@ struct interface {
char name[MAX_IFNAME_SIZE + 1];
char ts_label[MAX_IFNAME_SIZE + 1];
struct sk_ts_info ts_info;
+   struct sk_if_info if_info;
int vclock;
 };
 
@@ -46,6 +47,11 @@ int interface_get_tsinfo(struct interface *iface)
return sk_get_ts_info(iface->ts_label, >ts_info);
 }
 
+int interface_get_ifinfo(struct interface *iface)
+{
+   return 

[Linuxptp-devel] [PATCH] G.8275.2 support for delay_mechanism NO_MECHANISM

2022-06-06 Thread SyncMonk Technologies
As per IEEE1588-2019, Table 21 adding NO_MECHANISM support. In this
case port does not implement the delay mechanism.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 clock.c  |  4 +++-
 config.c |  1 +
 dm.h |  3 +++
 port.c   | 12 ++--
 port.h   |  7 +++
 ptp4l.8  |  7 ++-
 ptp4l.c  | 10 --
 unicast_client.c | 11 ---
 8 files changed, 46 insertions(+), 9 deletions(-)

diff --git a/clock.c b/clock.c
index f808b35..56adea7 100644
--- a/clock.c
+++ b/clock.c
@@ -1996,8 +1996,10 @@ static void handle_state_decision_event(struct clock *c)
if (c->sanity_check)
clockcheck_reset(c->sanity_check);
tsproc_reset(c->tsproc, 1);
-   if (!tmv_is_zero(c->initial_delay))
+   if (!tmv_is_zero(c->initial_delay) || (best &&
+   port_delay_mechanism(best->port) == DM_NO_MECHANISM)) {
tsproc_set_delay(c->tsproc, c->initial_delay);
+   }
c->ingress_ts = tmv_zero();
c->path_delay = c->initial_delay;
c->master_local_rr = 1.0;
diff --git a/config.c b/config.c
index 6ba9996..b5cf397 100644
--- a/config.c
+++ b/config.c
@@ -171,6 +171,7 @@ static struct config_enum delay_mech_enu[] = {
{ "Auto", DM_AUTO },
{ "E2E",  DM_E2E },
{ "P2P",  DM_P2P },
+   { "NONE", DM_NO_MECHANISM },
{ NULL, 0 },
 };
 
diff --git a/dm.h b/dm.h
index 2491c63..47bd847 100644
--- a/dm.h
+++ b/dm.h
@@ -33,6 +33,9 @@ enum delay_mechanism {
 
/** Peer delay mechanism. */
DM_P2P,
+
+   /** No Delay Mechanism. */
+   DM_NO_MECHANISM = 0xFE,
 };
 
 #endif
diff --git a/port.c b/port.c
index d9dac38..4ec7a02 100644
--- a/port.c
+++ b/port.c
@@ -1195,7 +1195,7 @@ int port_set_announce_tmo(struct port *p)
 
 int port_set_delay_tmo(struct port *p)
 {
-   if (p->inhibit_delay_req) {
+   if (p->inhibit_delay_req || p->delayMechanism == DM_NO_MECHANISM) {
return 0;
}
 
@@ -2031,7 +2031,10 @@ static int process_delay_req(struct port *p, struct 
ptp_message *m)
return 0;
}
 
-   if (p->delayMechanism == DM_P2P) {
+   if (p->delayMechanism == DM_NO_MECHANISM) {
+   pr_warning("port %hu: delay request not supported", portnum(p));
+   return 0;
+   } else if (p->delayMechanism == DM_P2P) {
pr_warning("%s: delay request on P2P port", p->log_name);
return 0;
}
@@ -3383,6 +3386,11 @@ enum port_state port_state(struct port *port)
return port->state;
 }
 
+enum delay_mechanism port_delay_mechanism(struct port *port)
+{
+   return port->delayMechanism;
+}
+
 int port_state_update(struct port *p, enum fsm_event event, int mdiff)
 {
enum port_state next = p->state_machine(p->state, event, mdiff);
diff --git a/port.h b/port.h
index 37a4e19..4854698 100644
--- a/port.h
+++ b/port.h
@@ -227,6 +227,13 @@ struct ptp_message *port_signaling_construct(struct port 
*p,
  */
 enum port_state port_state(struct port *port);
 
+/**
+ * Return  port's delay mechanism method.
+ * @param port A port instance.
+ * @return one of the @ref delay_mechanism values.
+ */
+enum delay_mechanism port_delay_mechanism(struct port *port);
+
 /**
  * Update a port's current state based on a given event.
  * @param pA pointer previously obtained via port_open().
diff --git a/ptp4l.8 b/ptp4l.8
index e33454a..d0a8cff 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -42,6 +42,11 @@ port using the E2E mechanism.
 Select the peer delay (P2P) mechanism. A warning will be printed when a delay
 request is received on port using the P2P mechanism.
 .TP
+.B \-N
+Select the NONE mechanism. The PTP port does not support delay mechanism.
+This is used when PTP instance supports only frequency transfer or path delay
+is neglected by the PTP instance.
+.TP
 .B \-2
 Select the IEEE 802.3 network transport.
 .TP
@@ -245,7 +250,7 @@ the fault be reset immediately.
 The default is 16 seconds.
 .TP
 .B delay_mechanism
-Select the delay mechanism. Possible values are E2E, P2P and Auto.
+Select the delay mechanism. Possible values are E2E, P2P, NONE and Auto.
 The default is E2E.
 .TP
 .B hybrid_e2e
diff --git a/ptp4l.c b/ptp4l.c
index c61175b..de04bb9 100644
--- a/ptp4l.c
+++ b/ptp4l.c
@@ -43,7 +43,8 @@ static void usage(char *progname)
" Delay Mechanism\n\n"
" -AAuto, starting with E2E\n"
" -EE2E, delay request-response (default)\n"
-   " -PP2P, peer delay mechanism\n\n"
+   " -PP2P, peer delay mechanism\n"
+   " -NNO_MECHANISM, no mechanism\n\n"
" Network Transport\n\n"
" -2IEEE 802.3\n"
" -4

[Linuxptp-devel] [PATCH] G.8275.2 support for delay_mechanism NO_MECHANISM

2022-06-03 Thread SyncMonk Technologies
As per IEEE1588-2019, Table 21 adding NO_MECHANISM support. In this
case port does not implement the delay mechanism.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 clock.c  |  4 +++-
 config.c | 15 ---
 dm.h |  3 +++
 port.c   | 12 ++--
 port.h   |  7 +++
 ptp4l.8  | 15 ++-
 ptp4l.c  | 10 --
 unicast_client.c | 11 ---
 8 files changed, 57 insertions(+), 20 deletions(-)

diff --git a/clock.c b/clock.c
index f808b35..1c68071 100644
--- a/clock.c
+++ b/clock.c
@@ -1996,8 +1996,10 @@ static void handle_state_decision_event(struct clock *c)
if (c->sanity_check)
clockcheck_reset(c->sanity_check);
tsproc_reset(c->tsproc, 1);
-   if (!tmv_is_zero(c->initial_delay))
+   if (!tmv_is_zero(c->initial_delay) || (best &&
+   port_delay_mechanism(best->port) == DM_NONE)) {
tsproc_set_delay(c->tsproc, c->initial_delay);
+   }
c->ingress_ts = tmv_zero();
c->path_delay = c->initial_delay;
c->master_local_rr = 1.0;
diff --git a/config.c b/config.c
index 6ba9996..b30d22e 100644
--- a/config.c
+++ b/config.c
@@ -168,9 +168,10 @@ static struct config_enum delay_filter_enu[] = {
 };
 
 static struct config_enum delay_mech_enu[] = {
-   { "Auto", DM_AUTO },
-   { "E2E",  DM_E2E },
-   { "P2P",  DM_P2P },
+   { "Auto", DM_AUTO },
+   { "E2E",  DM_E2E },
+   { "P2P",  DM_P2P },
+   { "NO_MECHANISM", DM_NONE },
{ NULL, 0 },
 };
 
@@ -205,10 +206,10 @@ static struct config_enum timestamping_enu[] = {
 };
 
 static struct config_enum tsproc_enu[] = {
-   { "filter",TSPROC_FILTER},
-   { "raw",   TSPROC_RAW   },
-   { "filter_weight", TSPROC_FILTER_WEIGHT },
-   { "raw_weight",TSPROC_RAW_WEIGHT},
+   { "filter",TSPROC_FILTER},
+   { "raw",   TSPROC_RAW   },
+   { "filter_weight", TSPROC_FILTER_WEIGHT },
+   { "raw_weight",TSPROC_RAW_WEIGHT},
{ NULL, 0 },
 };
 
diff --git a/dm.h b/dm.h
index 2491c63..9f76915 100644
--- a/dm.h
+++ b/dm.h
@@ -33,6 +33,9 @@ enum delay_mechanism {
 
/** Peer delay mechanism. */
DM_P2P,
+
+   /** No Delay Mechanism. */
+   DM_NONE = 0xFE,
 };
 
 #endif
diff --git a/port.c b/port.c
index d9dac38..3d5cb41 100644
--- a/port.c
+++ b/port.c
@@ -1195,7 +1195,7 @@ int port_set_announce_tmo(struct port *p)
 
 int port_set_delay_tmo(struct port *p)
 {
-   if (p->inhibit_delay_req) {
+   if (p->inhibit_delay_req || p->delayMechanism == DM_NONE) {
return 0;
}
 
@@ -2031,7 +2031,10 @@ static int process_delay_req(struct port *p, struct 
ptp_message *m)
return 0;
}
 
-   if (p->delayMechanism == DM_P2P) {
+   if (p->delayMechanism == DM_NONE) {
+   pr_warning("port %hu: delay request not supported", portnum(p));
+   return 0;
+   } else if (p->delayMechanism == DM_P2P) {
pr_warning("%s: delay request on P2P port", p->log_name);
return 0;
}
@@ -3383,6 +3386,11 @@ enum port_state port_state(struct port *port)
return port->state;
 }
 
+enum delay_mechanism port_delay_mechanism(struct port *port)
+{
+   return port->delayMechanism;
+}
+
 int port_state_update(struct port *p, enum fsm_event event, int mdiff)
 {
enum port_state next = p->state_machine(p->state, event, mdiff);
diff --git a/port.h b/port.h
index 37a4e19..4854698 100644
--- a/port.h
+++ b/port.h
@@ -227,6 +227,13 @@ struct ptp_message *port_signaling_construct(struct port 
*p,
  */
 enum port_state port_state(struct port *port);
 
+/**
+ * Return  port's delay mechanism method.
+ * @param port A port instance.
+ * @return one of the @ref delay_mechanism values.
+ */
+enum delay_mechanism port_delay_mechanism(struct port *port);
+
 /**
  * Update a port's current state based on a given event.
  * @param pA pointer previously obtained via port_open().
diff --git a/ptp4l.8 b/ptp4l.8
index e33454a..cdb9d42 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -42,6 +42,10 @@ port using the E2E mechanism.
 Select the peer delay (P2P) mechanism. A warning will be printed when a delay
 request is received on port using the P2P mechanism.
 .TP
+.B \-N
+The PTP port does not support delay mechanism. This is used when PTP instance
+supports only frequency transfer or path delay is neglected by the PTP 
instance.
+.TP
 .B \-2
 Select the IEEE 802.3 network transport.
 .TP
@@ -245,7 +249,8 @@ the fault be reset immediately.
 The default is 16 seconds.
 .TP
 .B delay_mechanism
-Select the delay mechanism. Possible values are E2E, P2P and Auto.
+Select the 

[Linuxptp-devel] [PATCH] v1.1 G.8275.2 support for delay_mechanism NO_MECHANISM

2022-06-01 Thread SyncMonk Technologies
As per IEEE1588-2019, Table 21 adding NO_MECHANISM support. In this
case port does not implement the delay mechanism.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 config.c | 16 +---
 dm.h |  3 +++
 port.c   |  7 +--
 ptp4l.8  | 15 ++-
 ptp4l.c  | 10 --
 tsproc.c |  5 +
 tsproc.h |  1 +
 unicast_client.c | 11 ---
 8 files changed, 49 insertions(+), 19 deletions(-)

diff --git a/config.c b/config.c
index 6ba9996..fe48b46 100644
--- a/config.c
+++ b/config.c
@@ -168,9 +168,10 @@ static struct config_enum delay_filter_enu[] = {
 };
 
 static struct config_enum delay_mech_enu[] = {
-   { "Auto", DM_AUTO },
-   { "E2E",  DM_E2E },
-   { "P2P",  DM_P2P },
+   { "Auto", DM_AUTO },
+   { "E2E",  DM_E2E },
+   { "P2P",  DM_P2P },
+   { "NO_MECHANISM", DM_NO_MECHANISM },
{ NULL, 0 },
 };
 
@@ -205,10 +206,11 @@ static struct config_enum timestamping_enu[] = {
 };
 
 static struct config_enum tsproc_enu[] = {
-   { "filter",TSPROC_FILTER},
-   { "raw",   TSPROC_RAW   },
-   { "filter_weight", TSPROC_FILTER_WEIGHT },
-   { "raw_weight",TSPROC_RAW_WEIGHT},
+   { "filter",TSPROC_FILTER},
+   { "raw",   TSPROC_RAW   },
+   { "filter_weight", TSPROC_FILTER_WEIGHT },
+   { "raw_weight",TSPROC_RAW_WEIGHT},
+   { "no_delay",  TSPROC_NO_DELAY_MECHANISM},
{ NULL, 0 },
 };
 
diff --git a/dm.h b/dm.h
index 2491c63..47bd847 100644
--- a/dm.h
+++ b/dm.h
@@ -33,6 +33,9 @@ enum delay_mechanism {
 
/** Peer delay mechanism. */
DM_P2P,
+
+   /** No Delay Mechanism. */
+   DM_NO_MECHANISM = 0xFE,
 };
 
 #endif
diff --git a/port.c b/port.c
index d9dac38..cba48ae 100644
--- a/port.c
+++ b/port.c
@@ -1195,7 +1195,7 @@ int port_set_announce_tmo(struct port *p)
 
 int port_set_delay_tmo(struct port *p)
 {
-   if (p->inhibit_delay_req) {
+   if (p->inhibit_delay_req || p->delayMechanism == DM_NO_MECHANISM) {
return 0;
}
 
@@ -2031,7 +2031,10 @@ static int process_delay_req(struct port *p, struct 
ptp_message *m)
return 0;
}
 
-   if (p->delayMechanism == DM_P2P) {
+   if (p->delayMechanism == DM_NO_MECHANISM) {
+   pr_warning("port %hu: delay request not supported", portnum(p));
+   return 0;
+   } else if (p->delayMechanism == DM_P2P) {
pr_warning("%s: delay request on P2P port", p->log_name);
return 0;
}
diff --git a/ptp4l.8 b/ptp4l.8
index e33454a..cdb9d42 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -42,6 +42,10 @@ port using the E2E mechanism.
 Select the peer delay (P2P) mechanism. A warning will be printed when a delay
 request is received on port using the P2P mechanism.
 .TP
+.B \-N
+The PTP port does not support delay mechanism. This is used when PTP instance
+supports only frequency transfer or path delay is neglected by the PTP 
instance.
+.TP
 .B \-2
 Select the IEEE 802.3 network transport.
 .TP
@@ -245,7 +249,8 @@ the fault be reset immediately.
 The default is 16 seconds.
 .TP
 .B delay_mechanism
-Select the delay mechanism. Possible values are E2E, P2P and Auto.
+Select the delay mechanism. Possible values are E2E, P2P, NO_MECHANISM
+and Auto.
 The default is E2E.
 .TP
 .B hybrid_e2e
@@ -338,10 +343,10 @@ smaller than this value the port is marked as not 802.1AS 
capable.
 .TP
 .B tsproc_mode
 Select the time stamp processing mode used to calculate offset and delay.
-Possible values are filter, raw, filter_weight, raw_weight. Raw modes perform
-well when the rate of sync messages (logSyncInterval) is similar to the rate of
-delay messages (logMinDelayReqInterval or logMinPdelayReqInterval). Weighting
-is useful with larger network jitters (e.g. software time stamping).
+Possible values are filter, raw, filter_weight, raw_weight, no_delay. Raw modes
+perform well when the rate of sync messages (logSyncInterval) is similar to the
+rate of delay messages (logMinDelayReqInterval or logMinPdelayReqInterval).
+Weighting is useful with larger network jitters (e.g. software time stamping).
 The default is filter.
 .TP
 .B delay_filter
diff --git a/ptp4l.c b/ptp4l.c
index c61175b..1763c6a 100644
--- a/ptp4l.c
+++ b/ptp4l.c
@@ -43,7 +43,8 @@ static void usage(char *progname)
" Delay Mechanism\n\n"
" -AAuto, starting with E2E\n"
" -EE2E, delay request-response (default)\n"
-   " -PP2P, peer delay mechanism\n\n"
+   " -PP2P, peer delay mechanism\n"
+   " -NNO_MECHANISM, no mechanism\n"
" Network Transport\n\n"
" -2IEEE 802.3\n"
" -4

[Linuxptp-devel] [PATCH] G.8275.2 support for delay_mechanism NO_MECHANISM

2022-06-01 Thread SyncMonk Technologies
As per IEEE1588-2019, Table 21 adding NO_MECHANISM support. In this
case port does not implement the delay mechanism.

Signed-off-by: Greg Armstrong 
Signed-off-by: Leon Goldin 
Signed-off-by: Devasish Dey 
Signed-off-by: Vipin Sharma 
---
 config.c | 16 +---
 dm.h |  3 +++
 port.c   |  7 +--
 ptp4l.c  |  8 +++-
 tsproc.c |  5 +
 tsproc.h |  1 +
 unicast_client.c | 11 ---
 7 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/config.c b/config.c
index 6ba9996..fe48b46 100644
--- a/config.c
+++ b/config.c
@@ -168,9 +168,10 @@ static struct config_enum delay_filter_enu[] = {
 };
 
 static struct config_enum delay_mech_enu[] = {
-   { "Auto", DM_AUTO },
-   { "E2E",  DM_E2E },
-   { "P2P",  DM_P2P },
+   { "Auto", DM_AUTO },
+   { "E2E",  DM_E2E },
+   { "P2P",  DM_P2P },
+   { "NO_MECHANISM", DM_NO_MECHANISM },
{ NULL, 0 },
 };
 
@@ -205,10 +206,11 @@ static struct config_enum timestamping_enu[] = {
 };
 
 static struct config_enum tsproc_enu[] = {
-   { "filter",TSPROC_FILTER},
-   { "raw",   TSPROC_RAW   },
-   { "filter_weight", TSPROC_FILTER_WEIGHT },
-   { "raw_weight",TSPROC_RAW_WEIGHT},
+   { "filter",TSPROC_FILTER},
+   { "raw",   TSPROC_RAW   },
+   { "filter_weight", TSPROC_FILTER_WEIGHT },
+   { "raw_weight",TSPROC_RAW_WEIGHT},
+   { "no_delay",  TSPROC_NO_DELAY_MECHANISM},
{ NULL, 0 },
 };
 
diff --git a/dm.h b/dm.h
index 2491c63..47bd847 100644
--- a/dm.h
+++ b/dm.h
@@ -33,6 +33,9 @@ enum delay_mechanism {
 
/** Peer delay mechanism. */
DM_P2P,
+
+   /** No Delay Mechanism. */
+   DM_NO_MECHANISM = 0xFE,
 };
 
 #endif
diff --git a/port.c b/port.c
index d9dac38..cba48ae 100644
--- a/port.c
+++ b/port.c
@@ -1195,7 +1195,7 @@ int port_set_announce_tmo(struct port *p)
 
 int port_set_delay_tmo(struct port *p)
 {
-   if (p->inhibit_delay_req) {
+   if (p->inhibit_delay_req || p->delayMechanism == DM_NO_MECHANISM) {
return 0;
}
 
@@ -2031,7 +2031,10 @@ static int process_delay_req(struct port *p, struct 
ptp_message *m)
return 0;
}
 
-   if (p->delayMechanism == DM_P2P) {
+   if (p->delayMechanism == DM_NO_MECHANISM) {
+   pr_warning("port %hu: delay request not supported", portnum(p));
+   return 0;
+   } else if (p->delayMechanism == DM_P2P) {
pr_warning("%s: delay request on P2P port", p->log_name);
return 0;
}
diff --git a/ptp4l.c b/ptp4l.c
index c61175b..3e88e87 100644
--- a/ptp4l.c
+++ b/ptp4l.c
@@ -43,7 +43,8 @@ static void usage(char *progname)
" Delay Mechanism\n\n"
" -AAuto, starting with E2E\n"
" -EE2E, delay request-response (default)\n"
-   " -PP2P, peer delay mechanism\n\n"
+   " -PP2P, peer delay mechanism\n"
+   " -NNO_MECHANISM, no mechanism\n"
" Network Transport\n\n"
" -2IEEE 802.3\n"
" -4UDP IPV4 (default)\n"
@@ -108,6 +109,11 @@ int main(int argc, char *argv[])
if (config_set_int(cfg, "delay_mechanism", DM_P2P))
goto out;
break;
+   case 'N':
+   if (config_set_int(cfg,
+   "delay_mechanism", DM_NO_MECHANISM))
+   goto out;
+   break;
case '2':
if (config_set_int(cfg, "network_transport",
TRANS_IEEE_802_3))
diff --git a/tsproc.c b/tsproc.c
index a871049..feb0ea5 100644
--- a/tsproc.c
+++ b/tsproc.c
@@ -52,6 +52,7 @@ static int weighting(struct tsproc *tsp)
switch (tsp->mode) {
case TSPROC_FILTER:
case TSPROC_RAW:
+   case TSPROC_NO_DELAY_MECHANISM:
return 0;
case TSPROC_FILTER_WEIGHT:
case TSPROC_RAW_WEIGHT:
@@ -74,6 +75,7 @@ struct tsproc *tsproc_create(enum tsproc_mode mode,
case TSPROC_RAW:
case TSPROC_FILTER_WEIGHT:
case TSPROC_RAW_WEIGHT:
+   case TSPROC_NO_DELAY_MECHANISM:
tsp->mode = mode;
break;
default:
@@ -171,6 +173,7 @@ int tsproc_update_delay(struct tsproc *tsp, tmv_t *delay)
break;
case TSPROC_RAW:
case TSPROC_RAW_WEIGHT:
+   case TSPROC_NO_DELAY_MECHANISM:
*delay = raw_delay;
break;
}
@@ -207,6 +210,8 @@ int tsproc_update_offset(struct tsproc *tsp, tmv_t *offset, 
double *weight)
raw_delay = get_raw_delay(tsp);
delay = tsp->filtered_delay;
 

[Linuxptp-devel] [PATCH] Adding following features to support Telecom profile G.8275.2

2022-05-16 Thread SyncMonk Technologies
From: SyncMonk 

1. Inclusion of virtual PTP port on a PTP clock. (G.8275 Annex B)
2. Alternate master support (G.8275.2 Section 6.9 and G.8275.2 Appendix III)
3. TLV support for interface rate (G.8275.2 Annex D)
   When master and slave instance interacting with each other operating
   at different interface speed, delay assymetry needs to be compensated
   as described in G.8271 appendix V.
4. Delay mechanism
   As per IEEE1588-2019, Table 21 adding NO_MECHANISM support. In this
   case port does not implement the delay mechanism.
5. Packet Timing Signal Fail (PTSF)(G.8275.2 Section 6.7.11)
 - PTSF-lossSync
signal raised due to  lack of reception of PTP Sycn, Followup or
delay response messages
 - PTSF-unusable
unusable PTP packet timing signal received by the request-port,
exceeding the input tolerance of the request-port
6. Dynamic data set updates for external servo.
- defaultDS.clockQuality.clockClass
To support holdover in the T-BC-P/A and T-GM.
- timePropertiesDS.frequencyTraceable
To support availability of a PRC-traceable physical layer
frequency input signal
- PTSF Unusable.

Signed-off-by: Greg Armstrong ;
Signed-off-by: Vipin Sharma ;
Signed-off-by: Devasish Dey ;
Signed-off-by: Leon Goldin 
---
 clock.c |  77 ++-
 clock.h |  23 
 config.c|  30 -
 configs/default.cfg |   3 +
 dm.h|  18 +++
 ds.h|  17 +++
 interface.c |  58 
 interface.h |  29 
 makefile|   8 +-
 monitor.c   |  71 ++
 monitor.h   |   3 +
 msg.h   |  17 +++
 pdt.h   |   9 ++
 pmc.c   |  69 +-
 pmc_common.c|  29 
 port.c  | 194 +++
 port_private.h  |  16 ++-
 port_signaling.c|  41 ++
 ptp4l.8 |  11 +-
 ptp4l.c |  19 ++-
 sk.c|  74 +++
 sk.h|  26 
 tlv.c   |  48 +++
 tlv.h   |  54 
 transport.c |  12 ++
 transport.h |   9 ++
 ts2phc_phc_pps_source.c |  24 
 ts2phc_phc_pps_source.h |   4 +
 ts2phc_pps_sink.c   |  14 +-
 ts2phc_vport.c  | 288 
 ts2phc_vport.h  |  31 +
 tsproc.c|  13 ++
 tsproc.h|   9 ++
 unicast_client.c|  18 ++-
 unicast_service.c   |  41 +-
 util.c  |   9 ++
 vport.c | 142 
 vport.h |  26 
 38 files changed, 1530 insertions(+), 54 deletions(-)
 create mode 100644 ts2phc_vport.c
 create mode 100644 ts2phc_vport.h
 create mode 100644 vport.c
 create mode 100644 vport.h

diff --git a/clock.c b/clock.c
index f808b35..2e854d8 100644
--- a/clock.c
+++ b/clock.c
@@ -15,6 +15,14 @@
  * You should have received a copy of the GNU General Public License along
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * @note Copyright (C) 2022 SyncMonk Technologies 
+ * Also, for each author's protection and ours, we want to make certain that
+ * everyone understands that there is no warranty for this free software.
+ * If the software is modified by someone else and passed on, we want its
+ * recipients to know that what they have is not the original, so that any
+ * problems introduced by others will not reflect on the original authors'
+ * reputations.
  */
 #include 
 #include 
@@ -43,6 +51,7 @@
 #include "tlv.h"
 #include "tsproc.h"
 #include "uds.h"
+#include "vport.h"
 #include "util.h"
 
 #define N_CLOCK_PFD (N_POLLFD + 1) /* one extra per port, for the fault timer 
*/
@@ -97,9 +106,10 @@ struct clock {
LIST_HEAD(ports_head, port) ports;
struct port *uds_rw_port;
struct port *uds_ro_port;
+   struct port *vport_port;
struct pollfd *pollfd;
int pollfd_valid;
-   int nports; /* does not include the two UDS ports */
+   int nports; /* does not include the two UDS ports + 1 Virtual Port */
int last_port_number;
int sde;
int free_running;
@@ -133,10 +143,12 @@ struct clock {
struct clockcheck *sanity_check;
struct interface *uds_rw_if;
struct interface *uds_ro_if;
+   struct interface *vport_if;
LIST_HEAD(clock_subscribers_head, clock_subscriber) subscribers;
struct monitor *slave_event_monitor;
int step_window_counter;
int step_window;
+   bool interface_rate_tlv_support;
 };
 
 struct clock the_clock;
@@ -272,6 +284,7 @@ void clock_destroy(struct clock *c)
 
interface_destroy(c->uds_rw_if);
interfa