Re: [PATCH v3 4/4] Enabling hardware supported PTP system/device crosstimestamping

2015-08-22 Thread Thomas Gleixner
On Fri, 21 Aug 2015, Christopher S. Hall wrote:
> From: Christopher Hall 
> 
> Add getsynctime() PTP device callback to cross timestamp system device
>   clock using ART translation depends on platform being >= SPT
>   and having ART
> 
> getsynctime() reads ART (TSC-derived)/device cross timestamp and
>   converts to realtime/device time reporting cross timestamp to
>   PTP driver

See patch 1/4
 
> index 25a0ad5..228f3f3 100644
> --- a/drivers/net/ethernet/intel/e1000e/ptp.c
> +++ b/drivers/net/ethernet/intel/e1000e/ptp.c
> @@ -25,6 +25,8 @@
>   */
>  
>  #include "e1000.h"
> +#include 
> +#include 

The usual way to order includes is:

#include 

#include 

#include "e1000.h"

> +/**
> + * e1000e_phc_getsynctime - Reads the current time from the hardware clock 
> and
> + * correlated system time
> + * @ptp: ptp clock structure
> + * @devts: timespec structure to hold the current device time value
> + * @systs: timespec structure to hold the current system time value
> + *
> + * Read device and system (ART) clock simultaneously and return the correct
> + * clock values in ns after converting into a struct timespec.
> + **/
> +static int e1000e_phc_getsynctime(struct ptp_clock_info *ptp,
> +   struct timespec64 *devts,
> +   struct timespec64 *systs)
> +{
> + struct e1000_adapter *adapter = container_of(ptp, struct e1000_adapter,
> +  ptp_clock_info);
> + unsigned long flags;
> + u32 remainder;
> + struct correlated_ts art_correlated_ts;
> + u64 device_time;
> + int ret;
> +
> + art_correlated_ts.get_ts = e1000e_phc_get_ts;
> + art_correlated_ts.private = adapter;
> + ret = get_correlated_timestamp(_correlated_ts,
> +_timestamper);

Pointless line break

> + if (ret != 0)
> + goto bail;

What's the purpose of this goto?

   if (ret)
return ret;

is completely sufficient.

> +
> + systs->tv_sec =
> + div_u64_rem(art_correlated_ts.system_real.tv64,
> + NSEC_PER_SEC, );
> + systs->tv_nsec = remainder;

ktime_to_timespec64() perhaps?

And please move that conversion to the ptp ioctl

> + spin_lock_irqsave(>systim_lock, flags);
> + device_time = timecounter_cyc2time(>tc,
> +art_correlated_ts.device_ts);



> + /* CPU must have ART and GBe must be from Sunrise Point or greater */
> + if (hw->mac.type < e1000_pch_spt || !cpu_has_art)
> + adapter->ptp_clock_info.getsynctime64 = NULL;

We do it the other way round. We leave the default NULL and update it
if we detect the feature.

Thanks,

tglx
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 4/4] Enabling hardware supported PTP system/device crosstimestamping

2015-08-22 Thread Thomas Gleixner
On Fri, 21 Aug 2015, Christopher S. Hall wrote:
 From: Christopher Hall christopher.s.h...@intel.com
 
 Add getsynctime() PTP device callback to cross timestamp system device
   clock using ART translation depends on platform being = SPT
   and having ART
 
 getsynctime() reads ART (TSC-derived)/device cross timestamp and
   converts to realtime/device time reporting cross timestamp to
   PTP driver

See patch 1/4
 
 index 25a0ad5..228f3f3 100644
 --- a/drivers/net/ethernet/intel/e1000e/ptp.c
 +++ b/drivers/net/ethernet/intel/e1000e/ptp.c
 @@ -25,6 +25,8 @@
   */
  
  #include e1000.h
 +#include asm/tsc.h
 +#include linux/timekeeping.h

The usual way to order includes is:

#include linux/timekeeping.h

#include asm/tsc.h

#include e1000.h

 +/**
 + * e1000e_phc_getsynctime - Reads the current time from the hardware clock 
 and
 + * correlated system time
 + * @ptp: ptp clock structure
 + * @devts: timespec structure to hold the current device time value
 + * @systs: timespec structure to hold the current system time value
 + *
 + * Read device and system (ART) clock simultaneously and return the correct
 + * clock values in ns after converting into a struct timespec.
 + **/
 +static int e1000e_phc_getsynctime(struct ptp_clock_info *ptp,
 +   struct timespec64 *devts,
 +   struct timespec64 *systs)
 +{
 + struct e1000_adapter *adapter = container_of(ptp, struct e1000_adapter,
 +  ptp_clock_info);
 + unsigned long flags;
 + u32 remainder;
 + struct correlated_ts art_correlated_ts;
 + u64 device_time;
 + int ret;
 +
 + art_correlated_ts.get_ts = e1000e_phc_get_ts;
 + art_correlated_ts.private = adapter;
 + ret = get_correlated_timestamp(art_correlated_ts,
 +art_timestamper);

Pointless line break

 + if (ret != 0)
 + goto bail;

What's the purpose of this goto?

   if (ret)
return ret;

is completely sufficient.

 +
 + systs-tv_sec =
 + div_u64_rem(art_correlated_ts.system_real.tv64,
 + NSEC_PER_SEC, remainder);
 + systs-tv_nsec = remainder;

ktime_to_timespec64() perhaps?

And please move that conversion to the ptp ioctl

 + spin_lock_irqsave(adapter-systim_lock, flags);
 + device_time = timecounter_cyc2time(adapter-tc,
 +art_correlated_ts.device_ts);



 + /* CPU must have ART and GBe must be from Sunrise Point or greater */
 + if (hw-mac.type  e1000_pch_spt || !cpu_has_art)
 + adapter-ptp_clock_info.getsynctime64 = NULL;

We do it the other way round. We leave the default NULL and update it
if we detect the feature.

Thanks,

tglx
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 4/4] Enabling hardware supported PTP system/device crosstimestamping

2015-08-21 Thread Christopher S. Hall
From: Christopher Hall 

Add getsynctime() PTP device callback to cross timestamp system device
clock using ART translation depends on platform being >= SPT
and having ART

getsynctime() reads ART (TSC-derived)/device cross timestamp and
converts to realtime/device time reporting cross timestamp to
PTP driver

Signed-off-by: Christopher S. Hall 
---
 drivers/net/ethernet/intel/e1000e/defines.h |  5 ++
 drivers/net/ethernet/intel/e1000e/ptp.c | 88 +
 drivers/net/ethernet/intel/e1000e/regs.h|  4 ++
 3 files changed, 97 insertions(+)

diff --git a/drivers/net/ethernet/intel/e1000e/defines.h 
b/drivers/net/ethernet/intel/e1000e/defines.h
index 133d407..13cff75 100644
--- a/drivers/net/ethernet/intel/e1000e/defines.h
+++ b/drivers/net/ethernet/intel/e1000e/defines.h
@@ -527,6 +527,11 @@
 #define E1000_RXCW_C  0x2000/* Receive config */
 #define E1000_RXCW_SYNCH  0x4000/* Receive config synch */
 
+/* HH Time Sync */
+#define E1000_TSYNCTXCTL_MAX_ALLOWED_DLY_MASK  0xF000 /* max delay */
+#define E1000_TSYNCTXCTL_SYNC_COMP 0x4000 /* sync complete */
+#define E1000_TSYNCTXCTL_START_SYNC0x8000 /* initiate sync */
+
 #define E1000_TSYNCTXCTL_VALID 0x0001 /* Tx timestamp valid */
 #define E1000_TSYNCTXCTL_ENABLED   0x0010 /* enable Tx timestamping */
 
diff --git a/drivers/net/ethernet/intel/e1000e/ptp.c 
b/drivers/net/ethernet/intel/e1000e/ptp.c
index 25a0ad5..228f3f3 100644
--- a/drivers/net/ethernet/intel/e1000e/ptp.c
+++ b/drivers/net/ethernet/intel/e1000e/ptp.c
@@ -25,6 +25,8 @@
  */
 
 #include "e1000.h"
