Commit cacfd6bf authored by Paolo Abeni's avatar Paolo Abeni

Merge branch 'dpll-expose-lock-status-error-value-to-user'

Jiri Pirko says:

====================
dpll: expose lock status error value to user

From: Jiri Pirko <jiri@nvidia.com>

Allow to expose lock status errort value over new DPLL generic netlink
attribute. Extend the lock_status_get() op by new argument to get the
value from the driver. Implement this new argument fill-up
in mlx5 driver.
====================

Link: https://lore.kernel.org/r/20240130120831.261085-1-jiri@resnulli.usSigned-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents 644c6431 2c54a4d7
...@@ -51,6 +51,40 @@ definitions: ...@@ -51,6 +51,40 @@ definitions:
if dpll lock-state was not DPLL_LOCK_STATUS_LOCKED_HO_ACQ, the if dpll lock-state was not DPLL_LOCK_STATUS_LOCKED_HO_ACQ, the
dpll's lock-state shall remain DPLL_LOCK_STATUS_UNLOCKED) dpll's lock-state shall remain DPLL_LOCK_STATUS_UNLOCKED)
render-max: true render-max: true
-
type: enum
name: lock-status-error
doc: |
if previous status change was done due to a failure, this provides
information of dpll device lock status error.
Valid values for DPLL_A_LOCK_STATUS_ERROR attribute
entries:
-
name: none
doc: |
dpll device lock status was changed without any error
value: 1
-
name: undefined
doc: |
dpll device lock status was changed due to undefined error.
Driver fills this value up in case it is not able
to obtain suitable exact error type.
-
name: media-down
doc: |
dpll device lock status was changed because of associated
media got down.
This may happen for example if dpll device was previously
locked on an input pin of type PIN_TYPE_SYNCE_ETH_PORT.
-
name: fractional-frequency-offset-too-high
doc: |
the FFO (Fractional Frequency Offset) between the RX and TX
symbol rate on the media got too high.
This may happen for example if dpll device was previously
locked on an input pin of type PIN_TYPE_SYNCE_ETH_PORT.
render-max: true
- -
type: const type: const
name: temp-divider name: temp-divider
...@@ -214,6 +248,10 @@ attribute-sets: ...@@ -214,6 +248,10 @@ attribute-sets:
name: type name: type
type: u32 type: u32
enum: type enum: type
-
name: lock-status-error
type: u32
enum: lock-status-error
- -
name: pin name: pin
enum-name: dpll_a_pin enum-name: dpll_a_pin
...@@ -379,6 +417,7 @@ operations: ...@@ -379,6 +417,7 @@ operations:
- mode - mode
- mode-supported - mode-supported
- lock-status - lock-status
- lock-status-error
- temp - temp
- clock-id - clock-id
- type - type
......
...@@ -121,14 +121,21 @@ dpll_msg_add_lock_status(struct sk_buff *msg, struct dpll_device *dpll, ...@@ -121,14 +121,21 @@ dpll_msg_add_lock_status(struct sk_buff *msg, struct dpll_device *dpll,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
const struct dpll_device_ops *ops = dpll_device_ops(dpll); const struct dpll_device_ops *ops = dpll_device_ops(dpll);
enum dpll_lock_status_error status_error = 0;
enum dpll_lock_status status; enum dpll_lock_status status;
int ret; int ret;
ret = ops->lock_status_get(dpll, dpll_priv(dpll), &status, extack); ret = ops->lock_status_get(dpll, dpll_priv(dpll), &status,
&status_error, extack);
if (ret) if (ret)
return ret; return ret;
if (nla_put_u32(msg, DPLL_A_LOCK_STATUS, status)) if (nla_put_u32(msg, DPLL_A_LOCK_STATUS, status))
return -EMSGSIZE; return -EMSGSIZE;
if (status_error &&
(status == DPLL_LOCK_STATUS_UNLOCKED ||
status == DPLL_LOCK_STATUS_HOLDOVER) &&
nla_put_u32(msg, DPLL_A_LOCK_STATUS_ERROR, status_error))
return -EMSGSIZE;
return 0; return 0;
} }
......
...@@ -488,6 +488,7 @@ ice_dpll_hw_input_prio_set(struct ice_pf *pf, struct ice_dpll *dpll, ...@@ -488,6 +488,7 @@ ice_dpll_hw_input_prio_set(struct ice_pf *pf, struct ice_dpll *dpll,
* @dpll: registered dpll pointer * @dpll: registered dpll pointer
* @dpll_priv: private data pointer passed on dpll registration * @dpll_priv: private data pointer passed on dpll registration
* @status: on success holds dpll's lock status * @status: on success holds dpll's lock status
* @status_error: status error value
* @extack: error reporting * @extack: error reporting
* *
* Dpll subsystem callback, provides dpll's lock status. * Dpll subsystem callback, provides dpll's lock status.
...@@ -500,6 +501,7 @@ ice_dpll_hw_input_prio_set(struct ice_pf *pf, struct ice_dpll *dpll, ...@@ -500,6 +501,7 @@ ice_dpll_hw_input_prio_set(struct ice_pf *pf, struct ice_dpll *dpll,
static int static int
ice_dpll_lock_status_get(const struct dpll_device *dpll, void *dpll_priv, ice_dpll_lock_status_get(const struct dpll_device *dpll, void *dpll_priv,
enum dpll_lock_status *status, enum dpll_lock_status *status,
enum dpll_lock_status_error *status_error,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
struct ice_dpll *d = dpll_priv; struct ice_dpll *d = dpll_priv;
......
...@@ -41,6 +41,7 @@ struct mlx5_dpll_synce_status { ...@@ -41,6 +41,7 @@ struct mlx5_dpll_synce_status {
enum mlx5_msees_oper_status oper_status; enum mlx5_msees_oper_status oper_status;
bool ho_acq; bool ho_acq;
bool oper_freq_measure; bool oper_freq_measure;
enum mlx5_msees_failure_reason failure_reason;
s32 frequency_diff; s32 frequency_diff;
}; };
...@@ -60,6 +61,7 @@ mlx5_dpll_synce_status_get(struct mlx5_core_dev *mdev, ...@@ -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->oper_status = MLX5_GET(msees_reg, out, oper_status);
synce_status->ho_acq = MLX5_GET(msees_reg, out, ho_acq); 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->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); synce_status->frequency_diff = MLX5_GET(msees_reg, out, frequency_diff);
return 0; return 0;
} }
...@@ -99,6 +101,26 @@ mlx5_dpll_lock_status_get(struct mlx5_dpll_synce_status *synce_status) ...@@ -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 static enum dpll_pin_state
mlx5_dpll_pin_state_get(struct mlx5_dpll_synce_status *synce_status) mlx5_dpll_pin_state_get(struct mlx5_dpll_synce_status *synce_status)
{ {
...@@ -118,10 +140,11 @@ mlx5_dpll_pin_ffo_get(struct mlx5_dpll_synce_status *synce_status, ...@@ -118,10 +140,11 @@ mlx5_dpll_pin_ffo_get(struct mlx5_dpll_synce_status *synce_status,
return 0; return 0;
} }
static int mlx5_dpll_device_lock_status_get(const struct dpll_device *dpll, static int
void *priv, mlx5_dpll_device_lock_status_get(const struct dpll_device *dpll, void *priv,
enum dpll_lock_status *status, enum dpll_lock_status *status,
struct netlink_ext_ack *extack) enum dpll_lock_status_error *status_error,
struct netlink_ext_ack *extack)
{ {
struct mlx5_dpll_synce_status synce_status; struct mlx5_dpll_synce_status synce_status;
struct mlx5_dpll *mdpll = priv; struct mlx5_dpll *mdpll = priv;
...@@ -131,6 +154,7 @@ static int mlx5_dpll_device_lock_status_get(const struct dpll_device *dpll, ...@@ -131,6 +154,7 @@ static int mlx5_dpll_device_lock_status_get(const struct dpll_device *dpll,
if (err) if (err)
return err; return err;
*status = mlx5_dpll_lock_status_get(&synce_status); *status = mlx5_dpll_lock_status_get(&synce_status);
*status_error = mlx5_dpll_lock_status_error_get(&synce_status);
return 0; return 0;
} }
......
...@@ -4209,10 +4209,11 @@ ptp_ocp_detach(struct ptp_ocp *bp) ...@@ -4209,10 +4209,11 @@ ptp_ocp_detach(struct ptp_ocp *bp)
device_unregister(&bp->dev); device_unregister(&bp->dev);
} }
static int ptp_ocp_dpll_lock_status_get(const struct dpll_device *dpll, static int
void *priv, ptp_ocp_dpll_lock_status_get(const struct dpll_device *dpll, void *priv,
enum dpll_lock_status *status, enum dpll_lock_status *status,
struct netlink_ext_ack *extack) enum dpll_lock_status_error *status_error,
struct netlink_ext_ack *extack)
{ {
struct ptp_ocp *bp = priv; struct ptp_ocp *bp = priv;
......
...@@ -19,6 +19,7 @@ struct dpll_device_ops { ...@@ -19,6 +19,7 @@ struct dpll_device_ops {
enum dpll_mode *mode, struct netlink_ext_ack *extack); enum dpll_mode *mode, struct netlink_ext_ack *extack);
int (*lock_status_get)(const struct dpll_device *dpll, void *dpll_priv, int (*lock_status_get)(const struct dpll_device *dpll, void *dpll_priv,
enum dpll_lock_status *status, enum dpll_lock_status *status,
enum dpll_lock_status_error *status_error,
struct netlink_ext_ack *extack); struct netlink_ext_ack *extack);
int (*temp_get)(const struct dpll_device *dpll, void *dpll_priv, int (*temp_get)(const struct dpll_device *dpll, void *dpll_priv,
s32 *temp, struct netlink_ext_ack *extack); s32 *temp, struct netlink_ext_ack *extack);
......
...@@ -12705,6 +12705,14 @@ enum mlx5_msees_oper_status { ...@@ -12705,6 +12705,14 @@ enum mlx5_msees_oper_status {
MLX5_MSEES_OPER_STATUS_FAIL_FREE_RUNNING = 0x5, 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 { struct mlx5_ifc_msees_reg_bits {
u8 reserved_at_0[0x8]; u8 reserved_at_0[0x8];
u8 local_port[0x8]; u8 local_port[0x8];
......
...@@ -50,6 +50,35 @@ enum dpll_lock_status { ...@@ -50,6 +50,35 @@ enum dpll_lock_status {
DPLL_LOCK_STATUS_MAX = (__DPLL_LOCK_STATUS_MAX - 1) DPLL_LOCK_STATUS_MAX = (__DPLL_LOCK_STATUS_MAX - 1)
}; };
/**
* enum dpll_lock_status_error - if previous status change was done due to a
* failure, this provides information of dpll device lock status error. Valid
* values for DPLL_A_LOCK_STATUS_ERROR attribute
* @DPLL_LOCK_STATUS_ERROR_NONE: dpll device lock status was changed without
* any error
* @DPLL_LOCK_STATUS_ERROR_UNDEFINED: dpll device lock status was changed due
* to undefined error. Driver fills this value up in case it is not able to
* obtain suitable exact error type.
* @DPLL_LOCK_STATUS_ERROR_MEDIA_DOWN: dpll device lock status was changed
* because of associated media got down. This may happen for example if dpll
* device was previously locked on an input pin of type
* PIN_TYPE_SYNCE_ETH_PORT.
* @DPLL_LOCK_STATUS_ERROR_FRACTIONAL_FREQUENCY_OFFSET_TOO_HIGH: the FFO
* (Fractional Frequency Offset) between the RX and TX symbol rate on the
* media got too high. This may happen for example if dpll device was
* previously locked on an input pin of type PIN_TYPE_SYNCE_ETH_PORT.
*/
enum dpll_lock_status_error {
DPLL_LOCK_STATUS_ERROR_NONE = 1,
DPLL_LOCK_STATUS_ERROR_UNDEFINED,
DPLL_LOCK_STATUS_ERROR_MEDIA_DOWN,
DPLL_LOCK_STATUS_ERROR_FRACTIONAL_FREQUENCY_OFFSET_TOO_HIGH,
/* private: */
__DPLL_LOCK_STATUS_ERROR_MAX,
DPLL_LOCK_STATUS_ERROR_MAX = (__DPLL_LOCK_STATUS_ERROR_MAX - 1)
};
#define DPLL_TEMP_DIVIDER 1000 #define DPLL_TEMP_DIVIDER 1000
/** /**
...@@ -150,6 +179,7 @@ enum dpll_a { ...@@ -150,6 +179,7 @@ enum dpll_a {
DPLL_A_LOCK_STATUS, DPLL_A_LOCK_STATUS,
DPLL_A_TEMP, DPLL_A_TEMP,
DPLL_A_TYPE, DPLL_A_TYPE,
DPLL_A_LOCK_STATUS_ERROR,
__DPLL_A_MAX, __DPLL_A_MAX,
DPLL_A_MAX = (__DPLL_A_MAX - 1) DPLL_A_MAX = (__DPLL_A_MAX - 1)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment