From: Arkadiusz Kubalewski <arkadiusz.kubalew...@intel.com> Add main code of synce4l - user space application implementing standard - Recommendation ITU-T G.8264/Y.1364. On init the application parses SyncE config file and initializes a synce_clock with SyncE devices and configured ports. synce_clock is later polled until application termination.
Add documentation in form of Linux manual and 'synce4l_README.md'. Add synce4l to the linuxptp makefile. Co-developed-by: Andrzej Sawula <andrzej.saw...@intel.com> Signed-off-by: Andrzej Sawula <andrzej.saw...@intel.com> 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> --- v4: - changed order of patch in patch-series - change default heartbeat to 1 second in example config - remove 'internal_mode'/'external_input' mode parameters and change - remove 'sync' parameter them to string parameter 'input_mode' - documentation change - change 'DPLL' -> 'EEC' to be more HW agnostic in documentation v3: - rebase patch series - fix typo in 'usage' - add synce4l to .gitignore v2: - fix duplicated entry in synce4l.8 - updated license headers .gitignore | 1 + README.org | 2 + configs/synce.cfg | 2 +- makefile | 9 ++- synce4l.8 | 222 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ synce4l.c | 132 ++++++++++++++++++++++++++++++++ synce4l_README.md | 202 +++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 567 insertions(+), 3 deletions(-) create mode 100644 synce4l.8 create mode 100644 synce4l.c create mode 100644 synce4l_README.md diff --git a/.gitignore b/.gitignore index 1e7d1ca..8c65e47 100644 --- a/.gitignore +++ b/.gitignore @@ -8,5 +8,6 @@ /ptp4l /phc_ctl /snmp4lptp +/synce4l /timemaster /ts2phc diff --git a/README.org b/README.org index 063b542..ab0d5a0 100644 --- a/README.org +++ b/README.org @@ -51,6 +51,8 @@ - Supports bonded, IPoIB, and vlan interfaces. + - Supports Synchronous Ethernet (Recommendation ITU-T G.8264/Y.1364). + * Getting the Code You can download the latest released version at Source Forge. diff --git a/configs/synce.cfg b/configs/synce.cfg index 64c5846..3b5a91d 100644 --- a/configs/synce.cfg +++ b/configs/synce.cfg @@ -136,7 +136,7 @@ eec_invalid_value 0 # As the standard expects 1 sec, it is not recommended to use different # than a 1000. # -tx_heartbeat_msec 2000 +tx_heartbeat_msec 1000 # # recovered PHY signal can be lost at anytime, this is msec resolution of diff --git a/makefile b/makefile index 5295b60..b7263a9 100644 --- a/makefile +++ b/makefile @@ -22,12 +22,14 @@ CC = $(CROSS_COMPILE)gcc VER = -DVER=$(version) CFLAGS = -Wall $(VER) $(incdefs) $(DEBUG) $(EXTRA_CFLAGS) LDLIBS = -lm -lrt -pthread $(EXTRA_LDFLAGS) -PRG = ptp4l hwstamp_ctl nsm phc2sys phc_ctl pmc timemaster ts2phc +PRG = ptp4l hwstamp_ctl nsm phc2sys phc_ctl pmc timemaster ts2phc synce4l 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 +SYNCE = esmc_socket.o synce_clock.o synce_dev.o synce_dev_ctrl.o \ + synce_msg.o synce_port.o synce_port_ctrl.o synce_transport.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) \ @@ -35,7 +37,7 @@ OBJ = bmc.o clock.o clockadj.o clockcheck.o config.o designated_fsm.o \ unicast_fsm.o unicast_service.o util.o version.o OBJECTS = $(OBJ) hwstamp_ctl.o nsm.o phc2sys.o phc_ctl.o pmc.o pmc_agent.o \ - pmc_common.o sysoff.o timemaster.o $(TS2PHC) + pmc_common.o $(SYNCE) sysoff.o timemaster.o $(TS2PHC) SRC = $(OBJECTS:.o=.c) DEPEND = $(OBJECTS:.o=.d) srcdir := $(dir $(lastword $(MAKEFILE_LIST))) @@ -50,6 +52,9 @@ man8dir = $(mandir)/man8 all: $(PRG) +synce4l: config.o hash.o interface.o phc.o print.o sk.o $(SYNCE) util.o \ + version.o + ptp4l: $(OBJ) nsm: config.o $(FILTERS) hash.o interface.o msg.o nsm.o phc.o print.o \ diff --git a/synce4l.8 b/synce4l.8 new file mode 100644 index 0000000..9b84acd --- /dev/null +++ b/synce4l.8 @@ -0,0 +1,222 @@ +.\" Manpage for synce4l. +.\" Contact linuxptp-devel@lists.sourceforge.net to correct errors or typos. +.TH man 8 "21 Apr 2022" "1.0" "synce4l man page" + +.SH NAME +synce4l \- Synchronous Ethernet (SyncE) controller application + +.SH SYNOPSIS +synce4l -f [file] [-l <num>] [-m] [-q] [-v] [-h] + +.SH DESCRIPTION +synce4l is an implementation of the Synchronous Ethernet (SyncE) protocol +according to ITU-T Rec. G.8264. The design goal is to provide logic to supported +hardware by processing Ethernet Synchronization Messaging Channel (ESMC) and +control Ethernet Equipment Clock (EEC) on Network Card Interface (NIC). +.P +Application can operate in two mutually exclusive modes: line or external. + +.TP +External input mode +If `synce4l` is configured to run in external input mode then EEC needs to +have external 1PPS source attached (GPS or other generator). +In this scenario `synce4l` always broadcasts clock quality level (QL) defined +in configuration file. Additionally, for external input mode incoming SyncE +frames do not participate in best source selection algorithm for EEC. + +.TP +Line input mode +In line input mode incoming SyncE frames are processed and best clock source is +extracted from the link having the best quality level. +`synce4l` configures such "best quality" port as a source to recover clock for +EEC. The recovered QL is broadcasted to all other interfaces then. +An external clock source cannot be used in this mode. + +.SH OPTIONS +.TP +.B \-f [file] +read configuration from 'file' (config file takes precedence over +command line arguments) +.TP +.B \-l [num] +set the logging level to 'num' (0: least detailed, 7: most detailed) +.TP +.B \-m +print messages to stdout +.TP +.B \-q +do not print messages to the syslog +.TP +.B \-v +print synce4l version and exit +.TP +.B \-h +print this message and exit + +.SH CONFIGURATION FILE +Configuration file contains three sections: +.IP - +global, +.IP - +device, +.IP - +port. + +.SS Global section +This section starts with `[global]` keyword. It sets the logging options. +.RS +Available options: +.IP logging_level +Minimum log level required to appear in a log. +.P +.RS +Defaults to 6, valid values are 0 - 7 +.RE +.IP message_tag +Tag reported in a log. +.IP use_syslog +Set to 1 if `syslog` should be used. +.P +.RS +Defaults to 1, valid values are 0 or 1 +.RE +.IP verbose +Set to 1 to log extra information. +.P +.RS +Defaults to 0, valid values are 0 or 1 +.RE +.RE + +.SS Device section +This section specifies the configuration of a one logical device e.g. 'synce1'. +The name is defined by the user. The name has no impact for any functionality +except traces. +The name must be enclosed in extra angle bracket when defining new device +section e.g. [<synce1>]. +All ports defined by port sections after the device section will create one +SyncE device (until next device section). +.RS +Available options: +.IP input_mode +Set to "line" to enable line input mode, set "external" for external input mode. +.P +.RS +Defaults to "line", valid values are "line" or "external" +.RE +.IP external_input_QL +Quality Level (QL) for "external input" mode. +.P +.RS +Valid values specified in ITU-T Recommendations +.RE +.IP external_input_ext_QL +Extended Quality Level for "external input" mode. +.P +.RS +Valid values specified in ITU-T Recommendations +.RE +.IP extended_tlv +Set to 1 to enable extended QL. +.P +.RS +Defaults to 0, valid values are 0 or 1 +.RE +.IP network_option +Network option according to T-REC-G.8264. All devices in SyncE domain +should have the same option configured. +.P +.RS +Defaults to 1, valid values are 1 or 2 +.RE +.IP recover_time +Seconds indicating the minimum time to recover from the QL-failed state on the port. +.P +.RS +Defaults to 60, valid values are 10 - 720 +.RE +.IP get_eec_state_cmd +Defines a shell command which will be executed by synce4l to acquire current +state of a SyncE EEC on the device. Separated command must be provided by the +user for each device confgured for frequency synchronization. The command shall +output current state of EEC to stdout, expected values are defined (also by the +user) with following configuration items: +eec_holdover_value, eec_locked_ho_value, eec_locked_value, +eec_freerun_value, eec_invalid_value. +.RS +.RE +.IP eec_holdover_value +Defines a string value expected on stdout stream when EEC is in HOLDOVER state. +.P +.RS +.RE +.IP eec_locked_ho_value +Defines a string value expected on stdout stream when EEC is in LOCKED HOLDOVER +state. +.P +.RS +.RE +.IP eec_locked_value +Defines a string value expected on stdout stream when EEC is in LOCKED state. +.P +.RS +.RE +.IP eec_freerun_value +Defines a string value expected on stdout stream when EEC is in FREERUN state. +.P +.RS +.RE +.IP eec_invalid_value +Defines a string value expected on stdout stream when EEC is in INVALID state. +.P +.RE + +.SS Port section +Any other section not starting with `<` (e.g. [eth0]) is the port section. +Multiple port sections are allowed. Each port participates in SyncE +communication. +.RS +Available options: +.IP tx_heartbeat_msec +Interval between consecutive SyncE frame transmissions (1000ms recommended). +.P +.RS +Defaults to 1000, valid values are 100 - 3000 +.RE +.IP rx_heartbeat_msec +Interval between consecutive SyncE socket polls (frame receive). +.P +.RS +Defaults to 50, valid values are 10 - 500 +.RE +.IP recover_clock_enable_cmd +A shell command which enables PHY port pointed by this Port section as a source +of frequency for the SyncE EEC on this device (required only in +"internal input" mode). +.RS +.RE +.IP recover_clock_disable_cmd +A shell command which disables PHY port pointed by this Port section as a source +of frequency for the SyncE EEC on this device (required only in +"internal input" mode). +.IP allowed_qls +List of integers containing allowed SSM QLs separated by comma (`,`), other +received ones would be discarded. If parameter is not provided, all QLs will be +accepted. +.P +.IP allowed_ext_qls +List of integers containing allowed extended SSM QLs separated by comma (`,`), +other received ones would be discarded. If parameter is not provided, all QLs will +be accepted. +.P +.RE + +.SH BUGS +No known bugs. + +.SH AUTHOR +Arkadiusz Kubalewski <arkadiusz.kubalew...@intel.com> +.P +Michal Michalik <michal.micha...@intel.com> +.P +Piotr Kwapulinski <piotr.kwapulin...@intel.com> diff --git a/synce4l.c b/synce4l.c new file mode 100644 index 0000000..552ed87 --- /dev/null +++ b/synce4l.c @@ -0,0 +1,132 @@ +/** + * @file synce4l.c + * @brief Synchronous Ethernet (SyncE) userspace client + * @note SPDX-FileCopyrightText: Copyright 2022 Intel Corporation + * @note SPDX-License-Identifier: GPL-2.0+ + */ +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/queue.h> +#include <errno.h> + +#include "synce_clock.h" +#include "config.h" +#include "print.h" +#include "version.h" + +static void usage(char *progname) +{ + fprintf(stderr, + "\nusage: %s [options]\n\n" + " \n\n" + " options:\n\n" + " -f [file] configuration file path (required)\n" + " (command line arguments takes precedence over config file)\n" + " -l [num] set the logging level to 'num'\n" + " (%d: least detailed, %d: most detailed)\n" + " -m print messages to stdout\n" + " -q do not print messages to the syslog\n" + " -v print synce4l version and exit\n" + " -h print this message and exit\n" + "\n", + progname, PRINT_LEVEL_MIN, PRINT_LEVEL_MAX); +} + +static void synce4l_cleanup(struct config *cfg) +{ + if (cfg) + config_destroy(cfg); +} + +int main(int argc, char *argv[]) +{ + int c, err = -EACCES, index, print_level; + char *config = NULL, *progname; + struct synce_clock *clock; + struct option *opts; + struct config *cfg; + + if (handle_term_signals()) + return -EPERM; + + cfg = config_create_synce(); + if (!cfg) { + return -EINVAL; + } + opts = config_long_options(cfg); + + /* Process the command line arguments. */ + progname = strrchr(argv[0], '/'); + progname = progname ? 1+progname : argv[0]; + while (EOF != (c = getopt_long(argc, argv, "f:l:mqvh", + opts, &index))) { + switch (c) { + case 'f': + config = optarg; + break; + case 'l': + if (get_arg_val_i(c, optarg, &print_level, + PRINT_LEVEL_MIN, PRINT_LEVEL_MAX)) + goto out; + config_set_int(cfg, "logging_level", print_level); + break; + case 'm': + config_set_int(cfg, "verbose", 1); + break; + case 'q': + config_set_int(cfg, "use_syslog", 0); + break; + case 'v': + version_show(stdout); + synce4l_cleanup(cfg); + return 0; + case 'h': + usage(progname); + synce4l_cleanup(cfg); + return 0; + case '?': + usage(progname); + goto out; + default: + usage(progname); + goto out; + } + } + + if (config && (c = config_read(config, cfg))) { + synce4l_cleanup(cfg); + return c; + } + + print_set_progname(progname); + print_set_tag(config_get_string(cfg, NULL, "message_tag")); + print_set_verbose(config_get_int(cfg, NULL, "verbose")); + print_set_syslog(config_get_int(cfg, NULL, "use_syslog")); + print_set_level(config_get_int(cfg, NULL, "logging_level")); + + if (STAILQ_EMPTY(&cfg->interfaces)) { + fprintf(stderr, "%s", "no interface specified\n"); + usage(progname); + goto out; + } + + clock = synce_clock_create(cfg); + if (!clock) { + fprintf(stderr, "%s", "failed to create a synce clock\n"); + goto out; + } + + while (is_running()) + if (synce_clock_poll(clock)) + break; + + synce_clock_destroy(clock); + + err = 0; +out: + synce4l_cleanup(cfg); + return err; +} diff --git a/synce4l_README.md b/synce4l_README.md new file mode 100644 index 0000000..79bfc83 --- /dev/null +++ b/synce4l_README.md @@ -0,0 +1,202 @@ +# Table of contents + +1. Introduction +2. Compilation +3. Installation +4. Usage +5. Config + +--- + +## 1\. Introduction + +`synce4l` is a software implementation of Synchronous Ethernet (SyncE) according +to ITU-T Recommendation G.8264. The design goal is to provide logic to supported +hardware by processing Ethernet Synchronization Messaging Channel (ESMC) and +control Ethernet Equipment Clock (EEC) on Network Card Interface (NIC). + +Application can operate in two mutually exclusive input modes: line or external. +Both modes are described in next paragraphs. + +The best source selection is done according to ITU-T Recommendations G.781 and +G.8264. Two network options are supported: option 1 and option 2. + +Table showing priority of quality levels (QLs) in option 1 networks: +| Quality Level | Priority* | SSM | Extended SSM** | +| ------------- | --------- | --- | -------------- | +| ePRTC | 0 | 0x2 | 0x21 | +| PRTC | 1 | 0x2 | 0x20 | +| PRC | 2 | 0x2 | 0xFF | +| SSU-A | 3 | 0x4 | 0xFF | +| SSU-B | 4 | 0x8 | 0xFF | + +Table showing priority of quality levels (QLs) in option 2 networks: +| Quality Level | Priority* | SSM | Extended SSM** | +| ------------- | --------- | --- | -------------- | +| ePRTC | 0 | 0x1 | 0x21 | +| PRTC | 1 | 0x1 | 0x20 | +| PRS | 2 | 0x1 | 0xFF | +| STU | 3 | 0x0 | 0xFF | +| ST2 | 4 | 0x7 | 0xFF | +| TNC | 5 | 0x4 | 0xFF | +| ST3E | 6 | 0xD | 0xFF | +| PROV | 7 | 0xE | 0xFF | + +> *Remark:* *Lower number means higher priority + +> *Remark:* **If extended SSM is not enabled, it's implicitly assumed as `0xFF` + +### External input mode + +If `synce4l` is configured to run in external input mode then EEC needs to have +external 1PPS source attached (GPS or other generator). +In this scenario `synce4l` always broadcasts clock quality level (QL) defined +in configuration file. Additionally, for “external” mode incoming SyncE +frames do not participate in best source selection algorithm for EEC. + +### Line input mode + +In line input mode incoming SyncE frames are processed and best clock source is +extracted from the link having the best quality level. +`synce4l` configures such "best quality" port as a source to recover clock +for EEC. The recovered QL is broadcasted to all other interfaces then. +An external clock cannot be used in this mode. + +--- + +## 2\. Compilation + +Makefile rules are included in linuxptp `makefile` and compilation is done using +the command: +``` +make synce4l +``` + +--- + +## 3\. Installation + +Use `make install` target to install `synce4l` in a system. + +--- + +## 4\. Usage + +Use `-h` command line argument to print the help page: +``` +$? ./synce4l -h +usage: synce4l [options] + + ... + + Other Options + + -f [file] read configuration from 'file' + (config file takes precedence over command line arguments) + -l [num] set the logging level to 'num' + (0: least detailed, 7: most detailed) + -m print messages to stdout + -q do not print messages to the syslog + -v print synce4l version and exit + -h print this message and exit +``` + +> *Remark:* `synce4l` requires root privileges since it opens raw sockets. + +--- + +## 5\. Config + +### Configuration file contains three sections: + +- global, +- device, +- port. + +### Global section + +This section starts with `[global]` keyword. It sets the logging options. + +| Parameter | Default | Valid values | Description | +| --------------- | ------- | ------------ | ---------------------------------------------- | +| `logging_level` | `6` | `0-7` | Minimum log level required to appear in a log. | +| `message_tag` | None | string | Tag reported in a log. | +| `use_syslog` | `1` | `0`, `1` | Set to 1 if `syslog` should be used. | +| `verbose` | `0` | `0`, `1` | Set to 1 to log extra information. | + +### Device section + +This section specifies the configuration of a one logical device e.g. 'synce1'. +The name is defined by the user. The name has no impact for any functionality +except traces. +The name must be enclosed in extra angle bracket when defining new device +section e.g. [<synce1>]. +All ports defined by port sections after the device section will create one +SyncE device (until next device section). + +| Parameter | Default | Valid values | Description | +| ----------------------- | ------- | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `input_mode` | `line` | `line`, `external` | Set to "line" to enable line input mode, set "external" for external input mode. | +| `external_input_QL` | `0` | `0-15` | Quality Level (QL) for "external input" mode. | +| `external_input_ext_QL` | `0` | `0-255` | Extended Quality Level for "external input" mode. | +| `extended_tlv` | `0` | `0`, `1` | Set to 1 to enable extended QL. | +| `network_option` | `1` | `1`, `2` | Network option according to T-REC-G.8264. All devices in SyncE domain should have the same option configured. | +| `recover_time` | `60` | `10-720` | Seconds indicating the minimum time to recover from the QL-failed state on the port. | +| `get_eec_state_cmd` | None | string | Shell command which will be executed by synce4l to acquire current state of a SyncE EEC on the device. The command shall output current state of EEC to stdout. | +| `eec_holdover_value` | None | string | Value expected on stdout stream when EEC is in HOLDOVER state, after calling command defined in get_eec_state_cmd | +| `eec_locked_ho_value` | None | string | Value expected on stdout stream when EEC is in LOCKED HOLDOVER state, after calling command defined in get_eec_state_cmd | +| `eec_locked_value` | None | string | Value expected on stdout stream when EEC is in LOCKED state, after calling command defined in get_eec_state_cmd | +| `eec_freerun_value` | None | string | Value expected on stdout stream when EEC is in FREERUN state, after calling command defined in get_eec_state_cmd | +| `eec_invalid_value` | None | string | Value expected on stdout stream when EEC is in INVALID state, after calling command defined in get_eec_state_cmd | + +### Port section + +Any other section not starting with `<` (e.g. [eth0]) is the port section. +Multiple port sections are allowed. Each port participates in SyncE +communication. + +| Parameter | Default | Valid values | Description | +| --------------------------- | ------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `tx_heartbeat_msec` | `1000` | `100-3000` | Interval between consecutive SyncE frame transmissions (1000ms is recommended). | +| `rx_heartbeat_msec` | `50` | `10-500` | Interval between consecutive SyncE socket polls (frame receive). | +| `recover_clock_enable_cmd` | None | string | Shell command which enables PHY port pointed by this Port section as a source of frequency for the SyncE EEC on this device (required only in "internal_input" mode). | +| `recover_clock_disable_cmd` | None | string | Shell command which disables PHY port pointed by this Port section as a source of frequency for the SyncE EEC on this device (required only in "internal_input" mode). | +| `allowed_qls` | None | string | List of integers containing allowed SSM QLs separated by comma (`,`), other received ones would be discarded - if parameter is not provided, all QLs will be accepted | +| `allowed_ext_qls` | None | string | List of integers containing allowed extended SSM QLs separated by comma (`,`), other received ones would be discarded - if parameter is not provided, all QLs will be accepted | + +> *Remark:* Please do not use backslashes in config file in 'string' fields - for example do not use it like this: `"/sys/kernel/debug/ice/0000\:5e\:00\.0/cgu_state"` + +### Config example + +``` +[global] +logging_level 7 +use_syslog 0 +verbose 1 +message_tag [synce4l] + +[<synce1>] +input_mode line +network_option 1 +external_input_QL 11 +external_input_ext_QL 33 +extended_tlv 1 +recover_time 20 +eec_get_state_cmd cat /sys/class/net/eth0/device/cgu_state +eec_holdover_value 4 +eec_locked_ho_value 3 +eec_locked_value 2 +eec_freerun_value 1 +eec_invalid_value 0 + +[eth0] +tx_heartbeat_msec 1000 +rx_heartbeat_msec 500 +recover_clock_enable_cmd echo 1 0 > /sys/class/net/eth0/device/phy/synce +recover_clock_disable_cmd echo 0 0 > /sys/class/net/eth0/device/phy/synce +allowed_qls 3,4,7 +allowed_ext_qls 20,21 + +``` + +--- -- 2.9.5 _______________________________________________ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel