net/mlx5: Query maximum frequency adjustment of the PTP hardware clock
authorRahul Rameshbabu <rrameshbabu@nvidia.com>
Thu, 30 Mar 2023 22:05:38 +0000 (15:05 -0700)
committerSaeed Mahameed <saeedm@nvidia.com>
Wed, 15 Nov 2023 19:34:31 +0000 (11:34 -0800)
Some mlx5 devices do not support the default advertised maximum frequency
adjustment value for the PTP hardware clock that is set by the driver.
These devices need to be queried when initializing the clock functionality
in order to get the maximum supported frequency adjustment value. This
value can be greater than the minimum supported frequency adjustment across
mlx5 devices (50 million ppb).

Signed-off-by: Rahul Rameshbabu <rrameshbabu@nvidia.com>
Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
include/linux/mlx5/mlx5_ifc.h

index 1daa4b01951323c0fa33d0b1f5569b025a0bf2d0..cac60a841e1db70d6e9338ad01be8f0846664591 100644 (file)
@@ -1000,6 +1000,25 @@ static void mlx5_init_clock_info(struct mlx5_core_dev *mdev)
        info->frac = timer->tc.frac;
 }
 
+static void mlx5_init_timer_max_freq_adjustment(struct mlx5_core_dev *mdev)
+{
+       struct mlx5_clock *clock = &mdev->clock;
+       u32 out[MLX5_ST_SZ_DW(mtutc_reg)] = {};
+       u32 in[MLX5_ST_SZ_DW(mtutc_reg)] = {};
+       u8 log_max_freq_adjustment = 0;
+       int err;
+
+       err = mlx5_core_access_reg(mdev, in, sizeof(in), out, sizeof(out),
+                                  MLX5_REG_MTUTC, 0, 0);
+       if (!err)
+               log_max_freq_adjustment =
+                       MLX5_GET(mtutc_reg, out, log_max_freq_adjustment);
+
+       if (log_max_freq_adjustment)
+               clock->ptp_info.max_adj =
+                       min(S32_MAX, 1 << log_max_freq_adjustment);
+}
+
 static void mlx5_init_timer_clock(struct mlx5_core_dev *mdev)
 {
        struct mlx5_clock *clock = &mdev->clock;
@@ -1007,6 +1026,9 @@ static void mlx5_init_timer_clock(struct mlx5_core_dev *mdev)
        /* Configure the PHC */
        clock->ptp_info = mlx5_ptp_clock_info;
 
+       if (MLX5_CAP_MCAM_REG(mdev, mtutc))
+               mlx5_init_timer_max_freq_adjustment(mdev);
+
        mlx5_timecounter_init(mdev);
        mlx5_init_clock_info(mdev);
        mlx5_init_overflow_period(clock);
index 6f3631425f386dad40e847aa592a31e12d1b5e9f..ce2e71cd6d2a3cd903870928ad9001baacee7470 100644 (file)
@@ -10103,7 +10103,10 @@ enum {
 struct mlx5_ifc_mtutc_reg_bits {
        u8         reserved_at_0[0x5];
        u8         freq_adj_units[0x3];
-       u8         reserved_at_8[0x14];
+       u8         reserved_at_8[0x3];
+       u8         log_max_freq_adjustment[0x5];
+
+       u8         reserved_at_10[0xc];
        u8         operation[0x4];
 
        u8         freq_adjustment[0x20];