Miroslav Lichvar 0c71bd
Backported commit f774703cb1eee058a346aec3341fee0be329bd6d
Miroslav Lichvar 0c71bd
Author: Karthikkumar V <kvaloor@altiostar.com>
Miroslav Lichvar 0c71bd
Date:   Fri Feb 26 06:54:07 2021 +0000
Miroslav Lichvar 0c71bd
Miroslav Lichvar 0c71bd
    Clock Class Threshold Feature addition for PTP4L
Miroslav Lichvar 0c71bd
    
Miroslav Lichvar 0c71bd
    This code changes brings in the ability to program the acceptable
Miroslav Lichvar 0c71bd
    clockClass threshold beyond which device will move to holdover/free-run.
Miroslav Lichvar 0c71bd
    Default clockClass threshold is 248.
Miroslav Lichvar 0c71bd
    Example Use-Case:
Miroslav Lichvar 0c71bd
    This is needed in the cases where T-SC/T-BC Slave might want to listen
Miroslav Lichvar 0c71bd
    only on PRC clockCLass and anything beyond that might not be acceptible
Miroslav Lichvar 0c71bd
    and would want to go to holdover (with SyncE backup or internal oscillator).
Miroslav Lichvar 0c71bd
    
Miroslav Lichvar 0c71bd
    Signed-off-by: Karthikkumar V <kvaloor@altiostar.com>
Miroslav Lichvar 0c71bd
    Signed-off-by: Ramana Reddy <rreddy@altiostar.com>