+#include 
+#include 
 
 /**
  * e1000e_phc_adjfreq - adjust the frequency of the hardware clock
@@ -98,6 +100,87 @@ static int e1000e_phc_adjtime(struct ptp_clock_info *ptp, 
s64 delta)
return 0;
 }
 
+#define MAX_HW_WAIT_COUNT (3)
+
+static int e1000e_phc_get_ts(struct correlated_ts *cts)
+{
+   struct e1000_adapter *adapter = (struct e1000_adapter *)cts->private;
+   struct e1000_hw *hw = >hw;
+   int i;
+   u32 tsync_ctrl;
+   int ret;
+
+   tsync_ctrl = er32(TSYNCTXCTL);
+   tsync_ctrl |= E1000_TSYNCTXCTL_START_SYNC |
+   E1000_TSYNCTXCTL_MAX_ALLOWED_DLY_MASK;
+   ew32(TSYNCTXCTL, tsync_ctrl);
+   for (i = 0; i < MAX_HW_WAIT_COUNT; ++i) {
+   udelay(1);
+   tsync_ctrl = er32(TSYNCTXCTL);
+   if (tsync_ctrl & E1000_TSYNCTXCTL_SYNC_COMP)
+   break;
+   }
+
+   if (i == MAX_HW_WAIT_COUNT) {
+   ret = -ETIMEDOUT;
+   } else {
+   ret = 0;
+   cts->system_ts = er32(PLTSTMPH);
+   cts->system_ts <<= 32;
+   cts->system_ts |= er32(PLTSTMPL);
+   cts->device_ts = er32(SYSSTMPH);
+   cts->device_ts <<= 32;
+   cts->device_ts |= er32(SYSSTMPL);
+   }
+
+   return ret;
+}
+
+/**
+ * e1000e_phc_getsynctime - Reads the current time from the hardware clock and
+ * correlated system time
+ * @ptp: ptp clock structure
+ * @devts: timespec structure to hold the current device time value
+ * @systs: timespec structure to hold the current system time value
+ *
+ * Read device and system (ART) clock simultaneously and return the correct
+ * clock values in ns after converting into a struct timespec.
+ **/
+static int e1000e_phc_getsynctime(struct ptp_clock_info *ptp,
+ struct timespec64 *devts,
+ struct timespec64 *systs)
+{
+   struct e1000_adapter *adapter = container_of(ptp, struct e1000_adapter,
+ptp_clock_info);
+   unsigned long flags;
+   u32 remainder;
+   struct correlated_ts art_correlated_ts;
+   u64 device_time;
+   int ret;
+
+   art_correlated_ts.get_ts = e1000e_phc_get_ts;
+   art_correlated_ts.private = adapter;
+   ret = get_correlated_timestamp(_correlated_ts,
+  _timestamper);
+   if (ret != 0)
+   goto bail;
+
+   systs->tv_sec =
+   div_u64_rem(art_correlated_ts.system_real.tv64,
+   NSEC_PER_SEC, );
+   systs->tv_nsec = remainder;
+   spin_lock_irqsave(>systim_lock, flags);
+   device_time = timecounter_cyc2time(>tc,
+  art_correlated_ts.device_ts);
+   spin_unlock_irqrestore(>systim_lock, flags);
+   devts->tv_sec =
+   div_u64_rem(device_time, NSEC_PER_SEC, );
+   devts->tv_nsec = remainder;
+
+bail:
+   return ret;
+}
+
 /**
  * e1000e_phc_gettime - Reads the current time from the hardware clock
  * @ptp: ptp clock structure
@@ -190,6 +273,7 @@ static const struct ptp_clock_info e1000e_ptp_clock_info = {
.adjfreq= e1000e_phc_adjfreq,
.adjtime= e1000e_phc_adjtime,

[PATCH v3 4/4] Enabling hardware supported PTP system/device crosstimestamping

2015-08-21 Thread Christopher S. Hall
From: Christopher Hall christopher.s.h...@intel.com

Add getsynctime() PTP device callback to cross timestamp system device
clock using ART translation depends on platform being = SPT
and having ART

getsynctime() reads ART (TSC-derived)/device cross timestamp and
converts to realtime/device time reporting cross timestamp to
PTP driver

Signed-off-by: Christopher S. Hall christopher.s.h...@intel.com
---
 drivers/net/ethernet/intel/e1000e/defines.h |  5 ++
 drivers/net/ethernet/intel/e1000e/ptp.c | 88 +
 drivers/net/ethernet/intel/e1000e/regs.h|  4 ++
 3 files changed, 97 insertions(+)

diff --git a/drivers/net/ethernet/intel/e1000e/defines.h 
b/drivers/net/ethernet/intel/e1000e/defines.h
index 133d407..13cff75 100644
--- a/drivers/net/ethernet/intel/e1000e/defines.h
+++ b/drivers/net/ethernet/intel/e1000e/defines.h
@@ -527,6 +527,11 @@
 #define E1000_RXCW_C  0x2000/* Receive config */
 #define E1000_RXCW_SYNCH  0x4000/* Receive config synch */
 
