Signed-off-by: Richard Cochran <[email protected]>
---
config.c | 15 ++++++++++++-
configs/default.cfg | 5 +++++
port.c | 53 +++++++++++++++++++++++++++++++++++++++++++++
port_private.h | 3 +++
power_profile.h | 31 ++++++++++++++++++++++++++
ptp4l.8 | 38 ++++++++++++++++++++++++++++++++
tlv.h | 8 +++++++
7 files changed, 152 insertions(+), 1 deletion(-)
create mode 100644 power_profile.h
diff --git a/config.c b/config.c
index f028b88..cb4421f 100644
--- a/config.c
+++ b/config.c
@@ -31,6 +31,7 @@
#include "config.h"
#include "ether.h"
#include "hash.h"
+#include "power_profile.h"
#include "print.h"
#include "util.h"
@@ -66,7 +67,7 @@ typedef union {
char *s;
} any_t;
-#define CONFIG_LABEL_SIZE 32
+#define CONFIG_LABEL_SIZE 64
#define CFG_ITEM_STATIC (1 << 0) /* statically allocated, not to be freed */
#define CFG_ITEM_LOCKED (1 << 1) /* command line value, may not be changed */
@@ -190,6 +191,13 @@ static struct config_enum hwts_filter_enu[] = {
{ NULL, 0 },
};
+static struct config_enum ieee_c37_238_enu[] = {
+ { "none", IEEE_C37_238_VERSION_NONE },
+ { "2011", IEEE_C37_238_VERSION_2011 },
+ { "2017", IEEE_C37_238_VERSION_2017 },
+ { NULL, 0 },
+};
+
static struct config_enum nw_trans_enu[] = {
{ "L2", TRANS_IEEE_802_3 },
{ "UDPv4", TRANS_UDP_IPV4 },
@@ -300,6 +308,11 @@ struct config_item config_tab[] = {
GLOB_ITEM_DBL("pi_proportional_exponent", -0.3, -DBL_MAX, DBL_MAX),
GLOB_ITEM_DBL("pi_proportional_norm_max", 0.7, DBL_MIN, 1.0),
GLOB_ITEM_DBL("pi_proportional_scale", 0.0, 0.0, DBL_MAX),
+ PORT_ITEM_ENU("power_profile.version", IEEE_C37_238_VERSION_NONE,
ieee_c37_238_enu),
+ PORT_ITEM_INT("power_profile.2011.grandmasterTimeInaccuracy",
0xFFFFFFFF, 0, INT_MAX),
+ PORT_ITEM_INT("power_profile.2011.networkTimeInaccuracy", 0, 0,
INT_MAX),
+ PORT_ITEM_INT("power_profile.2017.totalTimeInaccuracy", 0xFFFFFFFF, 0,
INT_MAX),
+ PORT_ITEM_INT("power_profile.grandmasterID", 0, 0, 0xFFFF),
GLOB_ITEM_INT("priority1", 128, 0, UINT8_MAX),
GLOB_ITEM_INT("priority2", 128, 0, UINT8_MAX),
GLOB_ITEM_STR("productDescription", ";;"),
diff --git a/configs/default.cfg b/configs/default.cfg
index 297a99d..a21ec66 100644
--- a/configs/default.cfg
+++ b/configs/default.cfg
@@ -41,6 +41,11 @@ BMCA ptp
inhibit_announce 0
inhibit_delay_req 0
ignore_source_id 0
+power_profile.2011.grandmasterTimeInaccuracy 0xFFFFFFFF
+power_profile.2011.networkTimeInaccuracy 0
+power_profile.2017.totalTimeInaccuracy 0xFFFFFFFF
+power_profile.grandmasterID 0
+power_profile.version none
#
# Run time options
#
diff --git a/port.c b/port.c
index 92f3ee3..23697a5 100644
--- a/port.c
+++ b/port.c
@@ -453,6 +453,46 @@ static int follow_up_info_append(struct ptp_message *m)
return 0;
}
+static int ieee_c37_238_append(struct port *p, struct ptp_message *m)
+{
+ struct ieee_c37_238_2017_tlv *p17;
+ struct ieee_c37_238_2011_tlv *p11;
+ struct tlv_extra *extra;
+
+ switch (p->pwr.version) {
+ case IEEE_C37_238_VERSION_NONE:
+ return 0;
+ case IEEE_C37_238_VERSION_2011:
+ extra = msg_tlv_append(m, sizeof(*p11));
+ if (!extra) {
+ return -1;
+ }
+ p11 = (struct ieee_c37_238_2011_tlv *) extra->tlv;
+ p11->type = TLV_ORGANIZATION_EXTENSION;
+ p11->length = sizeof(*p11) - sizeof(p11->type) -
sizeof(p11->length);
+ memcpy(p11->id, ieeec37_238_id, sizeof(ieeec37_238_id));
+ p11->subtype[2] = 1;
+ p11->grandmasterID = p->pwr.grandmasterID;
+ p11->grandmasterTimeInaccuracy =
p->pwr.grandmasterTimeInaccuracy;
+ p11->networkTimeInaccuracy = p->pwr.networkTimeInaccuracy;
+ break;
+ case IEEE_C37_238_VERSION_2017:
+ extra = msg_tlv_append(m, sizeof(*p17));
+ if (!extra) {
+ return -1;
+ }
+ p17 = (struct ieee_c37_238_2017_tlv *) extra->tlv;
+ p17->type = TLV_ORGANIZATION_EXTENSION;
+ p17->length = sizeof(*p17) - sizeof(p17->type) -
sizeof(p17->length);
+ memcpy(p17->id, ieeec37_238_id, sizeof(ieeec37_238_id));
+ p17->subtype[2] = 2;
+ p17->grandmasterID = p->pwr.grandmasterID;
+ p17->totalTimeInaccuracy = p->pwr.totalTimeInaccuracy;
+ break;
+ }
+ return 0;
+}
+
static int net_sync_resp_append(struct port *p, struct ptp_message *m)
{
struct timePropertiesDS tp = clock_time_properties(p->clock);
@@ -1622,6 +1662,9 @@ int port_tx_announce(struct port *p, struct address *dst,
uint16_t sequence_id)
if (p->path_trace_enabled && path_trace_append(p, msg, dad)) {
pr_err("%s: append path trace failed", p->log_name);
}
+ if (ieee_c37_238_append(p, msg)) {
+ pr_err("%s: append power profile failed", p->log_name);
+ }
err = port_prepare_and_send(p, msg, TRANS_GENERAL);
if (err) {
@@ -3332,6 +3375,16 @@ struct port *port_open(const char *phc_device,
p->state = PS_INITIALIZING;
p->delayMechanism = config_get_int(cfg, p->name, "delay_mechanism");
p->versionNumber = PTP_MAJOR_VERSION;
+ p->pwr.version =
+ config_get_int(cfg, p->name, "power_profile.version");
+ p->pwr.grandmasterID =
+ config_get_int(cfg, p->name, "power_profile.grandmasterID");
+ p->pwr.grandmasterTimeInaccuracy =
+ config_get_int(cfg, p->name,
"power_profile.2011.grandmasterTimeInaccuracy");
+ p->pwr.networkTimeInaccuracy =
+ config_get_int(cfg, p->name,
"power_profile.2011.networkTimeInaccuracy");
+ p->pwr.totalTimeInaccuracy =
+ config_get_int(cfg, p->name,
"power_profile.2017.totalTimeInaccuracy");
p->slave_event_monitor = clock_slave_monitor(clock);
if (!port_is_uds(p) && unicast_client_initialize(p)) {
diff --git a/port_private.h b/port_private.h
index e5837b9..3b02d2f 100644
--- a/port_private.h
+++ b/port_private.h
@@ -26,6 +26,7 @@
#include "fsm.h"
#include "monitor.h"
#include "msg.h"
+#include "power_profile.h"
#include "tmv.h"
#define NSEC2SEC 1000000000LL
@@ -153,6 +154,8 @@ struct port {
LIST_HEAD(fm, foreign_clock) foreign_masters;
/* TC book keeping */
TAILQ_HEAD(tct, tc_txd) tc_transmitted;
+ /* power profile */
+ struct ieee_c37_238_settings_np pwr;
/* unicast client mode */
struct unicast_master_table *unicast_master_table;
/* unicast service mode */
diff --git a/power_profile.h b/power_profile.h
new file mode 100644
index 0000000..6a7c8a4
--- /dev/null
+++ b/power_profile.h
@@ -0,0 +1,31 @@
+/**
+ * @file power_profile.h
+ * @brief Implements power profile features.
+ * @note Copyright (C) 2021 Richard Cochran <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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.
+ */
+#ifndef HAVE_POWER_PROFILE_H
+#define HAVE_POWER_PROFILE_H
+
+#include "pdt.h"
+
+enum power_profile_version {
+ IEEE_C37_238_VERSION_NONE,
+ IEEE_C37_238_VERSION_2011,
+ IEEE_C37_238_VERSION_2017,
+};
+
+#endif
diff --git a/ptp4l.8 b/ptp4l.8
index 55070aa..bb678c9 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -360,6 +360,44 @@ free-running physical clock (created by writing to
The default is -1, which means the index will be set to the PHC associated with
the interface, or the device specified by the \fB-p\fP option.
+.TP
+.B power_profile.2011.grandmasterTimeInaccuracy
+Specifies the time inaccuracy of the GM in nanoseconds. Relevant only
+when power_profile.version is 2011. This value may be changed
+dynamically using the POWER_PROFILE_SETTINGS_NP management message.
+The default is 0xFFFFFFFF.
+
+.TP
+.B power_profile.2011.networkTimeInaccuracy
+Specifies the time inaccuracy of the network in nanoseconds. Relevant
+only when power_profile.version is 2011. This value may be changed
+dynamically using the POWER_PROFILE_SETTINGS_NP management message.
+The default is 0xFFFFFFFF.
+
+.TP
+.B power_profile.2017.totalTimeInaccuracy
+Specifies the sum of the GM, network, and local node inaccuracies in
+nanoseconds. Relevant only when power_profile.version is 2017. This
+value may be changed dynamically using the POWER_PROFILE_SETTINGS_NP
+management message. The default is 0xFFFFFFFF meaning unknown
+inaccuracy.
+
+.TP
+.B power_profile.grandmasterID
+Specifies an optional, non-zero identification code for the GM. Note
+that the code is an arbitrary, power profile specific integer, not
+necessarily related to the clockIdentity in any way. This value may
+be changed dynamically using the POWER_PROFILE_SETTINGS_NP management
+message. The default is 0 meaning unused.
+
+.TP
+.B power_profile.version
+Specifies the power profile version to be used. Valid values are
+"none", "2011", or "2017".
+This value may be changed dynamically using the
+POWER_PROFILE_SETTINGS_NP management message.
+The default is "none".
+
.TP
.B ptp_dst_mac
The MAC address to which PTP messages should be sent.
diff --git a/tlv.h b/tlv.h
index 3d838b7..b973295 100644
--- a/tlv.h
+++ b/tlv.h
@@ -324,6 +324,14 @@ struct ieee_c37_238_2017_tlv {
Octet pad[2];
} PACKED;
+struct ieee_c37_238_settings_np {
+ Enumeration16 version;
+ UInteger16 grandmasterID;
+ UInteger32 grandmasterTimeInaccuracy;
+ UInteger32 networkTimeInaccuracy;
+ UInteger32 totalTimeInaccuracy;
+} PACKED;
+
struct msg_interval_req_tlv {
Enumeration16 type;
UInteger16 length;
--
2.30.2
_______________________________________________
Linuxptp-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel