summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/engleder/tsnep_ptp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/engleder/tsnep_ptp.c')
-rw-r--r--drivers/net/ethernet/engleder/tsnep_ptp.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/drivers/net/ethernet/engleder/tsnep_ptp.c b/drivers/net/ethernet/engleder/tsnep_ptp.c
index eaad453d487e..54fbf0126815 100644
--- a/drivers/net/ethernet/engleder/tsnep_ptp.c
+++ b/drivers/net/ethernet/engleder/tsnep_ptp.c
@@ -175,6 +175,33 @@ static int tsnep_ptp_settime64(struct ptp_clock_info *ptp,
return 0;
}
+static int tsnep_ptp_getcyclesx64(struct ptp_clock_info *ptp,
+ struct timespec64 *ts,
+ struct ptp_system_timestamp *sts)
+{
+ struct tsnep_adapter *adapter = container_of(ptp, struct tsnep_adapter,
+ ptp_clock_info);
+ u32 high_before;
+ u32 low;
+ u32 high;
+ u64 counter;
+
+ /* read high dword twice to detect overrun */
+ high = ioread32(adapter->addr + ECM_COUNTER_HIGH);
+ do {
+ ptp_read_system_prets(sts);
+ low = ioread32(adapter->addr + ECM_COUNTER_LOW);
+ ptp_read_system_postts(sts);
+ high_before = high;
+ high = ioread32(adapter->addr + ECM_COUNTER_HIGH);
+ } while (high != high_before);
+ counter = (((u64)high) << 32) | ((u64)low);
+
+ *ts = ns_to_timespec64(counter);
+
+ return 0;
+}
+
int tsnep_ptp_init(struct tsnep_adapter *adapter)
{
int retval = 0;
@@ -192,6 +219,7 @@ int tsnep_ptp_init(struct tsnep_adapter *adapter)
adapter->ptp_clock_info.adjtime = tsnep_ptp_adjtime;
adapter->ptp_clock_info.gettimex64 = tsnep_ptp_gettimex64;
adapter->ptp_clock_info.settime64 = tsnep_ptp_settime64;
+ adapter->ptp_clock_info.getcyclesx64 = tsnep_ptp_getcyclesx64;
spin_lock_init(&adapter->ptp_lock);