linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH (net.git) 0/3] stmmac: fix PTP support
@ 2016-10-26  6:56 Giuseppe Cavallaro
  2016-10-26  6:56 ` [PATCH (net.git) 1/3] stmmac: update the PTP header file Giuseppe Cavallaro
                   ` (5 more replies)
  0 siblings, 6 replies; 14+ messages in thread
From: Giuseppe Cavallaro @ 2016-10-26  6:56 UTC (permalink / raw)
  To: netdev
  Cc: alexandre.torgue, rayagond, richardcochran, linux-kernel,
	seraphin.bonnaffe, Giuseppe Cavallaro

This subset of patches aim to fix the PTP support
for the stmmac and especially for 4.x chip series.
While setting PTP on an ST box with 4.00a Ethernet
core, the kernel panics due to a broken settings
of the descriptors. The patches review the
register configuration, the algo used for configuring
the protocol, the way to get the timestamp inside
the RX/TX descriptors and, in the end, the statistics
displayed by ethtool.

Giuseppe Cavallaro (3):
  stmmac: update the PTP header file
  stmmac: fix PTP support for GMAC4
  stmmac: fix PTP type ethtool stats

 drivers/net/ethernet/stmicro/stmmac/common.h       | 24 +++---
 drivers/net/ethernet/stmicro/stmmac/descs.h        | 20 +++--
 drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 95 ++++++++++++++++-----
 drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h |  4 +
 drivers/net/ethernet/stmicro/stmmac/enh_desc.c     | 28 ++++---
 drivers/net/ethernet/stmicro/stmmac/stmmac.h       |  1 +
 .../net/ethernet/stmicro/stmmac/stmmac_ethtool.c   | 19 +++--
 .../net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c  | 43 ++++++++--
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  | 97 +++++++++++-----------
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c   |  9 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h   | 72 ++++++++--------
 11 files changed, 260 insertions(+), 152 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH (net.git) 1/3] stmmac: update the PTP header file
  2016-10-26  6:56 [PATCH (net.git) 0/3] stmmac: fix PTP support Giuseppe Cavallaro
@ 2016-10-26  6:56 ` Giuseppe Cavallaro
  2016-10-26  6:56 ` [PATCH (net.git) 2/3] stmmac: fix PTP support for GMAC4 Giuseppe Cavallaro
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Giuseppe Cavallaro @ 2016-10-26  6:56 UTC (permalink / raw)
  To: netdev
  Cc: alexandre.torgue, rayagond, richardcochran, linux-kernel,
	seraphin.bonnaffe, Giuseppe Cavallaro

This patch is to update this file by using BIT macros, removing
not used defines and fixes some typos.

Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Cc: Alexandre TORGUE <alexandre.torgue@st.com>
Cc: Rayagond Kokatanur <rayagond@vayavyalabs.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h | 72 ++++++++++++------------
 1 file changed, 37 insertions(+), 35 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
index 4535df3..c06938c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
@@ -22,51 +22,53 @@
   Author: Rayagond Kokatanur <rayagond@vayavyalabs.com>
 ******************************************************************************/
 
-#ifndef __STMMAC_PTP_H__
-#define __STMMAC_PTP_H__
+#ifndef	__STMMAC_PTP_H__
+#define	__STMMAC_PTP_H__
 
-/* IEEE 1588 PTP register offsets */
-#define PTP_TCR		0x0700	/* Timestamp Control Reg */
-#define PTP_SSIR	0x0704	/* Sub-Second Increment Reg */
-#define PTP_STSR	0x0708	/* System Time – Seconds Regr */
-#define PTP_STNSR	0x070C	/* System Time – Nanoseconds Reg */
-#define PTP_STSUR	0x0710	/* System Time – Seconds Update Reg */
-#define PTP_STNSUR	0x0714	/* System Time – Nanoseconds Update Reg */
-#define PTP_TAR		0x0718	/* Timestamp Addend Reg */
-#define PTP_TTSR	0x071C	/* Target Time Seconds Reg */
-#define PTP_TTNSR	0x0720	/* Target Time Nanoseconds Reg */
-#define	PTP_STHWSR	0x0724	/* System Time - Higher Word Seconds Reg */
-#define PTP_TSR		0x0728	/* Timestamp Status */
+#define	PTP_GMAC4_OFFSET	0xb00
+#define	PTP_GMAC3_X_OFFSET	0x700
 
-#define PTP_STNSUR_ADDSUB_SHIFT 31
+/* IEEE 1588 PTP register offsets */
+#define	PTP_TCR		0x00	/* Timestamp Control Reg */
+#define	PTP_SSIR	0x04	/* Sub-Second Increment Reg */
+#define	PTP_STSR	0x08	/* System Time – Seconds Regr */
+#define	PTP_STNSR	0x0c	/* System Time – Nanoseconds Reg */
+#define	PTP_STSUR	0x10	/* System Time – Seconds Update Reg */
+#define	PTP_STNSUR	0x14	/* System Time – Nanoseconds Update Reg */
+#define	PTP_TAR		0x18	/* Timestamp Addend Reg */
 
-/* PTP TCR defines */
-#define PTP_TCR_TSENA		0x00000001 /* Timestamp Enable */
-#define PTP_TCR_TSCFUPDT	0x00000002 /* Timestamp Fine/Coarse Update */
-#define PTP_TCR_TSINIT		0x00000004 /* Timestamp Initialize */
-#define PTP_TCR_TSUPDT		0x00000008 /* Timestamp Update */
-/* Timestamp Interrupt Trigger Enable */
-#define PTP_TCR_TSTRIG		0x00000010
-#define PTP_TCR_TSADDREG	0x00000020 /* Addend Reg Update */
-#define PTP_TCR_TSENALL		0x00000100 /* Enable Timestamp for All Frames */
-/* Timestamp Digital or Binary Rollover Control */
-#define PTP_TCR_TSCTRLSSR	0x00000200
+#define	PTP_STNSUR_ADDSUB_SHIFT	31
+#define	PTP_DIGITAL_ROLLOVER_MODE	0x3B9ACA00	/* 10e9-1 ns */
+#define	PTP_BINARY_ROLLOVER_MODE	0x80000000	/* ~0.466 ns */
 
+/* PTP Timestamp control register defines */
+#define	PTP_TCR_TSENA		BIT(0)	/* Timestamp Enable */
+#define	PTP_TCR_TSCFUPDT	BIT(1)	/* Timestamp Fine/Coarse Update */
+#define	PTP_TCR_TSINIT		BIT(2)	/* Timestamp Initialize */
+#define	PTP_TCR_TSUPDT		BIT(3)	/* Timestamp Update */
+#define	PTP_TCR_TSTRIG		BIT(4)	/* Timestamp Interrupt Trigger Enable */
+#define	PTP_TCR_TSADDREG	BIT(5)	/* Addend Reg Update */
+#define	PTP_TCR_TSENALL		BIT(8)	/* Enable Timestamp for All Frames */
+#define	PTP_TCR_TSCTRLSSR	BIT(9)	/* Digital or Binary Rollover Control */
 /* Enable PTP packet Processing for Version 2 Format */
-#define PTP_TCR_TSVER2ENA	0x00000400
+#define	PTP_TCR_TSVER2ENA	BIT(10)
 /* Enable Processing of PTP over Ethernet Frames */
-#define PTP_TCR_TSIPENA		0x00000800
+#define	PTP_TCR_TSIPENA		BIT(11)
 /* Enable Processing of PTP Frames Sent over IPv6-UDP */
-#define PTP_TCR_TSIPV6ENA	0x00001000
+#define	PTP_TCR_TSIPV6ENA	BIT(12)
 /* Enable Processing of PTP Frames Sent over IPv4-UDP */
-#define PTP_TCR_TSIPV4ENA	0x00002000
+#define	PTP_TCR_TSIPV4ENA	BIT(13)
 /* Enable Timestamp Snapshot for Event Messages */
-#define PTP_TCR_TSEVNTENA	0x00004000
+#define	PTP_TCR_TSEVNTENA	BIT(14)
 /* Enable Snapshot for Messages Relevant to Master */
-#define PTP_TCR_TSMSTRENA	0x00008000
+#define	PTP_TCR_TSMSTRENA	BIT(15)
 /* Select PTP packets for Taking Snapshots */
-#define PTP_TCR_SNAPTYPSEL_1	0x00010000
+#define	PTP_TCR_SNAPTYPSEL_1	GENMASK(17, 16)
 /* Enable MAC address for PTP Frame Filtering */
-#define PTP_TCR_TSENMACADDR	0x00040000
+#define	PTP_TCR_TSENMACADDR	BIT(18)
+
+/* SSIR defines */
+#define	PTP_SSIR_SSINC_MASK		0xff
+#define	GMAC4_PTP_SSIR_SSINC_SHIFT	16
 
-#endif /* __STMMAC_PTP_H__ */
+#endif	/* __STMMAC_PTP_H__ */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH (net.git) 2/3] stmmac: fix PTP support for GMAC4
  2016-10-26  6:56 [PATCH (net.git) 0/3] stmmac: fix PTP support Giuseppe Cavallaro
  2016-10-26  6:56 ` [PATCH (net.git) 1/3] stmmac: update the PTP header file Giuseppe Cavallaro
@ 2016-10-26  6:56 ` Giuseppe Cavallaro
  2016-10-27 10:25   ` Rayagond Kokatanur
  2016-10-26  6:56 ` [PATCH (net.git) 3/3] stmmac: fix PTP type ethtool stats Giuseppe Cavallaro
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Giuseppe Cavallaro @ 2016-10-26  6:56 UTC (permalink / raw)
  To: netdev
  Cc: alexandre.torgue, rayagond, richardcochran, linux-kernel,
	seraphin.bonnaffe, Giuseppe Cavallaro

Due to bad management of the descriptors, when use ptp4l,
kernel panics as shown below:
-----------------------------------------------------------
 Unable to handle kernel NULL pointer dereference at virtual
 address 000001ac
 ...
 Internal error: Oops: 17 [#1] SMP ARM
 ...
 Hardware name: STi SoC with Flattened Device Tree
 task: c0c05e80 task.stack: c0c00000
 PC is at dwmac4_wrback_get_tx_timestamp_status+0x0/0xc
 LR is at stmmac_tx_clean+0x2f8/0x4d4
-----------------------------------------------------------

In case of GMAC4 the extended descriptor pointers were
used for getting the timestamp. These are NULL for this HW,
and the normal ones must be used.

The PTP also had problems on this chip due to the bad
register management and issues on the algo adopted to
setup the PTP and getting the timestamp values from the
descriptors.

Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Cc: Alexandre TORGUE <alexandre.torgue@st.com>
Cc: Rayagond Kokatanur <rayagond@vayavyalabs.com>
---
 drivers/net/ethernet/stmicro/stmmac/common.h       |  5 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 68 ++++++++++++---
 drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h |  4 +
 drivers/net/ethernet/stmicro/stmmac/stmmac.h       |  1 +
 .../net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c  | 43 ++++++++--
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  | 97 +++++++++++-----------
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c   |  9 +-
 7 files changed, 154 insertions(+), 73 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index d3292c4..6fc214c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -482,11 +482,12 @@ struct stmmac_ops {
 /* PTP and HW Timer helpers */
 struct stmmac_hwtimestamp {
 	void (*config_hw_tstamping) (void __iomem *ioaddr, u32 data);
-	u32 (*config_sub_second_increment) (void __iomem *ioaddr, u32 clk_rate);
+	u32 (*config_sub_second_increment)(void __iomem *ioaddr, u32 ptp_clock,
+					   int gmac4);
 	int (*init_systime) (void __iomem *ioaddr, u32 sec, u32 nsec);
 	int (*config_addend) (void __iomem *ioaddr, u32 addend);
 	int (*adjust_systime) (void __iomem *ioaddr, u32 sec, u32 nsec,
-			       int add_sub);
+			       int add_sub, int gmac4);
 	 u64(*get_systime) (void __iomem *ioaddr);
 };
 
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
index a1b17cd..2ef2f0c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
@@ -204,14 +204,18 @@ static void dwmac4_rd_enable_tx_timestamp(struct dma_desc *p)
 
 static int dwmac4_wrback_get_tx_timestamp_status(struct dma_desc *p)
 {
-	return (p->des3 & TDES3_TIMESTAMP_STATUS)
-		>> TDES3_TIMESTAMP_STATUS_SHIFT;
+	/* Context type from W/B descriptor must be zero */
+	if (p->des3 & TDES3_CONTEXT_TYPE)
+		return -EINVAL;
+
+	/* Tx Timestamp Status is 1 so des0 and des1'll have valid values */
+	if (p->des3 & TDES3_TIMESTAMP_STATUS)
+		return 0;
+
+	return 1;
 }
 
-/*  NOTE: For RX CTX bit has to be checked before
- *  HAVE a specific function for TX and another one for RX
- */
-static u64 dwmac4_wrback_get_timestamp(void *desc, u32 ats)
+static inline u64 dwmac4_get_timestamp(void *desc, u32 ats)
 {
 	struct dma_desc *p = (struct dma_desc *)desc;
 	u64 ns;
@@ -223,12 +227,54 @@ static u64 dwmac4_wrback_get_timestamp(void *desc, u32 ats)
 	return ns;
 }
 
-static int dwmac4_context_get_rx_timestamp_status(void *desc, u32 ats)
+static int dwmac4_rx_check_timestamp(void *desc)
+{
+	struct dma_desc *p = (struct dma_desc *)desc;
+	u32 own, ctxt;
+	int ret = 1;
+
+	own = p->des3 & RDES3_OWN;
+	ctxt = ((p->des3 & RDES3_CONTEXT_DESCRIPTOR)
+		>> RDES3_CONTEXT_DESCRIPTOR_SHIFT);
+
+	if (likely(!own && ctxt)) {
+		if ((p->des0 == 0xffffffff) && (p->des1 == 0xffffffff))
+			/* Corrupted value */
+			ret = -EINVAL;
+		else
+			/* A valid Timestamp is ready to be read */
+			ret = 0;
+	}
+
+	/* Timestamp not ready */
+	return ret;
+}
+
+static int dwmac4_wrback_get_rx_timestamp_status(void *desc, u32 ats)
 {
 	struct dma_desc *p = (struct dma_desc *)desc;
+	int ret = -EINVAL;
+
+	/* Get the status from normal w/b descriptor */
+	if (likely(p->des3 & TDES3_RS1V)) {
+		if (likely(p->des1 & RDES1_TIMESTAMP_AVAILABLE)) {
+			int i = 0;
+
+			/* Check if timestamp is OK from context descriptor */
+			do {
+				ret = dwmac4_rx_check_timestamp(desc);
+				if (ret < 0)
+					goto exit;
+				i++;
 
-	return (p->des1 & RDES1_TIMESTAMP_AVAILABLE)
-		>> RDES1_TIMESTAMP_AVAILABLE_SHIFT;
+			} while ((ret == 1) || (i < 10));
+
+			if (i == 10)
+				ret = -EBUSY;
+		}
+	}
+exit:
+	return ret;
 }
 
 static void dwmac4_rd_init_rx_desc(struct dma_desc *p, int disable_rx_ic,
@@ -373,8 +419,8 @@ const struct stmmac_desc_ops dwmac4_desc_ops = {
 	.get_rx_frame_len = dwmac4_wrback_get_rx_frame_len,
 	.enable_tx_timestamp = dwmac4_rd_enable_tx_timestamp,
 	.get_tx_timestamp_status = dwmac4_wrback_get_tx_timestamp_status,
-	.get_timestamp = dwmac4_wrback_get_timestamp,
-	.get_rx_timestamp_status = dwmac4_context_get_rx_timestamp_status,
+	.get_rx_timestamp_status = dwmac4_wrback_get_rx_timestamp_status,
+	.get_timestamp = dwmac4_get_timestamp,
 	.set_tx_ic = dwmac4_rd_set_tx_ic,
 	.prepare_tx_desc = dwmac4_rd_prepare_tx_desc,
 	.prepare_tso_tx_desc = dwmac4_rd_prepare_tso_tx_desc,
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h
index 0902a2e..9736c50 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h
@@ -59,10 +59,13 @@
 #define TDES3_CTXT_TCMSSV		BIT(26)
 
 /* TDES3 Common */
+#define	TDES3_RS1V			BIT(26)
+#define	TDES3_RS1V_SHIFT		26
 #define TDES3_LAST_DESCRIPTOR		BIT(28)
 #define TDES3_LAST_DESCRIPTOR_SHIFT	28
 #define TDES3_FIRST_DESCRIPTOR		BIT(29)
 #define TDES3_CONTEXT_TYPE		BIT(30)
+#define	TDES3_CONTEXT_TYPE_SHIFT	30
 
 /* TDS3 use for both format (read and write back) */
 #define TDES3_OWN			BIT(31)
@@ -117,6 +120,7 @@
 #define RDES3_LAST_DESCRIPTOR		BIT(28)
 #define RDES3_FIRST_DESCRIPTOR		BIT(29)
 #define RDES3_CONTEXT_DESCRIPTOR	BIT(30)
+#define RDES3_CONTEXT_DESCRIPTOR_SHIFT	30
 
 /* RDES3 (read format) */
 #define RDES3_BUFFER1_VALID_ADDR	BIT(24)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index b15fc55..4d2a759 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -129,6 +129,7 @@ struct stmmac_priv {
 	int irq_wake;
 	spinlock_t ptp_lock;
 	void __iomem *mmcaddr;
+	void __iomem *ptpaddr;
 	u32 rx_tail_addr;
 	u32 tx_tail_addr;
 	u32 mss;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
index a77f689..10d6059 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
@@ -34,21 +34,29 @@ static void stmmac_config_hw_tstamping(void __iomem *ioaddr, u32 data)
 }
 
 static u32 stmmac_config_sub_second_increment(void __iomem *ioaddr,
-					      u32 ptp_clock)
+					      u32 ptp_clock, int gmac4)
 {
 	u32 value = readl(ioaddr + PTP_TCR);
 	unsigned long data;
 
-	/* Convert the ptp_clock to nano second
-	 * formula = (2/ptp_clock) * 1000000000
-	 * where, ptp_clock = 50MHz.
+	/* For GMAC3.x, 4.x versions, convert the ptp_clock to nano second
+	 *	formula = (1/ptp_clock) * 1000000000
+	 * where ptp_clock is 50MHz if fine method is used to update system
 	 */
-	data = (2000000000ULL / ptp_clock);
+	if (value & PTP_TCR_TSCFUPDT)
+		data = (1000000000ULL / 50000000);
+	else
+		data = (1000000000ULL / ptp_clock);
 
 	/* 0.465ns accuracy */
 	if (!(value & PTP_TCR_TSCTRLSSR))
 		data = (data * 1000) / 465;
 
+	data &= PTP_SSIR_SSINC_MASK;
+
+	if (gmac4)
+		data = data << GMAC4_PTP_SSIR_SSINC_SHIFT;
+
 	writel(data, ioaddr + PTP_SSIR);
 
 	return data;
@@ -104,14 +112,30 @@ static int stmmac_config_addend(void __iomem *ioaddr, u32 addend)
 }
 
 static int stmmac_adjust_systime(void __iomem *ioaddr, u32 sec, u32 nsec,
-				 int add_sub)
+				 int add_sub, int gmac4)
 {
 	u32 value;
 	int limit;
 
+	if (add_sub) {
+		/* If the new sec value needs to be subtracted with
+		 * the system time, then MAC_STSUR reg should be
+		 * programmed with (2^32 – <new_sec_value>)
+		 */
+		if (gmac4)
+			sec = (100000000ULL - sec);
+
+		value = readl(ioaddr + PTP_TCR);
+		if (value & PTP_TCR_TSCTRLSSR)
+			nsec = (PTP_DIGITAL_ROLLOVER_MODE - nsec);
+		else
+			nsec = (PTP_BINARY_ROLLOVER_MODE - nsec);
+	}
+
 	writel(sec, ioaddr + PTP_STSUR);
-	writel(((add_sub << PTP_STNSUR_ADDSUB_SHIFT) | nsec),
-		ioaddr + PTP_STNSUR);
+	value = (add_sub << PTP_STNSUR_ADDSUB_SHIFT) | nsec;
+	writel(value, ioaddr + PTP_STNSUR);
+
 	/* issue command to initialize the system time value */
 	value = readl(ioaddr + PTP_TCR);
 	value |= PTP_TCR_TSUPDT;
@@ -134,8 +158,9 @@ static u64 stmmac_get_systime(void __iomem *ioaddr)
 {
 	u64 ns;
 
+	/* Get the TSSS value */
 	ns = readl(ioaddr + PTP_STNSR);
-	/* convert sec time value to nanosecond */
+	/* Get the TSS and convert sec time value to nanosecond */
 	ns += readl(ioaddr + PTP_STSR) * 1000000000ULL;
 
 	return ns;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 48e71fa..2e228d5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -340,18 +340,17 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
 
 /* stmmac_get_tx_hwtstamp - get HW TX timestamps
  * @priv: driver private structure
- * @entry : descriptor index to be used.
+ * @p : descriptor pointer
  * @skb : the socket buffer
  * Description :
  * This function will read timestamp from the descriptor & pass it to stack.
  * and also perform some sanity checks.
  */
 static void stmmac_get_tx_hwtstamp(struct stmmac_priv *priv,
-				   unsigned int entry, struct sk_buff *skb)
+				   struct dma_desc *p, struct sk_buff *skb)
 {
 	struct skb_shared_hwtstamps shhwtstamp;
 	u64 ns;
-	void *desc = NULL;
 
 	if (!priv->hwts_tx_en)
 		return;
@@ -360,58 +359,55 @@ static void stmmac_get_tx_hwtstamp(struct stmmac_priv *priv,
 	if (likely(!skb || !(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)))
 		return;
 
-	if (priv->adv_ts)
-		desc = (priv->dma_etx + entry);
-	else
-		desc = (priv->dma_tx + entry);
-
 	/* check tx tstamp status */
-	if (!priv->hw->desc->get_tx_timestamp_status((struct dma_desc *)desc))
-		return;
+	if (!priv->hw->desc->get_tx_timestamp_status(p)) {
+		/* get the valid tstamp */
+		ns = priv->hw->desc->get_timestamp(p, priv->adv_ts);
 
-	/* get the valid tstamp */
-	ns = priv->hw->desc->get_timestamp(desc, priv->adv_ts);
+		memset(&shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps));
+		shhwtstamp.hwtstamp = ns_to_ktime(ns);
 
-	memset(&shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps));
-	shhwtstamp.hwtstamp = ns_to_ktime(ns);
-	/* pass tstamp to stack */
-	skb_tstamp_tx(skb, &shhwtstamp);
+		netdev_info(priv->dev, "get valid TX hw timestamp %llu\n", ns);
+		/* pass tstamp to stack */
+		skb_tstamp_tx(skb, &shhwtstamp);
+	}
 
 	return;
 }
 
 /* stmmac_get_rx_hwtstamp - get HW RX timestamps
  * @priv: driver private structure
- * @entry : descriptor index to be used.
+ * @p : descriptor pointer
+ * @np : next descriptor pointer
  * @skb : the socket buffer
  * Description :
  * This function will read received packet's timestamp from the descriptor
  * and pass it to stack. It also perform some sanity checks.
  */