+/* HH Time Sync */
+#define E1000_TSYNCTXCTL_MAX_ALLOWED_DLY_MASK  0xF000 /* max delay */
+#define E1000_TSYNCTXCTL_SYNC_COMP 0x4000 /* sync complete */
+#define E1000_TSYNCTXCTL_START_SYNC0x8000 /* initiate sync */
+
 #define E1000_TSYNCTXCTL_VALID 0x0001 /* Tx timestamp valid */
 #define E1000_TSYNCTXCTL_ENABLED   0x0010 /* enable Tx timestamping */
 
diff --git a/drivers/net/ethernet/intel/e1000e/ptp.c 
b/drivers/net/ethernet/intel/e1000e/ptp.c
index 25a0ad5..228f3f3 100644
--- a/drivers/net/ethernet/intel/e1000e/ptp.c
+++ b/drivers/net/ethernet/intel/e1000e/ptp.c
@@ -25,6 +25,8 @@
  */
 
 #include e1000.h
+#include asm/tsc.h
+#include linux/timekeeping.h
 
 /**
  * e1000e_phc_adjfreq - adjust the frequency of the hardware clock
@@ -98,6 +100,87 @@ static int e1000e_phc_adjtime(struct ptp_clock_info *ptp, 
s64 delta)
return 0;
 }
 
+#define MAX_HW_WAIT_COUNT (3)
+
+static int e1000e_phc_get_ts(struct correlated_ts *cts)
+{
+   struct e1000_adapter *adapter = (struct e1000_adapter *)cts-private;
+   struct e1000_hw *hw = adapter-hw;
+   int i;
+   u32 tsync_ctrl;
+   int ret;
+
+   tsync_ctrl = er32(TSYNCTXCTL);
+   tsync_ctrl |= E1000_TSYNCTXCTL_START_SYNC |
+   E1000_TSYNCTXCTL_MAX_ALLOWED_DLY_MASK;
+   ew32(TSYNCTXCTL, tsync_ctrl);
+   for (i = 0; i  MAX_HW_WAIT_COUNT; ++i) {
+   udelay(1);
+   tsync_ctrl = er32(TSYNCTXCTL);
+   if (tsync_ctrl  E1000_TSYNCTXCTL_SYNC_COMP)
+   break;
+   }
+
+   if (i == MAX_HW_WAIT_COUNT) {
+   ret = -ETIMEDOUT;
+   } else {
+   ret = 0;
+   cts-system_ts = er32(PLTSTMPH);
+   cts-system_ts = 32;
+   cts-system_ts |= er32(PLTSTMPL);
+   cts-device_ts = er32(SYSSTMPH);
+   cts-device_ts = 32;
+   cts-device_ts |= er32(SYSSTMPL);
+   }
+
+   return ret;
+}
+
+/**
+ * e1000e_phc_getsynctime - Reads the current time from the hardware clock and
+ * correlated system time
+ * @ptp: ptp clock structure
+ * @devts: timespec structure to hold the current device time value
+ * @systs: timespec structure to hold the current system time value
+ *
+ * Read device and system (ART) clock simultaneously and return the correct
+ * clock values in ns after converting into a struct timespec.
+ **/
+static int e1000e_phc_getsynctime(struct ptp_clock_info *ptp,
+ struct timespec64 *devts,
+ struct timespec64 *systs)
+{
+   struct e1000_adapter *adapter = container_of(ptp, struct e1000_adapter,
+ptp_clock_info);
+   unsigned long flags;
+   u32 remainder;
+   struct correlated_ts art_correlated_ts;
+   u64 device_time;
+   int ret;
+
+   art_correlated_ts.get_ts = e1000e_phc_get_ts;
+   art_correlated_ts.private = adapter;
+   ret = get_correlated_timestamp(art_correlated_ts,
+  art_timestamper);
+   if (ret != 0)
+   goto bail;
+
+   systs-tv_sec =
+   div_u64_rem(art_correlated_ts.system_real.tv64,
+   NSEC_PER_SEC, remainder);
+   systs-tv_nsec = remainder;
+   spin_lock_irqsave(adapter-systim_lock, flags);
+   device_time = timecounter_cyc2time(adapter-tc,
+  art_correlated_ts.device_ts);
+   spin_unlock_irqrestore(adapter-systim_lock, flags);
+   devts-tv_sec =
+   div_u64_rem(device_time, NSEC_PER_SEC, remainder);
+   devts-tv_nsec = remainder;
+
+bail:
+   return ret;
+}
+
 /**
  * e1000e_phc_gettime - Reads the current time from the hardware clock
  * @ptp: ptp clock structure
@@ -190,6 +273,7 @@ static const struct ptp_clock_info