Allow config interface to parse SyncE related config files.

Co-developed-by: Piotr Kwapulinski <piotr.kwapulin...@intel.com>
Signed-off-by: Piotr Kwapulinski <piotr.kwapulin...@intel.com>
Co-developed-by: Michal Michalik <michal.micha...@intel.com>
Signed-off-by: Michal Michalik <michal.micha...@intel.com>
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalew...@intel.com>
---
v2: remove redundant variable assignment
v3: rebase patch series

 config.c          | 197 ++++++++++++++++++++++++++++++++++++----------
 config.h          |   8 ++
 configs/synce.cfg | 194 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 357 insertions(+), 42 deletions(-)
 create mode 100644 configs/synce.cfg

diff --git a/config.c b/config.c
index 6ba9996..ae49b32 100644
--- a/config.c
+++ b/config.c
@@ -45,6 +45,7 @@ enum config_section {
        GLOBAL_SECTION,
        UC_MTAB_SECTION,
        PORT_SECTION,
+       DEVICE_SECTION,
        UNKNOWN_SECTION,
 };
 
@@ -72,6 +73,7 @@ typedef union {
 #define CFG_ITEM_LOCKED (1 << 1) /* command line value, may not be changed */
 #define CFG_ITEM_PORT   (1 << 2) /* item may appear in port sections */
 #define CFG_ITEM_DYNSTR (1 << 4) /* string value dynamically allocated */
+#define CFG_ITEM_DEVICE (1 << 8) /* item may appear in device sections */
 
 struct config_item {
        char label[CONFIG_LABEL_SIZE];
@@ -83,12 +85,18 @@ struct config_item {
        any_t max;
 };
 
-#define N_CONFIG_ITEMS (sizeof(config_tab) / sizeof(config_tab[0]))
+#define N_CONFIG_ITEMS_PTP (sizeof(config_tab_ptp) / sizeof(config_tab_ptp[0]))
+#define N_CONFIG_ITEMS_SYNCE ((sizeof(config_tab_synce) / \
+       sizeof(config_tab_synce[0])))
+
+#define PORT_TO_FLAG(_port) (_port == PORT_SECTION ? CFG_ITEM_PORT : \
+       _port == DEVICE_SECTION ? CFG_ITEM_DEVICE : \
+       CFG_ITEM_STATIC)
 
 #define CONFIG_ITEM_DBL(_label, _port, _default, _min, _max) { \
        .label  = _label,                               \
        .type   = CFG_TYPE_DOUBLE,                      \
-       .flags  = _port ? CFG_ITEM_PORT : 0,            \
+       .flags  = PORT_TO_FLAG(_port),                  \
        .val.d  = _default,                             \
        .min.d  = _min,                                 \
        .max.d  = _max,                                 \
@@ -96,14 +104,14 @@ struct config_item {
 #define CONFIG_ITEM_ENUM(_label, _port, _default, _table) { \
        .label  = _label,                               \
        .type   = CFG_TYPE_ENUM,                        \
-       .flags  = _port ? CFG_ITEM_PORT : 0,            \
+       .flags  = PORT_TO_FLAG(_port),                  \
        .tab    = _table,                               \
        .val.i  = _default,                             \
 }
 #define CONFIG_ITEM_INT(_label, _port, _default, _min, _max) { \
        .label  = _label,                               \
        .type   = CFG_TYPE_INT,                         \
-       .flags  = _port ? CFG_ITEM_PORT : 0,            \
+       .flags  = PORT_TO_FLAG(_port),                  \
        .val.i  = _default,                             \
        .min.i  = _min,                                 \
        .max.i  = _max,                                 \
@@ -111,33 +119,39 @@ struct config_item {
 #define CONFIG_ITEM_STRING(_label, _port, _default) {  \
        .label  = _label,                               \
        .type   = CFG_TYPE_STRING,                      \
-       .flags  = _port ? CFG_ITEM_PORT : 0,            \
+       .flags  = PORT_TO_FLAG(_port),                  \
        .val.s  = _default,                             \
 }
 
 #define GLOB_ITEM_DBL(label, _default, min, max) \
-       CONFIG_ITEM_DBL(label, 0, _default, min, max)
+       CONFIG_ITEM_DBL(label, GLOBAL_SECTION, _default, min, max)
 
 #define GLOB_ITEM_ENU(label, _default, table) \
