diff options
author | Jacob Keller <jacob.e.keller@intel.com> | 2022-10-28 04:04:13 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2022-10-31 11:14:16 +0000 |
commit | 1060707e380994e7c9b754b6eb74f25459b4a5b3 (patch) | |
tree | 749df69efb5af2cad701f04cdc35b5b1f87545ed /drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | |
parent | b9a61b97798ca6d0c856a217e61e2177bd8f6eae (diff) |
ptp: introduce helpers to adjust by scaled parts per million
Many drivers implement the .adjfreq or .adjfine PTP op function with the
same basic logic:
1. Determine a base frequency value
2. Multiply this by the abs() of the requested adjustment, then divide by
the appropriate divisor (1 billion, or 65,536 billion).
3. Add or subtract this difference from the base frequency to calculate a
new adjustment.
A few drivers need the difference and direction rather than the combined
new increment value.
I recently converted the Intel drivers to .adjfine and the scaled parts per
million (65.536 parts per billion) logic. To avoid overflow with minimal
loss of precision, mul_u64_u64_div_u64 was used.
The basic logic used by all of these drivers is very similar, and leads to
a lot of duplicate code to perform the same task.
Rather than keep this duplicate code, introduce diff_by_scaled_ppm and
adjust_by_scaled_ppm. These helper functions calculate the difference or
adjustment necessary based on the scaled parts per million input.
The diff_by_scaled_ppm function returns true if the difference should be
subtracted, and false otherwise.
Update the Intel drivers to use the new helper functions. Other vendor
drivers will be converted to .adjfine and this helper function in the
following changes.
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Acked-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c')
-rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 24 |
1 files changed, 4 insertions, 20 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index f8605f57bd06..fd3f77a9e28d 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c @@ -451,21 +451,11 @@ static int ixgbe_ptp_adjfine_82599(struct ptp_clock_info *ptp, long scaled_ppm) struct ixgbe_adapter *adapter = container_of(ptp, struct ixgbe_adapter, ptp_caps); struct ixgbe_hw *hw = &adapter->hw; - u64 incval, diff; - int neg_adj = 0; - - if (scaled_ppm < 0) { - neg_adj = 1; - scaled_ppm = -scaled_ppm; - } + u64 incval; smp_mb(); incval = READ_ONCE(adapter->base_incval); - - diff = mul_u64_u64_div_u64(incval, scaled_ppm, - 1000000ULL << 16); - - incval = neg_adj ? (incval - diff) : (incval + diff); + incval = adjust_by_scaled_ppm(incval, scaled_ppm); switch (hw->mac.type) { case ixgbe_mac_X540: @@ -502,17 +492,11 @@ static int ixgbe_ptp_adjfine_X550(struct ptp_clock_info *ptp, long scaled_ppm) struct ixgbe_adapter *adapter = container_of(ptp, struct ixgbe_adapter, ptp_caps); struct ixgbe_hw *hw = &adapter->hw; - int neg_adj = 0; + bool neg_adj; u64 rate; u32 inca; - if (scaled_ppm < 0) { - neg_adj = 1; - scaled_ppm = -scaled_ppm; - } - - rate = mul_u64_u64_div_u64(IXGBE_X550_BASE_PERIOD, scaled_ppm, - 1000000ULL << 16); + neg_adj = diff_by_scaled_ppm(IXGBE_X550_BASE_PERIOD, scaled_ppm, &rate); /* warn if rate is too large */ if (rate >= INCVALUE_MASK) |