summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/intel/e1000e
diff options
context:
space:
mode:
authorJacob Keller <jacob.e.keller@intel.com>2022-10-28 14:04:13 +0300
committerDavid S. Miller <davem@davemloft.net>2022-10-31 14:14:16 +0300
commit1060707e380994e7c9b754b6eb74f25459b4a5b3 (patch)
tree749df69efb5af2cad701f04cdc35b5b1f87545ed /drivers/net/ethernet/intel/e1000e
parentb9a61b97798ca6d0c856a217e61e2177bd8f6eae (diff)
downloadlinux-1060707e380994e7c9b754b6eb74f25459b4a5b3.tar.xz
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/e1000e')
-rw-r--r--drivers/net/ethernet/intel/e1000e/ptp.c16
1 files changed, 3 insertions, 13 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/ptp.c b/drivers/net/ethernet/intel/e1000e/ptp.c
index 0e488e4fa5c1..6e5a1720e6cd 100644
--- a/drivers/net/ethernet/intel/e1000e/ptp.c
+++ b/drivers/net/ethernet/intel/e1000e/ptp.c
@@ -29,17 +29,11 @@ static int e1000e_phc_adjfine(struct ptp_clock_info *ptp, long delta)
struct e1000_adapter *adapter = container_of(ptp, struct e1000_adapter,
ptp_clock_info);
struct e1000_hw *hw = &adapter->hw;
- bool neg_adj = false;
unsigned long flags;
- u64 adjustment;
- u32 timinca, incvalue;
+ u64 incvalue;
+ u32 timinca;
s32 ret_val;
- if (delta < 0) {
- neg_adj = true;
- delta = -delta;
- }
-
/* Get the System Time Register SYSTIM base frequency */
ret_val = e1000e_get_base_timinca(adapter, &timinca);
if (ret_val)
@@ -48,11 +42,7 @@ static int e1000e_phc_adjfine(struct ptp_clock_info *ptp, long delta)
spin_lock_irqsave(&adapter->systim_lock, flags);
incvalue = timinca & E1000_TIMINCA_INCVALUE_MASK;
-
- adjustment = mul_u64_u64_div_u64(incvalue, (u64)delta,
- 1000000ULL << 16);
-
- incvalue = neg_adj ? (incvalue - adjustment) : (incvalue + adjustment);
+ incvalue = adjust_by_scaled_ppm(incvalue, delta);
timinca &= ~E1000_TIMINCA_INCVALUE_MASK;
timinca |= incvalue;