Add support for testing the new PTP_SYS_OFFSET_EXTENDED_ATTRS and
PTP_SYS_OFFSET_PRECISE_ATTRS ioctls in the testptp utility.
New command-line options:
-a: Get extended offset with attributes (error_bound, clock_status,
timescale)
-A: Get precise cross-timestamp with attributes
These options allow testing and validation of PHC devices that provide
clock quality information alongside timestamps.
Also display the new clock_attrs capability in the -c output, and
update print_system_timestamp to print unrecognized clock types instead
of silently dropping them.
Signed-off-by: Amit Bernstein <[email protected]>
Signed-off-by: Arthur Kiyanovski <[email protected]>
---
tools/testing/selftests/ptp/testptp.c | 111 +++++++++++++++++++++++++-
1 file changed, 109 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/ptp/testptp.c
b/tools/testing/selftests/ptp/testptp.c
index d3bcfd03fce4..99607da01b22 100644
--- a/tools/testing/selftests/ptp/testptp.c
+++ b/tools/testing/selftests/ptp/testptp.c
@@ -147,10 +147,13 @@ static void usage(char *progname)
" -t val shift the ptp clock time by 'val' seconds\n"
" -T val set the ptp clock time to 'val' seconds\n"
" -x val get an extended ptp clock time with the desired
number of samples (up to %d)\n"
+ " -a val get extended timestamps with attributes
(error_bound,\n"
+ " clock_status, timescale, counter), up to %d
samples\n"
" -X get a ptp clock cross timestamp\n"
+ " -A get a precise cross timestamp with attributes\n"
" -y val pre/post tstamp timebase to use
{realtime|monotonic|monotonic-raw}\n"
" -z test combinations of rising/falling external time
stamp flags\n",
- progname, PTP_MAX_SAMPLES);
+ progname, PTP_MAX_SAMPLES, PTP_MAX_SAMPLES);
}
static void print_system_timestamp(int sample_num, __kernel_clockid_t clockid,
@@ -171,6 +174,8 @@ static void print_system_timestamp(int sample_num,
__kernel_clockid_t clockid,
sample_num, when, sec, nsec);
break;
default:
+ printf("sample #%2d: unknown clock %d %s: %lld.%09u\n",
+ sample_num, clockid, when, sec, nsec);
break;
}
}
@@ -188,6 +193,7 @@ int main(int argc, char *argv[])
struct ptp_sys_offset *sysoff;
struct ptp_sys_offset_extended *soe;
struct ptp_sys_offset_precise *xts;
+ struct ptp_sys_offset_attrs *attrs_data;
char *progname;
unsigned int i;
@@ -208,7 +214,9 @@ int main(int argc, char *argv[])
int list_pins = 0;
int pct_offset = 0;
int getextended = 0;
+ int getextendedattrs = 0;
int getcross = 0;
+ int getcrossattrs = 0;
int n_samples = 0;
int pin_index = -1, pin_func;
int pps = -1;
@@ -226,7 +234,8 @@ int main(int argc, char *argv[])
progname = strrchr(argv[0], '/');
progname = progname ? 1+progname : argv[0];
- while (EOF != (c = getopt(argc, argv,
"cd:e:E:f:F:ghH:i:k:lL:n:o:p:P:rsSt:T:w:x:Xy:z"))) {
+ while (EOF != (c = getopt(argc, argv,
+
"a:Acd:e:E:f:F:ghH:i:k:lL:n:o:p:P:rsSt:T:w:x:Xy:z"))) {
switch (c) {
case 'c':
capabilities = 1;
@@ -311,9 +320,22 @@ int main(int argc, char *argv[])
return -1;
}
break;
+ case 'a':
+ getextendedattrs = atoi(optarg);
+ if (getextendedattrs < 1 ||
+ getextendedattrs > PTP_MAX_SAMPLES) {
+ fprintf(stderr,
+ "number of extended attrs timestamp
samples must be between 1 and %d; was asked for %d\n",
+ PTP_MAX_SAMPLES, getextendedattrs);
+ return -1;
+ }
+ break;
case 'X':
getcross = 1;
break;
+ case 'A':
+ getcrossattrs = 1;
+ break;
case 'y':
if (!strcasecmp(optarg, "realtime"))
ext_clockid = CLOCK_REALTIME;
@@ -367,6 +389,8 @@ int main(int argc, char *argv[])
" %d programmable pins\n"
" %d cross timestamping\n"
" %d adjust_phase\n"
+ " %d extended_attrs\n"
+ " %d precise_attrs\n"
" %d maximum phase adjustment (ns)\n",
caps.max_adj,
caps.n_alarm,
@@ -376,6 +400,8 @@ int main(int argc, char *argv[])
caps.n_pins,
caps.cross_timestamping,
caps.adjust_phase,
+ caps.extended_attrs,
+ caps.precise_attrs,
caps.max_phase_adj);
}
}
@@ -648,6 +674,49 @@ int main(int argc, char *argv[])
free(soe);
}
+ if (getextendedattrs) {
+ attrs_data = calloc(1, sizeof(*attrs_data) +
+ getextendedattrs * sizeof(struct
ptp_timestamp));
+ if (!attrs_data) {
+ perror("calloc");
+ return -1;
+ }
+
+ attrs_data->request.num_samples = getextendedattrs;
+ attrs_data->request.clock_id = ext_clockid;
+
+ if (ioctl(fd, PTP_SYS_OFFSET_EXTENDED_ATTRS, attrs_data)) {
+ perror("PTP_SYS_OFFSET_EXTENDED_ATTRS");
+ } else {
+ printf("extended attrs timestamp request returned %d
samples\n",
+ getextendedattrs);
+
+ for (i = 0; i < getextendedattrs; i++) {
+ struct ptp_timestamp *ts =
&attrs_data->timestamps[i];
+
+ printf(" sample #%u:\n", i);
+ printf(" sys before: %lld ns\n",
+ (long long)ts->pre_systime.sys_time);
+ printf(" phc time: %lld.%09u\n",
+ ts->devtime.device_time.sec,
+ ts->devtime.device_time.nsec);
+ if (ts->devtime.attrs.valid &
PTP_ATTRS_VALID_ERROR_BOUND)
+ printf(" error_bound: %u ns\n",
+ ts->devtime.attrs.error_bound);
+ if (ts->devtime.attrs.valid &
PTP_ATTRS_VALID_STATUS)
+ printf(" status: %u\n",
+ ts->devtime.attrs.status);
+ if (ts->devtime.attrs.valid &
PTP_ATTRS_VALID_TIMESCALE)
+ printf(" timescale: %u\n",
+ ts->devtime.attrs.timescale);
+ printf(" sys after: %lld ns\n",
+ (long long)ts->post_systime.sys_time);
+ }
+ }
+
+ free(attrs_data);
+ }
+
if (getcross) {
xts = calloc(1, sizeof(*xts));
if (!xts) {
@@ -671,6 +740,44 @@ int main(int argc, char *argv[])
free(xts);
}
+ if (getcrossattrs) {
+ attrs_data = calloc(1, sizeof(*attrs_data) +
+ sizeof(struct ptp_timestamp));
+ if (!attrs_data) {
+ perror("calloc");
+ return -1;
+ }
+
+ attrs_data->request.num_samples = 1;
+ attrs_data->request.clock_id = ext_clockid;
+
+ if (ioctl(fd, PTP_SYS_OFFSET_PRECISE_ATTRS, attrs_data)) {
+ perror("PTP_SYS_OFFSET_PRECISE_ATTRS");
+ } else {
+ struct ptp_timestamp *ts = &attrs_data->timestamps[0];
+
+ puts("precise attrs crosstimestamp request okay");
+ printf("device time: %lld.%09u\n",
+ ts->devtime.device_time.sec,
+ ts->devtime.device_time.nsec);
+ printf("system time: %lld ns\n",
+ (long long)ts->systime.sys_time);
+ printf("raw time: %lld ns\n",
+ (long long)ts->systime.sys_rawtime);
+ if (ts->devtime.attrs.valid &
PTP_ATTRS_VALID_ERROR_BOUND)
+ printf("error_bound: %u ns\n",
+ ts->devtime.attrs.error_bound);
+ if (ts->devtime.attrs.valid & PTP_ATTRS_VALID_STATUS)
+ printf("status: %u\n",
+ ts->devtime.attrs.status);
+ if (ts->devtime.attrs.valid & PTP_ATTRS_VALID_TIMESCALE)
+ printf("timescale: %u\n",
+ ts->devtime.attrs.timescale);
+ }
+
+ free(attrs_data);
+ }
+
if (channel >= 0) {
if (ioctl(fd, PTP_MASK_CLEAR_ALL)) {
perror("PTP_MASK_CLEAR_ALL");
--
2.47.3