Lines Matching +full:timing +full:- +full:adjustment

1 // SPDX-License-Identifier: GPL-2.0
14 /* FBNIC timing & PTP implementation
17 * 32bit of the HW time counter. Since this makes our time reporting non-atomic
19 * Time offset is 64bit - we need a seq counter for 32bit machines.
21 * a coherent snapshot of both - READ_ONCE()/WRITE_ONCE() + writer side lock
37 * is correct based on low instead of re-reading, and skip reading @hi
44 lockdep_assert_held(&fbd->time_lock); in __fbnic_time_get_slow()
56 lockdep_assert_held(&fbd->time_lock); in __fbnic_time_set_addend()
65 if (time_is_after_jiffies(fbd->last_read + in fbnic_ptp_fresh_check()
69 dev_warn(fbd->dev, "NIC timestamp refresh stall, delayed by %lu sec\n", in fbnic_ptp_fresh_check()
70 (jiffies - fbd->last_read - FBNIC_TS_HIGH_REFRESH_JIF) / HZ); in fbnic_ptp_fresh_check()
78 spin_lock_irqsave(&fbd->time_lock, flags); in fbnic_ptp_refresh_time()
79 hi = fbnic_rd32(fbn->fbd, FBNIC_PTP_CTR_VAL_HI); in fbnic_ptp_refresh_time()
88 WRITE_ONCE(fbn->time_high, hi - 16); in fbnic_ptp_refresh_time()
89 fbd->last_read = jiffies; in fbnic_ptp_refresh_time()
91 spin_unlock_irqrestore(&fbd->time_lock, flags); in fbnic_ptp_refresh_time()
99 fbn = netdev_priv(fbd->netdev); in fbnic_ptp_do_aux_work()
117 spin_lock_irqsave(&fbd->time_lock, flags); in fbnic_ptp_adjfine()
123 spin_unlock_irqrestore(&fbd->time_lock, flags); in fbnic_ptp_adjfine()
125 return fbnic_present(fbd) ? 0 : -EIO; in fbnic_ptp_adjfine()
134 fbn = netdev_priv(fbd->netdev); in fbnic_ptp_adjtime()
136 spin_lock_irqsave(&fbd->time_lock, flags); in fbnic_ptp_adjtime()
137 u64_stats_update_begin(&fbn->time_seq); in fbnic_ptp_adjtime()
138 WRITE_ONCE(fbn->time_offset, READ_ONCE(fbn->time_offset) + delta); in fbnic_ptp_adjtime()
139 u64_stats_update_end(&fbn->time_seq); in fbnic_ptp_adjtime()
140 spin_unlock_irqrestore(&fbd->time_lock, flags); in fbnic_ptp_adjtime()
155 fbn = netdev_priv(fbd->netdev); in fbnic_ptp_gettimex64()
157 spin_lock_irqsave(&fbd->time_lock, flags); in fbnic_ptp_gettimex64()
165 * - this can be optimized if needed. in fbnic_ptp_gettimex64()
169 time_ns = ((u64)hi << 32 | lo) + fbn->time_offset; in fbnic_ptp_gettimex64()
170 spin_unlock_irqrestore(&fbd->time_lock, flags); in fbnic_ptp_gettimex64()
173 return -EIO; in fbnic_ptp_gettimex64()
189 fbn = netdev_priv(fbd->netdev); in fbnic_ptp_settime64()
193 spin_lock_irqsave(&fbd->time_lock, flags); in fbnic_ptp_settime64()
198 u64_stats_update_begin(&fbn->time_seq); in fbnic_ptp_settime64()
199 WRITE_ONCE(fbn->time_offset, host_ns - dev_ns); in fbnic_ptp_settime64()
200 u64_stats_update_end(&fbn->time_seq); in fbnic_ptp_settime64()
203 ret = -EIO; in fbnic_ptp_settime64()
205 spin_unlock_irqrestore(&fbd->time_lock, flags); in fbnic_ptp_settime64()
212 /* 1,000,000,000 - 1 PPB to ensure increment is positive
213 * after max negative adjustment.
225 struct fbnic_net *fbn = netdev_priv(fbd->netdev); in fbnic_ptp_reset()
250 fbn->time_offset = 0; in fbnic_ptp_reset()
251 fbn->time_high = 0; in fbnic_ptp_reset()
260 u64_stats_init(&fbn->time_seq); in fbnic_time_init()
265 fbnic_ptp_refresh_time(fbn->fbd, fbn); in fbnic_time_start()
269 return ptp_schedule_worker(fbn->fbd->ptp, FBNIC_TS_HIGH_REFRESH_JIF); in fbnic_time_start()
274 ptp_cancel_worker_sync(fbn->fbd->ptp); in fbnic_time_stop()
275 fbnic_ptp_fresh_check(fbn->fbd); in fbnic_time_stop()
280 struct device *dev = fbd->dev; in fbnic_ptp_setup()
283 spin_lock_init(&fbd->time_lock); in fbnic_ptp_setup()
285 spin_lock_irqsave(&fbd->time_lock, flags); /* Appease lockdep */ in fbnic_ptp_setup()
287 spin_unlock_irqrestore(&fbd->time_lock, flags); in fbnic_ptp_setup()
289 memcpy(&fbd->ptp_info, &fbnic_ptp_info, sizeof(fbnic_ptp_info)); in fbnic_ptp_setup()
291 fbd->ptp = ptp_clock_register(&fbd->ptp_info, dev); in fbnic_ptp_setup()
292 if (IS_ERR(fbd->ptp)) in fbnic_ptp_setup()
293 dev_err(dev, "Failed to register PTP: %pe\n", fbd->ptp); in fbnic_ptp_setup()
295 return PTR_ERR_OR_ZERO(fbd->ptp); in fbnic_ptp_setup()
300 if (!fbd->ptp) in fbnic_ptp_destroy()
302 ptp_clock_unregister(fbd->ptp); in fbnic_ptp_destroy()