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 <greg.armstrong...@renesas.com> Signed-off-by: Leon Goldin <leon.goldin...@renesas.com> Signed-off-by: Vipin Sharma <vipin.sha...@syncmonk.net> Signed-off-by: Devasish Dey <devasish....@syncmonk.net> 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, &c->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 = &the_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(&c->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 */ } } + /* Check the Virtual port. */ + if (c->vport_port) { + cur += N_CLOCK_PFD; + for (i = 0; i < N_POLLFD; i++) { + if (cur[i].revents & (POLLIN|POLLPRI)) { + event = port_event(c->vport_port, i); + if (event == EV_STATE_DECISION_EVENT) { + c->sde = 1; + } + } + } + } if (c->sde) { handle_state_decision_event(c); diff --git a/config.c b/config.c index b5cf397..aeae356 100644 --- a/config.c +++ b/config.c @@ -193,6 +193,7 @@ static struct config_enum nw_trans_enu[] = { { "L2", TRANS_IEEE_802_3 }, { "UDPv4", TRANS_UDP_IPV4 }, { "UDPv6", TRANS_UDP_IPV6 }, + { "vPort", TRANS_VPORT }, { NULL, 0 }, }; @@ -345,6 +346,7 @@ struct config_item config_tab[] = { GLOB_ITEM_STR("userDescription", ""), GLOB_ITEM_INT("utc_offset", CURRENT_UTC_OFFSET, 0, INT_MAX), GLOB_ITEM_INT("verbose", 0, 0, 1), + GLOB_ITEM_STR("vport_address", ""), GLOB_ITEM_INT("write_phase_mode", 0, 0, 1), }; diff --git a/interface.c b/interface.c index 6c2630c..9506097 100644 --- a/interface.c +++ b/interface.c @@ -35,6 +35,13 @@ void interface_destroy(struct interface *iface) free(iface); } +void interface_ensure_tslabel(struct interface *iface) +{ + if (!iface->ts_label[0]) { + memcpy(iface->ts_label, iface->name, MAX_IFNAME_SIZE); + } +} + int interface_get_tsinfo(struct interface *iface) { return sk_get_ts_info(iface->ts_label, &iface->ts_info); diff --git a/interface.h b/interface.h index 5fc7836..752f4f1 100644 --- a/interface.h +++ b/interface.h @@ -33,6 +33,12 @@ struct interface *interface_create(const char *name); */ void interface_destroy(struct interface *iface); +/** + * Ensures that an interface has a proper time stamping label. + * @param iface The interface of interest. + */ +void interface_ensure_tslabel(struct interface *iface); + /** * Populate the time stamping information of a given interface. * @param iface The interface of interest. diff --git a/port.c b/port.c index 871ad68..020e2c5 100644 --- a/port.c +++ b/port.c @@ -57,6 +57,7 @@ enum syfu_event { static int port_is_ieee8021as(struct port *p); static int port_is_uds(struct port *p); +static int port_is_vport(struct port *p); static void port_nrate_initialize(struct port *p); static int announce_compare(struct ptp_message *m1, struct ptp_message *m2) @@ -822,6 +823,11 @@ static int port_is_uds(struct port *p) return transport_type(p->trp) == TRANS_UDS; } +static int port_is_vport(struct port *p) +{ + return transport_type(p->trp) == TRANS_VPORT; +} + static void port_management_send_error(struct port *p, struct port *ingress, struct ptp_message *msg, int error_id) { @@ -3266,8 +3272,8 @@ struct port *port_open(const char *phc_device, p->state_machine = clock_slave_only(clock) ? ptp_slave_fsm : ptp_fsm; } - if (port_is_uds(p)) { - ; /* UDS cannot have a PHC. */ + if (port_is_uds(p) || port_is_vport(p)) { + ; /* UDS & VPORT cannot have a PHC. */ } else if (!interface_tsinfo_valid(interface)) { pr_warning("%s: get_ts_info not supported", p->log_name); } else if (p->phc_index >= 0 && diff --git a/ptp4l.8 b/ptp4l.8 index 1268802..a0479f6 100644 --- a/ptp4l.8 +++ b/ptp4l.8 @@ -658,6 +658,11 @@ File mode of the second (read-only) UNIX domain socket used for receiving local management messages. The mode should be specified as an octal number, i.e. it should start with a 0 literal. The default mode is 0666. .TP +.B vport_address +Specifies the address of the UNIX domain socket for communicating with the +virtual PTP port on a PTP clock as defined in the G.8275 Annex B. The default +is NULL +.TP .B dscp_event Defines the Differentiated Services Codepoint (DSCP) to be used for PTP event messages. Must be a value between 0 and 63. There are several media diff --git a/sk.c b/sk.c index 80075be..d24fc4c 100644 --- a/sk.c +++ b/sk.c @@ -508,6 +508,7 @@ int sk_timestamping_init(int fd, const char *device, enum timestamp_type type, case TRANS_CONTROLNET: case TRANS_PROFINET: case TRANS_UDS: + case TRANS_VPORT: return -1; } err = hwts_init(fd, device, filter1, filter2, tx_type); diff --git a/transport.c b/transport.c index 9366fbf..86b9576 100644 --- a/transport.c +++ b/transport.c @@ -25,6 +25,7 @@ #include "udp.h" #include "udp6.h" #include "uds.h" +#include "vport.h" int transport_close(struct transport *t, struct fdarray *fda) { @@ -115,6 +116,9 @@ struct transport *transport_create(struct config *cfg, case TRANS_IEEE_802_3: t = raw_transport_create(); break; + case TRANS_VPORT: + t = vport_transport_create(); + break; case TRANS_DEVICENET: case TRANS_CONTROLNET: case TRANS_PROFINET: diff --git a/transport.h b/transport.h index 7a7f87b..a4c73d3 100644 --- a/transport.h +++ b/transport.h @@ -39,6 +39,7 @@ enum transport_type { TRANS_DEVICENET, TRANS_CONTROLNET, TRANS_PROFINET, + TRANS_VPORT, }; /** diff --git a/util.c b/util.c index a59b559..8077084 100644 --- a/util.c +++ b/util.c @@ -114,6 +114,7 @@ int addreq(enum transport_type type, struct address *a, struct address *b) case TRANS_DEVICENET: case TRANS_CONTROLNET: case TRANS_PROFINET: + case TRANS_VPORT: default: pr_err("sorry, cannot compare addresses for this transport"); return 0; @@ -280,6 +281,7 @@ int str2addr(enum transport_type type, const char *s, struct address *addr) case TRANS_DEVICENET: case TRANS_CONTROLNET: case TRANS_PROFINET: + case TRANS_VPORT: pr_err("sorry, cannot convert addresses for this transport"); return -1; case TRANS_UDP_IPV4: -- 2.25.1 _______________________________________________ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel