0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 #ifndef __LIB_CLOCK_H__
0034 #define __LIB_CLOCK_H__
0035
0036 static inline bool mlx5_is_real_time_rq(struct mlx5_core_dev *mdev)
0037 {
0038 u8 rq_ts_format_cap = MLX5_CAP_GEN(mdev, rq_ts_format);
0039
0040 return (rq_ts_format_cap == MLX5_TIMESTAMP_FORMAT_CAP_REAL_TIME ||
0041 rq_ts_format_cap ==
0042 MLX5_TIMESTAMP_FORMAT_CAP_FREE_RUNNING_AND_REAL_TIME);
0043 }
0044
0045 static inline bool mlx5_is_real_time_sq(struct mlx5_core_dev *mdev)
0046 {
0047 u8 sq_ts_format_cap = MLX5_CAP_GEN(mdev, sq_ts_format);
0048
0049 return (sq_ts_format_cap == MLX5_TIMESTAMP_FORMAT_CAP_REAL_TIME ||
0050 sq_ts_format_cap ==
0051 MLX5_TIMESTAMP_FORMAT_CAP_FREE_RUNNING_AND_REAL_TIME);
0052 }
0053
0054 typedef ktime_t (*cqe_ts_to_ns)(struct mlx5_clock *, u64);
0055
0056 #if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
0057 void mlx5_init_clock(struct mlx5_core_dev *mdev);
0058 void mlx5_cleanup_clock(struct mlx5_core_dev *mdev);
0059
0060 static inline int mlx5_clock_get_ptp_index(struct mlx5_core_dev *mdev)
0061 {
0062 return mdev->clock.ptp ? ptp_clock_index(mdev->clock.ptp) : -1;
0063 }
0064
0065 static inline ktime_t mlx5_timecounter_cyc2time(struct mlx5_clock *clock,
0066 u64 timestamp)
0067 {
0068 struct mlx5_timer *timer = &clock->timer;
0069 unsigned int seq;
0070 u64 nsec;
0071
0072 do {
0073 seq = read_seqbegin(&clock->lock);
0074 nsec = timecounter_cyc2time(&timer->tc, timestamp);
0075 } while (read_seqretry(&clock->lock, seq));
0076
0077 return ns_to_ktime(nsec);
0078 }
0079
0080 #define REAL_TIME_TO_NS(hi, low) (((u64)hi) * NSEC_PER_SEC + ((u64)low))
0081
0082 static inline ktime_t mlx5_real_time_cyc2time(struct mlx5_clock *clock,
0083 u64 timestamp)
0084 {
0085 u64 time = REAL_TIME_TO_NS(timestamp >> 32, timestamp & 0xFFFFFFFF);
0086
0087 return ns_to_ktime(time);
0088 }
0089 #else
0090 static inline void mlx5_init_clock(struct mlx5_core_dev *mdev) {}
0091 static inline void mlx5_cleanup_clock(struct mlx5_core_dev *mdev) {}
0092 static inline int mlx5_clock_get_ptp_index(struct mlx5_core_dev *mdev)
0093 {
0094 return -1;
0095 }
0096
0097 static inline ktime_t mlx5_timecounter_cyc2time(struct mlx5_clock *clock,
0098 u64 timestamp)
0099 {
0100 return 0;
0101 }
0102
0103 static inline ktime_t mlx5_real_time_cyc2time(struct mlx5_clock *clock,
0104 u64 timestamp)
0105 {
0106 return 0;
0107 }
0108 #endif
0109
0110 static inline cqe_ts_to_ns mlx5_rq_ts_translator(struct mlx5_core_dev *mdev)
0111 {
0112 return mlx5_is_real_time_rq(mdev) ? mlx5_real_time_cyc2time :
0113 mlx5_timecounter_cyc2time;
0114 }
0115
0116 static inline cqe_ts_to_ns mlx5_sq_ts_translator(struct mlx5_core_dev *mdev)
0117 {
0118 return mlx5_is_real_time_sq(mdev) ? mlx5_real_time_cyc2time :
0119 mlx5_timecounter_cyc2time;
0120 }
0121 #endif