Signed-off-by: Hangbin Liu <liuhang...@gmail.com> --- clock.c | 60 +++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 19 deletions(-)
diff --git a/clock.c b/clock.c index 582438c..256d52f 100644 --- a/clock.c +++ b/clock.c @@ -110,6 +110,7 @@ struct clock { int time_flags; /* grand master role */ int time_source; /* grand master role */ enum servo_state servo_state; + enum timestamp_type timestamping; tmv_t master_offset; tmv_t path_delay; tmv_t ingress_ts; @@ -326,12 +327,40 @@ static void clock_freq_est_reset(struct clock *c) c->fest.count = 0; } +static int clock_required_modes(enum timestamp_type timestamping) +{ + int required_modes = 0; + + switch (timestamping) { + case TS_SOFTWARE: + required_modes |= SOF_TIMESTAMPING_TX_SOFTWARE | + SOF_TIMESTAMPING_RX_SOFTWARE | + SOF_TIMESTAMPING_SOFTWARE; + break; + case TS_LEGACY_HW: + required_modes |= SOF_TIMESTAMPING_TX_HARDWARE | + SOF_TIMESTAMPING_RX_HARDWARE | + SOF_TIMESTAMPING_SYS_HARDWARE; + break; + case TS_HARDWARE: + case TS_ONESTEP: + required_modes |= SOF_TIMESTAMPING_TX_HARDWARE | + SOF_TIMESTAMPING_RX_HARDWARE | + SOF_TIMESTAMPING_RAW_HARDWARE; + break; + default: + break; + } + + return required_modes; +} static void clock_link_status(void *ctx, int index, int linkup, char *ts_iface) { struct clock *c = ctx; struct port *p; char key[16]; struct interface *iface; + int required_modes = 0; snprintf(key, sizeof(key), "%d", index); p = hash_lookup(c->index2port, key); @@ -344,6 +373,15 @@ static void clock_link_status(void *ctx, int index, int linkup, char *ts_iface) if (linkup && ts_iface[0] != '\0' && strcmp(iface->ts_iface, ts_iface)) { strncpy(iface->ts_iface, ts_iface, MAX_IFNAME_SIZE); sk_get_ts_info(iface->ts_iface, &iface->ts_info); + + required_modes = clock_required_modes(c->timestamping); + if (iface->ts_info.valid && + (iface->ts_info.so_timestamping & required_modes) != required_modes) { + pr_err("interface '%s' does not support " + "requested timestamping mode", iface->ts_iface); + return; + } + if (iface->ts_info.valid) { port_set_phc(p, iface->ts_info.phc_index); clock_switch_phc(c, iface->ts_info.phc_index); @@ -976,31 +1014,14 @@ struct clock *clock_create(enum clock_type type, struct config *config, } /* Check the time stamping mode on each interface. */ - switch (timestamping) { - case TS_SOFTWARE: - required_modes |= SOF_TIMESTAMPING_TX_SOFTWARE | - SOF_TIMESTAMPING_RX_SOFTWARE | - SOF_TIMESTAMPING_SOFTWARE; - break; - case TS_LEGACY_HW: - required_modes |= SOF_TIMESTAMPING_TX_HARDWARE | - SOF_TIMESTAMPING_RX_HARDWARE | - SOF_TIMESTAMPING_SYS_HARDWARE; - break; - case TS_HARDWARE: - case TS_ONESTEP: - required_modes |= SOF_TIMESTAMPING_TX_HARDWARE | - SOF_TIMESTAMPING_RX_HARDWARE | - SOF_TIMESTAMPING_RAW_HARDWARE; - break; - } + required_modes = clock_required_modes(timestamping); STAILQ_FOREACH(iface, &config->interfaces, list) { rtnl_link_info(iface); sk_get_ts_info(iface->ts_iface, &iface->ts_info); if (iface->ts_info.valid && ((iface->ts_info.so_timestamping & required_modes) != required_modes)) { pr_err("interface '%s' does not support " - "requested timestamping mode", iface->name); + "requested timestamping mode", iface->ts_iface); return NULL; } } @@ -1059,6 +1080,7 @@ struct clock *clock_create(enum clock_type type, struct config *config, c->kernel_leap = config_get_int(config, NULL, "kernel_leap"); c->utc_offset = c->current_utc_offset = config_get_int(config, NULL, "utc_offset"); c->time_source = config_get_int(config, NULL, "timeSource"); + c->timestamping = timestamping; if (c->free_running) { c->clkid = CLOCK_INVALID; -- 2.5.5 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel