net/mlx5: DPLL, Implement lock status error value
authorJiri Pirko <jiri@nvidia.com>
Tue, 30 Jan 2024 12:08:31 +0000 (13:08 +0100)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 1 Feb 2024 14:39:44 +0000 (15:39 +0100)
Fill-up the lock status error value properly.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
Acked-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/ethernet/mellanox/mlx5/core/dpll.c
include/linux/mlx5/mlx5_ifc.h

index 07f43d5c90c6ebc4ed638da02a6cbcd045d44264..4ad3d2d3d4c8e7a24d5e74f7c76a43a37698ac43 100644 (file)
@@ -41,6 +41,7 @@ struct mlx5_dpll_synce_status {
        enum mlx5_msees_oper_status oper_status;
        bool ho_acq;
        bool oper_freq_measure;
+       enum mlx5_msees_failure_reason failure_reason;
        s32 frequency_diff;
 };
 
@@ -60,6 +61,7 @@ mlx5_dpll_synce_status_get(struct mlx5_core_dev *mdev,
        synce_status->oper_status = MLX5_GET(msees_reg, out, oper_status);
        synce_status->ho_acq = MLX5_GET(msees_reg, out, ho_acq);
        synce_status->oper_freq_measure = MLX5_GET(msees_reg, out, oper_freq_measure);
+       synce_status->failure_reason = MLX5_GET(msees_reg, out, failure_reason);
        synce_status->frequency_diff = MLX5_GET(msees_reg, out, frequency_diff);
        return 0;
 }
@@ -99,6 +101,26 @@ mlx5_dpll_lock_status_get(struct mlx5_dpll_synce_status *synce_status)
        }
 }
 
+static enum dpll_lock_status_error
+mlx5_dpll_lock_status_error_get(struct mlx5_dpll_synce_status *synce_status)
+{
+       switch (synce_status->oper_status) {
+       case MLX5_MSEES_OPER_STATUS_FAIL_HOLDOVER:
+               fallthrough;
+       case MLX5_MSEES_OPER_STATUS_FAIL_FREE_RUNNING:
+               switch (synce_status->failure_reason) {
+               case MLX5_MSEES_FAILURE_REASON_PORT_DOWN:
+                       return DPLL_LOCK_STATUS_ERROR_MEDIA_DOWN;
+               case MLX5_MSEES_FAILURE_REASON_TOO_HIGH_FREQUENCY_DIFF:
+                       return DPLL_LOCK_STATUS_ERROR_FRACTIONAL_FREQUENCY_OFFSET_TOO_HIGH;
+               default:
+                       return DPLL_LOCK_STATUS_ERROR_UNDEFINED;
+               }
+       default:
+               return DPLL_LOCK_STATUS_ERROR_NONE;
+       }
+}
+
 static enum dpll_pin_state
 mlx5_dpll_pin_state_get(struct mlx5_dpll_synce_status *synce_status)
 {
@@ -132,6 +154,7 @@ mlx5_dpll_device_lock_status_get(const struct dpll_device *dpll, void *priv,
        if (err)
                return err;
        *status = mlx5_dpll_lock_status_get(&synce_status);
+       *status_error = mlx5_dpll_lock_status_error_get(&synce_status);
        return 0;
 }
 
index c726f90ab752452cbe9726462ecedd72b21656f6..6c44f107b8ba7bb0e72dc7168a2b844b74e7cf38 100644 (file)
@@ -12705,6 +12705,14 @@ enum mlx5_msees_oper_status {
        MLX5_MSEES_OPER_STATUS_FAIL_FREE_RUNNING        = 0x5,
 };
 
+enum mlx5_msees_failure_reason {
+       MLX5_MSEES_FAILURE_REASON_UNDEFINED_ERROR               = 0x0,
+       MLX5_MSEES_FAILURE_REASON_PORT_DOWN                     = 0x1,
+       MLX5_MSEES_FAILURE_REASON_TOO_HIGH_FREQUENCY_DIFF       = 0x2,
+       MLX5_MSEES_FAILURE_REASON_NET_SYNCHRONIZER_DEVICE_ERROR = 0x3,
+       MLX5_MSEES_FAILURE_REASON_LACK_OF_RESOURCES             = 0x4,
+};
+
 struct mlx5_ifc_msees_reg_bits {
        u8         reserved_at_0[0x8];
        u8         local_port[0x8];