@@ -2,5 +2,6 @@ rdma_man_pages(
mlx5dv_get_clock_info.3
mlx5dv_init_obj.3
mlx5dv_query_device.3
+ mlx5dv_ts_to_ns.3
mlx5dv.7
)
new file mode 100644
@@ -0,0 +1,35 @@
+.\" -*- nroff -*-
+.\" Licensed under the OpenIB.org (MIT) - See COPYING.md
+.\"
+.TH MLX5DV_TS_TO_NS 3 2017-11-08 1.0.0
+.SH "NAME"
+mlx5dv_ts_to_ns \- Convert device timestamp from HCA core clock units to
+the corresponding nanosecond counts
+.SH "SYNOPSIS"
+.nf
+.B #include <infiniband/mlx5dv.h>
+.sp
+.BI "uint64_t mlx5dv_ts_to_ns(struct mlx5dv_clock_info *clock_info,
+.BI " uint64_t device_timestamp);
+.fi
+.SH "DESCRIPTION"
+.B mlx5dv_ts_to_ns(3)
+Converts a host byte order
+.I device_timestamp
+from HCA core clock units into the corresponding nanosecond wallclock time.
+.PP
+\fBstruct mlx5dv_clock_info\fR can be retrieved using \fBmlx5dv_get_clock_info(3)\fR.
+.PP
+The greater the difference between the device reporting a timestamp and the last
+mlx5dv_clock_info update, the greater the inaccuracy of the clock time conversion.
+
+.fi
+.SH "RETURN VALUE"
+Timestamp in nanoseconds
+.SH "SEE ALSO"
+.BR mlx5dv (7),
+.BR mlx5dv_get_clock_info (3),
+.BR mlx5dv_query_device (3)
+.SH "AUTHORS"
+.TP
+Feras Daoud <ferasda@mellanox.com>
@@ -811,4 +811,44 @@ struct mlx5dv_clock_info {
int mlx5dv_get_clock_info(struct ibv_context *context,
struct mlx5dv_clock_info *clock_info);
+/*
+ * Translate device timestamp to nano-sec
+ *
+ * Input:
+ * clock_info - clock info to be filled
+ * device_timestamp - timestamp to translate
+ *
+ * Return: nano-sec
+ */
+static inline uint64_t mlx5dv_ts_to_ns(struct mlx5dv_clock_info *clock_info,
+ uint64_t device_timestamp)
+{
+ uint64_t delta, nsec;
+
+ /*
+ * device_timestamp & cycles are the free running 'mask' bit counters
+ * from the hardware hca_core_clock clock.
+ */
+ delta = (device_timestamp - clock_info->last_cycles) & clock_info->mask;
+ nsec = clock_info->nsec;
+
+ /*
+ * Guess if the device_timestamp is more recent than
+ * clock_info->last_cycles, if not (too far in the future) treat
+ * it as old time stamp. This will break every max_clock_info_update_nsec.
+ */
+
+ if (delta > clock_info->mask / 2) {
+ delta = (clock_info->last_cycles - device_timestamp) &
+ clock_info->mask;
+ nsec -= ((delta * clock_info->mult) - clock_info->frac) >>
+ clock_info->shift;
+ } else {
+ nsec += ((delta * clock_info->mult) + clock_info->frac) >>
+ clock_info->shift;
+ }
+
+ return nsec;
+}
+
#endif /* _MLX5DV_H_ */