Miroslav Lichvar 0c71bd
Miroslav Lichvar 0c71bd
diff --git a/clock.c b/clock.c
Miroslav Lichvar 0c71bd
index c1fcff6..d584748 100644
Miroslav Lichvar 0c71bd
--- a/clock.c
Miroslav Lichvar 0c71bd
+++ b/clock.c
Miroslav Lichvar 0c71bd
@@ -114,6 +114,7 @@ struct clock {
Miroslav Lichvar 0c71bd
 	int utc_offset;
Miroslav Lichvar 0c71bd
 	int time_flags;  /* grand master role */
Miroslav Lichvar 0c71bd
 	int time_source; /* grand master role */
Miroslav Lichvar 0c71bd
+	UInteger8 clock_class_threshold;
Miroslav Lichvar 0c71bd
 	UInteger8 max_steps_removed;
Miroslav Lichvar 0c71bd
 	enum servo_state servo_state;
Miroslav Lichvar 0c71bd
 	enum timestamp_type timestamping;
Miroslav Lichvar 0c71bd
@@ -978,6 +979,7 @@ struct clock *clock_create(enum clock_type type, struct config *config,
Miroslav Lichvar 0c71bd
 	c->default_dataset.localPriority =
Miroslav Lichvar 0c71bd
 		config_get_int(config, NULL, "G.8275.defaultDS.localPriority");
Miroslav Lichvar 0c71bd
 	c->max_steps_removed = config_get_int(config, NULL,"maxStepsRemoved");
Miroslav Lichvar 0c71bd
+	c->clock_class_threshold = config_get_int(config, NULL, "clock_class_threshold");
Miroslav Lichvar 0c71bd
 
Miroslav Lichvar 0c71bd
 	/* Harmonize the twoStepFlag with the time_stamping option. */
Miroslav Lichvar 0c71bd
 	if (config_harmonize_onestep(config)) {
Miroslav Lichvar 0c71bd
@@ -1711,6 +1713,11 @@ UInteger8 clock_max_steps_removed(struct clock *c)
Miroslav Lichvar 0c71bd
 	return c->max_steps_removed;
Miroslav Lichvar 0c71bd
 }
Miroslav Lichvar 0c71bd
 
Miroslav Lichvar 0c71bd
+UInteger8 clock_get_clock_class_threshold(struct clock *c)
Miroslav Lichvar 0c71bd
+{
Miroslav Lichvar 0c71bd
+	return c->clock_class_threshold;
Miroslav Lichvar 0c71bd
+}
Miroslav Lichvar 0c71bd
+
Miroslav Lichvar 0c71bd
 UInteger16 clock_steps_removed(struct clock *c)
Miroslav Lichvar 0c71bd
 {
Miroslav Lichvar 0c71bd
 	return c->cur.stepsRemoved;
Miroslav Lichvar 0c71bd
diff --git a/clock.h b/clock.h
Miroslav Lichvar 0c71bd
index e7daf97..845d54f 100644
Miroslav Lichvar 0c71bd
--- a/clock.h
Miroslav Lichvar 0c71bd
+++ b/clock.h
Miroslav Lichvar 0c71bd
@@ -289,6 +289,13 @@ int clock_slave_only(struct clock *c);
Miroslav Lichvar 0c71bd
  */
Miroslav Lichvar 0c71bd
 UInteger8 clock_max_steps_removed(struct clock *c);
Miroslav Lichvar 0c71bd
 
Miroslav Lichvar 0c71bd
+/**
Miroslav Lichvar 0c71bd
+ * Obtain the clock class threshold field from a clock's default data set.
Miroslav Lichvar 0c71bd
+ * @param c  The clock instance.
Miroslav Lichvar 0c71bd
+ * @return   Configured clock class threshold value.
Miroslav Lichvar 0c71bd
+ */
Miroslav Lichvar 0c71bd
+UInteger8 clock_get_clock_class_threshold(struct clock *c);
Miroslav Lichvar 0c71bd
+
Miroslav Lichvar 0c71bd
 /**
Miroslav Lichvar 0c71bd
  * Obtain the steps removed field from a clock's current data set.
Miroslav Lichvar 0c71bd
  * @param c  The clock instance.
Miroslav Lichvar 0c71bd
diff --git a/config.c b/config.c
Miroslav Lichvar 0c71bd
index c3deddb..bf1049f 100644
Miroslav Lichvar 0c71bd
--- a/config.c
Miroslav Lichvar 0c71bd
+++ b/config.c
Miroslav Lichvar 0c71bd
@@ -231,6 +231,7 @@ struct config_item config_tab[] = {
Miroslav Lichvar 0c71bd
 	GLOB_ITEM_INT("clockAccuracy", 0xfe, 0, UINT8_MAX),
Miroslav Lichvar 0c71bd
 	GLOB_ITEM_INT("clockClass", 248, 0, UINT8_MAX),
Miroslav Lichvar 0c71bd
 	GLOB_ITEM_STR("clockIdentity", "000000.0000.000000"),
Miroslav Lichvar 0c71bd
+	GLOB_ITEM_INT("clock_class_threshold", CLOCK_CLASS_THRESHOLD_DEFAULT, 6, CLOCK_CLASS_THRESHOLD_DEFAULT),
Miroslav Lichvar 0c71bd
 	GLOB_ITEM_ENU("clock_servo", CLOCK_SERVO_PI, clock_servo_enu),
Miroslav Lichvar 0c71bd
 	GLOB_ITEM_ENU("clock_type", CLOCK_TYPE_ORDINARY, clock_type_enu),
Miroslav Lichvar 0c71bd
 	GLOB_ITEM_ENU("dataset_comparison", DS_CMP_IEEE1588, dataset_comp_enu),
Miroslav Lichvar 0c71bd
diff --git a/configs/default.cfg b/configs/default.cfg
Miroslav Lichvar 0c71bd
index 9604219..b2ffa94 100644
Miroslav Lichvar 0c71bd
--- a/configs/default.cfg
Miroslav Lichvar 0c71bd
+++ b/configs/default.cfg
Miroslav Lichvar 0c71bd
@@ -60,6 +60,7 @@ verbose			0
Miroslav Lichvar 0c71bd
 summary_interval	0
Miroslav Lichvar 0c71bd
 kernel_leap		1
Miroslav Lichvar 0c71bd
 check_fup_sync		0
Miroslav Lichvar 0c71bd
+clock_class_threshold	248
Miroslav Lichvar 0c71bd
 #
Miroslav Lichvar 0c71bd
 # Servo Options
Miroslav Lichvar 0c71bd
 #
Miroslav Lichvar 0c71bd
diff --git a/ds.h b/ds.h
Miroslav Lichvar 0c71bd
index 9d9c417..dff6d5e 100644
Miroslav Lichvar 0c71bd
--- a/ds.h
Miroslav Lichvar 0c71bd
+++ b/ds.h
Miroslav Lichvar 0c71bd
@@ -87,6 +87,7 @@ struct parent_ds {
Miroslav Lichvar 0c71bd
 
Miroslav Lichvar 0c71bd
 #define CURRENT_UTC_OFFSET  37 /* 1 Jan 2017 */
Miroslav Lichvar 0c71bd
 #define INTERNAL_OSCILLATOR 0xA0
Miroslav Lichvar 0c71bd
+#define CLOCK_CLASS_THRESHOLD_DEFAULT 248
Miroslav Lichvar 0c71bd
 
Miroslav Lichvar 0c71bd
 struct timePropertiesDS {
Miroslav Lichvar 0c71bd
 	Integer16    currentUtcOffset;
Miroslav Lichvar 0c71bd
diff --git a/port.c b/port.c
Miroslav Lichvar 0c71bd
index 2bb974c..eb3b319 100644
Miroslav Lichvar 0c71bd
--- a/port.c
Miroslav Lichvar 0c71bd
+++ b/port.c
Miroslav Lichvar 0c71bd
@@ -1870,6 +1870,14 @@ int process_announce(struct port *p, struct ptp_message *m)
Miroslav Lichvar 0c71bd
 		return result;
Miroslav Lichvar 0c71bd
 	}
Miroslav Lichvar 0c71bd
 
Miroslav Lichvar 0c71bd
+	if (m->announce.grandmasterClockQuality.clockClass >
Miroslav Lichvar 0c71bd
+		clock_get_clock_class_threshold(p->clock)) {
Miroslav Lichvar 0c71bd
+		pl_err(60, "port %hu: Master clock quality received is "
Miroslav Lichvar 0c71bd
+			"greater than configured, ignoring master!",
Miroslav Lichvar 0c71bd
+			portnum(p));
Miroslav Lichvar 0c71bd
+		return result;
Miroslav Lichvar 0c71bd
+	}
Miroslav Lichvar 0c71bd
+
Miroslav Lichvar 0c71bd
 	switch (p->state) {
Miroslav Lichvar 0c71bd
 	case PS_INITIALIZING:
Miroslav Lichvar 0c71bd
 	case PS_FAULTY:
Miroslav Lichvar 0c71bd
diff --git a/ptp4l.8 b/ptp4l.8
Miroslav Lichvar 0c71bd
index b04936a..ca76175 100644
Miroslav Lichvar 0c71bd
--- a/ptp4l.8
Miroslav Lichvar 0c71bd
+++ b/ptp4l.8
Miroslav Lichvar 0c71bd
@@ -455,6 +455,11 @@ message is greater than or equal to the value of maxStepsRemoved the
Miroslav Lichvar 0c71bd
 Announce message is not considered in the operation of the BMCA.
Miroslav Lichvar 0c71bd
 The default value is 255.
Miroslav Lichvar 0c71bd
 .TP
Miroslav Lichvar 0c71bd
+.B clock_class_threshold
Miroslav Lichvar 0c71bd
+The maximum clock class value from master, acceptible to sub-ordinate
Miroslav Lichvar 0c71bd
+clock beyond which it moves out of lock state.
Miroslav Lichvar 0c71bd
+The default value is 248.
Miroslav Lichvar 0c71bd
+.TP
Miroslav Lichvar 0c71bd
 
Miroslav Lichvar 0c71bd
 .B domainNumber
Miroslav Lichvar 0c71bd
 The domain attribute of the local clock.