From cdd3bf98592117f59be2daa0f2ca00f352d7abbc Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Thu, 21 Jul 2022 14:29:59 -0700 Subject: [PATCH] use mul_u64_u64_div_u64 and convert .adjfreq to .adjfine Conflict:NA Reference:https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ccd3bf98592117f59be2daa0f2ca00f352d7abbc https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3626a690b717c18a969274e1fe000f8885d5afad --- src/i40e_ptp.c | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/src/i40e_ptp.c b/src/i40e_ptp.c index a94b774..710c02b 100644 --- a/src/i40e_ptp.c +++ b/src/i40e_ptp.c @@ -349,44 +349,37 @@ static void i40e_ptp_convert_to_hwtstamp(struct skb_shared_hwtstamps *hwtstamps, } /** - * i40e_ptp_adjfreq - Adjust the PHC frequency + * i40e_ptp_adjfine - Adjust the PHC frequency * @ptp: The PTP clock structure - * @ppb: Parts per billion adjustment from the base + * @scaled_ppm: Scaled_ppm Parts per million adjustment from the base * - * Adjust the frequency of the PHC by the indicated parts per billion from the - * base frequency. + * Adjust the frequency of the PHC by the indicated delta from the base + * frequency. + * + * Scaled parts per million is ppm with a 16 bit binary fractional filed. **/ -static int i40e_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) +static int i40e_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) { struct i40e_pf *pf = container_of(ptp, struct i40e_pf, ptp_caps); struct i40e_hw *hw = &pf->hw; u64 adj, freq, diff; int neg_adj = 0; - if (ppb < 0) { + if (scaled_ppm < 0) { neg_adj = 1; - ppb = -ppb; + scaled_ppm = -scaled_ppm; } - freq = I40E_PTP_40GB_INCVAL; - freq *= ppb; - diff = div_u64(freq, 1000000000ULL); + smp_mb(); /* Force any pending update before accessing. */ + freq = I40E_PTP_40GB_INCVAL * READ_ONCE(pf->ptp_adj_mult); + diff = mul_u64_u64_div_u64(freq, (u64)scaled_ppm, + 1000000000ULL << 16); if (neg_adj) adj = I40E_PTP_40GB_INCVAL - diff; else adj = I40E_PTP_40GB_INCVAL + diff; - /* At some link speeds, the base incval is so large that directly - * multiplying by ppb would result in arithmetic overflow even when - * using a u64. Avoid this by instead calculating the new incval - * always in terms of the 40GbE clock rate and then multiplying by the - * link speed factor afterwards. This does result in slightly lower - * precision at lower link speeds, but it is fairly minor. - */ - smp_mb(); /* Force any pending update before accessing. */ - adj *= READ_ONCE(pf->ptp_adj_mult); - wr32(hw, I40E_PRTTSYN_INC_L, (u32)adj); wr32(hw, I40E_PRTTSYN_INC_H, (u32)(adj >> 32)); @@ -1558,7 +1551,7 @@ static long i40e_ptp_create_clock(struct i40e_pf *pf) sizeof(pf->ptp_caps.name) - 1); pf->ptp_caps.owner = THIS_MODULE; pf->ptp_caps.max_adj = 999999999; - pf->ptp_caps.adjfreq = i40e_ptp_adjfreq; + pf->ptp_caps.adjfine = i40e_ptp_adjfine; pf->ptp_caps.adjtime = i40e_ptp_adjtime; #ifdef HAVE_PTP_CLOCK_INFO_GETTIME64 pf->ptp_caps.gettime64 = i40e_ptp_gettime; -- 2.23.0