Skip to content

Commit 31c128b

Browse files
Eugenia Emantayevdavem330
authored andcommitted
net/mlx4_en: Choose time-stamping shift value according to HW frequency
Previously, the shift value used for time-stamping was constant and didn't depend on the HW chip frequency. Change that to take the frequency into account and calculate the maximal value in cycles per wraparound of ten seconds. This time slot was chosen since it gives a good accuracy in time synchronization. Algorithm for shift value calculation: * Round up the maximal value in cycles to nearest power of two * Calculate maximal multiplier by division of all 64 bits set to above result * Then, invert the function clocksource_khz2mult() to get the shift from maximal mult value Fixes: ec693d4 ('net/mlx4_en: Add HW timestamping (TS) support') Signed-off-by: Eugenia Emantayev <[email protected]> Reviewed-by: Matan Barak <[email protected]> Signed-off-by: Or Gerlitz <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 281e8b2 commit 31c128b

File tree

1 file changed

+19
-6
lines changed

1 file changed

+19
-6
lines changed

drivers/net/ethernet/mellanox/mlx4/en_clock.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,24 @@ static const struct ptp_clock_info mlx4_en_ptp_clock_info = {
236236
.enable = mlx4_en_phc_enable,
237237
};
238238

239+
#define MLX4_EN_WRAP_AROUND_SEC 10ULL
240+
241+
/* This function calculates the max shift that enables the user range
242+
* of MLX4_EN_WRAP_AROUND_SEC values in the cycles register.
243+
*/
244+
static u32 freq_to_shift(u16 freq)
245+
{
246+
u32 freq_khz = freq * 1000;
247+
u64 max_val_cycles = freq_khz * 1000 * MLX4_EN_WRAP_AROUND_SEC;
248+
u64 max_val_cycles_rounded = is_power_of_2(max_val_cycles + 1) ?
249+
max_val_cycles : roundup_pow_of_two(max_val_cycles) - 1;
250+
/* calculate max possible multiplier in order to fit in 64bit */
251+
u64 max_mul = div_u64(0xffffffffffffffffULL, max_val_cycles_rounded);
252+
253+
/* This comes from the reverse of clocksource_khz2mult */
254+
return ilog2(div_u64(max_mul * freq_khz, 1000000));
255+
}
256+
239257
void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev)
240258
{
241259
struct mlx4_dev *dev = mdev->dev;
@@ -254,12 +272,7 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev)
254272
memset(&mdev->cycles, 0, sizeof(mdev->cycles));
255273
mdev->cycles.read = mlx4_en_read_clock;
256274
mdev->cycles.mask = CLOCKSOURCE_MASK(48);
257-
/* Using shift to make calculation more accurate. Since current HW
258-
* clock frequency is 427 MHz, and cycles are given using a 48 bits
259-
* register, the biggest shift when calculating using u64, is 14
260-
* (max_cycles * multiplier < 2^64)
261-
*/
262-
mdev->cycles.shift = 14;
275+
mdev->cycles.shift = freq_to_shift(dev->caps.hca_core_clock);
263276
mdev->cycles.mult =
264277
clocksource_khz2mult(1000 * dev->caps.hca_core_clock, mdev->cycles.shift);
265278
mdev->nominal_c_mult = mdev->cycles.mult;

0 commit comments

Comments
 (0)