-       CONFIG_ITEM_ENUM(label, 0, _default, table)
+       CONFIG_ITEM_ENUM(label, GLOBAL_SECTION, _default, table)
 
 #define GLOB_ITEM_INT(label, _default, min, max) \
-       CONFIG_ITEM_INT(label, 0, _default, min, max)
+       CONFIG_ITEM_INT(label, GLOBAL_SECTION, _default, min, max)
 
 #define GLOB_ITEM_STR(label, _default) \
-       CONFIG_ITEM_STRING(label, 0, _default)
+       CONFIG_ITEM_STRING(label, GLOBAL_SECTION, _default)
 
 #define PORT_ITEM_DBL(label, _default, min, max) \
-       CONFIG_ITEM_DBL(label, 1, _default, min, max)
+       CONFIG_ITEM_DBL(label, PORT_SECTION, _default, min, max)
 
 #define PORT_ITEM_ENU(label, _default, table) \
-       CONFIG_ITEM_ENUM(label, 1, _default, table)
+       CONFIG_ITEM_ENUM(label, PORT_SECTION, _default, table)
 
 #define PORT_ITEM_INT(label, _default, min, max) \
-       CONFIG_ITEM_INT(label, 1, _default, min, max)
+       CONFIG_ITEM_INT(label, PORT_SECTION, _default, min, max)
 
 #define PORT_ITEM_STR(label, _default) \
