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)
        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;
 
 {
        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 (scaled_ppm < 0) {
-               neg_adj = 1;
-               scaled_ppm = -scaled_ppm;
-       }
+       u64 adj, base_adj;
 
        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,
-                                  1000000ULL << 16);
+       base_adj = I40E_PTP_40GB_INCVAL * READ_ONCE(pf->ptp_adj_mult);
 
-       if (neg_adj)
-               adj = I40E_PTP_40GB_INCVAL - diff;
-       else
-               adj = I40E_PTP_40GB_INCVAL + diff;
+       adj = adjust_by_scaled_ppm(base_adj, scaled_ppm);
 
        wr32(hw, I40E_PRTTSYN_INC_L, adj & 0xFFFFFFFF);
        wr32(hw, I40E_PRTTSYN_INC_H, adj >> 32);
 
 {
        struct ice_pf *pf = ptp_info_to_pf(info);
        struct ice_hw *hw = &pf->hw;
-       u64 incval, diff;
-       int neg_adj = 0;
+       u64 incval;
        int err;
 
-       incval = ice_base_incval(pf);
-
-       if (scaled_ppm < 0) {
-               neg_adj = 1;
-               scaled_ppm = -scaled_ppm;
-       }
-
-       diff = mul_u64_u64_div_u64(incval, (u64)scaled_ppm,
-                                  1000000ULL << 16);
-       if (neg_adj)
-               incval -= diff;
-       else
-               incval += diff;
-
+       incval = adjust_by_scaled_ppm(ice_base_incval(pf), scaled_ppm);
        err = ice_ptp_write_incval_locked(hw, incval);
        if (err) {
                dev_err(ice_pf_to_dev(pf), "PTP failed to set incval, err %d\n",
 
        struct igb_adapter *igb = container_of(ptp, struct igb_adapter,
                                               ptp_caps);
        struct e1000_hw *hw = &igb->hw;
-       int neg_adj = 0;
-       u64 rate;
-       u32 incvalue;
-
-       if (scaled_ppm < 0) {
-               neg_adj = 1;
-               scaled_ppm = -scaled_ppm;
-       }
-
-       incvalue = INCVALUE_82576;
-       rate = mul_u64_u64_div_u64(incvalue, (u64)scaled_ppm,
-                                  1000000ULL << 16);
+       u64 incvalue;
 
-       if (neg_adj)
-               incvalue -= rate;
-       else
-               incvalue += rate;
+       incvalue = adjust_by_scaled_ppm(INCVALUE_82576, scaled_ppm);
 
        wr32(E1000_TIMINCA, INCPERIOD_82576 | (incvalue & INCVALUE_82576_MASK));
 
 
        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:
        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)
 
        return (long)ppb;
 }
 
+/**
+ * diff_by_scaled_ppm - Calculate difference using scaled ppm
+ * @base: the base increment value to adjust
+ * @scaled_ppm: scaled parts per million to adjust by
+ * @diff: on return, the absolute value of calculated diff
+ *
+ * Calculate the difference to adjust the base increment using scaled parts
+ * per million.
+ *
+ * Use mul_u64_u64_div_u64 to perform the difference calculation in avoid
+ * possible overflow.
+ *
+ * Returns: true if scaled_ppm is negative, false otherwise
+ */
+static inline bool diff_by_scaled_ppm(u64 base, long scaled_ppm, u64 *diff)
+{
+       bool negative = false;
+
+       if (scaled_ppm < 0) {
+               negative = true;
+               scaled_ppm = -scaled_ppm;
+       }
+
+       *diff = mul_u64_u64_div_u64(base, (u64)scaled_ppm, 1000000ULL << 16);
+
+       return negative;
+}
+
+/**
+ * adjust_by_scaled_ppm - Adjust a base increment by scaled parts per million
+ * @base: the base increment value to adjust
+ * @scaled_ppm: scaled parts per million frequency adjustment
+ *
+ * Helper function which calculates a new increment value based on the
+ * requested scaled parts per million adjustment.
+ */
+static inline u64 adjust_by_scaled_ppm(u64 base, long scaled_ppm)
+{
+       u64 diff;
+
+       if (diff_by_scaled_ppm(base, scaled_ppm, &diff))
+               return base - diff;
+
+       return base + diff;
+}
+
 #if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
 
 /**