Page MenuHomeFreeBSD

D36327.diff
No OneTemporary

D36327.diff

diff --git a/sys/dev/mlx5/mlx5_en/en.h b/sys/dev/mlx5/mlx5_en/en.h
--- a/sys/dev/mlx5/mlx5_en/en.h
+++ b/sys/dev/mlx5/mlx5_en/en.h
@@ -1144,6 +1144,7 @@
int clbr_curr;
struct mlx5e_clbr_point clbr_points[2];
u_int clbr_gen;
+ uint64_t cclk;
struct mlx5e_dcbx dcbx;
bool sw_is_port_buf_owner;
diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
@@ -4797,6 +4797,8 @@
&priv->clbr_done, 0,
"RX timestamps calibration state");
callout_init(&priv->tstmp_clbr, 1);
+ /* Pull out the frequency of the clock in hz */
+ priv->cclk = (uint64_t)MLX5_CAP_GEN(mdev, device_frequency_khz) * 1000ULL;
mlx5e_reset_calibration_callout(priv);
pa.pa_version = PFIL_VERSION;
diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c b/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c
--- a/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c
+++ b/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c
@@ -214,7 +214,10 @@
mlx5e_mbuf_tstmp(struct mlx5e_priv *priv, uint64_t hw_tstmp)
{
struct mlx5e_clbr_point *cp, dcp;
- uint64_t a1, a2, res;
+ uint64_t tstmp_sec, tstmp_nsec;
+ uint64_t hw_clocks;
+ uint64_t rt_cur_to_prev, res_s, res_n, res_s_modulo, res;
+ uint64_t hw_clk_div;
u_int gen;
do {
@@ -224,19 +227,49 @@
return (0);
dcp = *cp;
atomic_thread_fence_acq();
- } while (gen != cp->clbr_gen);
-
- a1 = (hw_tstmp - dcp.clbr_hw_prev) >> MLX5E_TSTMP_PREC;
- a2 = (dcp.base_curr - dcp.base_prev) >> MLX5E_TSTMP_PREC;
- res = (a1 * a2) << MLX5E_TSTMP_PREC;
-
+ } while (gen != dcp.clbr_gen);
/*
- * Divisor cannot be zero because calibration callback
- * checks for the condition and disables timestamping
- * if clock halted.
+ * Our goal here is to have a result that is:
+ *
+ * ( (cur_time - prev_time) )
+ * ((hw_tstmp - hw_prev) * ----------------------------- ) + prev_time
+ * ( (hw_cur - hw_prev) )
+ *
+ * With the constraints that we cannot use float and we
+ * don't want to overflow the uint64_t numbers we are using.
+ *
+ * The plan is to take the clocking value of the hw timestamps
+ * and split them into seconds and nanosecond equivalent portions.
+ * Then we operate on the two portions seperately making sure to
+ * bring back the carry over from the seconds when we divide.
+ *
+ * First up lets get the two divided into separate entities
+ * i.e. the seconds. We use the clock frequency for this.
+ * Note that priv->cclk was setup with the clock frequency
+ * in hz so we are all set to go.
*/
- res /= (dcp.clbr_hw_curr - dcp.clbr_hw_prev) >> MLX5E_TSTMP_PREC;
-
+ hw_clocks = hw_tstmp - dcp.clbr_hw_prev;
+ tstmp_sec = hw_clocks / priv->cclk;
+ tstmp_nsec = hw_clocks % priv->cclk;
+ /* Now work with them separately */
+ rt_cur_to_prev = (dcp.base_curr - dcp.base_prev);
+ res_s = tstmp_sec * rt_cur_to_prev;
+ res_n = tstmp_nsec * rt_cur_to_prev;
+ /* Now lets get our divider */
+ hw_clk_div = dcp.clbr_hw_curr - dcp.clbr_hw_prev;
+ /* Make sure to save the remainder from the seconds divide */
+ res_s_modulo = res_s % hw_clk_div;
+ res_s /= hw_clk_div;
+ /* scale the remainder to where it should be */
+ res_s_modulo *= priv->cclk;
+ /* Now add in the remainder */
+ res_n += res_s_modulo;
+ /* Now do the divide */
+ res_n /= hw_clk_div;
+ res_s *= priv->cclk;
+ /* Recombine the two */
+ res = res_s + res_n;
+ /* And now add in the base time to get to the real timestamp */
res += dcp.base_prev;
return (res);
}
@@ -370,10 +403,11 @@
tstmp &= ~MLX5_CQE_TSTMP_PTP;
mb->m_flags |= M_TSTMP_HPREC;
}
- mb->m_pkthdr.rcv_tstmp = tstmp;
- mb->m_flags |= M_TSTMP;
+ if (tstmp != 0) {
+ mb->m_pkthdr.rcv_tstmp = tstmp;
+ mb->m_flags |= M_TSTMP;
+ }
}
-
switch (get_cqe_tls_offload(cqe)) {
case CQE_TLS_OFFLOAD_DECRYPTED:
/* set proper checksum flag for decrypted packets */

File Metadata

Mime Type
text/plain
Expires
Tue, Oct 1, 5:26 AM (22 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
13231855
Default Alt Text
D36327.diff (3 KB)

Event Timeline