diff --git a/config.c b/config.c index aecc58e..9a9420f 100644 --- a/config.c +++ b/config.c @@ -464,6 +464,8 @@ int config_create_interface(char *name, struct config *cfg) iface->transport = cfg->transport; memcpy(&iface->pod, &cfg->pod, sizeof(cfg->pod)); + sk_get_ts_info(name, &iface->ts_info); + cfg->nports++; return i; diff --git a/config.h b/config.h index 7cffc32..b1f5fc6 100644 --- a/config.h +++ b/config.h @@ -24,6 +24,7 @@ #include "dm.h" #include "transport.h" #include "servo.h" +#include "sk.h" #define MAX_PORTS 8 #define MAX_IFNAME_SIZE 16 @@ -34,6 +35,7 @@ struct interface { enum delay_mechanism dm; enum transport_type transport; struct port_defaults pod; + struct sk_ts_info ts_info; }; #define CFG_IGNORE_DM (1 << 0) diff --git a/phc2sys.c b/phc2sys.c index fced164..a6586a2 100644 --- a/phc2sys.c +++ b/phc2sys.c @@ -298,13 +298,13 @@ int main(int argc, char *argv[]) } if (src == CLOCK_INVALID && ethdev) { - int phc_index = -1; + struct sk_ts_info ts_info; char phc_device[16]; - if (sk_interface_phc(ethdev, &phc_index) || phc_index < 0) { + if (sk_get_ts_info(ethdev, &ts_info) || !ts_info.valid) { fprintf(stderr, "can't autodiscover PHC device\n"); return -1; } - sprintf(phc_device, "/dev/ptp%d", phc_index); + sprintf(phc_device, "/dev/ptp%d", ts_info.phc_index); src = clock_open(phc_device); } if (!(device || src != CLOCK_INVALID) || dst == CLOCK_INVALID) { diff --git a/port.c b/port.c index f2be7bc..7dcce0d 100644 --- a/port.c +++ b/port.c @@ -1663,7 +1663,6 @@ struct port *port_open(int phc_index, struct clock *clock) { struct port *p = malloc(sizeof(*p)); - int checked_phc_index = -1; if (!p) return NULL; @@ -1672,12 +1671,12 @@ struct port *port_open(int phc_index, if (interface->transport == TRANS_UDS) ; /* UDS cannot have a PHC. */ - else if (sk_interface_phc(interface->name, &checked_phc_index)) + else if (!interface->ts_info.valid) pr_warning("port %d: get_ts_info not supported", number); - else if (phc_index >= 0 && phc_index != checked_phc_index) { + else if (phc_index >= 0 && phc_index != interface->ts_info.phc_index) { pr_err("port %d: PHC device mismatch", number); pr_err("port %d: /dev/ptp%d requested, but /dev/ptp%d attached", - number, phc_index, checked_phc_index); + number, phc_index, interface->ts_info.phc_index); free(p); return NULL; } diff --git a/ptp4l.c b/ptp4l.c index 5838d53..35cf5c9 100644 --- a/ptp4l.c +++ b/ptp4l.c @@ -263,9 +263,12 @@ int main(int argc, char *argv[]) fprintf(stderr, "bad ptp device string\n"); return -1; } - } else if (sk_interface_phc(iface[0].name, &phc_index)) { - fprintf(stderr, "get_ts_info not supported\n" - "please specify ptp device\n"); + } else if (iface[0].ts_info.valid) { + phc_index = iface[0].ts_info.phc_index; + } else { + fprintf(stderr, "ptp device not specified and\n" + "automatic determination is not\n" + "supported. please specify ptp device\n"); return -1; } diff --git a/sk.c b/sk.c index b6ba8a5..46030d4 100644 --- a/sk.c +++ b/sk.c @@ -88,7 +88,7 @@ int sk_interface_index(int fd, char *name) return ifreq.ifr_ifindex; } -int sk_interface_phc(char *name, int *index) +int sk_get_ts_info(char *name, struct sk_ts_info *sk_info) { #ifdef ETHTOOL_GET_TS_INFO struct ethtool_ts_info info; @@ -98,29 +98,38 @@ int sk_interface_phc(char *name, int *index) memset(&ifr, 0, sizeof(ifr)); memset(&info, 0, sizeof(info)); info.cmd = ETHTOOL_GET_TS_INFO; - strcpy(ifr.ifr_name, name); + strncpy(ifr.ifr_name, name, IFNAMSIZ - 1); ifr.ifr_data = (char *) &info; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { pr_err("socket failed: %m"); - return -1; + goto failed; } err = ioctl(fd, SIOCETHTOOL, &ifr); if (err < 0) { pr_err("ioctl SIOCETHTOOL failed: %m"); close(fd); - return -1; + goto failed; } close(fd); - *index = info.phc_index; - return info.phc_index < 0 ? -1 : 0; -#else - return -1; + /* copy the necessary data to sk_info */ + memset(sk_info, 0, sizeof(struct sk_ts_info)); + sk_info->valid = 1; + sk_info->phc_index = info.phc_index; + sk_info->so_timestamping = info.so_timestamping; + sk_info->tx_types = info.tx_types; + sk_info->rx_filters = info.rx_filters; + + return 0; #endif +failed: + /* clear data and ensure it is not marked valid */ + memset(sk_info, 0, sizeof(struct sk_ts_info)); + return -1; } int sk_interface_macaddr(char *name, unsigned char *mac, int len) diff --git a/sk.h b/sk.h index 671e839..44025cb 100644 --- a/sk.h +++ b/sk.h @@ -22,6 +22,19 @@ #include "transport.h" +/** + * struct sk_ts_info - supported timestamping information + * @valid: set to non-zero when the info struct contains valid data + * @info: structure containing the values returned by GET_TS_INFO + */ +struct sk_ts_info { + int valid; + int phc_index; + unsigned int so_timestamping; + unsigned int tx_types; + unsigned int rx_filters; +}; + /** * Obtain the numerical index from a network interface by name. * @param fd An open socket. @@ -31,12 +44,12 @@ int sk_interface_index(int fd, char *device); /** - * Obtain the PHC device index of a network interface. + * Obtain supported timestamping information * @param name The name of the interface - * @return index The non-negative phc index associated with this iface. - * On error a negative integer is returned. + * @param info Struct containing obtained timestamping information. + * @return zero on success, negative on failure. */ -int sk_interface_phc(char *name, int *index); +int sk_get_ts_info(char *name, struct sk_ts_info *sk_info); /** * Obtain the MAC address of a network interface.