net/mlx5: Fix a bug of using ptp channel index as pin index
authorEran Ben Elisha <eranbe@mellanox.com>
Wed, 8 Jul 2020 15:53:19 +0000 (18:53 +0300)
committerSaeed Mahameed <saeedm@mellanox.com>
Tue, 28 Jul 2020 19:55:40 +0000 (12:55 -0700)
On PTP mlx5_ptp_enable(on=0) flow, driver mistakenly used channel index
as pin index.

After ptp patch marked in fixes tag was introduced, driver can freely
call ptp_find_pin() as part of the .enable() callback.

Fix driver mlx5_ptp_enable(on=0) flow to always use ptp_find_pin(). With
that, Driver will use the correct pin index in mlx5_ptp_enable(on=0) flow.

In addition, when initializing the pins, always set channel to zero. As
all pins can be attached to all channels, let ptp_set_pinfunc() to move
them between the channels.

For stable branches, this fix to be applied only on kernels that includes
both patches in fixes tag. Otherwise, mlx5_ptp_enable(on=0) will be stuck
on pincfg_mux.

Fixes: 62582a7ee783 ("ptp: Avoid deadlocks in the programmable pin code.")
Fixes: ee7f12205abc ("net/mlx5e: Implement 1PPS support")
Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
Reviewed-by: Ariel Levkovich <lariel@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c

index ef0706d..c6967e1 100644 (file)
@@ -273,17 +273,17 @@ static int mlx5_extts_configure(struct ptp_clock_info *ptp,
        if (rq->extts.index >= clock->ptp_info.n_pins)
                return -EINVAL;
 
+       pin = ptp_find_pin(clock->ptp, PTP_PF_EXTTS, rq->extts.index);
+       if (pin < 0)
+               return -EBUSY;
+
        if (on) {
-               pin = ptp_find_pin(clock->ptp, PTP_PF_EXTTS, rq->extts.index);
-               if (pin < 0)
-                       return -EBUSY;
                pin_mode = MLX5_PIN_MODE_IN;
                pattern = !!(rq->extts.flags & PTP_FALLING_EDGE);
                field_select = MLX5_MTPPS_FS_PIN_MODE |
                               MLX5_MTPPS_FS_PATTERN |
                               MLX5_MTPPS_FS_ENABLE;
        } else {
-               pin = rq->extts.index;
                field_select = MLX5_MTPPS_FS_ENABLE;
        }
 
@@ -331,12 +331,12 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp,
        if (rq->perout.index >= clock->ptp_info.n_pins)
                return -EINVAL;
 
-       if (on) {
-               pin = ptp_find_pin(clock->ptp, PTP_PF_PEROUT,
-                                  rq->perout.index);
-               if (pin < 0)
-                       return -EBUSY;
+       pin = ptp_find_pin(clock->ptp, PTP_PF_PEROUT,
+                          rq->perout.index);
+       if (pin < 0)
+               return -EBUSY;
 
+       if (on) {
                pin_mode = MLX5_PIN_MODE_OUT;
                pattern = MLX5_OUT_PATTERN_PERIODIC;
                ts.tv_sec = rq->perout.period.sec;
@@ -362,7 +362,6 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp,
                               MLX5_MTPPS_FS_ENABLE |
                               MLX5_MTPPS_FS_TIME_STAMP;
        } else {
-               pin = rq->perout.index;
                field_select = MLX5_MTPPS_FS_ENABLE;
        }
 
@@ -452,7 +451,7 @@ static int mlx5_init_pin_config(struct mlx5_clock *clock)
                         "mlx5_pps%d", i);
                clock->ptp_info.pin_config[i].index = i;
                clock->ptp_info.pin_config[i].func = PTP_PF_NONE;
-               clock->ptp_info.pin_config[i].chan = i;
+               clock->ptp_info.pin_config[i].chan = 0;
        }
 
        return 0;