diff options
-rw-r--r-- | drivers/net/ethernet/intel/iavf/iavf_ptp.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/iavf/iavf_ptp.c b/drivers/net/ethernet/intel/iavf/iavf_ptp.c index b9a341e98a98..c2e0d27552b0 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_ptp.c +++ b/drivers/net/ethernet/intel/iavf/iavf_ptp.c @@ -159,6 +159,56 @@ static int iavf_ptp_gettimex64(struct ptp_clock_info *info, } /** + * iavf_ptp_cache_phc_time - Cache PHC time for performing timestamp extension + * @adapter: private adapter structure + * + * Periodically cache the PHC time in order to allow for timestamp extension. + * This is required because the Tx and Rx timestamps only contain 32bits of + * nanoseconds. Timestamp extension allows calculating the corrected 64bit + * timestamp. This algorithm relies on the cached time being within ~1 second + * of the timestamp. + */ +static void iavf_ptp_cache_phc_time(struct iavf_adapter *adapter) +{ + if (!time_is_before_jiffies(adapter->ptp.cached_phc_updated + HZ)) + return; + + /* The response from virtchnl will store the time into + * cached_phc_time. + */ + iavf_send_phc_read(adapter); +} + +/** + * iavf_ptp_do_aux_work - Perform periodic work required for PTP support + * @info: PTP clock info structure + * + * Handler to take care of periodic work required for PTP operation. This + * includes the following tasks: + * + * 1) updating cached_phc_time + * + * cached_phc_time is used by the Tx and Rx timestamp flows in order to + * perform timestamp extension, by carefully comparing the timestamp + * 32bit nanosecond timestamps and determining the corrected 64bit + * timestamp value to report to userspace. This algorithm only works if + * the cached_phc_time is within ~1 second of the Tx or Rx timestamp + * event. This task periodically reads the PHC time and stores it, to + * ensure that timestamp extension operates correctly. + * + * Returns: time in jiffies until the periodic task should be re-scheduled. + */ +static long iavf_ptp_do_aux_work(struct ptp_clock_info *info) +{ + struct iavf_adapter *adapter = iavf_clock_to_adapter(info); + + iavf_ptp_cache_phc_time(adapter); + + /* Check work about twice a second */ + return msecs_to_jiffies(500); +} + +/** * iavf_ptp_register_clock - Register a new PTP for userspace * @adapter: private adapter structure * @@ -176,6 +226,7 @@ static int iavf_ptp_register_clock(struct iavf_adapter *adapter) KBUILD_MODNAME, dev_name(dev)); ptp_info->owner = THIS_MODULE; ptp_info->gettimex64 = iavf_ptp_gettimex64; + ptp_info->do_aux_work = iavf_ptp_do_aux_work; clock = ptp_clock_register(ptp_info, dev); if (IS_ERR(clock)) @@ -219,6 +270,8 @@ void iavf_ptp_init(struct iavf_adapter *adapter) rx_ring->ptp = &adapter->ptp; } + + ptp_schedule_worker(adapter->ptp.clock, 0); } /** |