-static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv,
-				   unsigned int entry, struct sk_buff *skb)
+static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, struct dma_desc *p,
+				   struct dma_desc *np, struct sk_buff *skb)
 {
 	struct skb_shared_hwtstamps *shhwtstamp = NULL;
 	u64 ns;
-	void *desc = NULL;
 
 	if (!priv->hwts_rx_en)
 		return;
 
-	if (priv->adv_ts)
-		desc = (priv->dma_erx + entry);
-	else
-		desc = (priv->dma_rx + entry);
-
-	/* exit if rx tstamp is not valid */
-	if (!priv->hw->desc->get_rx_timestamp_status(desc, priv->adv_ts))
-		return;
+	/* Check if timestamp is available */
+	if (!priv->hw->desc->get_rx_timestamp_status(p, priv->adv_ts)) {
+		/* For GMAC4, the valid timestamp is from CTX next desc. */
+		if (priv->plat->has_gmac4)
+			ns = priv->hw->desc->get_timestamp(np, priv->adv_ts);
+		else
+			ns = priv->hw->desc->get_timestamp(p, priv->adv_ts);
 
-	/* get valid tstamp */
-	ns = priv->hw->desc->get_timestamp(desc, priv->adv_ts);
-	shhwtstamp = skb_hwtstamps(skb);
-	memset(shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps));
-	shhwtstamp->hwtstamp = ns_to_ktime(ns);
+		netdev_info(priv->dev, "get valid RX hw timestamp %llu\n", ns);
+		shhwtstamp = skb_hwtstamps(skb);
+		memset(shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps));
+		shhwtstamp->hwtstamp = ns_to_ktime(ns);
+	} else  {
+		netdev_err(priv->dev, "cannot get RX hw timestamp\n");
+	}
 }
 
 /**
@@ -598,17 +594,18 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
 	priv->hwts_tx_en = config.tx_type == HWTSTAMP_TX_ON;
 
 	if (!priv->hwts_tx_en && !priv->hwts_rx_en)
-		priv->hw->ptp->config_hw_tstamping(priv->ioaddr, 0);
+		priv->hw->ptp->config_hw_tstamping(priv->ptpaddr, 0);
 	else {
 		value = (PTP_TCR_TSENA | PTP_TCR_TSCFUPDT | PTP_TCR_TSCTRLSSR |
 			 tstamp_all | ptp_v2 | ptp_over_ethernet |
 			 ptp_over_ipv6_udp | ptp_over_ipv4_udp | ts_event_en |
 			 ts_master_en | snap_type_sel);
-		priv->hw->ptp->config_hw_tstamping(priv->ioaddr, value);
+		priv->hw->ptp->config_hw_tstamping(priv->ptpaddr, value);
 
 		/* program Sub Second Increment reg */
 		sec_inc = priv->hw->ptp->config_sub_second_increment(
-			priv->ioaddr, priv->clk_ptp_rate);
+			priv->ptpaddr, priv->clk_ptp_rate,
+			priv->plat->has_gmac4);
 		temp = div_u64(1000000000ULL, sec_inc);
 
 		/* calculate default added value:
@@ -618,14 +615,14 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
 		 */
 		temp = (u64)(temp << 32);
 		priv->default_addend = div_u64(temp, priv->clk_ptp_rate);
-		priv->hw->ptp->config_addend(priv->ioaddr,
+		priv->hw->ptp->config_addend(priv->ptpaddr,
 					     priv->default_addend);
 
 		/* initialize system time */
 		ktime_get_real_ts64(&now);
 
 		/* lower 32 bits of tv_sec are safe until y2106 */
-		priv->hw->ptp->init_systime(priv->ioaddr, (u32)now.tv_sec,
+		priv->hw->ptp->init_systime(priv->ptpaddr, (u32)now.tv_sec,
 					    now.tv_nsec);
 	}
 
@@ -1333,7 +1330,7 @@ static void stmmac_tx_clean(struct stmmac_priv *priv)
 				priv->dev->stats.tx_packets++;
 				priv->xstats.tx_pkt_n++;
 			}
