diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c index 7e292579e200..e2d0b44d7444 100644 --- a/sys/dev/mlx5/mlx5_en/mlx5_en_main.c +++ b/sys/dev/mlx5/mlx5_en/mlx5_en_main.c @@ -833,11 +833,15 @@ mlx5e_calibration_callout(void *arg) next->clbr_hw_prev = curr->clbr_hw_curr; next->clbr_hw_curr = mlx5e_hw_clock(priv); - if (((next->clbr_hw_curr - curr->clbr_hw_prev) >> MLX5E_TSTMP_PREC) == + if (((next->clbr_hw_curr - curr->clbr_hw_curr) >> MLX5E_TSTMP_PREC) == 0) { - if_printf(priv->ifp, "HW failed tstmp frozen %#jx %#jx," - "disabling\n", next->clbr_hw_curr, curr->clbr_hw_prev); - priv->clbr_done = 0; + if (priv->clbr_done != 0) { + if_printf(priv->ifp, "HW failed tstmp frozen %#jx %#jx," + "disabling\n", + next->clbr_hw_curr, curr->clbr_hw_prev); + priv->clbr_done = 0; + } + atomic_store_rel_int(&curr->clbr_gen, 0); return; } diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c b/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c index ca7abee0b0e9..bb6bc8d4840d 100644 --- a/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c +++ b/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c @@ -222,28 +222,31 @@ mlx5e_lro_update_hdr(struct mbuf *mb, struct mlx5_cqe64 *cqe) static uint64_t mlx5e_mbuf_tstmp(struct mlx5e_priv *priv, uint64_t hw_tstmp) { - struct mlx5e_clbr_point *cp; + struct mlx5e_clbr_point *cp, dcp; uint64_t a1, a2, res; u_int gen; do { cp = &priv->clbr_points[priv->clbr_curr]; gen = atomic_load_acq_int(&cp->clbr_gen); - a1 = (hw_tstmp - cp->clbr_hw_prev) >> MLX5E_TSTMP_PREC; - a2 = (cp->base_curr - cp->base_prev) >> MLX5E_TSTMP_PREC; - res = (a1 * a2) << MLX5E_TSTMP_PREC; - - /* - * Divisor cannot be zero because calibration callback - * checks for the condition and disables timestamping - * if clock halted. - */ - res /= (cp->clbr_hw_curr - cp->clbr_hw_prev) >> - MLX5E_TSTMP_PREC; - - res += cp->base_prev; + if (gen == 0) + return (0); + dcp = *cp; atomic_thread_fence_acq(); - } while (gen == 0 || gen != cp->clbr_gen); + } 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; + + /* + * Divisor cannot be zero because calibration callback + * checks for the condition and disables timestamping + * if clock halted. + */ + res /= (dcp.clbr_hw_curr - dcp.clbr_hw_prev) >> MLX5E_TSTMP_PREC; + + res += dcp.base_prev; return (res); }