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. ====================
Unified · Split
| @@ -51,6 +51,40 @@ definitions: · 50 unmodified lines | |||
| 51 | if dpll lock-state was not DPLL_LOCK_STATUS_LOCKED_HO_ACQ, the | 51 | if dpll lock-state was not DPLL_LOCK_STATUS_LOCKED_HO_ACQ, the |
| 52 | dpll's lock-state shall remain DPLL_LOCK_STATUS_UNLOCKED) | 52 | dpll's lock-state shall remain DPLL_LOCK_STATUS_UNLOCKED) |
| 53 | render-max: true | 53 | render-max: true |
| 54 | - | ||
| 55 | type: enum | ||
| 56 | name: lock-status-error | ||
| 57 | doc: | | ||
| 58 | if previous status change was done due to a failure, this provides | ||
| 59 | information of dpll device lock status error. | ||
| 60 | Valid values for DPLL_A_LOCK_STATUS_ERROR attribute | ||
| 61 | entries: | ||
| 62 | - | ||
| 63 | name: none | ||
| 64 | doc: | | ||
| 65 | dpll device lock status was changed without any error | ||
| 66 | value: 1 | ||
| 67 | - | ||
| 68 | name: undefined | ||
| 69 | doc: | | ||
| 70 | dpll device lock status was changed due to undefined error. | ||
| 71 | Driver fills this value up in case it is not able | ||
| 72 | to obtain suitable exact error type. | ||
| 73 | - | ||
| 74 | name: media-down | ||
| 75 | doc: | | ||
| 76 | dpll device lock status was changed because of associated | ||
| 77 | media got down. | ||
| 78 | This may happen for example if dpll device was previously | ||
| 79 | locked on an input pin of type PIN_TYPE_SYNCE_ETH_PORT. | ||
| 80 | - | ||
| 81 | name: fractional-frequency-offset-too-high | ||
| 82 | doc: | | ||
| 83 | the FFO (Fractional Frequency Offset) between the RX and TX | ||
| 84 | symbol rate on the media got too high. | ||
| 85 | This may happen for example if dpll device was previously | ||
| 86 | locked on an input pin of type PIN_TYPE_SYNCE_ETH_PORT. | ||
| 87 | render-max: true | ||
| 54 | - | 88 | - |
| 55 | type: const | 89 | type: const |
| 56 | name: temp-divider | 90 | name: temp-divider |
| @@ -214,6 +248,10 @@ attribute-sets: · 157 unmodified lines | |||
| 214 | name: type | 248 | name: type |
| 215 | type: u32 | 249 | type: u32 |
| 216 | enum: type | 250 | enum: type |
| 251 | - | ||
| 252 | name: lock-status-error | ||
| 253 | type: u32 | ||
| 254 | enum: lock-status-error | ||
| 217 | - | 255 | - |
| 218 | name: pin | 256 | name: pin |
| 219 | enum-name: dpll_a_pin | 257 | enum-name: dpll_a_pin |
| @@ -379,6 +417,7 @@ operations: · 159 unmodified lines | |||
| 379 | - mode | 417 | - mode |
| 380 | - mode-supported | 418 | - mode-supported |
| 381 | - lock-status | 419 | - lock-status |
| 420 | - lock-status-error | ||
| 382 | - temp | 421 | - temp |
| 383 | - clock-id | 422 | - clock-id |
| 384 | - type | 423 | - type |
| @@ -121,14 +121,21 @@ dpll_msg_add_lock_status(struct sk_buff *msg, struct dpll_device *dpll, · 120 unmodified lines | |||
| 121 | struct netlink_ext_ack *extack) | 121 | struct netlink_ext_ack *extack) |
| 122 | { | 122 | { |
| 123 | const struct dpll_device_ops *ops = dpll_device_ops(dpll); | 123 | const struct dpll_device_ops *ops = dpll_device_ops(dpll); |
| 124 | enum dpll_lock_status_error status_error = 0; | ||
| 124 | enum dpll_lock_status status; | 125 | enum dpll_lock_status status; |
| 125 | int ret; | 126 | int ret; |
| 126 | 127 | ||
| 127 | ret = ops->lock_status_get(dpll, dpll_priv(dpll), &status, extack); | 128 | ret = ops->lock_status_get(dpll, dpll_priv(dpll), &status, |
| 129 | &status_error, extack); | ||
| 128 | if (ret) | 130 | if (ret) |
| 129 | return ret; | 131 | return ret; |
| 130 | if (nla_put_u32(msg, DPLL_A_LOCK_STATUS, status)) | 132 | if (nla_put_u32(msg, DPLL_A_LOCK_STATUS, status)) |
| 131 | return -EMSGSIZE; | 133 | return -EMSGSIZE; |
| 134 | if (status_error && | ||
| 135 | (status == DPLL_LOCK_STATUS_UNLOCKED || | ||
| 136 | status == DPLL_LOCK_STATUS_HOLDOVER) && | ||
| 137 | nla_put_u32(msg, DPLL_A_LOCK_STATUS_ERROR, status_error)) | ||
| 138 | return -EMSGSIZE; | ||
| 132 | 139 | ||
| 133 | return 0; | 140 | return 0; |
| 134 | } | 141 | } |
| @@ -488,6 +488,7 @@ ice_dpll_hw_input_prio_set(struct ice_pf *pf, struct ice_dpll *dpll, · 487 unmodified lines | |||
| 488 | * @dpll: registered dpll pointer | 488 | * @dpll: registered dpll pointer |
| 489 | * @dpll_priv: private data pointer passed on dpll registration | 489 | * @dpll_priv: private data pointer passed on dpll registration |
| 490 | * @status: on success holds dpll's lock status | 490 | * @status: on success holds dpll's lock status |
| 491 | * @status_error: status error value | ||
| 491 | * @extack: error reporting | 492 | * @extack: error reporting |
| 492 | * | 493 | * |
| 493 | * Dpll subsystem callback, provides dpll's lock status. | 494 | * 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, · 6 unmodified lines | |||
| 500 | static int | 501 | static int |
| 501 | ice_dpll_lock_status_get(const struct dpll_device *dpll, void *dpll_priv, | 502 | ice_dpll_lock_status_get(const struct dpll_device *dpll, void *dpll_priv, |
| 502 | enum dpll_lock_status *status, | 503 | enum dpll_lock_status *status, |
| 504 | enum dpll_lock_status_error *status_error, | ||
| 503 | struct netlink_ext_ack *extack) | 505 | struct netlink_ext_ack *extack) |
| 504 | { | 506 | { |
| 505 | struct ice_dpll *d = dpll_priv; | 507 | struct ice_dpll *d = dpll_priv; |
| @@ -41,6 +41,7 @@ struct mlx5_dpll_synce_status { · 40 unmodified lines | |||
| 41 | enum mlx5_msees_oper_status oper_status; | 41 | enum mlx5_msees_oper_status oper_status; |
| 42 | bool ho_acq; | 42 | bool ho_acq; |
| 43 | bool oper_freq_measure; | 43 | bool oper_freq_measure; |
| 44 | enum mlx5_msees_failure_reason failure_reason; | ||
| 44 | s32 frequency_diff; | 45 | s32 frequency_diff; |
| 45 | }; | 46 | }; |
| 46 | 47 | ||
| @@ -60,6 +61,7 @@ mlx5_dpll_synce_status_get(struct mlx5_core_dev *mdev, · 13 unmodified lines | |||
| 60 | synce_status->oper_status = MLX5_GET(msees_reg, out, oper_status); | 61 | synce_status->oper_status = MLX5_GET(msees_reg, out, oper_status); |
| 61 | synce_status->ho_acq = MLX5_GET(msees_reg, out, ho_acq); | 62 | synce_status->ho_acq = MLX5_GET(msees_reg, out, ho_acq); |
| 62 | synce_status->oper_freq_measure = MLX5_GET(msees_reg, out, oper_freq_measure); | 63 | synce_status->oper_freq_measure = MLX5_GET(msees_reg, out, oper_freq_measure); |
| 64 | synce_status->failure_reason = MLX5_GET(msees_reg, out, failure_reason); | ||
| 63 | synce_status->frequency_diff = MLX5_GET(msees_reg, out, frequency_diff); | 65 | synce_status->frequency_diff = MLX5_GET(msees_reg, out, frequency_diff); |
| 64 | return 0; | 66 | return 0; |
| 65 | } | 67 | } |
| @@ -99,6 +101,26 @@ mlx5_dpll_lock_status_get(struct mlx5_dpll_synce_status *synce_status) · 33 unmodified lines | |||
| 99 | } | 101 | } |
| 100 | } | 102 | } |
| 101 | 103 | ||
| 104 | static enum dpll_lock_status_error | ||
| 105 | mlx5_dpll_lock_status_error_get(struct mlx5_dpll_synce_status *synce_status) | ||
| 106 | { | ||
| 107 | switch (synce_status->oper_status) { | ||
| 108 | case MLX5_MSEES_OPER_STATUS_FAIL_HOLDOVER: | ||
| 109 | fallthrough; | ||
| 110 | case MLX5_MSEES_OPER_STATUS_FAIL_FREE_RUNNING: | ||
| 111 | switch (synce_status->failure_reason) { | ||
| 112 | case MLX5_MSEES_FAILURE_REASON_PORT_DOWN: | ||
| 113 | return DPLL_LOCK_STATUS_ERROR_MEDIA_DOWN; | ||
| 114 | case MLX5_MSEES_FAILURE_REASON_TOO_HIGH_FREQUENCY_DIFF: | ||
| 115 | return DPLL_LOCK_STATUS_ERROR_FRACTIONAL_FREQUENCY_OFFSET_TOO_HIGH; | ||
| 116 | default: | ||
| 117 | return DPLL_LOCK_STATUS_ERROR_UNDEFINED; | ||
| 118 | } | ||
| 119 | default: | ||
| 120 | return DPLL_LOCK_STATUS_ERROR_NONE; | ||
| 121 | } | ||
| 122 | } | ||
| 123 | |||
| 102 | static enum dpll_pin_state | 124 | static enum dpll_pin_state |
| 103 | mlx5_dpll_pin_state_get(struct mlx5_dpll_synce_status *synce_status) | 125 | mlx5_dpll_pin_state_get(struct mlx5_dpll_synce_status *synce_status) |
| 104 | { | 126 | { |
| @@ -118,10 +140,11 @@ mlx5_dpll_pin_ffo_get(struct mlx5_dpll_synce_status *synce_status, · 13 unmodified lines | |||
| 118 | return 0; | 140 | return 0; |
| 119 | } | 141 | } |
| 120 | 142 | ||
| 121 | static int mlx5_dpll_device_lock_status_get(const struct dpll_device *dpll, | 143 | static int |
| 122 | void *priv, | 144 | mlx5_dpll_device_lock_status_get(const struct dpll_device *dpll, void *priv, |
| 123 | enum dpll_lock_status *status, | 145 | enum dpll_lock_status *status, |
| 124 | struct netlink_ext_ack *extack) | 146 | enum dpll_lock_status_error *status_error, |
| 147 | struct netlink_ext_ack *extack) | ||
| 125 | { | 148 | { |
| 126 | struct mlx5_dpll_synce_status synce_status; | 149 | struct mlx5_dpll_synce_status synce_status; |
| 127 | struct mlx5_dpll *mdpll = priv; | 150 | struct mlx5_dpll *mdpll = priv; |
| @@ -131,6 +154,7 @@ static int mlx5_dpll_device_lock_status_get(const struct dpll_device *dpll, · 3 unmodified lines | |||
| 131 | if (err) | 154 | if (err) |
| 132 | return err; | 155 | return err; |
| 133 | *status = mlx5_dpll_lock_status_get(&synce_status); | 156 | *status = mlx5_dpll_lock_status_get(&synce_status); |
| 157 | *status_error = mlx5_dpll_lock_status_error_get(&synce_status); | ||
| 134 | return 0; | 158 | return 0; |
| 135 | } | 159 | } |
| 136 | 160 | ||
| @@ -4209,10 +4209,11 @@ ptp_ocp_detach(struct ptp_ocp *bp) · 4208 unmodified lines | |||
| 4209 | device_unregister(&bp->dev); | 4209 | device_unregister(&bp->dev); |
| 4210 | } | 4210 | } |
| 4211 | 4211 | ||
| 4212 | static int ptp_ocp_dpll_lock_status_get(const struct dpll_device *dpll, | 4212 | static int |
| 4213 | void *priv, | 4213 | ptp_ocp_dpll_lock_status_get(const struct dpll_device *dpll, void *priv, |
| 4214 | enum dpll_lock_status *status, | 4214 | enum dpll_lock_status *status, |
| 4215 | struct netlink_ext_ack *extack) | 4215 | enum dpll_lock_status_error *status_error, |
| 4216 | struct netlink_ext_ack *extack) | ||
| 4216 | { | 4217 | { |
| 4217 | struct ptp_ocp *bp = priv; | 4218 | struct ptp_ocp *bp = priv; |
| 4218 | 4219 | ||
| @@ -19,6 +19,7 @@ struct dpll_device_ops { · 18 unmodified lines | |||
| 19 | enum dpll_mode *mode, struct netlink_ext_ack *extack); | 19 | enum dpll_mode *mode, struct netlink_ext_ack *extack); |
| 20 | int (*lock_status_get)(const struct dpll_device *dpll, void *dpll_priv, | 20 | int (*lock_status_get)(const struct dpll_device *dpll, void *dpll_priv, |
| 21 | enum dpll_lock_status *status, | 21 | enum dpll_lock_status *status, |
| 22 | enum dpll_lock_status_error *status_error, | ||
| 22 | struct netlink_ext_ack *extack); | 23 | struct netlink_ext_ack *extack); |
| 23 | int (*temp_get)(const struct dpll_device *dpll, void *dpll_priv, | 24 | int (*temp_get)(const struct dpll_device *dpll, void *dpll_priv, |
| 24 | s32 *temp, struct netlink_ext_ack *extack); | 25 | s32 *temp, struct netlink_ext_ack *extack); |
| @@ -12705,6 +12705,14 @@ enum mlx5_msees_oper_status { · 12704 unmodified lines | |||
| 12705 | MLX5_MSEES_OPER_STATUS_FAIL_FREE_RUNNING = 0x5, | 12705 | MLX5_MSEES_OPER_STATUS_FAIL_FREE_RUNNING = 0x5, |
| 12706 | }; | 12706 | }; |
| 12707 | 12707 | ||
| 12708 | enum mlx5_msees_failure_reason { | ||
| 12709 | MLX5_MSEES_FAILURE_REASON_UNDEFINED_ERROR = 0x0, | ||
| 12710 | MLX5_MSEES_FAILURE_REASON_PORT_DOWN = 0x1, | ||
| 12711 | MLX5_MSEES_FAILURE_REASON_TOO_HIGH_FREQUENCY_DIFF = 0x2, | ||
| 12712 | MLX5_MSEES_FAILURE_REASON_NET_SYNCHRONIZER_DEVICE_ERROR = 0x3, | ||
| 12713 | MLX5_MSEES_FAILURE_REASON_LACK_OF_RESOURCES = 0x4, | ||
| 12714 | }; | ||
| 12715 | |||
| 12708 | struct mlx5_ifc_msees_reg_bits { | 12716 | struct mlx5_ifc_msees_reg_bits { |
| 12709 | u8 reserved_at_0[0x8]; | 12717 | u8 reserved_at_0[0x8]; |
| 12710 | u8 local_port[0x8]; | 12718 | u8 local_port[0x8]; |
| @@ -50,6 +50,35 @@ enum dpll_lock_status { · 49 unmodified lines | |||
| 50 | DPLL_LOCK_STATUS_MAX = (__DPLL_LOCK_STATUS_MAX - 1) | 50 | DPLL_LOCK_STATUS_MAX = (__DPLL_LOCK_STATUS_MAX - 1) |
| 51 | }; | 51 | }; |
| 52 | 52 | ||
| 53 | /** | ||
| 54 | * enum dpll_lock_status_error - if previous status change was done due to a | ||
| 55 | * failure, this provides information of dpll device lock status error. Valid | ||
| 56 | * values for DPLL_A_LOCK_STATUS_ERROR attribute | ||
| 57 | * @DPLL_LOCK_STATUS_ERROR_NONE: dpll device lock status was changed without | ||
| 58 | * any error | ||
| 59 | * @DPLL_LOCK_STATUS_ERROR_UNDEFINED: dpll device lock status was changed due | ||
| 60 | * to undefined error. Driver fills this value up in case it is not able to | ||
| 61 | * obtain suitable exact error type. | ||
| 62 | * @DPLL_LOCK_STATUS_ERROR_MEDIA_DOWN: dpll device lock status was changed | ||
| 63 | * because of associated media got down. This may happen for example if dpll | ||
| 64 | * device was previously locked on an input pin of type | ||
| 65 | * PIN_TYPE_SYNCE_ETH_PORT. | ||
| 66 | * @DPLL_LOCK_STATUS_ERROR_FRACTIONAL_FREQUENCY_OFFSET_TOO_HIGH: the FFO | ||
| 67 | * (Fractional Frequency Offset) between the RX and TX symbol rate on the | ||
| 68 | * media got too high. This may happen for example if dpll device was | ||
| 69 | * previously locked on an input pin of type PIN_TYPE_SYNCE_ETH_PORT. | ||
| 70 | */ | ||
| 71 | enum dpll_lock_status_error { | ||
| 72 | DPLL_LOCK_STATUS_ERROR_NONE = 1, | ||
| 73 | DPLL_LOCK_STATUS_ERROR_UNDEFINED, | ||
| 74 | DPLL_LOCK_STATUS_ERROR_MEDIA_DOWN, | ||
| 75 | DPLL_LOCK_STATUS_ERROR_FRACTIONAL_FREQUENCY_OFFSET_TOO_HIGH, | ||
| 76 | |||
| 77 | /* private: */ | ||
| 78 | __DPLL_LOCK_STATUS_ERROR_MAX, | ||
| 79 | DPLL_LOCK_STATUS_ERROR_MAX = (__DPLL_LOCK_STATUS_ERROR_MAX - 1) | ||
| 80 | }; | ||
| 81 | |||
| 53 | #define DPLL_TEMP_DIVIDER 1000 | 82 | #define DPLL_TEMP_DIVIDER 1000 |
| 54 | 83 | ||
| 55 | /** | 84 | /** |
| @@ -150,6 +179,7 @@ enum dpll_a { · 94 unmodified lines | |||
| 150 | DPLL_A_LOCK_STATUS, | 179 | DPLL_A_LOCK_STATUS, |
| 151 | DPLL_A_TEMP, | 180 | DPLL_A_TEMP, |
| 152 | DPLL_A_TYPE, | 181 | DPLL_A_TYPE, |
| 182 | DPLL_A_LOCK_STATUS_ERROR, | ||
| 153 | 183 | ||
| 154 | __DPLL_A_MAX, | 184 | __DPLL_A_MAX, |
| 155 | DPLL_A_MAX = (__DPLL_A_MAX - 1) | 185 | DPLL_A_MAX = (__DPLL_A_MAX - 1) |