Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 018ed23d authored by Miroslav Lichvar's avatar Miroslav Lichvar Committed by David S. Miller
Browse files

ixgbe: extend PTP gettime function to read system clock



This adds support for the PTP_SYS_OFFSET_EXTENDED ioctl.

Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Jacob Keller <jacob.e.keller@intel.com>
Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: default avatarMiroslav Lichvar <mlichvar@redhat.com>
Acked-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent cff8ba28
Loading
Loading
Loading
Loading
+44 −10
Original line number Diff line number Diff line
@@ -443,22 +443,52 @@ static int ixgbe_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
}

/**
 * ixgbe_ptp_gettime
 * ixgbe_ptp_gettimex
 * @ptp: the ptp clock structure
 * @ts: timespec structure to hold the current time value
 * @ts: timespec to hold the PHC timestamp
 * @sts: structure to hold the system time before and after reading the PHC
 *
 * read the timecounter and return the correct value on ns,
 * after converting it into a struct timespec.
 */
static int ixgbe_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
static int ixgbe_ptp_gettimex(struct ptp_clock_info *ptp,
			      struct timespec64 *ts,
			      struct ptp_system_timestamp *sts)
{
	struct ixgbe_adapter *adapter =
		container_of(ptp, struct ixgbe_adapter, ptp_caps);
	struct ixgbe_hw *hw = &adapter->hw;
	unsigned long flags;
	u64 ns;
	u64 ns, stamp;

	spin_lock_irqsave(&adapter->tmreg_lock, flags);
	ns = timecounter_read(&adapter->hw_tc);

	switch (adapter->hw.mac.type) {
	case ixgbe_mac_X550:
	case ixgbe_mac_X550EM_x:
	case ixgbe_mac_x550em_a:
		/* Upper 32 bits represent billions of cycles, lower 32 bits
		 * represent cycles. However, we use timespec64_to_ns for the
		 * correct math even though the units haven't been corrected
		 * yet.
		 */
		ptp_read_system_prets(sts);
		IXGBE_READ_REG(hw, IXGBE_SYSTIMR);
		ptp_read_system_postts(sts);
		ts->tv_nsec = IXGBE_READ_REG(hw, IXGBE_SYSTIML);
		ts->tv_sec = IXGBE_READ_REG(hw, IXGBE_SYSTIMH);
		stamp = timespec64_to_ns(ts);
		break;
	default:
		ptp_read_system_prets(sts);
		stamp = IXGBE_READ_REG(hw, IXGBE_SYSTIML);
		ptp_read_system_postts(sts);
		stamp |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIMH) << 32;
		break;
	}

	ns = timecounter_cyc2time(&adapter->hw_tc, stamp);

	spin_unlock_irqrestore(&adapter->tmreg_lock, flags);

	*ts = ns_to_timespec64(ns);
@@ -567,10 +597,14 @@ void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter)
{
	bool timeout = time_is_before_jiffies(adapter->last_overflow_check +
					     IXGBE_OVERFLOW_PERIOD);
	struct timespec64 ts;
	unsigned long flags;

	if (timeout) {
		ixgbe_ptp_gettime(&adapter->ptp_caps, &ts);
		/* Update the timecounter */
		spin_lock_irqsave(&adapter->tmreg_lock, flags);
		timecounter_read(&adapter->hw_tc);
		spin_unlock_irqrestore(&adapter->tmreg_lock, flags);

		adapter->last_overflow_check = jiffies;
	}
}
@@ -1216,7 +1250,7 @@ static long ixgbe_ptp_create_clock(struct ixgbe_adapter *adapter)
		adapter->ptp_caps.pps = 1;
		adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq_82599;
		adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime;
		adapter->ptp_caps.gettime64 = ixgbe_ptp_gettime;
		adapter->ptp_caps.gettimex64 = ixgbe_ptp_gettimex;
		adapter->ptp_caps.settime64 = ixgbe_ptp_settime;
		adapter->ptp_caps.enable = ixgbe_ptp_feature_enable;
		adapter->ptp_setup_sdp = ixgbe_ptp_setup_sdp_x540;
@@ -1233,7 +1267,7 @@ static long ixgbe_ptp_create_clock(struct ixgbe_adapter *adapter)
		adapter->ptp_caps.pps = 0;
		adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq_82599;
		adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime;
		adapter->ptp_caps.gettime64 = ixgbe_ptp_gettime;
		adapter->ptp_caps.gettimex64 = ixgbe_ptp_gettimex;
		adapter->ptp_caps.settime64 = ixgbe_ptp_settime;
		adapter->ptp_caps.enable = ixgbe_ptp_feature_enable;
		break;
@@ -1249,7 +1283,7 @@ static long ixgbe_ptp_create_clock(struct ixgbe_adapter *adapter)
		adapter->ptp_caps.pps = 0;
		adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq_X550;
		adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime;
		adapter->ptp_caps.gettime64 = ixgbe_ptp_gettime;
		adapter->ptp_caps.gettimex64 = ixgbe_ptp_gettimex;
		adapter->ptp_caps.settime64 = ixgbe_ptp_settime;
		adapter->ptp_caps.enable = ixgbe_ptp_feature_enable;
		adapter->ptp_setup_sdp = NULL;