-       CONFIG_ITEM_STRING(label, 1, _default)
+       CONFIG_ITEM_STRING(label, PORT_SECTION, _default)
+
+#define DEV_ITEM_INT(label, _default, min, max) \
+       CONFIG_ITEM_INT(label, DEVICE_SECTION, _default, min, max)
+
+#define DEV_ITEM_STR(label, _default) \
+       CONFIG_ITEM_STRING(label, DEVICE_SECTION, _default)
 
 static struct config_enum clock_servo_enu[] = {
        { "pi",     CLOCK_SERVO_PI     },
@@ -224,7 +238,7 @@ static struct config_enum bmca_enu[] = {
        { NULL, 0 },
 };
 
-struct config_item config_tab[] = {
+struct config_item config_tab_ptp[] = {
        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),
@@ -347,7 +361,37 @@ struct config_item config_tab[] = {
        GLOB_ITEM_INT("write_phase_mode", 0, 0, 1),
 };
 
+struct config_item config_tab_synce[] = {
+       GLOB_ITEM_INT("logging_level", LOG_INFO, PRINT_LEVEL_MIN, 
PRINT_LEVEL_MAX),
+       GLOB_ITEM_STR("message_tag", NULL),
+       GLOB_ITEM_INT("use_syslog", 1, 0, 1),
+       GLOB_ITEM_STR("userDescription", ""),
+       GLOB_ITEM_INT("verbose", 0, 0, 1),
+       DEV_ITEM_INT("internal_input", 1, 0, 1),
+       DEV_ITEM_INT("external_input", 0, 0, 1),
+       DEV_ITEM_INT("external_input_QL", 0, 0, 15),
+       DEV_ITEM_INT("external_input_ext_QL", 0, 0, 255),
+       DEV_ITEM_INT("extended_tlv", 0, 0, 1),
+       DEV_ITEM_INT("network_option", 1, 1, 2),
+       DEV_ITEM_INT("recover_time", 300, 10, 720),
+       DEV_ITEM_STR("dpll_get_state_cmd", NULL),
+       DEV_ITEM_STR("dpll_holdover_value", NULL),
+       DEV_ITEM_STR("dpll_locked_ho_value", NULL),
+       DEV_ITEM_STR("dpll_locked_value", NULL),
+       DEV_ITEM_STR("dpll_freerun_value", NULL),
+       DEV_ITEM_STR("dpll_invalid_value", NULL),
+       PORT_ITEM_STR("allowed_qls", NULL),
+       PORT_ITEM_STR("allowed_ext_qls", NULL),
+       PORT_ITEM_INT("sync", 0, 0, 1),
+       PORT_ITEM_STR("recover_clock_enable_cmd", NULL),
+       PORT_ITEM_STR("recover_clock_disable_cmd", NULL),
+       PORT_ITEM_INT("tx_heartbeat_msec", 1000, 100, 3000),
+       PORT_ITEM_INT("rx_heartbeat_msec", 50, 10, 500),
+};
+
 static struct unicast_master_table *current_uc_mtab;
+static struct interface *__config_create_interface(const char *name, struct 
config *cfg,
+                                                  const char *type);
 
 static enum parser_result
 parse_fault_interval(struct config *cfg, const char *section,
@@ -398,6 +442,8 @@ static struct config_item *config_item_alloc(struct config 
*cfg,
        }
        strncpy(ci->label, name, CONFIG_LABEL_SIZE - 1);
        ci->type = type;
+       ci->val.s = NULL;
+       ci->flags = 0;
 
        snprintf(buf, sizeof(buf), "%s.%s", section, ci->label);
        if (hash_insert(cfg->htab, buf, ci)) {
@@ -412,8 +458,11 @@ static struct config_item *config_item_alloc(struct config 
*cfg,
 static void config_item_free(void *ptr)
 {
        struct config_item *ci = ptr;
-       if (ci->type == CFG_TYPE_STRING && ci->flags & CFG_ITEM_DYNSTR)
+       if (ci->type == CFG_TYPE_STRING && ci->flags & CFG_ITEM_DYNSTR
+           && ci->val.s != NULL) {
                free(ci->val.s);
+               ci->val.s = NULL;
+       }
        if (ci->flags & CFG_ITEM_STATIC)
                return;
        free(ci);
@@ -518,10 +567,13 @@ static enum parser_result parse_section_line(char *s, 
enum config_section *secti
                current_uc_mtab = NULL;
        } else if (s[0] == '[') {
                char c;
-               *section = PORT_SECTION;
-               /* Replace square brackets with white space. */
+               if (s[1] == '<')
+                       *section = DEVICE_SECTION;
+               else
+                       *section = PORT_SECTION;
+               /* Replace brackets with white space. */
                while (0 != (c = *s)) {
-                       if (c == '[' || c == ']')
+                       if (c == '[' || c == ']' || c == '<' || c == '>')
                                *s = ' ';
                        s++;
                }
@@ -579,7 +631,8 @@ static enum parser_result parse_item(struct config *cfg,
        }
 
        if (section) {
-               if (!(cgi->flags & CFG_ITEM_PORT)) {
+               if (!(cgi->flags & CFG_ITEM_PORT) &&
+                   !(cgi->flags & CFG_ITEM_DEVICE)) {
                        return NOT_PARSED;
                }
                /* Create or update this port specific item. */
@@ -607,8 +660,9 @@ static enum parser_result parse_item(struct config *cfg,
                dst->val.d = df;
                break;
        case CFG_TYPE_STRING:
-               if (dst->flags & CFG_ITEM_DYNSTR) {
+               if (dst->flags & CFG_ITEM_DYNSTR && dst->val.s != NULL) {
                        free(dst->val.s);
+                       dst->val.s = NULL;
                }
                dst->val.s = strdup(value);
                if (!dst->val.s) {
@@ -734,18 +788,25 @@ static void check_deprecated_options(const char **option)
        }
 }
 
-static struct option *config_alloc_longopts(void)
+static struct option *config_alloc_longopts(enum feature_type type)
 {
-       struct config_item *ci;
+       struct config_item *ci, *ci_tab;
        struct option *opts;
-       int i;
+       int i, n_items;
 
-       opts = calloc(1, (1 + N_CONFIG_ITEMS) * sizeof(*opts));
+       if (type == PTP) {
+               ci_tab = &config_tab_ptp[0];
+               n_items = N_CONFIG_ITEMS_PTP;
+       } else {
+               ci_tab = &config_tab_synce[0];
+               n_items = N_CONFIG_ITEMS_SYNCE;
+       }
+       opts = calloc(1, (1 + n_items) * sizeof(*opts));
        if (!opts) {
                return NULL;
        }
-       for (i = 0; i < N_CONFIG_ITEMS; i++) {
-               ci = &config_tab[i];
+       for (i = 0; i < n_items; i++) {
+               ci = &ci_tab[i];
                opts[i].name = ci->label;
                opts[i].has_arg = required_argument;
                /* Avoid bug in detection of ambiguous options in glibc */
@@ -763,6 +824,8 @@ int config_read(const char *name, struct config *cfg)
        char buf[1024], *line, *c;
        const char *option, *value;
        struct interface *current_port = NULL;
+       struct interface *current_device = NULL;
+       bool is_synce = (cfg->type == SYNCE);
        int line_num;
 
        fp = 0 == strncmp(name, "-", 2) ? stdin : fopen(name, "r");
@@ -793,6 +856,7 @@ int config_read(const char *name, struct config *cfg)
                if (parse_section_line(line, &current_section) == PARSED_OK) {
                        if (current_section == PORT_SECTION) {
                                char port[17];
+
                                if (1 != sscanf(line, " %16s", port)) {
                                        fprintf(stderr, "could not parse port 
name on line %d\n",
                                                        line_num);
@@ -801,6 +865,27 @@ int config_read(const char *name, struct config *cfg)
                                current_port = config_create_interface(port, 
cfg);
                                if (!current_port)
                                        goto parse_error;
+                               if (is_synce) {
+                                       if (current_device) {
+                                               
interface_se_set_parent_dev(current_port,
+                                                       
interface_name(current_device));
+                                       } else {
+                                               goto parse_error;
+                                       }
+                               }
+                       } else if (current_section == DEVICE_SECTION) {
+                               /* clear port on new device found in config */
+                               current_port = NULL;
+                               char device[17];
+
+                               if (sscanf(line, " %16s", device) != 1) {
+                                       fprintf(stderr, "could not parse device 
name on line %d\n",
+                                               line_num);
+                                       goto parse_error;
+                               }
+                               current_device = 
__config_create_interface(device, cfg, "device");
+                               if (!current_device)
+                                       goto parse_error;
                        }
                        continue;
                }
@@ -820,14 +905,16 @@ int config_read(const char *name, struct config *cfg)
                if (parse_setting_line(line, &option, &value)) {
                        fprintf(stderr, "could not parse line %d in %s 
section\n",
                                line_num, current_section == GLOBAL_SECTION ?
-                               "global" : interface_name(current_port));
+                               "global" : interface_name(current_port ?
+                                                         current_port : 
current_device));
                        goto parse_error;
                }
 
                check_deprecated_options(&option);
 
                parser_res = parse_item(cfg, 0, current_section == 
GLOBAL_SECTION ?
-                                       NULL : interface_name(current_port),
+                                       NULL : interface_name(current_port ?
+                                                             current_port : 
current_device),
                                        option, value);
                switch (parser_res) {
                case PARSED_OK:
@@ -836,7 +923,8 @@ int config_read(const char *name, struct config *cfg)
                        fprintf(stderr, "unknown option %s at line %d in %s 
section\n",
                                option, line_num,
                                current_section == GLOBAL_SECTION ? "global" :
-                               interface_name(current_port));
+                               interface_name(current_port ?
+                                              current_port : current_device));
                        goto parse_error;
                case BAD_VALUE:
                        fprintf(stderr, "%s is a bad value for option %s at 
line %d\n",
@@ -862,7 +950,7 @@ parse_error:
        return -2;
 }
 
-struct interface *config_create_interface(const char *name, struct config *cfg)
+struct interface *__config_create_interface(const char *name, struct config 
*cfg, const char *type)
 {
        struct interface *iface;
        const char *ifname;
@@ -876,7 +964,7 @@ struct interface *config_create_interface(const char *name, 
struct config *cfg)
 
        iface = interface_create(name);
        if (!iface) {
-               fprintf(stderr, "cannot allocate memory for a port\n");
+               fprintf(stderr, "cannot allocate memory for a %s\n", type);
                return NULL;
        }
        STAILQ_INSERT_TAIL(&cfg->interfaces, iface, list);
@@ -885,12 +973,17 @@ struct interface *config_create_interface(const char 
*name, struct config *cfg)
        return iface;
 }
 
-struct config *config_create(void)
+struct interface *config_create_interface(const char *name, struct config *cfg)
+{
+       return __config_create_interface(name, cfg, "port");
+}
+
+struct config *__config_create(enum feature_type type)
 {
        char buf[CONFIG_LABEL_SIZE + 8];
-       struct config_item *ci;
+       struct config_item *ci, *ci_tab;
        struct config *cfg;
-       int i;
+       int i, end;
 
        cfg = calloc(1, sizeof(*cfg));
        if (!cfg) {
@@ -899,7 +992,7 @@ struct config *config_create(void)
        STAILQ_INIT(&cfg->interfaces);
        STAILQ_INIT(&cfg->unicast_master_tables);
 
-       cfg->opts = config_alloc_longopts();
+       cfg->opts = config_alloc_longopts(type);
        if (!cfg->opts) {
                free(cfg);
                return NULL;
@@ -912,9 +1005,18 @@ struct config *config_create(void)
                return NULL;
        }
 
+       cfg->type = type;
+       if (type == PTP) {
+               ci_tab = &config_tab_ptp[0];
+               end = N_CONFIG_ITEMS_PTP;
+       } else {
+               ci_tab = &config_tab_synce[0];
+               end = N_CONFIG_ITEMS_SYNCE;
+       }
+
        /* Populate the hash table with global defaults. */
-       for (i = 0; i < N_CONFIG_ITEMS; i++) {
-               ci = &config_tab[i];
+       for (i = 0; i < end; i++) {
+               ci = &ci_tab[i];
                ci->flags |= CFG_ITEM_STATIC;
                snprintf(buf, sizeof(buf), "global.%s", ci->label);
                if (hash_insert(cfg->htab, buf, ci)) {
@@ -924,12 +1026,12 @@ struct config *config_create(void)
        }
 
        /* Perform a Built In Self Test.*/
-       for (i = 0; i < N_CONFIG_ITEMS; i++) {
-               ci = &config_tab[i];
+       for (i = 0; i < end; i++) {
+               ci = &ci_tab[i];
                ci = config_global_item(cfg, ci->label);
-               if (ci != &config_tab[i]) {
+               if (ci != &ci_tab[i]) {
                        fprintf(stderr, "config BIST failed at %s\n",
-                               config_tab[i].label);
+                               ci_tab[i].label);
                        goto fail;
                }
        }
@@ -941,6 +1043,16 @@ fail:
        return NULL;
 }
 
+struct config *config_create(void)
+{
+       return __config_create(PTP);
+}
+
+struct config *config_create_synce(void)
+{
+       return __config_create(SYNCE);
+}
+
 void config_destroy(struct config *cfg)
 {
        struct unicast_master_address *address;
@@ -1143,8 +1255,9 @@ int config_set_string(struct config *cfg, const char 
*option,
                return -1;
        }
        ci->flags |= CFG_ITEM_LOCKED;
-       if (ci->flags & CFG_ITEM_DYNSTR) {
+       if (ci->flags & CFG_ITEM_DYNSTR && ci->val.s != NULL) {
                free(ci->val.s);
+               ci->val.s = NULL;
        }
        ci->val.s = strdup(val);
        if (!ci->val.s) {
diff --git a/config.h b/config.h
index 14d2f64..a32e007 100644
--- a/config.h
+++ b/config.h
@@ -32,10 +32,16 @@
 #include "servo.h"
 #include "sk.h"
 
+enum feature_type {
+       PTP = 0,
+       SYNCE
+};
+
 struct config {
        /* configured interfaces */
        STAILQ_HEAD(interfaces_head, interface) interfaces;
        int n_interfaces;
+       enum feature_type type;
 
        /* for parsing command line options */
        struct option *opts;
@@ -55,6 +61,8 @@ void config_destroy(struct config *cfg);
 
 struct config *config_create(void);
 
+struct config *config_create_synce(void);
+
 double config_get_double(struct config *cfg, const char *section,
                         const char *option);
 
diff --git a/configs/synce.cfg b/configs/synce.cfg
new file mode 100644
index 0000000..eadb318
--- /dev/null
+++ b/configs/synce.cfg
@@ -0,0 +1,194 @@
+# Global section is for debuging mostly
+[global]
+#
+# Runtime options
+#
+logging_level          7
+use_syslog             0
+verbose                        1
+message_tag            [synce4l]
+
+
+#
+# Device section
+# Per-device configuration
+#
+# User defined name of a one logical device configured for SyncE in the system.
+# All the ports configured after this section will be a part of this device
+# (until next device section).
+[<synce1>]
+
+#
+# If internal inputs are allowed
+# 0 if internal input sources shall not be used
+# 1 if internal input sources shall be used
+# default: 1
+#
+# Internal inputs mean the inputs recovered from the PHY's.
+# The ports configured (in the port-sections [<dev name>], under the device
+# section) will be monitored for the QL (Quality Level).
+# QL is sent by the peer connected to the port and represents the Holdover
+# performance of the peer.
+# The best QL (from all the ports where "sync = 1") is selected and frequency
+# recovered on that port shall be used to feed its frequency to all the other
+# ports.
+#
+internal_input         1
+
+#
+# If external inputs are allowed
+# 0 if external input sources shall not be used
+# 1 if external input sources shall be used
+# default: 0
+#
+# External inputs are either 1PPS from buil-in GPS module or 1PPS from the
+# on-board SMA connectors
+#
+# Device must be pre-confiured to use this setting.
+# Before running the application, one of the external inputs shall be selected.
+# This is done through the interface supplied by the NIC vendor.
+#
+# In this mode synce4l application is only responsible for sending
+# the QL to the peers on all configured ports (where "sync = 1")
+# The QL value that is sent equals configured "external_input_QL"
+# (and "external_input_ext_QL" in case of "extended_tlv=1")
+#
+external_input         0
+
+#
+# These values are sent to the peers on configured ports ONLY when 'external
+# input' mode is enabled.
+# Valid values are defined in Table 11-7 and Table 11-8 of recommendation
+# ITU-T G.8264.
+# They shall be configured appropriately so they are understood by the peer.
+#
+# external_input_QL corresponds to the SSM code column.
+#
+# external_input_ext_QL corresponds to the Enhanced SSM code column
+# (is used only if "extended_tlv = 1")
+#
+external_input_QL      2
+external_input_ext_QL  255
+
+#
+# If extended TLV shall be supported on the device.
+# 0 if no extended tlv shall be supported
+# 1 if extended tlv shall be supported
+# default: 0
+#
+# In case of 0:
+#       - the port will always TX the non-extended TLV, for RX only
+#         non-extended TLV will be processed for reference signal selection
+# In case of 1:
+#       - If port is configured with external_input=1, the TX will always use
+#         extended TLV (no RX is required in this case)
+#       - If port is configured with external_input=0 and internal_input=1, the
+#         TX version of TLV will be propagated from the port that was chosen as
+#         candidate for frequency synchronization
+#
+extended_tlv           1
+
+#
+# Which network option shall be supported
+#
+# 1 or 2 as defined in T-REC-G.8264
+# default: 1
+#
+# This is rather per-network option, all device in SyncE network
+# shall have this configured for the same value
+#
+network_option         1
+
+#
+# Seconds indicating minimum time to recover from the QL-failed state on the
+# port.
+# Range: 10-720
+# Default: 300
+#
+# If valid QL was not received from one of the source ports within 5 seconds
+# the port is no longer a valid source (marked as QL-failed)
+#
+# Valid QL must be received for more then "recover_time" seconds on that port
+# to use its PHY recovered signal again as a valid source
+#
+recover_time           10
+
+#
+# Shell command to be executed in order to obtain current DPLL status of a
+# device.
+#
+dpll_get_state_cmd             cat /sys/class/net/enp1s0f0/device/cgu_state
+
+#
+# DPLL state values, must equal to values produced by stdout of
+# "dpll_get_state_cmd" command
+#
+dpll_holdover_value    4
+dpll_locked_ho_value   3
+dpll_locked_value      2
+dpll_freerun_value     1
+dpll_invalid_value     0
+
+#
+# Port section(s)
+#
+# It starts per-port configuration.
+# Each port (of the device) that is used for SyncE, shall have its own section
+# with at least sync = 1 (which defines port as synchronous mode)
+#
+[enp1s0f0]
+
+#
+# msec resolution of TX the QL from this port to the peer
+# [100-3000], default:1000 (1000 = 1 second is expected by the standard)
+#
+# As the standard expects 1 sec, it is not recommended to use different
+# than a 1000.
+#
+tx_heartbeat_msec      2000
+
+#
+# recovered PHY signal can be lost at anytime, this is msec resolution of
+# reading the socket, acting on signal lost shall be done just after
+# [10-500], default:50
+#
+rx_heartbeat_msec      500
+
+#
+# Sync mode as defined by standard
+# 0 (non-sync mode) - port not used for best signal source selection or TX its 
QL
+# 1 (sync mode) - port used for best signal source selection or TX its QL
+#
+sync                   1
+
+#
+# Shell commands for enabling/disabling this port as main recovered clock on a
+# device.
+#
+recover_clock_enable_cmd       echo 1 0 > 
/sys/class/net/enp1s0f0/device/phy/synce
+recover_clock_disable_cmd      echo 0 0 > 
/sys/class/net/enp1s0f0/device/phy/synce
+
+#
+# next configured interface for the device
+#
+[enp1s0f1]
+sync                   1
+recover_clock_enable_cmd       echo 1 0 > 
/sys/class/net/enp1s0f1/device/phy/synce
+recover_clock_disable_cmd      echo 0 0 > 
/sys/class/net/enp1s0f1/device/phy/synce
+
+
+
+############################################################
+#
+# next SyncE device section
+#
+#[<synce2>]
+#internal_input                0
+#external_input                1
+
+#
+# new port belonging to the "new" device
+#
+#[enp7s0f0]
+#sync                  1
+
-- 
2.26.0



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

Reply via email to