-			stmmac_get_tx_hwtstamp(priv, entry, skb);
+			stmmac_get_tx_hwtstamp(priv, p, skb);
 		}
 
 		if (likely(priv->tx_skbuff_dma[entry].buf)) {
@@ -1479,10 +1476,13 @@ static void stmmac_mmc_setup(struct stmmac_priv *priv)
 	unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET |
 			    MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET;
 
-	if (priv->synopsys_id >= DWMAC_CORE_4_00)
+	if (priv->synopsys_id >= DWMAC_CORE_4_00) {
+		priv->ptpaddr = priv->ioaddr + PTP_GMAC4_OFFSET;
 		priv->mmcaddr = priv->ioaddr + MMC_GMAC4_OFFSET;
-	else
+	} else {
+		priv->ptpaddr = priv->ioaddr + PTP_GMAC3_X_OFFSET;
 		priv->mmcaddr = priv->ioaddr + MMC_GMAC3_X_OFFSET;
+	}
 
 	dwmac_mmc_intr_all_mask(priv->mmcaddr);
 
@@ -2477,7 +2477,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
 	if (netif_msg_rx_status(priv)) {
 		void *rx_head;
 
-		pr_debug("%s: descriptor ring:\n", __func__);
+		pr_info(">>>>>> %s: descriptor ring:\n", __func__);
 		if (priv->extend_desc)
 			rx_head = (void *)priv->dma_erx;
 		else
@@ -2488,6 +2488,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
 	while (count < limit) {
 		int status;
 		struct dma_desc *p;
+		struct dma_desc *np;
 
 		if (priv->extend_desc)
 			p = (struct dma_desc *)(priv->dma_erx + entry);
@@ -2507,9 +2508,11 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
 		next_entry = priv->cur_rx;
 
 		if (priv->extend_desc)
-			prefetch(priv->dma_erx + next_entry);
+			np = (struct dma_desc *)(priv->dma_erx + next_entry);
 		else
-			prefetch(priv->dma_rx + next_entry);
+			np = priv->dma_rx + next_entry;
+
+		prefetch(np);
 
 		if ((priv->extend_desc) && (priv->hw->desc->rx_extended_status))
 			priv->hw->desc->rx_extended_status(&priv->dev->stats,
@@ -2561,7 +2564,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
 				frame_len -= ETH_FCS_LEN;
 
 			if (netif_msg_rx_status(priv)) {
-				pr_debug("\tdesc: %p [entry %d] buff=0x%x\n",
+				pr_info("\tdesc: %p [entry %d] buff=0x%x\n",
 					p, entry, des);
 				if (frame_len > ETH_FRAME_LEN)
 					pr_debug("\tframe size %d, COE: %d\n",
@@ -2618,13 +2621,13 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
 						 DMA_FROM_DEVICE);
 			}
 
-			stmmac_get_rx_hwtstamp(priv, entry, skb);
-
 			if (netif_msg_pktdata(priv)) {
 				pr_debug("frame received (%dbytes)", frame_len);
 				print_pkt(skb->data, frame_len);
 			}
 
+			stmmac_get_rx_hwtstamp(priv, p, np, skb);
+
 			stmmac_rx_vlan(priv->dev, skb);
 
 			skb->protocol = eth_type_trans(skb, priv->dev);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
index 1477471..3eb281d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
@@ -54,7 +54,7 @@ static int stmmac_adjust_freq(struct ptp_clock_info *ptp, s32 ppb)
 
 	spin_lock_irqsave(&priv->ptp_lock, flags);
 
-	priv->hw->ptp->config_addend(priv->ioaddr, addend);
+	priv->hw->ptp->config_addend(priv->ptpaddr, addend);
 
 	spin_unlock_irqrestore(&priv->ptp_lock, flags);
 
@@ -89,7 +89,8 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 delta)
 
 	spin_lock_irqsave(&priv->ptp_lock, flags);
 
-	priv->hw->ptp->adjust_systime(priv->ioaddr, sec, nsec, neg_adj);
+	priv->hw->ptp->adjust_systime(priv->ptpaddr, sec, nsec, neg_adj,
+				      priv->plat->has_gmac4);
 
 	spin_unlock_irqrestore(&priv->ptp_lock, flags);
 
@@ -114,7 +115,7 @@ static int stmmac_get_time(struct ptp_clock_info *ptp, struct timespec64 *ts)
 
 	spin_lock_irqsave(&priv->ptp_lock, flags);
 
-	ns = priv->hw->ptp->get_systime(priv->ioaddr);
+	ns = priv->hw->ptp->get_systime(priv->ptpaddr);
 
 	spin_unlock_irqrestore(&priv->ptp_lock, flags);
 
@@ -141,7 +142,7 @@ static int stmmac_set_time(struct ptp_clock_info *ptp,
 
 	spin_lock_irqsave(&priv->ptp_lock, flags);
 
-	priv->hw->ptp->init_systime(priv->ioaddr, ts->tv_sec, ts->tv_nsec);
+	priv->hw->ptp->init_systime(priv->ptpaddr, ts->tv_sec, ts->tv_nsec);
 
 	spin_unlock_irqrestore(&priv->ptp_lock, flags);
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH (net.git) 3/3] stmmac: fix PTP type ethtool stats
  2016-10-26  6:56 [PATCH (net.git) 0/3] stmmac: fix PTP support Giuseppe Cavallaro
  2016-10-26  6:56 ` [PATCH (net.git) 1/3] stmmac: update the PTP header file Giuseppe Cavallaro
  2016-10-26  6:56 ` [PATCH (net.git) 2/3] stmmac: fix PTP support for GMAC4 Giuseppe Cavallaro
@ 2016-10-26  6:56 ` Giuseppe Cavallaro
  2016-10-26  7:29 ` [PATCH (net.git) 0/3] stmmac: fix PTP support Alexandre Torgue
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Giuseppe Cavallaro @ 2016-10-26  6:56 UTC (permalink / raw)
  To: netdev
  Cc: alexandre.torgue, rayagond, richardcochran, linux-kernel,
	seraphin.bonnaffe, Giuseppe Cavallaro

This patch fixes the ethtool stats for PTP frames; previous
version does not take care about some message types: i.e.
announce, management and signaling. It also provided a
broken statistic in case of "No PTP message received".

Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Cc: Alexandre TORGUE <alexandre.torgue@st.com>
Cc: Rayagond Kokatanur <rayagond@vayavyalabs.com>
---
 drivers/net/ethernet/stmicro/stmmac/common.h       | 19 ++++++++-------
 drivers/net/ethernet/stmicro/stmmac/descs.h        | 20 +++++++++-------
 drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 27 +++++++++++++--------
 drivers/net/ethernet/stmicro/stmmac/enh_desc.c     | 28 ++++++++++++++--------
 .../net/ethernet/stmicro/stmmac/stmmac_ethtool.c   | 19 ++++++++-------
 5 files changed, 69 insertions(+), 44 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 6fc214c..6d2de4e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -120,14 +120,17 @@ struct stmmac_extra_stats {
 	unsigned long ip_csum_bypassed;
 	unsigned long ipv4_pkt_rcvd;
 	unsigned long ipv6_pkt_rcvd;
-	unsigned long rx_msg_type_ext_no_ptp;
-	unsigned long rx_msg_type_sync;
-	unsigned long rx_msg_type_follow_up;
-	unsigned long rx_msg_type_delay_req;
-	unsigned long rx_msg_type_delay_resp;
-	unsigned long rx_msg_type_pdelay_req;
-	unsigned long rx_msg_type_pdelay_resp;
-	unsigned long rx_msg_type_pdelay_follow_up;
+	unsigned long no_ptp_rx_msg_type_ext;
+	unsigned long ptp_rx_msg_type_sync;
+	unsigned long ptp_rx_msg_type_follow_up;
+	unsigned long ptp_rx_msg_type_delay_req;
+	unsigned long ptp_rx_msg_type_delay_resp;
+	unsigned long ptp_rx_msg_type_pdelay_req;
+	unsigned long ptp_rx_msg_type_pdelay_resp;
+	unsigned long ptp_rx_msg_type_pdelay_follow_up;
+	unsigned long ptp_rx_msg_type_announce;
+	unsigned long ptp_rx_msg_type_management;
+	unsigned long ptp_rx_msg_pkt_reserved_type;
 	unsigned long ptp_frame_type;
 	unsigned long ptp_ver;
 	unsigned long timestamp_dropped;
diff --git a/drivers/net/ethernet/stmicro/stmmac/descs.h b/drivers/net/ethernet/stmicro/stmmac/descs.h
index 2e4c171..e3c86d4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/descs.h
+++ b/drivers/net/ethernet/stmicro/stmmac/descs.h
@@ -155,14 +155,18 @@
 #define	ERDES4_L3_L4_FILT_NO_MATCH_MASK	GENMASK(27, 26)
 
 /* Extended RDES4 message type definitions */
-#define RDES_EXT_NO_PTP			0
-#define RDES_EXT_SYNC			1
-#define RDES_EXT_FOLLOW_UP		2
-#define RDES_EXT_DELAY_REQ		3
-#define RDES_EXT_DELAY_RESP		4
-#define RDES_EXT_PDELAY_REQ		5
-#define RDES_EXT_PDELAY_RESP		6
-#define RDES_EXT_PDELAY_FOLLOW_UP	7
+#define RDES_EXT_NO_PTP			0x0
+#define RDES_EXT_SYNC			0x1
+#define RDES_EXT_FOLLOW_UP		0x2
+#define RDES_EXT_DELAY_REQ		0x3
+#define RDES_EXT_DELAY_RESP		0x4
+#define RDES_EXT_PDELAY_REQ		0x5
+#define RDES_EXT_PDELAY_RESP		0x6
+#define RDES_EXT_PDELAY_FOLLOW_UP	0x7
+#define RDES_PTP_ANNOUNCE		0x8
+#define RDES_PTP_MANAGEMENT		0x9
+#define RDES_PTP_SIGNALING		0xa
+#define RDES_PTP_PKT_RESERVED_TYPE	0xf
 
 /* Basic descriptor structure for normal and alternate descriptors */
 struct dma_desc {
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
index 2ef2f0c..a601f8d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
@@ -123,22 +123,29 @@ static int dwmac4_wrback_get_rx_status(void *data, struct stmmac_extra_stats *x,
 		x->ipv4_pkt_rcvd++;
 	if (rdes1 & RDES1_IPV6_HEADER)
 		x->ipv6_pkt_rcvd++;
-	if (message_type == RDES_EXT_SYNC)
-		x->rx_msg_type_sync++;
+
+	if (message_type == RDES_EXT_NO_PTP)
+		x->no_ptp_rx_msg_type_ext++;
+	else if (message_type == RDES_EXT_SYNC)
+		x->ptp_rx_msg_type_sync++;
 	else if (message_type == RDES_EXT_FOLLOW_UP)
-		x->rx_msg_type_follow_up++;
+		x->ptp_rx_msg_type_follow_up++;
 	else if (message_type == RDES_EXT_DELAY_REQ)
-		x->rx_msg_type_delay_req++;
+		x->ptp_rx_msg_type_delay_req++;
 	else if (message_type == RDES_EXT_DELAY_RESP)
-		x->rx_msg_type_delay_resp++;
+		x->ptp_rx_msg_type_delay_resp++;
 	else if (message_type == RDES_EXT_PDELAY_REQ)
-		x->rx_msg_type_pdelay_req++;
+		x->ptp_rx_msg_type_pdelay_req++;
 	else if (message_type == RDES_EXT_PDELAY_RESP)
-		x->rx_msg_type_pdelay_resp++;
+		x->ptp_rx_msg_type_pdelay_resp++;
 	else if (message_type == RDES_EXT_PDELAY_FOLLOW_UP)
-		x->rx_msg_type_pdelay_follow_up++;
-	else
-		x->rx_msg_type_ext_no_ptp++;
+		x->ptp_rx_msg_type_pdelay_follow_up++;
+	else if (message_type == RDES_PTP_ANNOUNCE)
+		x->ptp_rx_msg_type_announce++;
+	else if (message_type == RDES_PTP_MANAGEMENT)
+		x->ptp_rx_msg_type_management++;
+	else if (message_type == RDES_PTP_PKT_RESERVED_TYPE)
+		x->ptp_rx_msg_pkt_reserved_type++;
 
 	if (rdes1 & RDES1_PTP_PACKET_TYPE)
 		x->ptp_frame_type++;
diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
index 38f19c9..e755493 100644
--- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
@@ -150,22 +150,30 @@ static void enh_desc_get_ext_status(void *data, struct stmmac_extra_stats *x,
 			x->ipv4_pkt_rcvd++;
 		if (rdes4 & ERDES4_IPV6_PKT_RCVD)
 			x->ipv6_pkt_rcvd++;
-		if (message_type == RDES_EXT_SYNC)
-			x->rx_msg_type_sync++;
+
+		if (message_type == RDES_EXT_NO_PTP)
+			x->no_ptp_rx_msg_type_ext++;
+		else if (message_type == RDES_EXT_SYNC)
+			x->ptp_rx_msg_type_sync++;
 		else if (message_type == RDES_EXT_FOLLOW_UP)
-			x->rx_msg_type_follow_up++;
+			x->ptp_rx_msg_type_follow_up++;
 		else if (message_type == RDES_EXT_DELAY_REQ)
-			x->rx_msg_type_delay_req++;
+			x->ptp_rx_msg_type_delay_req++;
 		else if (message_type == RDES_EXT_DELAY_RESP)
-			x->rx_msg_type_delay_resp++;
+			x->ptp_rx_msg_type_delay_resp++;
 		else if (message_type == RDES_EXT_PDELAY_REQ)
-			x->rx_msg_type_pdelay_req++;
+			x->ptp_rx_msg_type_pdelay_req++;
 		else if (message_type == RDES_EXT_PDELAY_RESP)
-			x->rx_msg_type_pdelay_resp++;
+			x->ptp_rx_msg_type_pdelay_resp++;
 		else if (message_type == RDES_EXT_PDELAY_FOLLOW_UP)
-			x->rx_msg_type_pdelay_follow_up++;
-		else
-			x->rx_msg_type_ext_no_ptp++;
+			x->ptp_rx_msg_type_pdelay_follow_up++;
+		else if (message_type == RDES_PTP_ANNOUNCE)
+			x->ptp_rx_msg_type_announce++;
+		else if (message_type == RDES_PTP_MANAGEMENT)
+			x->ptp_rx_msg_type_management++;
+		else if (message_type == RDES_PTP_PKT_RESERVED_TYPE)
+			x->ptp_rx_msg_pkt_reserved_type++;
+
 		if (rdes4 & ERDES4_PTP_FRAME_TYPE)
 			x->ptp_frame_type++;
 		if (rdes4 & ERDES4_PTP_VER)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 1e06173..c5d0142 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -115,14 +115,17 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = {
 	STMMAC_STAT(ip_csum_bypassed),
 	STMMAC_STAT(ipv4_pkt_rcvd),
 	STMMAC_STAT(ipv6_pkt_rcvd),
-	STMMAC_STAT(rx_msg_type_ext_no_ptp),
-	STMMAC_STAT(rx_msg_type_sync),
-	STMMAC_STAT(rx_msg_type_follow_up),
-	STMMAC_STAT(rx_msg_type_delay_req),
-	STMMAC_STAT(rx_msg_type_delay_resp),
-	STMMAC_STAT(rx_msg_type_pdelay_req),
-	STMMAC_STAT(rx_msg_type_pdelay_resp),
-	STMMAC_STAT(rx_msg_type_pdelay_follow_up),
+	STMMAC_STAT(no_ptp_rx_msg_type_ext),
+	STMMAC_STAT(ptp_rx_msg_type_sync),
+	STMMAC_STAT(ptp_rx_msg_type_follow_up),
+	STMMAC_STAT(ptp_rx_msg_type_delay_req),
+	STMMAC_STAT(ptp_rx_msg_type_delay_resp),
+	STMMAC_STAT(ptp_rx_msg_type_pdelay_req),
+	STMMAC_STAT(ptp_rx_msg_type_pdelay_resp),
+	STMMAC_STAT(ptp_rx_msg_type_pdelay_follow_up),
+	STMMAC_STAT(ptp_rx_msg_type_announce),
+	STMMAC_STAT(ptp_rx_msg_type_management),
+	STMMAC_STAT(ptp_rx_msg_pkt_reserved_type),
 	STMMAC_STAT(ptp_frame_type),
 	STMMAC_STAT(ptp_ver),
 	STMMAC_STAT(timestamp_dropped),
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH (net.git) 0/3] stmmac: fix PTP support
  2016-10-26  6:56 [PATCH (net.git) 0/3] stmmac: fix PTP support Giuseppe Cavallaro
                   ` (2 preceding siblings ...)
  2016-10-26  6:56 ` [PATCH (net.git) 3/3] stmmac: fix PTP type ethtool stats Giuseppe Cavallaro
@ 2016-10-26  7:29 ` Alexandre Torgue
  2016-10-26  8:58 ` Richard Cochran
  2016-11-04 13:53 ` Giuseppe CAVALLARO
  5 siblings, 0 replies; 14+ messages in thread
From: Alexandre Torgue @ 2016-10-26  7:29 UTC (permalink / raw)
  To: Giuseppe Cavallaro, netdev
  Cc: rayagond, richardcochran, linux-kernel, seraphin.bonnaffe

Hi Peppe,


On 10/26/2016 08:56 AM, Giuseppe Cavallaro wrote:
> This subset of patches aim to fix the PTP support
> for the stmmac and especially for 4.x chip series.
> While setting PTP on an ST box with 4.00a Ethernet
> core, the kernel panics due to a broken settings
> of the descriptors. The patches review the
> register configuration, the algo used for configuring
> the protocol, the way to get the timestamp inside
> the RX/TX descriptors and, in the end, the statistics
> displayed by ethtool.
>
> Giuseppe Cavallaro (3):
>   stmmac: update the PTP header file
>   stmmac: fix PTP support for GMAC4
>   stmmac: fix PTP type ethtool stats
>
>  drivers/net/ethernet/stmicro/stmmac/common.h       | 24 +++---
>  drivers/net/ethernet/stmicro/stmmac/descs.h        | 20 +++--
>  drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 95 ++++++++++++++++-----
>  drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h |  4 +
>  drivers/net/ethernet/stmicro/stmmac/enh_desc.c     | 28 ++++---
>  drivers/net/ethernet/stmicro/stmmac/stmmac.h       |  1 +
>  .../net/ethernet/stmicro/stmmac/stmmac_ethtool.c   | 19 +++--
>  .../net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c  | 43 ++++++++--
>  drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  | 97 +++++++++++-----------
>  drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c   |  9 +-
>  drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h   | 72 ++++++++--------
>  11 files changed, 260 insertions(+), 152 deletions(-)
>

For the series:
Acked-by: Alexandre Torgue <alexandre.torgue@st.com>

Thanks
Alex

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH (net.git) 0/3] stmmac: fix PTP support
  2016-10-26  6:56 [PATCH (net.git) 0/3] stmmac: fix PTP support Giuseppe Cavallaro
                   ` (3 preceding siblings ...)
  2016-10-26  7:29 ` [PATCH (net.git) 0/3] stmmac: fix PTP support Alexandre Torgue
@ 2016-10-26  8:58 ` Richard Cochran
  2016-11-02  7:03   ` Rayagond Kokatanur
  2016-11-04 13:53 ` Giuseppe CAVALLARO
  5 siblings, 1 reply; 14+ messages in thread
From: Richard Cochran @ 2016-10-26  8:58 UTC (permalink / raw)
  To: Giuseppe Cavallaro
  Cc: netdev, alexandre.torgue, rayagond, linux-kernel, seraphin.bonnaffe

On Wed, Oct 26, 2016 at 08:56:01AM +0200, Giuseppe Cavallaro wrote:
> This subset of patches aim to fix the PTP support
> for the stmmac and especially for 4.x chip series.
> While setting PTP on an ST box with 4.00a Ethernet
> core, the kernel panics due to a broken settings
> of the descriptors. The patches review the
> register configuration, the algo used for configuring
> the protocol, the way to get the timestamp inside
> the RX/TX descriptors and, in the end, the statistics
> displayed by ethtool.
> 
> Giuseppe Cavallaro (3):
>   stmmac: update the PTP header file
>   stmmac: fix PTP support for GMAC4
>   stmmac: fix PTP type ethtool stats

Acked-by: Richard Cochran <richardcochran@gmail.com>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH (net.git) 2/3] stmmac: fix PTP support for GMAC4
  2016-10-26  6:56 ` [PATCH (net.git) 2/3] stmmac: fix PTP support for GMAC4 Giuseppe Cavallaro
@ 2016-10-27 10:25   ` Rayagond Kokatanur
  2016-10-27 10:32     ` Giuseppe CAVALLARO
  0 siblings, 1 reply; 14+ messages in thread
From: Rayagond Kokatanur @ 2016-10-27 10:25 UTC (permalink / raw)
  To: Giuseppe Cavallaro
  Cc: netdev, alexandre.torgue, Richard Cochran, linux-kernel,
	seraphin.bonnaffe

Hi Giuseppe,

On Wed, Oct 26, 2016 at 12:26 PM, Giuseppe Cavallaro
<peppe.cavallaro@st.com> wrote:
> Due to bad management of the descriptors, when use ptp4l,
> kernel panics as shown below:
> -----------------------------------------------------------
>  Unable to handle kernel NULL pointer dereference at virtual
>  address 000001ac
>  ...
>  Internal error: Oops: 17 [#1] SMP ARM
>  ...
>  Hardware name: STi SoC with Flattened Device Tree
>  task: c0c05e80 task.stack: c0c00000
>  PC is at dwmac4_wrback_get_tx_timestamp_status+0x0/0xc
>  LR is at stmmac_tx_clean+0x2f8/0x4d4
> -----------------------------------------------------------
>
> In case of GMAC4 the extended descriptor pointers were
> used for getting the timestamp. These are NULL for this HW,
> and the normal ones must be used.
>
> The PTP also had problems on this chip due to the bad
> register management and issues on the algo adopted to
> setup the PTP and getting the timestamp values from the
> descriptors.
>
> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
> Cc: Alexandre TORGUE <alexandre.torgue@st.com>
> Cc: Rayagond Kokatanur <rayagond@vayavyalabs.com>
> ---
>  drivers/net/ethernet/stmicro/stmmac/common.h       |  5 +-
>  drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 68 ++++++++++++---
>  drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h |  4 +
>  drivers/net/ethernet/stmicro/stmmac/stmmac.h       |  1 +
>  .../net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c  | 43 ++++++++--
>  drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  | 97 +++++++++++-----------
>  drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c   |  9 +-
>  7 files changed, 154 insertions(+), 73 deletions(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
> index d3292c4..6fc214c 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
> @@ -482,11 +482,12 @@ struct stmmac_ops {
>  /* PTP and HW Timer helpers */
>  struct stmmac_hwtimestamp {
>         void (*config_hw_tstamping) (void __iomem *ioaddr, u32 data);
> -       u32 (*config_sub_second_increment) (void __iomem *ioaddr, u32 clk_rate);
> +       u32 (*config_sub_second_increment)(void __iomem *ioaddr, u32 ptp_clock,
> +                                          int gmac4);
>         int (*init_systime) (void __iomem *ioaddr, u32 sec, u32 nsec);
>         int (*config_addend) (void __iomem *ioaddr, u32 addend);
>         int (*adjust_systime) (void __iomem *ioaddr, u32 sec, u32 nsec,
> -                              int add_sub);
> +                              int add_sub, int gmac4);
>          u64(*get_systime) (void __iomem *ioaddr);
>  };
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
> index a1b17cd..2ef2f0c 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
> @@ -204,14 +204,18 @@ static void dwmac4_rd_enable_tx_timestamp(struct dma_desc *p)
>
>  static int dwmac4_wrback_get_tx_timestamp_status(struct dma_desc *p)
>  {
> -       return (p->des3 & TDES3_TIMESTAMP_STATUS)
> -               >> TDES3_TIMESTAMP_STATUS_SHIFT;
> +       /* Context type from W/B descriptor must be zero */
> +       if (p->des3 & TDES3_CONTEXT_TYPE)
> +               return -EINVAL;
> +
> +       /* Tx Timestamp Status is 1 so des0 and des1'll have valid values */
> +       if (p->des3 & TDES3_TIMESTAMP_STATUS)
> +               return 0;
> +
> +       return 1;
>  }
>
> -/*  NOTE: For RX CTX bit has to be checked before
> - *  HAVE a specific function for TX and another one for RX
> - */
> -static u64 dwmac4_wrback_get_timestamp(void *desc, u32 ats)
> +static inline u64 dwmac4_get_timestamp(void *desc, u32 ats)
>  {
>         struct dma_desc *p = (struct dma_desc *)desc;
>         u64 ns;
> @@ -223,12 +227,54 @@ static u64 dwmac4_wrback_get_timestamp(void *desc, u32 ats)
>         return ns;
>  }
>
> -static int dwmac4_context_get_rx_timestamp_status(void *desc, u32 ats)
> +static int dwmac4_rx_check_timestamp(void *desc)
> +{
> +       struct dma_desc *p = (struct dma_desc *)desc;
> +       u32 own, ctxt;
> +       int ret = 1;
> +
> +       own = p->des3 & RDES3_OWN;
> +       ctxt = ((p->des3 & RDES3_CONTEXT_DESCRIPTOR)
> +               >> RDES3_CONTEXT_DESCRIPTOR_SHIFT);
> +
> +       if (likely(!own && ctxt)) {
> +               if ((p->des0 == 0xffffffff) && (p->des1 == 0xffffffff))
> +                       /* Corrupted value */
> +                       ret = -EINVAL;
> +               else
> +                       /* A valid Timestamp is ready to be read */
> +                       ret = 0;
> +       }
> +
> +       /* Timestamp not ready */
> +       return ret;
> +}
> +
> +static int dwmac4_wrback_get_rx_timestamp_status(void *desc, u32 ats)
>  {
>         struct dma_desc *p = (struct dma_desc *)desc;
> +       int ret = -EINVAL;
> +
> +       /* Get the status from normal w/b descriptor */
> +       if (likely(p->des3 & TDES3_RS1V)) {
> +               if (likely(p->des1 & RDES1_TIMESTAMP_AVAILABLE)) {
> +                       int i = 0;
> +
> +                       /* Check if timestamp is OK from context descriptor */
> +                       do {
> +                               ret = dwmac4_rx_check_timestamp(desc);

Here, "desc" is not pointing to next descriptor (ie context
descriptor). Driver should check the context descriptor.

> +                               if (ret < 0)
> +                                       goto exit;
> +                               i++;
>
> -       return (p->des1 & RDES1_TIMESTAMP_AVAILABLE)
> -               >> RDES1_TIMESTAMP_AVAILABLE_SHIFT;
> +                       } while ((ret == 1) || (i < 10));
> +
> +                       if (i == 10)
> +                               ret = -EBUSY;
> +               }
> +       }
> +exit:
> +       return ret;
>  }
>
>  static void dwmac4_rd_init_rx_desc(struct dma_desc *p, int disable_rx_ic,
> @@ -373,8 +419,8 @@ const struct stmmac_desc_ops dwmac4_desc_ops = {
>         .get_rx_frame_len = dwmac4_wrback_get_rx_frame_len,
>         .enable_tx_timestamp = dwmac4_rd_enable_tx_timestamp,
>         .get_tx_timestamp_status = dwmac4_wrback_get_tx_timestamp_status,
> -       .get_timestamp = dwmac4_wrback_get_timestamp,
> -       .get_rx_timestamp_status = dwmac4_context_get_rx_timestamp_status,
> +       .get_rx_timestamp_status = dwmac4_wrback_get_rx_timestamp_status,
> +       .get_timestamp = dwmac4_get_timestamp,
>         .set_tx_ic = dwmac4_rd_set_tx_ic,
>         .prepare_tx_desc = dwmac4_rd_prepare_tx_desc,
>         .prepare_tso_tx_desc = dwmac4_rd_prepare_tso_tx_desc,
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h
> index 0902a2e..9736c50 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h
> @@ -59,10 +59,13 @@
>  #define TDES3_CTXT_TCMSSV              BIT(26)
>
>  /* TDES3 Common */
> +#define        TDES3_RS1V                      BIT(26)
> +#define        TDES3_RS1V_SHIFT                26
>  #define TDES3_LAST_DESCRIPTOR          BIT(28)
>  #define TDES3_LAST_DESCRIPTOR_SHIFT    28
>  #define TDES3_FIRST_DESCRIPTOR         BIT(29)
>  #define TDES3_CONTEXT_TYPE             BIT(30)
> +#define        TDES3_CONTEXT_TYPE_SHIFT        30
>
>  /* TDS3 use for both format (read and write back) */
>  #define TDES3_OWN                      BIT(31)
> @@ -117,6 +120,7 @@
>  #define RDES3_LAST_DESCRIPTOR          BIT(28)
>  #define RDES3_FIRST_DESCRIPTOR         BIT(29)
>  #define RDES3_CONTEXT_DESCRIPTOR       BIT(30)
> +#define RDES3_CONTEXT_DESCRIPTOR_SHIFT 30
>
>  /* RDES3 (read format) */
>  #define RDES3_BUFFER1_VALID_ADDR       BIT(24)
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> index b15fc55..4d2a759 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> @@ -129,6 +129,7 @@ struct stmmac_priv {
>         int irq_wake;
>         spinlock_t ptp_lock;
>         void __iomem *mmcaddr;
> +       void __iomem *ptpaddr;
>         u32 rx_tail_addr;
>         u32 tx_tail_addr;
>         u32 mss;
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
> index a77f689..10d6059 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
> @@ -34,21 +34,29 @@ static void stmmac_config_hw_tstamping(void __iomem *ioaddr, u32 data)
>  }
>
>  static u32 stmmac_config_sub_second_increment(void __iomem *ioaddr,
> -                                             u32 ptp_clock)
> +                                             u32 ptp_clock, int gmac4)
>  {
>         u32 value = readl(ioaddr + PTP_TCR);
>         unsigned long data;
>
> -       /* Convert the ptp_clock to nano second
> -        * formula = (2/ptp_clock) * 1000000000
> -        * where, ptp_clock = 50MHz.
> +       /* For GMAC3.x, 4.x versions, convert the ptp_clock to nano second
> +        *      formula = (1/ptp_clock) * 1000000000
> +        * where ptp_clock is 50MHz if fine method is used to update system
>          */
> -       data = (2000000000ULL / ptp_clock);
> +       if (value & PTP_TCR_TSCFUPDT)
> +               data = (1000000000ULL / 50000000);
> +       else
> +               data = (1000000000ULL / ptp_clock);
>
>         /* 0.465ns accuracy */
>         if (!(value & PTP_TCR_TSCTRLSSR))
>                 data = (data * 1000) / 465;
>
> +       data &= PTP_SSIR_SSINC_MASK;
> +
> +       if (gmac4)
> +               data = data << GMAC4_PTP_SSIR_SSINC_SHIFT;
> +
>         writel(data, ioaddr + PTP_SSIR);
>
>         return data;
> @@ -104,14 +112,30 @@ static int stmmac_config_addend(void __iomem *ioaddr, u32 addend)
>  }
>
>  static int stmmac_adjust_systime(void __iomem *ioaddr, u32 sec, u32 nsec,
> -                                int add_sub)
> +                                int add_sub, int gmac4)
>  {
>         u32 value;
>         int limit;
>
> +       if (add_sub) {
> +               /* If the new sec value needs to be subtracted with
> +                * the system time, then MAC_STSUR reg should be
> +                * programmed with (2^32 – <new_sec_value>)
> +                */
> +               if (gmac4)
> +                       sec = (100000000ULL - sec);
> +
> +               value = readl(ioaddr + PTP_TCR);
> +               if (value & PTP_TCR_TSCTRLSSR)
> +                       nsec = (PTP_DIGITAL_ROLLOVER_MODE - nsec);
> +               else
> +                       nsec = (PTP_BINARY_ROLLOVER_MODE - nsec);
> +       }
> +
>         writel(sec, ioaddr + PTP_STSUR);
> -       writel(((add_sub << PTP_STNSUR_ADDSUB_SHIFT) | nsec),
> -               ioaddr + PTP_STNSUR);
> +       value = (add_sub << PTP_STNSUR_ADDSUB_SHIFT) | nsec;
> +       writel(value, ioaddr + PTP_STNSUR);
> +
>         /* issue command to initialize the system time value */
>         value = readl(ioaddr + PTP_TCR);
>         value |= PTP_TCR_TSUPDT;
> @@ -134,8 +158,9 @@ static u64 stmmac_get_systime(void __iomem *ioaddr)
>  {
>         u64 ns;
>
> +       /* Get the TSSS value */
>         ns = readl(ioaddr + PTP_STNSR);
> -       /* convert sec time value to nanosecond */
> +       /* Get the TSS and convert sec time value to nanosecond */
>         ns += readl(ioaddr + PTP_STSR) * 1000000000ULL;
>
>         return ns;
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 48e71fa..2e228d5 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -340,18 +340,17 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
>
>  /* stmmac_get_tx_hwtstamp - get HW TX timestamps
>   * @priv: driver private structure
> - * @entry : descriptor index to be used.
> + * @p : descriptor pointer
>   * @skb : the socket buffer
>   * Description :
>   * This function will read timestamp from the descriptor & pass it to stack.
>   * and also perform some sanity checks.
>   */
>  static void stmmac_get_tx_hwtstamp(struct stmmac_priv *priv,
> -                                  unsigned int entry, struct sk_buff *skb)
> +                                  struct dma_desc *p, struct sk_buff *skb)
>  {
>         struct skb_shared_hwtstamps shhwtstamp;
>         u64 ns;
> -       void *desc = NULL;
>
>         if (!priv->hwts_tx_en)
>                 return;
> @@ -360,58 +359,55 @@ static void stmmac_get_tx_hwtstamp(struct stmmac_priv *priv,
>         if (likely(!skb || !(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)))
>                 return;
>
> -       if (priv->adv_ts)
> -               desc = (priv->dma_etx + entry);
> -       else
> -               desc = (priv->dma_tx + entry);
> -
>         /* check tx tstamp status */
> -       if (!priv->hw->desc->get_tx_timestamp_status((struct dma_desc *)desc))
> -               return;
> +       if (!priv->hw->desc->get_tx_timestamp_status(p)) {
> +               /* get the valid tstamp */
> +               ns = priv->hw->desc->get_timestamp(p, priv->adv_ts);
>
> -       /* get the valid tstamp */
> -       ns = priv->hw->desc->get_timestamp(desc, priv->adv_ts);
> +               memset(&shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps));
> +               shhwtstamp.hwtstamp = ns_to_ktime(ns);
>
> -       memset(&shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps));
> -       shhwtstamp.hwtstamp = ns_to_ktime(ns);
> -       /* pass tstamp to stack */
> -       skb_tstamp_tx(skb, &shhwtstamp);
> +               netdev_info(priv->dev, "get valid TX hw timestamp %llu\n", ns);
> +               /* pass tstamp to stack */
> +               skb_tstamp_tx(skb, &shhwtstamp);
> +       }
>
>         return;
>  }
>
>  /* stmmac_get_rx_hwtstamp - get HW RX timestamps
>   * @priv: driver private structure
> - * @entry : descriptor index to be used.
> + * @p : descriptor pointer
> + * @np : next descriptor pointer
>   * @skb : the socket buffer
>   * Description :
>   * This function will read received packet's timestamp from the descriptor
>   * and pass it to stack. It also perform some sanity checks.
>   */
> -static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv,
> -                                  unsigned int entry, struct sk_buff *skb)
> +static void stmmac_get_rx_hwtstamp(struct stmmac_priv *priv, struct dma_desc *p,
> +                                  struct dma_desc *np, struct sk_buff *skb)
>  {
>         struct skb_shared_hwtstamps *shhwtstamp = NULL;
>         u64 ns;
> -       void *desc = NULL;
>
>         if (!priv->hwts_rx_en)
>                 return;
>
> -       if (priv->adv_ts)
> -               desc = (priv->dma_erx + entry);
> -       else
> -               desc = (priv->dma_rx + entry);
> -
> -       /* exit if rx tstamp is not valid */
> -       if (!priv->hw->desc->get_rx_timestamp_status(desc, priv->adv_ts))
> -               return;
> +       /* Check if timestamp is available */
> +       if (!priv->hw->desc->get_rx_timestamp_status(p, priv->adv_ts)) {
> +               /* For GMAC4, the valid timestamp is from CTX next desc. */
> +               if (priv->plat->has_gmac4)
> +                       ns = priv->hw->desc->get_timestamp(np, priv->adv_ts);
> +               else
> +                       ns = priv->hw->desc->get_timestamp(p, priv->adv_ts);
>
> -       /* get valid tstamp */
> -       ns = priv->hw->desc->get_timestamp(desc, priv->adv_ts);
> -       shhwtstamp = skb_hwtstamps(skb);
> -       memset(shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps));
> -       shhwtstamp->hwtstamp = ns_to_ktime(ns);
> +               netdev_info(priv->dev, "get valid RX hw timestamp %llu\n", ns);
> +               shhwtstamp = skb_hwtstamps(skb);
> +               memset(shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps));
> +               shhwtstamp->hwtstamp = ns_to_ktime(ns);
> +       } else  {
> +               netdev_err(priv->dev, "cannot get RX hw timestamp\n");
> +       }
>  }
>
>  /**
> @@ -598,17 +594,18 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
>         priv->hwts_tx_en = config.tx_type == HWTSTAMP_TX_ON;
>
>         if (!priv->hwts_tx_en && !priv->hwts_rx_en)
> -               priv->hw->ptp->config_hw_tstamping(priv->ioaddr, 0);
> +               priv->hw->ptp->config_hw_tstamping(priv->ptpaddr, 0);
>         else {
>                 value = (PTP_TCR_TSENA | PTP_TCR_TSCFUPDT | PTP_TCR_TSCTRLSSR |
>                          tstamp_all | ptp_v2 | ptp_over_ethernet |
>                          ptp_over_ipv6_udp | ptp_over_ipv4_udp | ts_event_en |
>                          ts_master_en | snap_type_sel);
> -               priv->hw->ptp->config_hw_tstamping(priv->ioaddr, value);
> +               priv->hw->ptp->config_hw_tstamping(priv->ptpaddr, value);
>
>                 /* program Sub Second Increment reg */
>                 sec_inc = priv->hw->ptp->config_sub_second_increment(
> -                       priv->ioaddr, priv->clk_ptp_rate);
> +                       priv->ptpaddr, priv->clk_ptp_rate,
> +                       priv->plat->has_gmac4);
>                 temp = div_u64(1000000000ULL, sec_inc);
>
>                 /* calculate default added value:
> @@ -618,14 +615,14 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
>                  */
>                 temp = (u64)(temp << 32);
>                 priv->default_addend = div_u64(temp, priv->clk_ptp_rate);
> -               priv->hw->ptp->config_addend(priv->ioaddr,
> +               priv->hw->ptp->config_addend(priv->ptpaddr,
>                                              priv->default_addend);
>
>                 /* initialize system time */
>                 ktime_get_real_ts64(&now);
>
>                 /* lower 32 bits of tv_sec are safe until y2106 */
> -               priv->hw->ptp->init_systime(priv->ioaddr, (u32)now.tv_sec,
> +               priv->hw->ptp->init_systime(priv->ptpaddr, (u32)now.tv_sec,
>                                             now.tv_nsec);
>         }
>
> @@ -1333,7 +1330,7 @@ static void stmmac_tx_clean(struct stmmac_priv *priv)
>                                 priv->dev->stats.tx_packets++;
>                                 priv->xstats.tx_pkt_n++;
>                         }
> -                       stmmac_get_tx_hwtstamp(priv, entry, skb);
> +                       stmmac_get_tx_hwtstamp(priv, p, skb);
>                 }
>
>                 if (likely(priv->tx_skbuff_dma[entry].buf)) {
> @@ -1479,10 +1476,13 @@ static void stmmac_mmc_setup(struct stmmac_priv *priv)
>         unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET |
>                             MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET;
>
> -       if (priv->synopsys_id >= DWMAC_CORE_4_00)
> +       if (priv->synopsys_id >= DWMAC_CORE_4_00) {
> +               priv->ptpaddr = priv->ioaddr + PTP_GMAC4_OFFSET;
>                 priv->mmcaddr = priv->ioaddr + MMC_GMAC4_OFFSET;
> -       else
> +       } else {
> +               priv->ptpaddr = priv->ioaddr + PTP_GMAC3_X_OFFSET;
>                 priv->mmcaddr = priv->ioaddr + MMC_GMAC3_X_OFFSET;
> +       }
>
>         dwmac_mmc_intr_all_mask(priv->mmcaddr);
>
> @@ -2477,7 +2477,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
>         if (netif_msg_rx_status(priv)) {
>                 void *rx_head;
>
> -               pr_debug("%s: descriptor ring:\n", __func__);
> +               pr_info(">>>>>> %s: descriptor ring:\n", __func__);
>                 if (priv->extend_desc)
>                         rx_head = (void *)priv->dma_erx;
>                 else
> @@ -2488,6 +2488,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
>         while (count < limit) {
>                 int status;
>                 struct dma_desc *p;
> +               struct dma_desc *np;
>
>                 if (priv->extend_desc)
>                         p = (struct dma_desc *)(priv->dma_erx + entry);
> @@ -2507,9 +2508,11 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
>                 next_entry = priv->cur_rx;
>
>                 if (priv->extend_desc)
> -                       prefetch(priv->dma_erx + next_entry);
> +                       np = (struct dma_desc *)(priv->dma_erx + next_entry);
>                 else
> -                       prefetch(priv->dma_rx + next_entry);
> +                       np = priv->dma_rx + next_entry;
> +
> +               prefetch(np);
>
>                 if ((priv->extend_desc) && (priv->hw->desc->rx_extended_status))
>                         priv->hw->desc->rx_extended_status(&priv->dev->stats,
> @@ -2561,7 +2564,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
>                                 frame_len -= ETH_FCS_LEN;
>
>                         if (netif_msg_rx_status(priv)) {
> -                               pr_debug("\tdesc: %p [entry %d] buff=0x%x\n",
> +                               pr_info("\tdesc: %p [entry %d] buff=0x%x\n",
>                                         p, entry, des);
>                                 if (frame_len > ETH_FRAME_LEN)
>                                         pr_debug("\tframe size %d, COE: %d\n",
> @@ -2618,13 +2621,13 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
>                                                  DMA_FROM_DEVICE);
>                         }
>
> -                       stmmac_get_rx_hwtstamp(priv, entry, skb);
> -
>                         if (netif_msg_pktdata(priv)) {
>                                 pr_debug("frame received (%dbytes)", frame_len);
>                                 print_pkt(skb->data, frame_len);
>                         }
>
> +                       stmmac_get_rx_hwtstamp(priv, p, np, skb);
> +
>                         stmmac_rx_vlan(priv->dev, skb);
>
>                         skb->protocol = eth_type_trans(skb, priv->dev);
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
> index 1477471..3eb281d 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
> @@ -54,7 +54,7 @@ static int stmmac_adjust_freq(struct ptp_clock_info *ptp, s32 ppb)
>
>         spin_lock_irqsave(&priv->ptp_lock, flags);
>
> -       priv->hw->ptp->config_addend(priv->ioaddr, addend);
> +       priv->hw->ptp->config_addend(priv->ptpaddr, addend);
>
>         spin_unlock_irqrestore(&priv->ptp_lock, flags);
>
> @@ -89,7 +89,8 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 delta)
>
>         spin_lock_irqsave(&priv->ptp_lock, flags);
>
> -       priv->hw->ptp->adjust_systime(priv->ioaddr, sec, nsec, neg_adj);
> +       priv->hw->ptp->adjust_systime(priv->ptpaddr, sec, nsec, neg_adj,
> +                                     priv->plat->has_gmac4);
>
>         spin_unlock_irqrestore(&priv->ptp_lock, flags);
>
> @@ -114,7 +115,7 @@ static int stmmac_get_time(struct ptp_clock_info *ptp, struct timespec64 *ts)
>
>         spin_lock_irqsave(&priv->ptp_lock, flags);
>
> -       ns = priv->hw->ptp->get_systime(priv->ioaddr);
> +       ns = priv->hw->ptp->get_systime(priv->ptpaddr);
>
>         spin_unlock_irqrestore(&priv->ptp_lock, flags);
>
> @@ -141,7 +142,7 @@ static int stmmac_set_time(struct ptp_clock_info *ptp,
>
>         spin_lock_irqsave(&priv->ptp_lock, flags);
>
> -       priv->hw->ptp->init_systime(priv->ioaddr, ts->tv_sec, ts->tv_nsec);
> +       priv->hw->ptp->init_systime(priv->ptpaddr, ts->tv_sec, ts->tv_nsec);
>
>         spin_unlock_irqrestore(&priv->ptp_lock, flags);
>
> --
> 2.7.4
>



-- 
wwr
Rayagond

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH (net.git) 2/3] stmmac: fix PTP support for GMAC4
  2016-10-27 10:25   ` Rayagond Kokatanur
@ 2016-10-27 10:32     ` Giuseppe CAVALLARO
  2016-10-27 10:51       ` Rayagond Kokatanur
  0 siblings, 1 reply; 14+ messages in thread
From: Giuseppe CAVALLARO @ 2016-10-27 10:32 UTC (permalink / raw)
  To: Rayagond Kokatanur
  Cc: netdev, alexandre.torgue, Richard Cochran, linux-kernel,
	seraphin.bonnaffe

Hello Rayagond !

On 10/27/2016 12:25 PM, Rayagond Kokatanur wrote:
>> +static int dwmac4_wrback_get_rx_timestamp_status(void *desc, u32 ats)
>> >  {
>> >         struct dma_desc *p = (struct dma_desc *)desc;
>> > +       int ret = -EINVAL;
>> > +
>> > +       /* Get the status from normal w/b descriptor */
>> > +       if (likely(p->des3 & TDES3_RS1V)) {
>> > +               if (likely(p->des1 & RDES1_TIMESTAMP_AVAILABLE)) {
>> > +                       int i = 0;
>> > +
>> > +                       /* Check if timestamp is OK from context descriptor */
>> > +                       do {
>> > +                               ret = dwmac4_rx_check_timestamp(desc);
> Here, "desc" is not pointing to next descriptor (ie context
> descriptor). Driver should check the context descriptor.

you are right and this is done by the caller:  stmmac_get_rx_hwtstamp

Cheers
peppe

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH (net.git) 2/3] stmmac: fix PTP support for GMAC4
  2016-10-27 10:32     ` Giuseppe CAVALLARO
@ 2016-10-27 10:51       ` Rayagond Kokatanur
  2016-11-02  6:34         ` Giuseppe CAVALLARO
  0 siblings, 1 reply; 14+ messages in thread
From: Rayagond Kokatanur @ 2016-10-27 10:51 UTC (permalink / raw)
  To: Giuseppe CAVALLARO
  Cc: netdev, alexandre.torgue, Richard Cochran, linux-kernel,
	seraphin.bonnaffe

On Thu, Oct 27, 2016 at 4:02 PM, Giuseppe CAVALLARO
<peppe.cavallaro@st.com> wrote:
> Hello Rayagond !
>
> On 10/27/2016 12:25 PM, Rayagond Kokatanur wrote:
>>>
>>> +static int dwmac4_wrback_get_rx_timestamp_status(void *desc, u32 ats)
>>> >  {
>>> >         struct dma_desc *p = (struct dma_desc *)desc;
>>> > +       int ret = -EINVAL;
>>> > +
>>> > +       /* Get the status from normal w/b descriptor */
>>> > +       if (likely(p->des3 & TDES3_RS1V)) {
>>> > +               if (likely(p->des1 & RDES1_TIMESTAMP_AVAILABLE)) {
>>> > +                       int i = 0;
>>> > +
>>> > +                       /* Check if timestamp is OK from context
>>> > descriptor */
>>> > +                       do {
>>> > +                               ret = dwmac4_rx_check_timestamp(desc);
>>
>> Here, "desc" is not pointing to next descriptor (ie context
>> descriptor). Driver should check the context descriptor.
>
>
> you are right and this is done by the caller:  stmmac_get_rx_hwtstamp

Yes.

>
> Cheers
> peppe
>



-- 
wwr
Rayagond

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH (net.git) 2/3] stmmac: fix PTP support for GMAC4
  2016-10-27 10:51       ` Rayagond Kokatanur
@ 2016-11-02  6:34         ` Giuseppe CAVALLARO
  2016-11-02  7:04           ` Rayagond Kokatanur
  0 siblings, 1 reply; 14+ messages in thread
From: Giuseppe CAVALLARO @ 2016-11-02  6:34 UTC (permalink / raw)
  To: Rayagond Kokatanur
  Cc: netdev, alexandre.torgue, Richard Cochran, linux-kernel,
	seraphin.bonnaffe

Hello Rayagond

if patches are ok, can we consider you Acked-by ?

Thx
Peppe

On 10/27/2016 12:51 PM, Rayagond Kokatanur wrote:
> On Thu, Oct 27, 2016 at 4:02 PM, Giuseppe CAVALLARO
> <peppe.cavallaro@st.com> wrote:
>> Hello Rayagond !
>>
>> On 10/27/2016 12:25 PM, Rayagond Kokatanur wrote:
>>>>
>>>> +static int dwmac4_wrback_get_rx_timestamp_status(void *desc, u32 ats)
>>>>>  {
>>>>>         struct dma_desc *p = (struct dma_desc *)desc;
>>>>> +       int ret = -EINVAL;
>>>>> +
>>>>> +       /* Get the status from normal w/b descriptor */
>>>>> +       if (likely(p->des3 & TDES3_RS1V)) {
>>>>> +               if (likely(p->des1 & RDES1_TIMESTAMP_AVAILABLE)) {
>>>>> +                       int i = 0;
>>>>> +
>>>>> +                       /* Check if timestamp is OK from context
>>>>> descriptor */
>>>>> +                       do {
>>>>> +                               ret = dwmac4_rx_check_timestamp(desc);
>>>
>>> Here, "desc" is not pointing to next descriptor (ie context
>>> descriptor). Driver should check the context descriptor.
>>
>>
>> you are right and this is done by the caller:  stmmac_get_rx_hwtstamp
>
> Yes.
>
>>
>> Cheers
>> peppe
>>
>
>
>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH (net.git) 0/3] stmmac: fix PTP support
  2016-10-26  8:58 ` Richard Cochran
@ 2016-11-02  7:03   ` Rayagond Kokatanur
  0 siblings, 0 replies; 14+ messages in thread
From: Rayagond Kokatanur @ 2016-11-02  7:03 UTC (permalink / raw)
  To: Richard Cochran
  Cc: Giuseppe Cavallaro, netdev, alexandre.torgue, linux-kernel,
	Seraphin Bonnaffe

On Wed, Oct 26, 2016 at 2:28 PM, Richard Cochran
<richardcochran@gmail.com> wrote:
> On Wed, Oct 26, 2016 at 08:56:01AM +0200, Giuseppe Cavallaro wrote:
>> This subset of patches aim to fix the PTP support
>> for the stmmac and especially for 4.x chip series.
>> While setting PTP on an ST box with 4.00a Ethernet
>> core, the kernel panics due to a broken settings
>> of the descriptors. The patches review the
>> register configuration, the algo used for configuring
>> the protocol, the way to get the timestamp inside
>> the RX/TX descriptors and, in the end, the statistics
>> displayed by ethtool.
>>
>> Giuseppe Cavallaro (3):
>>   stmmac: update the PTP header file
>>   stmmac: fix PTP support for GMAC4
>>   stmmac: fix PTP type ethtool stats
>
> Acked-by: Richard Cochran <richardcochran@gmail.com>

Acked-by: Rayagond Kokatanur <rayagond@vayavyalabs.com>



-- 
wwr
Rayagond

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH (net.git) 2/3] stmmac: fix PTP support for GMAC4
  2016-11-02  6:34         ` Giuseppe CAVALLARO
@ 2016-11-02  7:04           ` Rayagond Kokatanur
  0 siblings, 0 replies; 14+ messages in thread
From: Rayagond Kokatanur @ 2016-11-02  7:04 UTC (permalink / raw)
  To: Giuseppe CAVALLARO
  Cc: netdev, alexandre.torgue, Richard Cochran, linux-kernel,
	Seraphin Bonnaffe

On Wed, Nov 2, 2016 at 12:04 PM, Giuseppe CAVALLARO
<peppe.cavallaro@st.com> wrote:
> Hello Rayagond
>
> if patches are ok, can we consider you Acked-by ?
Yes.

>
> Thx
> Peppe
>
>
> On 10/27/2016 12:51 PM, Rayagond Kokatanur wrote:
>>
>> On Thu, Oct 27, 2016 at 4:02 PM, Giuseppe CAVALLARO
>> <peppe.cavallaro@st.com> wrote:
>>>
>>> Hello Rayagond !
>>>
>>> On 10/27/2016 12:25 PM, Rayagond Kokatanur wrote:
>>>>>
>>>>>
>>>>> +static int dwmac4_wrback_get_rx_timestamp_status(void *desc, u32 ats)
>>>>>>
>>>>>>  {
>>>>>>         struct dma_desc *p = (struct dma_desc *)desc;
>>>>>> +       int ret = -EINVAL;
>>>>>> +
>>>>>> +       /* Get the status from normal w/b descriptor */
>>>>>> +       if (likely(p->des3 & TDES3_RS1V)) {
>>>>>> +               if (likely(p->des1 & RDES1_TIMESTAMP_AVAILABLE)) {
>>>>>> +                       int i = 0;
>>>>>> +
>>>>>> +                       /* Check if timestamp is OK from context
>>>>>> descriptor */
>>>>>> +                       do {
>>>>>> +                               ret = dwmac4_rx_check_timestamp(desc);
>>>>
>>>>
>>>> Here, "desc" is not pointing to next descriptor (ie context
>>>> descriptor). Driver should check the context descriptor.
>>>
>>>
>>>
>>> you are right and this is done by the caller:  stmmac_get_rx_hwtstamp
>>
>>
>> Yes.
>>
>>>
>>> Cheers
>>> peppe
>>>
>>
>>
>>
>



-- 
wwr
Rayagond

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH (net.git) 0/3] stmmac: fix PTP support
  2016-10-26  6:56 [PATCH (net.git) 0/3] stmmac: fix PTP support Giuseppe Cavallaro
                   ` (4 preceding siblings ...)
  2016-10-26  8:58 ` Richard Cochran
@ 2016-11-04 13:53 ` Giuseppe CAVALLARO
  2016-11-04 15:30   ` David Miller
  5 siblings, 1 reply; 14+ messages in thread
From: Giuseppe CAVALLARO @ 2016-11-04 13:53 UTC (permalink / raw)
  To: netdev, David Miller
  Cc: alexandre.torgue, rayagond, richardcochran, linux-kernel,
	seraphin.bonnaffe

Hi David,

the series have some Acked-by, do you prefer a new
series (I can rebase them if you ask me) or you can keep
this one? Or you have some advice or issue to warn?

Regards,
peppe

On 10/26/2016 8:56 AM, Giuseppe Cavallaro wrote:
> This subset of patches aim to fix the PTP support
> for the stmmac and especially for 4.x chip series.
> While setting PTP on an ST box with 4.00a Ethernet
> core, the kernel panics due to a broken settings
> of the descriptors. The patches review the
> register configuration, the algo used for configuring
> the protocol, the way to get the timestamp inside
> the RX/TX descriptors and, in the end, the statistics
> displayed by ethtool.
>
> Giuseppe Cavallaro (3):
>   stmmac: update the PTP header file
>   stmmac: fix PTP support for GMAC4
>   stmmac: fix PTP type ethtool stats
>
>  drivers/net/ethernet/stmicro/stmmac/common.h       | 24 +++---
>  drivers/net/ethernet/stmicro/stmmac/descs.h        | 20 +++--
>  drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 95 ++++++++++++++++-----
>  drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h |  4 +
>  drivers/net/ethernet/stmicro/stmmac/enh_desc.c     | 28 ++++---
>  drivers/net/ethernet/stmicro/stmmac/stmmac.h       |  1 +
>  .../net/ethernet/stmicro/stmmac/stmmac_ethtool.c   | 19 +++--
>  .../net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c  | 43 ++++++++--
>  drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  | 97 +++++++++++-----------
>  drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c   |  9 +-
>  drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h   | 72 ++++++++--------
>  11 files changed, 260 insertions(+), 152 deletions(-)
>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH (net.git) 0/3] stmmac: fix PTP support
  2016-11-04 13:53 ` Giuseppe CAVALLARO
@ 2016-11-04 15:30   ` David Miller
  0 siblings, 0 replies; 14+ messages in thread
From: David Miller @ 2016-11-04 15:30 UTC (permalink / raw)
  To: peppe.cavallaro
  Cc: netdev, alexandre.torgue, rayagond, richardcochran, linux-kernel,
	seraphin.bonnaffe

From: Giuseppe CAVALLARO <peppe.cavallaro@st.com>
Date: Fri, 4 Nov 2016 14:53:09 +0100

> the series have some Acked-by, do you prefer a new
> series (I can rebase them if you ask me) or you can keep
> this one? Or you have some advice or issue to warn?

If it's not in an "Action Required" state in patchwork, you
can safely assume it must be resubmitted in order for me to
consider it.

Thanks.

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2016-11-04 15:30 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-26  6:56 [PATCH (net.git) 0/3] stmmac: fix PTP support Giuseppe Cavallaro
2016-10-26  6:56 ` [PATCH (net.git) 1/3] stmmac: update the PTP header file Giuseppe Cavallaro
2016-10-26  6:56 ` [PATCH (net.git) 2/3] stmmac: fix PTP support for GMAC4 Giuseppe Cavallaro
2016-10-27 10:25   ` Rayagond Kokatanur
2016-10-27 10:32     ` Giuseppe CAVALLARO
2016-10-27 10:51       ` Rayagond Kokatanur
2016-11-02  6:34         ` Giuseppe CAVALLARO
2016-11-02  7:04           ` Rayagond Kokatanur
2016-10-26  6:56 ` [PATCH (net.git) 3/3] stmmac: fix PTP type ethtool stats Giuseppe Cavallaro
2016-10-26  7:29 ` [PATCH (net.git) 0/3] stmmac: fix PTP support Alexandre Torgue
2016-10-26  8:58 ` Richard Cochran
2016-11-02  7:03   ` Rayagond Kokatanur
2016-11-04 13:53 ` Giuseppe CAVALLARO
2016-11-04 15:30   ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).