1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33#ifndef __LIB_CLOCK_H__
34#define __LIB_CLOCK_H__
35
36static inline bool mlx5_is_real_time_rq(struct mlx5_core_dev *mdev)
37{
38 u8 rq_ts_format_cap = MLX5_CAP_GEN(mdev, rq_ts_format);
39
40 return (rq_ts_format_cap == MLX5_TIMESTAMP_FORMAT_CAP_REAL_TIME ||
41 rq_ts_format_cap ==
42 MLX5_TIMESTAMP_FORMAT_CAP_FREE_RUNNING_AND_REAL_TIME);
43}
44
45static inline bool mlx5_is_real_time_sq(struct mlx5_core_dev *mdev)
46{
47 u8 sq_ts_format_cap = MLX5_CAP_GEN(mdev, sq_ts_format);
48
49 return (sq_ts_format_cap == MLX5_TIMESTAMP_FORMAT_CAP_REAL_TIME ||
50 sq_ts_format_cap ==
51 MLX5_TIMESTAMP_FORMAT_CAP_FREE_RUNNING_AND_REAL_TIME);
52}
53
54typedef ktime_t (*cqe_ts_to_ns)(struct mlx5_clock *, u64);
55
56#if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
57void mlx5_init_clock(struct mlx5_core_dev *mdev);
58void mlx5_cleanup_clock(struct mlx5_core_dev *mdev);
59
60static inline int mlx5_clock_get_ptp_index(struct mlx5_core_dev *mdev)
61{
62 return mdev->clock.ptp ? ptp_clock_index(mdev->clock.ptp) : -1;
63}
64
65static inline ktime_t mlx5_timecounter_cyc2time(struct mlx5_clock *clock,
66 u64 timestamp)
67{
68 struct mlx5_timer *timer = &clock->timer;
69 unsigned int seq;
70 u64 nsec;
71
72 do {
73 seq = read_seqbegin(&clock->lock);
74 nsec = timecounter_cyc2time(&timer->tc, timestamp);
75 } while (read_seqretry(&clock->lock, seq));
76
77 return ns_to_ktime(nsec);
78}
79
80#define REAL_TIME_TO_NS(hi, low) (((u64)hi) * NSEC_PER_SEC + ((u64)low))
81
82static inline ktime_t mlx5_real_time_cyc2time(struct mlx5_clock *clock,
83 u64 timestamp)
84{
85 u64 time = REAL_TIME_TO_NS(timestamp >> 32, timestamp & 0xFFFFFFFF);
86
87 return ns_to_ktime(time);
88}
89#else
90static inline void mlx5_init_clock(struct mlx5_core_dev *mdev) {}
91static inline void mlx5_cleanup_clock(struct mlx5_core_dev *mdev) {}
92static inline int mlx5_clock_get_ptp_index(struct mlx5_core_dev *mdev)
93{
94 return -1;
95}
96
97static inline ktime_t mlx5_timecounter_cyc2time(struct mlx5_clock *clock,
98 u64 timestamp)
99{
100 return 0;
101}
102
103static inline ktime_t mlx5_real_time_cyc2time(struct mlx5_clock *clock,
104 u64 timestamp)
105{
106 return 0;
107}
108#endif
109
110static inline cqe_ts_to_ns mlx5_rq_ts_translator(struct mlx5_core_dev *mdev)
111{
112 return mlx5_is_real_time_rq(mdev) ? mlx5_real_time_cyc2time :
113 mlx5_timecounter_cyc2time;
114}
115
116static inline cqe_ts_to_ns mlx5_sq_ts_translator(struct mlx5_core_dev *mdev)
117{
118 return mlx5_is_real_time_sq(mdev) ? mlx5_real_time_cyc2time :
119 mlx5_timecounter_cyc2time;
120}
121#endif
122