netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/10] net: eth: altera: tse: Add PTP and mSGDMA prefetcher
@ 2020-06-04  7:32 Ooi, Joyce
  2020-06-04  7:32 ` [PATCH v3 01/10] net: eth: altera: tse_start_xmit ignores tx_buffer call response Ooi, Joyce
                   ` (10 more replies)
  0 siblings, 11 replies; 16+ messages in thread
From: Ooi, Joyce @ 2020-06-04  7:32 UTC (permalink / raw)
  To: Thor Thayer, David S . Miller, Jakub Kicinski
  Cc: netdev, linux-kernel, Dalon Westergreen, Joyce Ooi, Tan Ley Foon,
	See Chin Liang, Dinh Nguyen

From: Joyce Ooi <joyce.ooi@intel.com>

This patch series cleans up the Altera TSE driver and adds support
for the newer msgdma prefetcher as well as ptp support when using
the msgdma prefetcher.

v2: Rename altera_ptp to intel_fpga_tod, modify msgdma and sgdma tx_buffer
    functions to be of type netdev_tx_t, and minor suggested edits
v3: Modify tx_buffer to stop queue before returning NETDEV_TX_BUSY

Dalon Westergreen (10):
  net: eth: altera: tse_start_xmit ignores tx_buffer call response
  net: eth: altera: set rx and tx ring size before init_dma call
  net: eth: altera: fix altera_dmaops declaration
  net: eth: altera: add optional function to start tx dma
  net: eth: altera: Move common functions to altera_utils
  net: eth: altera: Add missing identifier names to function
    declarations
  net: eth: altera: change tx functions to type netdev_tx_t
  net: eth: altera: add support for ptp and timestamping
  net: eth: altera: add msgdma prefetcher
  net: eth: altera: update devicetree bindings documentation

 .../devicetree/bindings/net/altera_tse.txt         | 103 ++++-
 drivers/net/ethernet/altera/Kconfig                |   1 +
 drivers/net/ethernet/altera/Makefile               |   3 +-
 drivers/net/ethernet/altera/altera_msgdma.c        |   5 +-
 drivers/net/ethernet/altera/altera_msgdma.h        |  30 +-
 .../net/ethernet/altera/altera_msgdma_prefetcher.c | 431 +++++++++++++++++++++
 .../net/ethernet/altera/altera_msgdma_prefetcher.h |  30 ++
 .../ethernet/altera/altera_msgdmahw_prefetcher.h   |  87 +++++
 drivers/net/ethernet/altera/altera_sgdma.c         |  22 +-
 drivers/net/ethernet/altera/altera_sgdma.h         |  32 +-
 drivers/net/ethernet/altera/altera_tse.h           |  98 ++---
 drivers/net/ethernet/altera/altera_tse_ethtool.c   |  29 ++
 drivers/net/ethernet/altera/altera_tse_main.c      | 218 +++++++++--
 drivers/net/ethernet/altera/altera_utils.c         |  29 ++
 drivers/net/ethernet/altera/altera_utils.h         |  51 +++
 drivers/net/ethernet/altera/intel_fpga_tod.c       | 358 +++++++++++++++++
 drivers/net/ethernet/altera/intel_fpga_tod.h       |  56 +++
 17 files changed, 1429 insertions(+), 154 deletions(-)
 create mode 100644 drivers/net/ethernet/altera/altera_msgdma_prefetcher.c
 create mode 100644 drivers/net/ethernet/altera/altera_msgdma_prefetcher.h
 create mode 100644 drivers/net/ethernet/altera/altera_msgdmahw_prefetcher.h
 create mode 100644 drivers/net/ethernet/altera/intel_fpga_tod.c
 create mode 100644 drivers/net/ethernet/altera/intel_fpga_tod.h

-- 
2.13.0


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

* [PATCH v3 01/10] net: eth: altera: tse_start_xmit ignores tx_buffer call response
  2020-06-04  7:32 [PATCH v3 00/10] net: eth: altera: tse: Add PTP and mSGDMA prefetcher Ooi, Joyce
@ 2020-06-04  7:32 ` Ooi, Joyce
  2020-06-04  7:32 ` [PATCH v3 02/10] net: eth: altera: set rx and tx ring size before init_dma call Ooi, Joyce
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Ooi, Joyce @ 2020-06-04  7:32 UTC (permalink / raw)
  To: Thor Thayer, David S . Miller, Jakub Kicinski
  Cc: netdev, linux-kernel, Dalon Westergreen, Joyce Ooi, Tan Ley Foon,
	See Chin Liang, Dinh Nguyen, Dalon Westergreen

From: Dalon Westergreen <dalon.westergreen@intel.com>

The return from tx_buffer call in tse_start_xmit is
inapropriately ignored.  tse_buffer calls should return
0 for success or NETDEV_TX_BUSY.  tse_start_xmit should
return not report a successful transmit when the tse_buffer
call returns an error condition.

In addition to the above, the msgdma and sgdma do not return
the same value on success or failure.  The sgdma_tx_buffer
returned 0 on failure and a positive number of transmitted
packets on success.  Given that it only ever sends 1 packet,
this made no sense.  The msgdma implementation msgdma_tx_buffer
returns 0 on success.

  -> Don't ignore the return from tse_buffer calls
  -> Fix sgdma tse_buffer call to return 0 on success
     and NETDEV_TX_BUSY on failure.

Signed-off-by: Dalon Westergreen <dalon.westergreen@intel.com>
Signed-off-by: Joyce Ooi <joyce.ooi@intel.com>
---
v2: no change
v3: queue is stopped before returning NETDEV_TX_BUSY
---
 drivers/net/ethernet/altera/altera_sgdma.c    | 19 ++++++++++++-------
 drivers/net/ethernet/altera/altera_tse_main.c |  4 +++-
 2 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/altera/altera_sgdma.c b/drivers/net/ethernet/altera/altera_sgdma.c
index db97170da8c7..fe6276c7e4a3 100644
--- a/drivers/net/ethernet/altera/altera_sgdma.c
+++ b/drivers/net/ethernet/altera/altera_sgdma.c
@@ -4,6 +4,7 @@
  */
 
 #include <linux/list.h>
+#include <linux/netdevice.h>
 #include "altera_utils.h"
 #include "altera_tse.h"
 #include "altera_sgdmahw.h"
@@ -159,10 +160,11 @@ void sgdma_clear_txirq(struct altera_tse_private *priv)
 		    SGDMA_CTRLREG_CLRINT);
 }
 
-/* transmits buffer through SGDMA. Returns number of buffers
- * transmitted, 0 if not possible.
- *
- * tx_lock is held by the caller
+/* transmits buffer through SGDMA.
+ *   original behavior returned the number of transmitted packets (always 1) &
+ *   returned 0 on error.  This differs from the msgdma.  the calling function
+ *   will now actually look at the code, so from now, 0 is good and return
+ *   NETDEV_TX_BUSY when busy.
  */
 int sgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer)
 {
@@ -173,8 +175,11 @@ int sgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer)
 	struct sgdma_descrip __iomem *ndesc = &descbase[1];
 
 	/* wait 'til the tx sgdma is ready for the next transmit request */
-	if (sgdma_txbusy(priv))
-		return 0;
+	if (sgdma_txbusy(priv)) {
+		if (!netif_queue_stopped(priv->dev))
+			netif_stop_queue(priv->dev);
+		return NETDEV_TX_BUSY;
+	}
 
 	sgdma_setup_descrip(cdesc,			/* current descriptor */
 			    ndesc,			/* next descriptor */
@@ -191,7 +196,7 @@ int sgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer)
 	/* enqueue the request to the pending transmit queue */
 	queue_tx(priv, buffer);
 
-	return 1;
+	return 0;
 }
 
 
diff --git a/drivers/net/ethernet/altera/altera_tse_main.c b/drivers/net/ethernet/altera/altera_tse_main.c
index 1671c1f36691..2a9e6157a8a1 100644
--- a/drivers/net/ethernet/altera/altera_tse_main.c
+++ b/drivers/net/ethernet/altera/altera_tse_main.c
@@ -595,7 +595,9 @@ static int tse_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	buffer->dma_addr = dma_addr;
 	buffer->len = nopaged_len;
 
-	priv->dmaops->tx_buffer(priv, buffer);
+	ret = priv->dmaops->tx_buffer(priv, buffer);
+	if (ret)
+		goto out;
 
 	skb_tx_timestamp(skb);
 
-- 
2.13.0


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

* [PATCH v3 02/10] net: eth: altera: set rx and tx ring size before init_dma call
  2020-06-04  7:32 [PATCH v3 00/10] net: eth: altera: tse: Add PTP and mSGDMA prefetcher Ooi, Joyce
  2020-06-04  7:32 ` [PATCH v3 01/10] net: eth: altera: tse_start_xmit ignores tx_buffer call response Ooi, Joyce
@ 2020-06-04  7:32 ` Ooi, Joyce
  2020-06-04  7:32 ` [PATCH v3 03/10] net: eth: altera: fix altera_dmaops declaration Ooi, Joyce
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Ooi, Joyce @ 2020-06-04  7:32 UTC (permalink / raw)
  To: Thor Thayer, David S . Miller, Jakub Kicinski
  Cc: netdev, linux-kernel, Dalon Westergreen, Joyce Ooi, Tan Ley Foon,
	See Chin Liang, Dinh Nguyen, Dalon Westergreen

From: Dalon Westergreen <dalon.westergreen@intel.com>

It is more appropriate to set the rx and tx ring size before calling
the init function for the dma.

Signed-off-by: Dalon Westergreen <dalon.westergreen@intel.com>
Signed-off-by: Joyce Ooi <joyce.ooi@intel.com>
---
v2: no change
v3: no change
---
 drivers/net/ethernet/altera/altera_tse_main.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/altera/altera_tse_main.c b/drivers/net/ethernet/altera/altera_tse_main.c
index 2a9e6157a8a1..539e744e23f7 100644
--- a/drivers/net/ethernet/altera/altera_tse_main.c
+++ b/drivers/net/ethernet/altera/altera_tse_main.c
@@ -1154,6 +1154,10 @@ static int tse_open(struct net_device *dev)
 	int i;
 	unsigned long int flags;
 
+	/* set tx and rx ring size */
+	priv->rx_ring_size = dma_rx_num;
+	priv->tx_ring_size = dma_tx_num;
+
 	/* Reset and configure TSE MAC and probe associated PHY */
 	ret = priv->dmaops->init_dma(priv);
 	if (ret != 0) {
@@ -1196,8 +1200,6 @@ static int tse_open(struct net_device *dev)
 	priv->dmaops->reset_dma(priv);
 
 	/* Create and initialize the TX/RX descriptors chains. */
-	priv->rx_ring_size = dma_rx_num;
-	priv->tx_ring_size = dma_tx_num;
 	ret = alloc_init_skbufs(priv);
 	if (ret) {
 		netdev_err(dev, "DMA descriptors initialization failed\n");
-- 
2.13.0


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

* [PATCH v3 03/10] net: eth: altera: fix altera_dmaops declaration
  2020-06-04  7:32 [PATCH v3 00/10] net: eth: altera: tse: Add PTP and mSGDMA prefetcher Ooi, Joyce
  2020-06-04  7:32 ` [PATCH v3 01/10] net: eth: altera: tse_start_xmit ignores tx_buffer call response Ooi, Joyce
  2020-06-04  7:32 ` [PATCH v3 02/10] net: eth: altera: set rx and tx ring size before init_dma call Ooi, Joyce
@ 2020-06-04  7:32 ` Ooi, Joyce
  2020-06-04  7:32 ` [PATCH v3 04/10] net: eth: altera: add optional function to start tx dma Ooi, Joyce
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Ooi, Joyce @ 2020-06-04  7:32 UTC (permalink / raw)
  To: Thor Thayer, David S . Miller, Jakub Kicinski
  Cc: netdev, linux-kernel, Dalon Westergreen, Joyce Ooi, Tan Ley Foon,
	See Chin Liang, Dinh Nguyen, Dalon Westergreen

From: Dalon Westergreen <dalon.westergreen@intel.com>

The declaration of struct altera_dmaops does not have
identifier names.  Add identifier names to confrom with
required coding styles.

Signed-off-by: Dalon Westergreen <dalon.westergreen@intel.com>
Signed-off-by: Joyce Ooi <joyce.ooi@intel.com>
---
v2: no change
v3: no change
---
 drivers/net/ethernet/altera/altera_tse.h | 30 ++++++++++++++++--------------
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/altera/altera_tse.h b/drivers/net/ethernet/altera/altera_tse.h
index f17acfb579a0..7d0c98fc103e 100644
--- a/drivers/net/ethernet/altera/altera_tse.h
+++ b/drivers/net/ethernet/altera/altera_tse.h
@@ -385,20 +385,22 @@ struct altera_tse_private;
 struct altera_dmaops {
 	int altera_dtype;
 	int dmamask;
-	void (*reset_dma)(struct altera_tse_private *);
-	void (*enable_txirq)(struct altera_tse_private *);
-	void (*enable_rxirq)(struct altera_tse_private *);
-	void (*disable_txirq)(struct altera_tse_private *);
-	void (*disable_rxirq)(struct altera_tse_private *);
-	void (*clear_txirq)(struct altera_tse_private *);
-	void (*clear_rxirq)(struct altera_tse_private *);
-	int (*tx_buffer)(struct altera_tse_private *, struct tse_buffer *);
-	u32 (*tx_completions)(struct altera_tse_private *);
-	void (*add_rx_desc)(struct altera_tse_private *, struct tse_buffer *);
-	u32 (*get_rx_status)(struct altera_tse_private *);
-	int (*init_dma)(struct altera_tse_private *);
-	void (*uninit_dma)(struct altera_tse_private *);
-	void (*start_rxdma)(struct altera_tse_private *);
+	void (*reset_dma)(struct altera_tse_private *priv);
+	void (*enable_txirq)(struct altera_tse_private *priv);
+	void (*enable_rxirq)(struct altera_tse_private *priv);
+	void (*disable_txirq)(struct altera_tse_private *priv);
+	void (*disable_rxirq)(struct altera_tse_private *priv);
+	void (*clear_txirq)(struct altera_tse_private *priv);
+	void (*clear_rxirq)(struct altera_tse_private *priv);
+	int (*tx_buffer)(struct altera_tse_private *priv,
+			 struct tse_buffer *buffer);
+	u32 (*tx_completions)(struct altera_tse_private *priv);
+	void (*add_rx_desc)(struct altera_tse_private *priv,
+			    struct tse_buffer *buffer);
+	u32 (*get_rx_status)(struct altera_tse_private *priv);
+	int (*init_dma)(struct altera_tse_private *priv);
+	void (*uninit_dma)(struct altera_tse_private *priv);
+	void (*start_rxdma)(struct altera_tse_private *priv);
 };
 
 /* This structure is private to each device.
-- 
2.13.0


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

* [PATCH v3 04/10] net: eth: altera: add optional function to start tx dma
  2020-06-04  7:32 [PATCH v3 00/10] net: eth: altera: tse: Add PTP and mSGDMA prefetcher Ooi, Joyce
                   ` (2 preceding siblings ...)
  2020-06-04  7:32 ` [PATCH v3 03/10] net: eth: altera: fix altera_dmaops declaration Ooi, Joyce
@ 2020-06-04  7:32 ` Ooi, Joyce
  2020-06-04  7:32 ` [PATCH v3 05/10] net: eth: altera: Move common functions to altera_utils Ooi, Joyce
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Ooi, Joyce @ 2020-06-04  7:32 UTC (permalink / raw)
  To: Thor Thayer, David S . Miller, Jakub Kicinski
  Cc: netdev, linux-kernel, Dalon Westergreen, Joyce Ooi, Tan Ley Foon,
	See Chin Liang, Dinh Nguyen, Dalon Westergreen

From: Dalon Westergreen <dalon.westergreen@intel.com>

Allow for optional start up of tx dma if the start_txdma
function is defined in altera_dmaops.

Signed-off-by: Dalon Westergreen <dalon.westergreen@intel.com>
Signed-off-by: Joyce Ooi <joyce.ooi@intel.com>
---
v2: no change
v3: no change
---
 drivers/net/ethernet/altera/altera_tse.h      | 1 +
 drivers/net/ethernet/altera/altera_tse_main.c | 5 +++++
 2 files changed, 6 insertions(+)

diff --git a/drivers/net/ethernet/altera/altera_tse.h b/drivers/net/ethernet/altera/altera_tse.h
index 7d0c98fc103e..26c5541fda27 100644
--- a/drivers/net/ethernet/altera/altera_tse.h
+++ b/drivers/net/ethernet/altera/altera_tse.h
@@ -401,6 +401,7 @@ struct altera_dmaops {
 	int (*init_dma)(struct altera_tse_private *priv);
 	void (*uninit_dma)(struct altera_tse_private *priv);
 	void (*start_rxdma)(struct altera_tse_private *priv);
+	void (*start_txdma)(struct altera_tse_private *priv);
 };
 
 /* This structure is private to each device.
diff --git a/drivers/net/ethernet/altera/altera_tse_main.c b/drivers/net/ethernet/altera/altera_tse_main.c
index 539e744e23f7..3c756afd0d39 100644
--- a/drivers/net/ethernet/altera/altera_tse_main.c
+++ b/drivers/net/ethernet/altera/altera_tse_main.c
@@ -1244,6 +1244,9 @@ static int tse_open(struct net_device *dev)
 
 	priv->dmaops->start_rxdma(priv);
 
+	if (priv->dmaops->start_txdma)
+		priv->dmaops->start_txdma(priv);
+
 	/* Start MAC Rx/Tx */
 	spin_lock(&priv->mac_cfg_lock);
 	tse_set_mac(priv, true);
@@ -1646,6 +1649,7 @@ static const struct altera_dmaops altera_dtype_sgdma = {
 	.init_dma = sgdma_initialize,
 	.uninit_dma = sgdma_uninitialize,
 	.start_rxdma = sgdma_start_rxdma,
+	.start_txdma = NULL,
 };
 
 static const struct altera_dmaops altera_dtype_msgdma = {
@@ -1665,6 +1669,7 @@ static const struct altera_dmaops altera_dtype_msgdma = {
 	.init_dma = msgdma_initialize,
 	.uninit_dma = msgdma_uninitialize,
 	.start_rxdma = msgdma_start_rxdma,
+	.start_txdma = NULL,
 };
 
 static const struct of_device_id altera_tse_ids[] = {
-- 
2.13.0


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

* [PATCH v3 05/10] net: eth: altera: Move common functions to altera_utils
  2020-06-04  7:32 [PATCH v3 00/10] net: eth: altera: tse: Add PTP and mSGDMA prefetcher Ooi, Joyce
                   ` (3 preceding siblings ...)
  2020-06-04  7:32 ` [PATCH v3 04/10] net: eth: altera: add optional function to start tx dma Ooi, Joyce
@ 2020-06-04  7:32 ` Ooi, Joyce
  2020-06-04  7:32 ` [PATCH v3 06/10] net: eth: altera: Add missing identifier names to function declarations Ooi, Joyce
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Ooi, Joyce @ 2020-06-04  7:32 UTC (permalink / raw)
  To: Thor Thayer, David S . Miller, Jakub Kicinski
  Cc: netdev, linux-kernel, Dalon Westergreen, Joyce Ooi, Tan Ley Foon,
	See Chin Liang, Dinh Nguyen, Dalon Westergreen

From: Dalon Westergreen <dalon.westergreen@intel.com>

Move request_and_map and other shared functions to altera_utils. This
is the first step to moving common code out of tse specific code so
that it can be shared with future altera ethernet ip.

Signed-off-by: Dalon Westergreen <dalon.westergreen@intel.com>
Signed-off-by: Joyce Ooi <joyce.ooi@intel.com>
---
v2: no change
v3: no change
---
 drivers/net/ethernet/altera/altera_tse.h         | 45 ---------------------
 drivers/net/ethernet/altera/altera_tse_ethtool.c |  1 +
 drivers/net/ethernet/altera/altera_tse_main.c    | 32 +--------------
 drivers/net/ethernet/altera/altera_utils.c       | 29 ++++++++++++++
 drivers/net/ethernet/altera/altera_utils.h       | 51 ++++++++++++++++++++++++
 5 files changed, 82 insertions(+), 76 deletions(-)

diff --git a/drivers/net/ethernet/altera/altera_tse.h b/drivers/net/ethernet/altera/altera_tse.h
index 26c5541fda27..fa24ab3c7d6a 100644
--- a/drivers/net/ethernet/altera/altera_tse.h
+++ b/drivers/net/ethernet/altera/altera_tse.h
@@ -489,49 +489,4 @@ struct altera_tse_private {
  */
 void altera_tse_set_ethtool_ops(struct net_device *);
 
-static inline
-u32 csrrd32(void __iomem *mac, size_t offs)
-{
-	void __iomem *paddr = (void __iomem *)((uintptr_t)mac + offs);
-	return readl(paddr);
-}
-
-static inline
-u16 csrrd16(void __iomem *mac, size_t offs)
-{
-	void __iomem *paddr = (void __iomem *)((uintptr_t)mac + offs);
-	return readw(paddr);
-}
-
-static inline
-u8 csrrd8(void __iomem *mac, size_t offs)
-{
-	void __iomem *paddr = (void __iomem *)((uintptr_t)mac + offs);
-	return readb(paddr);
-}
-
-static inline
-void csrwr32(u32 val, void __iomem *mac, size_t offs)
-{
-	void __iomem *paddr = (void __iomem *)((uintptr_t)mac + offs);
-
-	writel(val, paddr);
-}
-
-static inline
-void csrwr16(u16 val, void __iomem *mac, size_t offs)
-{
-	void __iomem *paddr = (void __iomem *)((uintptr_t)mac + offs);
-
-	writew(val, paddr);
-}
-
-static inline
-void csrwr8(u8 val, void __iomem *mac, size_t offs)
-{
-	void __iomem *paddr = (void __iomem *)((uintptr_t)mac + offs);
-
-	writeb(val, paddr);
-}
-
 #endif /* __ALTERA_TSE_H__ */
diff --git a/drivers/net/ethernet/altera/altera_tse_ethtool.c b/drivers/net/ethernet/altera/altera_tse_ethtool.c
index 4299f1301149..420d77f00eab 100644
--- a/drivers/net/ethernet/altera/altera_tse_ethtool.c
+++ b/drivers/net/ethernet/altera/altera_tse_ethtool.c
@@ -22,6 +22,7 @@
 #include <linux/phy.h>
 
 #include "altera_tse.h"
+#include "altera_utils.h"
 
 #define TSE_STATS_LEN	31
 #define TSE_NUM_REGS	128
diff --git a/drivers/net/ethernet/altera/altera_tse_main.c b/drivers/net/ethernet/altera/altera_tse_main.c
index 3c756afd0d39..87f789e42b6e 100644
--- a/drivers/net/ethernet/altera/altera_tse_main.c
+++ b/drivers/net/ethernet/altera/altera_tse_main.c
@@ -23,7 +23,6 @@
 #include <linux/if_vlan.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mii.h>
@@ -33,7 +32,7 @@
 #include <linux/of_net.h>
 #include <linux/of_platform.h>
 #include <linux/phy.h>
-#include <linux/platform_device.h>
+#include <linux/ptp_classify.h>
 #include <linux/skbuff.h>
 #include <asm/cacheflush.h>
 
@@ -1320,35 +1319,6 @@ static struct net_device_ops altera_tse_netdev_ops = {
 	.ndo_validate_addr	= eth_validate_addr,
 };
 
-static int request_and_map(struct platform_device *pdev, const char *name,
-			   struct resource **res, void __iomem **ptr)
-{
-	struct resource *region;
-	struct device *device = &pdev->dev;
-
-	*res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
-	if (*res == NULL) {
-		dev_err(device, "resource %s not defined\n", name);
-		return -ENODEV;
-	}
-
-	region = devm_request_mem_region(device, (*res)->start,
-					 resource_size(*res), dev_name(device));
-	if (region == NULL) {
-		dev_err(device, "unable to request %s\n", name);
-		return -EBUSY;
-	}
-
-	*ptr = devm_ioremap(device, region->start,
-				    resource_size(region));
-	if (*ptr == NULL) {
-		dev_err(device, "ioremap of %s failed!", name);
-		return -ENOMEM;
-	}
-
-	return 0;
-}
-
 /* Probe Altera TSE MAC device
  */
 static int altera_tse_probe(struct platform_device *pdev)
diff --git a/drivers/net/ethernet/altera/altera_utils.c b/drivers/net/ethernet/altera/altera_utils.c
index e6a7fc9d8fb1..c9bc7d0ea02a 100644
--- a/drivers/net/ethernet/altera/altera_utils.c
+++ b/drivers/net/ethernet/altera/altera_utils.c
@@ -31,3 +31,32 @@ int tse_bit_is_clear(void __iomem *ioaddr, size_t offs, u32 bit_mask)
 	u32 value = csrrd32(ioaddr, offs);
 	return (value & bit_mask) ? 0 : 1;
 }
+
+int request_and_map(struct platform_device *pdev, const char *name,
+		    struct resource **res, void __iomem **ptr)
+{
+	struct resource *region;
+	struct device *device = &pdev->dev;
+
+	*res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
+	if (!*res) {
+		dev_err(device, "resource %s not defined\n", name);
+		return -ENODEV;
+	}
+
+	region = devm_request_mem_region(device, (*res)->start,
+					 resource_size(*res), dev_name(device));
+	if (!region) {
+		dev_err(device, "unable to request %s\n", name);
+		return -EBUSY;
+	}
+
+	*ptr = devm_ioremap(device, region->start,
+			    resource_size(region));
+	if (!*ptr) {
+		dev_err(device, "ioremap of %s failed!", name);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
diff --git a/drivers/net/ethernet/altera/altera_utils.h b/drivers/net/ethernet/altera/altera_utils.h
index b7d772f2dcbb..fbe985099a44 100644
--- a/drivers/net/ethernet/altera/altera_utils.h
+++ b/drivers/net/ethernet/altera/altera_utils.h
@@ -3,7 +3,9 @@
  * Copyright (C) 2014 Altera Corporation. All rights reserved
  */
 
+#include <linux/platform_device.h>
 #include <linux/kernel.h>
+#include <linux/io.h>
 
 #ifndef __ALTERA_UTILS_H__
 #define __ALTERA_UTILS_H__
@@ -12,5 +14,54 @@ void tse_set_bit(void __iomem *ioaddr, size_t offs, u32 bit_mask);
 void tse_clear_bit(void __iomem *ioaddr, size_t offs, u32 bit_mask);
 int tse_bit_is_set(void __iomem *ioaddr, size_t offs, u32 bit_mask);
 int tse_bit_is_clear(void __iomem *ioaddr, size_t offs, u32 bit_mask);
+int request_and_map(struct platform_device *pdev, const char *name,
+		    struct resource **res, void __iomem **ptr);
 
+static inline
+u32 csrrd32(void __iomem *mac, size_t offs)
+{
+	void __iomem *paddr = (void __iomem *)((uintptr_t)mac + offs);
+
+	return readl(paddr);
+}
+
+static inline
+u16 csrrd16(void __iomem *mac, size_t offs)
+{
+	void __iomem *paddr = (void __iomem *)((uintptr_t)mac + offs);
+
+	return readw(paddr);
+}
+
+static inline
+u8 csrrd8(void __iomem *mac, size_t offs)
+{
+	void __iomem *paddr = (void __iomem *)((uintptr_t)mac + offs);
+
+	return readb(paddr);
+}
+
+static inline
+void csrwr32(u32 val, void __iomem *mac, size_t offs)
+{
+	void __iomem *paddr = (void __iomem *)((uintptr_t)mac + offs);
+
+	writel(val, paddr);
+}
+
+static inline
+void csrwr16(u16 val, void __iomem *mac, size_t offs)
+{
+	void __iomem *paddr = (void __iomem *)((uintptr_t)mac + offs);
+
+	writew(val, paddr);
+}
+
+static inline
+void csrwr8(u8 val, void __iomem *mac, size_t offs)
+{
+	void __iomem *paddr = (void __iomem *)((uintptr_t)mac + offs);
+
+	writeb(val, paddr);
+}
 #endif /* __ALTERA_UTILS_H__*/
-- 
2.13.0


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

* [PATCH v3 06/10] net: eth: altera: Add missing identifier names to function declarations
  2020-06-04  7:32 [PATCH v3 00/10] net: eth: altera: tse: Add PTP and mSGDMA prefetcher Ooi, Joyce
                   ` (4 preceding siblings ...)
  2020-06-04  7:32 ` [PATCH v3 05/10] net: eth: altera: Move common functions to altera_utils Ooi, Joyce
@ 2020-06-04  7:32 ` Ooi, Joyce
  2020-06-04  7:32 ` [PATCH v3 07/10] net: eth: altera: change tx functions to type netdev_tx_t Ooi, Joyce
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Ooi, Joyce @ 2020-06-04  7:32 UTC (permalink / raw)
  To: Thor Thayer, David S . Miller, Jakub Kicinski
  Cc: netdev, linux-kernel, Dalon Westergreen, Joyce Ooi, Tan Ley Foon,
	See Chin Liang, Dinh Nguyen

From: Dalon Westergreen <dalon.westergreen@linux.intel.com>

The sgdma and msgdma header files included function declarations
without identifier names for pointers.  Add appropriate identifier
names.

Signed-off-by: Dalon Westergreen <dalon.westergreen@linux.intel.com>
Signed-off-by: Joyce Ooi <joyce.ooi@intel.com>
---
v2: this patch is added in patch version 2
v3: no change
---
 drivers/net/ethernet/altera/altera_msgdma.h | 30 ++++++++++++++-------------
 drivers/net/ethernet/altera/altera_sgdma.h  | 32 +++++++++++++++--------------
 2 files changed, 33 insertions(+), 29 deletions(-)

diff --git a/drivers/net/ethernet/altera/altera_msgdma.h b/drivers/net/ethernet/altera/altera_msgdma.h
index 9813fbfff4d3..23f5b2a13898 100644
--- a/drivers/net/ethernet/altera/altera_msgdma.h
+++ b/drivers/net/ethernet/altera/altera_msgdma.h
@@ -6,19 +6,21 @@
 #ifndef __ALTERA_MSGDMA_H__
 #define __ALTERA_MSGDMA_H__
 
-void msgdma_reset(struct altera_tse_private *);
-void msgdma_enable_txirq(struct altera_tse_private *);
-void msgdma_enable_rxirq(struct altera_tse_private *);
-void msgdma_disable_rxirq(struct altera_tse_private *);
-void msgdma_disable_txirq(struct altera_tse_private *);
-void msgdma_clear_rxirq(struct altera_tse_private *);
-void msgdma_clear_txirq(struct altera_tse_private *);
-u32 msgdma_tx_completions(struct altera_tse_private *);
-void msgdma_add_rx_desc(struct altera_tse_private *, struct tse_buffer *);
-int msgdma_tx_buffer(struct altera_tse_private *, struct tse_buffer *);
-u32 msgdma_rx_status(struct altera_tse_private *);
-int msgdma_initialize(struct altera_tse_private *);
-void msgdma_uninitialize(struct altera_tse_private *);
-void msgdma_start_rxdma(struct altera_tse_private *);
+void msgdma_reset(struct altera_tse_private *priv);
+void msgdma_enable_txirq(struct altera_tse_private *priv);
+void msgdma_enable_rxirq(struct altera_tse_private *priv);
+void msgdma_disable_rxirq(struct altera_tse_private *priv);
+void msgdma_disable_txirq(struct altera_tse_private *priv);
+void msgdma_clear_rxirq(struct altera_tse_private *priv);
+void msgdma_clear_txirq(struct altera_tse_private *priv);
+u32 msgdma_tx_completions(struct altera_tse_private *priv);
+void msgdma_add_rx_desc(struct altera_tse_private *priv,
+			struct tse_buffer *buffer);
+int msgdma_tx_buffer(struct altera_tse_private *priv,
+		     struct tse_buffer *buffer);
+u32 msgdma_rx_status(struct altera_tse_private *priv);
+int msgdma_initialize(struct altera_tse_private *priv);
+void msgdma_uninitialize(struct altera_tse_private *priv);
+void msgdma_start_rxdma(struct altera_tse_private *priv);
 
 #endif /*  __ALTERA_MSGDMA_H__ */
diff --git a/drivers/net/ethernet/altera/altera_sgdma.h b/drivers/net/ethernet/altera/altera_sgdma.h
index 08afe1c9994f..3fb201417820 100644
--- a/drivers/net/ethernet/altera/altera_sgdma.h
+++ b/drivers/net/ethernet/altera/altera_sgdma.h
@@ -6,20 +6,22 @@
 #ifndef __ALTERA_SGDMA_H__
 #define __ALTERA_SGDMA_H__
 
-void sgdma_reset(struct altera_tse_private *);
-void sgdma_enable_txirq(struct altera_tse_private *);
-void sgdma_enable_rxirq(struct altera_tse_private *);
-void sgdma_disable_rxirq(struct altera_tse_private *);
-void sgdma_disable_txirq(struct altera_tse_private *);
-void sgdma_clear_rxirq(struct altera_tse_private *);
-void sgdma_clear_txirq(struct altera_tse_private *);
-int sgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *);
-u32 sgdma_tx_completions(struct altera_tse_private *);
-void sgdma_add_rx_desc(struct altera_tse_private *priv, struct tse_buffer *);
-void sgdma_status(struct altera_tse_private *);
-u32 sgdma_rx_status(struct altera_tse_private *);
-int sgdma_initialize(struct altera_tse_private *);
-void sgdma_uninitialize(struct altera_tse_private *);
-void sgdma_start_rxdma(struct altera_tse_private *);
+void sgdma_reset(struct altera_tse_private *priv);
+void sgdma_enable_txirq(struct altera_tse_private *priv);
+void sgdma_enable_rxirq(struct altera_tse_private *priv);
+void sgdma_disable_rxirq(struct altera_tse_private *priv);
+void sgdma_disable_txirq(struct altera_tse_private *priv);
+void sgdma_clear_rxirq(struct altera_tse_private *priv);
+void sgdma_clear_txirq(struct altera_tse_private *priv);
+int sgdma_tx_buffer(struct altera_tse_private *priv,
+		    struct tse_buffer *buffer);
+u32 sgdma_tx_completions(struct altera_tse_private *priv);
+void sgdma_add_rx_desc(struct altera_tse_private *priv,
+		       struct tse_buffer *buffer);
+void sgdma_status(struct altera_tse_private *priv);
+u32 sgdma_rx_status(struct altera_tse_private *priv);
+int sgdma_initialize(struct altera_tse_private *priv);
+void sgdma_uninitialize(struct altera_tse_private *priv);
+void sgdma_start_rxdma(struct altera_tse_private *priv);
 
 #endif /*  __ALTERA_SGDMA_H__ */
-- 
2.13.0


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

* [PATCH v3 07/10] net: eth: altera: change tx functions to type netdev_tx_t
  2020-06-04  7:32 [PATCH v3 00/10] net: eth: altera: tse: Add PTP and mSGDMA prefetcher Ooi, Joyce
                   ` (5 preceding siblings ...)
  2020-06-04  7:32 ` [PATCH v3 06/10] net: eth: altera: Add missing identifier names to function declarations Ooi, Joyce
@ 2020-06-04  7:32 ` Ooi, Joyce
  2020-06-04  7:32 ` [PATCH v3 08/10] net: eth: altera: add support for ptp and timestamping Ooi, Joyce
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Ooi, Joyce @ 2020-06-04  7:32 UTC (permalink / raw)
  To: Thor Thayer, David S . Miller, Jakub Kicinski
  Cc: netdev, linux-kernel, Dalon Westergreen, Joyce Ooi, Tan Ley Foon,
	See Chin Liang, Dinh Nguyen

From: Dalon Westergreen <dalon.westergreen@linux.intel.com>

Modify all msgdma and sgdma tx_buffer functions to be of type
netdev_tx_t, and also modify main tx function to be of
netdev_tx_t type.

Signed-off-by: Dalon Westergreen <dalon.westergreen@linux.intel.com>
Signed-off-by: Joyce Ooi <joyce.ooi@intel.com>
---
v2: this patch is added in patch version 2
v3: no change
---
 drivers/net/ethernet/altera/altera_msgdma.c   | 5 +++--
 drivers/net/ethernet/altera/altera_msgdma.h   | 4 ++--
 drivers/net/ethernet/altera/altera_sgdma.c    | 5 +++--
 drivers/net/ethernet/altera/altera_sgdma.h    | 4 ++--
 drivers/net/ethernet/altera/altera_tse.h      | 4 ++--
 drivers/net/ethernet/altera/altera_tse_main.c | 2 +-
 6 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/altera/altera_msgdma.c b/drivers/net/ethernet/altera/altera_msgdma.c
index ac1efd08267a..ac68151a7f47 100644
--- a/drivers/net/ethernet/altera/altera_msgdma.c
+++ b/drivers/net/ethernet/altera/altera_msgdma.c
@@ -106,7 +106,8 @@ void msgdma_clear_txirq(struct altera_tse_private *priv)
 }
 
 /* return 0 to indicate transmit is pending */
-int msgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer)
+netdev_tx_t
+msgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer)
 {
 	csrwr32(lower_32_bits(buffer->dma_addr), priv->tx_dma_desc,
 		msgdma_descroffs(read_addr_lo));
@@ -120,7 +121,7 @@ int msgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer)
 		msgdma_descroffs(stride));
 	csrwr32(MSGDMA_DESC_CTL_TX_SINGLE, priv->tx_dma_desc,
 		msgdma_descroffs(control));
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 u32 msgdma_tx_completions(struct altera_tse_private *priv)
diff --git a/drivers/net/ethernet/altera/altera_msgdma.h b/drivers/net/ethernet/altera/altera_msgdma.h
index 23f5b2a13898..d816b24dfa7f 100644
--- a/drivers/net/ethernet/altera/altera_msgdma.h
+++ b/drivers/net/ethernet/altera/altera_msgdma.h
@@ -16,8 +16,8 @@ void msgdma_clear_txirq(struct altera_tse_private *priv);
 u32 msgdma_tx_completions(struct altera_tse_private *priv);
 void msgdma_add_rx_desc(struct altera_tse_private *priv,
 			struct tse_buffer *buffer);
-int msgdma_tx_buffer(struct altera_tse_private *priv,
-		     struct tse_buffer *buffer);
+netdev_tx_t msgdma_tx_buffer(struct altera_tse_private *priv,
+			     struct tse_buffer *buffer);
 u32 msgdma_rx_status(struct altera_tse_private *priv);
 int msgdma_initialize(struct altera_tse_private *priv);
 void msgdma_uninitialize(struct altera_tse_private *priv);
diff --git a/drivers/net/ethernet/altera/altera_sgdma.c b/drivers/net/ethernet/altera/altera_sgdma.c
index fe6276c7e4a3..6898ec682425 100644
--- a/drivers/net/ethernet/altera/altera_sgdma.c
+++ b/drivers/net/ethernet/altera/altera_sgdma.c
@@ -166,7 +166,8 @@ void sgdma_clear_txirq(struct altera_tse_private *priv)
  *   will now actually look at the code, so from now, 0 is good and return
  *   NETDEV_TX_BUSY when busy.
  */
-int sgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer)
+netdev_tx_t
+sgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer)
 {
 	struct sgdma_descrip __iomem *descbase =
 		(struct sgdma_descrip __iomem *)priv->tx_dma_desc;
@@ -196,7 +197,7 @@ int sgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer)
 	/* enqueue the request to the pending transmit queue */
 	queue_tx(priv, buffer);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
diff --git a/drivers/net/ethernet/altera/altera_sgdma.h b/drivers/net/ethernet/altera/altera_sgdma.h
index 3fb201417820..6a41833f0965 100644
--- a/drivers/net/ethernet/altera/altera_sgdma.h
+++ b/drivers/net/ethernet/altera/altera_sgdma.h
@@ -13,8 +13,8 @@ void sgdma_disable_rxirq(struct altera_tse_private *priv);
 void sgdma_disable_txirq(struct altera_tse_private *priv);
 void sgdma_clear_rxirq(struct altera_tse_private *priv);
 void sgdma_clear_txirq(struct altera_tse_private *priv);
-int sgdma_tx_buffer(struct altera_tse_private *priv,
-		    struct tse_buffer *buffer);
+netdev_tx_t sgdma_tx_buffer(struct altera_tse_private *priv,
+			    struct tse_buffer *buffer);
 u32 sgdma_tx_completions(struct altera_tse_private *priv);
 void sgdma_add_rx_desc(struct altera_tse_private *priv,
 		       struct tse_buffer *buffer);
diff --git a/drivers/net/ethernet/altera/altera_tse.h b/drivers/net/ethernet/altera/altera_tse.h
index fa24ab3c7d6a..79d02748c89d 100644
--- a/drivers/net/ethernet/altera/altera_tse.h
+++ b/drivers/net/ethernet/altera/altera_tse.h
@@ -392,8 +392,8 @@ struct altera_dmaops {
 	void (*disable_rxirq)(struct altera_tse_private *priv);
 	void (*clear_txirq)(struct altera_tse_private *priv);
 	void (*clear_rxirq)(struct altera_tse_private *priv);
-	int (*tx_buffer)(struct altera_tse_private *priv,
-			 struct tse_buffer *buffer);
+	netdev_tx_t (*tx_buffer)(struct altera_tse_private *priv,
+				 struct tse_buffer *buffer);
 	u32 (*tx_completions)(struct altera_tse_private *priv);
 	void (*add_rx_desc)(struct altera_tse_private *priv,
 			    struct tse_buffer *buffer);
diff --git a/drivers/net/ethernet/altera/altera_tse_main.c b/drivers/net/ethernet/altera/altera_tse_main.c
index 87f789e42b6e..24a1d30c6780 100644
--- a/drivers/net/ethernet/altera/altera_tse_main.c
+++ b/drivers/net/ethernet/altera/altera_tse_main.c
@@ -553,7 +553,7 @@ static irqreturn_t altera_isr(int irq, void *dev_id)
  * physically contiguous fragment starting at
  * skb->data, for length of skb_headlen(skb).
  */
-static int tse_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t tse_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct altera_tse_private *priv = netdev_priv(dev);
 	unsigned int txsize = priv->tx_ring_size;
-- 
2.13.0


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

* [PATCH v3 08/10] net: eth: altera: add support for ptp and timestamping
  2020-06-04  7:32 [PATCH v3 00/10] net: eth: altera: tse: Add PTP and mSGDMA prefetcher Ooi, Joyce
                   ` (6 preceding siblings ...)
  2020-06-04  7:32 ` [PATCH v3 07/10] net: eth: altera: change tx functions to type netdev_tx_t Ooi, Joyce
@ 2020-06-04  7:32 ` Ooi, Joyce
  2020-06-04  7:32 ` [PATCH v3 09/10] net: eth: altera: add msgdma prefetcher Ooi, Joyce
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: Ooi, Joyce @ 2020-06-04  7:32 UTC (permalink / raw)
  To: Thor Thayer, David S . Miller, Jakub Kicinski
  Cc: netdev, linux-kernel, Dalon Westergreen, Joyce Ooi, Tan Ley Foon,
	See Chin Liang, Dinh Nguyen, Dalon Westergreen, Richard Cochran

From: Dalon Westergreen <dalon.westergreen@intel.com>

Add support for the ptp clock used with the tse, and update
the driver to support timestamping when enabled.  We also
enable debugfs entries for the ptp clock to allow some user
control and interaction with the ptp clock.

Cc: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: Dalon Westergreen <dalon.westergreen@intel.com>
Signed-off-by: Joyce Ooi <joyce.ooi@intel.com>
---
v2: this patch is added in patch version 2
v3: no change
---
 drivers/net/ethernet/altera/Kconfig              |   1 +
 drivers/net/ethernet/altera/Makefile             |   3 +-
 drivers/net/ethernet/altera/altera_tse.h         |   8 +
 drivers/net/ethernet/altera/altera_tse_ethtool.c |  28 ++
 drivers/net/ethernet/altera/altera_tse_main.c    | 118 +++++++-
 drivers/net/ethernet/altera/intel_fpga_tod.c     | 358 +++++++++++++++++++++++
 drivers/net/ethernet/altera/intel_fpga_tod.h     |  56 ++++
 7 files changed, 570 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/altera/intel_fpga_tod.c
 create mode 100644 drivers/net/ethernet/altera/intel_fpga_tod.h

diff --git a/drivers/net/ethernet/altera/Kconfig b/drivers/net/ethernet/altera/Kconfig
index 2690c398d2b2..6dec7094cb4b 100644
--- a/drivers/net/ethernet/altera/Kconfig
+++ b/drivers/net/ethernet/altera/Kconfig
@@ -3,6 +3,7 @@ config ALTERA_TSE
 	tristate "Altera Triple-Speed Ethernet MAC support"
 	depends on HAS_DMA
 	select PHYLIB
+	imply PTP_1588_CLOCK
 	---help---
 	  This driver supports the Altera Triple-Speed (TSE) Ethernet MAC.
 
diff --git a/drivers/net/ethernet/altera/Makefile b/drivers/net/ethernet/altera/Makefile
index a52db80aee9f..fc2e460926b3 100644
--- a/drivers/net/ethernet/altera/Makefile
+++ b/drivers/net/ethernet/altera/Makefile
@@ -5,4 +5,5 @@
 
 obj-$(CONFIG_ALTERA_TSE) += altera_tse.o
 altera_tse-objs := altera_tse_main.o altera_tse_ethtool.o \
-altera_msgdma.o altera_sgdma.o altera_utils.o
+		   altera_msgdma.o altera_sgdma.o altera_utils.o \
+		   intel_fpga_tod.o
diff --git a/drivers/net/ethernet/altera/altera_tse.h b/drivers/net/ethernet/altera/altera_tse.h
index 79d02748c89d..b7c176a808ac 100644
--- a/drivers/net/ethernet/altera/altera_tse.h
+++ b/drivers/net/ethernet/altera/altera_tse.h
@@ -28,6 +28,8 @@
 #include <linux/netdevice.h>
 #include <linux/phy.h>
 
+#include "intel_fpga_tod.h"
+
 #define ALTERA_TSE_SW_RESET_WATCHDOG_CNTR	10000
 #define ALTERA_TSE_MAC_FIFO_WIDTH		4	/* TX/RX FIFO width in
 							 * bytes
@@ -417,6 +419,12 @@ struct altera_tse_private {
 	/* TSE Revision */
 	u32	revision;
 
+	/* Shared PTP structure */
+	struct intel_fpga_tod_private ptp_priv;
+	int hwts_tx_en;
+	int hwts_rx_en;
+	u32 ptp_enable;
+
 	/* mSGDMA Rx Dispatcher address space */
 	void __iomem *rx_dma_csr;
 	void __iomem *rx_dma_desc;
diff --git a/drivers/net/ethernet/altera/altera_tse_ethtool.c b/drivers/net/ethernet/altera/altera_tse_ethtool.c
index 420d77f00eab..cec41a2c7b00 100644
--- a/drivers/net/ethernet/altera/altera_tse_ethtool.c
+++ b/drivers/net/ethernet/altera/altera_tse_ethtool.c
@@ -19,6 +19,7 @@
 #include <linux/ethtool.h>
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
+#include <linux/net_tstamp.h>
 #include <linux/phy.h>
 
 #include "altera_tse.h"
@@ -222,6 +223,32 @@ static void tse_get_regs(struct net_device *dev, struct ethtool_regs *regs,
 		buf[i] = csrrd32(priv->mac_dev, i * 4);
 }
 
+static int tse_get_ts_info(struct net_device *dev,
+			   struct ethtool_ts_info *info)
+{
+	struct altera_tse_private *priv = netdev_priv(dev);
+
+	if (priv->ptp_enable) {
+		if (priv->ptp_priv.ptp_clock)
+			info->phc_index =
+				ptp_clock_index(priv->ptp_priv.ptp_clock);
+
+		info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
+					SOF_TIMESTAMPING_RX_HARDWARE |
+					SOF_TIMESTAMPING_RAW_HARDWARE;
+
+		info->tx_types = (1 << HWTSTAMP_TX_OFF) |
+						 (1 << HWTSTAMP_TX_ON);
+
+		info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
+						   (1 << HWTSTAMP_FILTER_ALL);
+
+		return 0;
+	} else {
+		return ethtool_op_get_ts_info(dev, info);
+	}
+}
+
 static const struct ethtool_ops tse_ethtool_ops = {
 	.get_drvinfo = tse_get_drvinfo,
 	.get_regs_len = tse_reglen,
@@ -234,6 +261,7 @@ static const struct ethtool_ops tse_ethtool_ops = {
 	.set_msglevel = tse_set_msglevel,
 	.get_link_ksettings = phy_ethtool_get_link_ksettings,
 	.set_link_ksettings = phy_ethtool_set_link_ksettings,
+	.get_ts_info = tse_get_ts_info,
 };
 
 void altera_tse_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/ethernet/altera/altera_tse_main.c b/drivers/net/ethernet/altera/altera_tse_main.c
index 24a1d30c6780..c874b8c1dd48 100644
--- a/drivers/net/ethernet/altera/altera_tse_main.c
+++ b/drivers/net/ethernet/altera/altera_tse_main.c
@@ -18,14 +18,17 @@
  */
 
 #include <linux/atomic.h>
+#include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/etherdevice.h>
+#include <linux/if_ether.h>
 #include <linux/if_vlan.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mii.h>
+#include <linux/net_tstamp.h>
 #include <linux/netdevice.h>
 #include <linux/of_device.h>
 #include <linux/of_mdio.h>
@@ -40,6 +43,7 @@
 #include "altera_tse.h"
 #include "altera_sgdma.h"
 #include "altera_msgdma.h"
+#include "intel_fpga_tod.h"
 
 static atomic_t instance_count = ATOMIC_INIT(~0);
 /* Module parameters */
@@ -598,7 +602,11 @@ static netdev_tx_t tse_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (ret)
 		goto out;
 
-	skb_tx_timestamp(skb);
+	if (unlikely((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
+		     priv->hwts_tx_en))
+		skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+	else
+		skb_tx_timestamp(skb);
 
 	priv->tx_prod++;
 	dev->stats.tx_bytes += skb->len;
@@ -1238,6 +1246,13 @@ static int tse_open(struct net_device *dev)
 	if (dev->phydev)
 		phy_start(dev->phydev);
 
+	ret = intel_fpga_tod_init(&priv->ptp_priv);
+	if (ret)
+		netdev_warn(dev, "Failed PTP initialization\n");
+
+	priv->hwts_tx_en = 0;
+	priv->hwts_rx_en = 0;
+
 	napi_enable(&priv->napi);
 	netif_start_queue(dev);
 
@@ -1309,6 +1324,83 @@ static int tse_shutdown(struct net_device *dev)
 	return 0;
 }
 
+/* ioctl to configure timestamping */
+static int tse_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	struct altera_tse_private *priv = netdev_priv(dev);
+	struct hwtstamp_config config;
+
+	if (!netif_running(dev))
+		return -EINVAL;
+
+	if (!priv->ptp_enable)	{
+		netdev_alert(priv->dev, "Timestamping not supported");
+		return -EOPNOTSUPP;
+	}
+
+	if (cmd == SIOCSHWTSTAMP) {
+		if (copy_from_user(&config, ifr->ifr_data,
+				   sizeof(struct hwtstamp_config)))
+			return -EFAULT;
+
+		if (config.flags)
+			return -EINVAL;
+
+		switch (config.tx_type) {
+		case HWTSTAMP_TX_OFF:
+			priv->hwts_tx_en = 0;
+			break;
+		case HWTSTAMP_TX_ON:
+			priv->hwts_tx_en = 1;
+			break;
+		default:
+			return -ERANGE;
+		}
+
+		switch (config.rx_filter) {
+		case HWTSTAMP_FILTER_NONE:
+			priv->hwts_rx_en = 0;
+			config.rx_filter = HWTSTAMP_FILTER_NONE;
+			break;
+		default:
+			priv->hwts_rx_en = 1;
+			config.rx_filter = HWTSTAMP_FILTER_ALL;
+			break;
+		}
+
+		if (copy_to_user(ifr->ifr_data, &config,
+				 sizeof(struct hwtstamp_config)))
+			return -EFAULT;
+		else
+			return 0;
+	}
+
+	if (cmd == SIOCGHWTSTAMP) {
+		config.flags = 0;
+
+		if (priv->hwts_tx_en)
+			config.tx_type = HWTSTAMP_TX_ON;
+		else
+			config.tx_type = HWTSTAMP_TX_OFF;
+
+		if (priv->hwts_rx_en)
+			config.rx_filter = HWTSTAMP_FILTER_ALL;
+		else
+			config.rx_filter = HWTSTAMP_FILTER_NONE;
+
+		if (copy_to_user(ifr->ifr_data, &config,
+				 sizeof(struct hwtstamp_config)))
+			return -EFAULT;
+		else
+			return 0;
+	}
+
+	if (!dev->phydev)
+		return -EINVAL;
+
+	return phy_mii_ioctl(dev->phydev, ifr, cmd);
+}
+
 static struct net_device_ops altera_tse_netdev_ops = {
 	.ndo_open		= tse_open,
 	.ndo_stop		= tse_shutdown,
@@ -1317,6 +1409,7 @@ static struct net_device_ops altera_tse_netdev_ops = {
 	.ndo_set_rx_mode	= tse_set_rx_mode,
 	.ndo_change_mtu		= tse_change_mtu,
 	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_do_ioctl		= tse_do_ioctl,
 };
 
 /* Probe Altera TSE MAC device
@@ -1568,6 +1661,27 @@ static int altera_tse_probe(struct platform_device *pdev)
 		netdev_err(ndev, "Cannot attach to PHY (error: %d)\n", ret);
 		goto err_init_phy;
 	}
+
+	priv->ptp_enable = of_property_read_bool(pdev->dev.of_node,
+						 "altr,has-ptp");
+	dev_info(&pdev->dev, "PTP Enable: %d\n", priv->ptp_enable);
+
+	if (priv->ptp_enable) {
+		/* MAP PTP */
+		ret = intel_fpga_tod_probe(pdev, &priv->ptp_priv);
+		if (ret) {
+			dev_err(&pdev->dev, "cannot map PTP\n");
+			goto err_init_phy;
+		}
+		ret = intel_fpga_tod_register(&priv->ptp_priv,
+					      priv->device);
+		if (ret) {
+			dev_err(&pdev->dev, "Failed to register PTP clock\n");
+			ret = -ENXIO;
+			goto err_init_phy;
+		}
+	}
+
 	return 0;
 
 err_init_phy:
@@ -1595,6 +1709,8 @@ static int altera_tse_remove(struct platform_device *pdev)
 	}
 
 	platform_set_drvdata(pdev, NULL);
+	if (priv->ptp_enable)
+		intel_fpga_tod_unregister(&priv->ptp_priv);
 	altera_tse_mdio_destroy(ndev);
 	unregister_netdev(ndev);
 	free_netdev(ndev);
diff --git a/drivers/net/ethernet/altera/intel_fpga_tod.c b/drivers/net/ethernet/altera/intel_fpga_tod.c
new file mode 100644
index 000000000000..3771597642da
--- /dev/null
+++ b/drivers/net/ethernet/altera/intel_fpga_tod.c
@@ -0,0 +1,358 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Intel FPGA ToD PTP Hardware Clock (PHC) Linux driver
+ * Copyright (C) 2015-2016 Altera Corporation. All rights reserved.
+ * Copyright (C) 2017-2020 Intel Corporation. All rights reserved.
+ *
+ * Author(s):
+ *	Dalon Westergreen <dalon.westergreen@intel.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gcd.h>
+#include <linux/module.h>
+#include <linux/math64.h>
+#include <linux/net_tstamp.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+
+#include "altera_utils.h"
+#include "intel_fpga_tod.h"
+
+#define NOMINAL_PPB			1000000000ULL
+#define TOD_PERIOD_MAX			0xfffff
+#define TOD_PERIOD_MIN			0
+#define TOD_DRIFT_ADJUST_FNS_MAX	0xffff
+#define TOD_DRIFT_ADJUST_RATE_MAX	0xffff
+#define TOD_ADJUST_COUNT_MAX		0xfffff
+#define TOD_ADJUST_MS_MAX		(((((TOD_PERIOD_MAX) >> 16) + 1) * \
+					  ((TOD_ADJUST_COUNT_MAX) + 1)) /  \
+					 1000000UL)
+
+/* A fine ToD HW clock offset adjustment.
+ * To perform the fine offset adjustment the AdjustPeriod register is used
+ * to replace the Period register for AdjustCount clock cycles in hardware.
+ */
+static int fine_adjust_tod_clock(struct intel_fpga_tod_private *priv,
+				 u32 adjust_period, u32 adjust_count)
+{
+	int limit;
+
+	csrwr32(adjust_period, priv->tod_ctrl, tod_csroffs(adjust_period));
+	csrwr32(adjust_count, priv->tod_ctrl, tod_csroffs(adjust_count));
+
+	/* Wait for present offset adjustment update to complete */
+	limit = TOD_ADJUST_MS_MAX;
+	while (limit--) {
+		if (!csrrd32(priv->tod_ctrl, tod_csroffs(adjust_count)))
+			break;
+		mdelay(1);
+	}
+	if (limit < 0)
+		return -EBUSY;
+
+	return 0;
+}
+
+/* A coarse ToD HW clock offset adjustment.
+ * The coarse time adjustment performs by adding or subtracting the delta value
+ * from the current ToD HW clock time.
+ */
+static int coarse_adjust_tod_clock(struct intel_fpga_tod_private *priv,
+				   s64 delta)
+{
+	u32 seconds_msb, seconds_lsb, nanosec;
+	u64 seconds, now;
+
+	if (delta == 0)
+		goto out;
+
+	/* Get current time */
+	nanosec = csrrd32(priv->tod_ctrl, tod_csroffs(nanosec));
+	seconds_lsb = csrrd32(priv->tod_ctrl, tod_csroffs(seconds_lsb));
+	seconds_msb = csrrd32(priv->tod_ctrl, tod_csroffs(seconds_msb));
+
+	/* Calculate new time */
+	seconds = (((u64)(seconds_msb & 0x0000ffff)) << 32) | seconds_lsb;
+	now = seconds * NSEC_PER_SEC + nanosec + delta;
+
+	seconds = div_u64_rem(now, NSEC_PER_SEC, &nanosec);
+	seconds_msb = upper_32_bits(seconds) & 0x0000ffff;
+	seconds_lsb = lower_32_bits(seconds);
+
+	/* Set corrected time */
+	csrwr32(seconds_msb, priv->tod_ctrl, tod_csroffs(seconds_msb));
+	csrwr32(seconds_lsb, priv->tod_ctrl, tod_csroffs(seconds_lsb));
+	csrwr32(nanosec, priv->tod_ctrl, tod_csroffs(nanosec));
+
+out:
+	return 0;
+}
+
+static int intel_fpga_tod_adjust_fine(struct ptp_clock_info *ptp,
+				      long scaled_ppm)
+{
+	struct intel_fpga_tod_private *priv =
+		container_of(ptp, struct intel_fpga_tod_private, ptp_clock_ops);
+	u32 tod_period, tod_rem, tod_drift_adjust_fns, tod_drift_adjust_rate;
+	unsigned long flags;
+	unsigned long rate;
+	int ret = 0;
+	u64 ppb;
+
+	rate = clk_get_rate(priv->tod_clk);
+
+	/* From scaled_ppm_to_ppb */
+	ppb = 1 + scaled_ppm;
+	ppb *= 125;
+	ppb >>= 13;
+
+	ppb += NOMINAL_PPB;
+
+	tod_period = div_u64_rem(ppb << 16, rate, &tod_rem);
+	if (tod_period > TOD_PERIOD_MAX) {
+		ret = -ERANGE;
+		goto out;
+	}
+
+	/* The drift of ToD adjusted periodically by adding a drift_adjust_fns
+	 * correction value every drift_adjust_rate count of clock cycles.
+	 */
+	tod_drift_adjust_fns = tod_rem / gcd(tod_rem, rate);
+	tod_drift_adjust_rate = rate / gcd(tod_rem, rate);
+
+	while ((tod_drift_adjust_fns > TOD_DRIFT_ADJUST_FNS_MAX) |
+		(tod_drift_adjust_rate > TOD_DRIFT_ADJUST_RATE_MAX)) {
+		tod_drift_adjust_fns = tod_drift_adjust_fns >> 1;
+		tod_drift_adjust_rate = tod_drift_adjust_rate >> 1;
+	}
+
+	if (tod_drift_adjust_fns == 0)
+		tod_drift_adjust_rate = 0;
+
+	spin_lock_irqsave(&priv->tod_lock, flags);
+	csrwr32(tod_period, priv->tod_ctrl, tod_csroffs(period));
+	csrwr32(0, priv->tod_ctrl, tod_csroffs(adjust_period));
+	csrwr32(0, priv->tod_ctrl, tod_csroffs(adjust_count));
+	csrwr32(tod_drift_adjust_fns, priv->tod_ctrl,
+		tod_csroffs(drift_adjust));
+	csrwr32(tod_drift_adjust_rate, priv->tod_ctrl,
+		tod_csroffs(drift_adjust_rate));
+	spin_unlock_irqrestore(&priv->tod_lock, flags);
+
+out:
+	return ret;
+}
+
+static int intel_fpga_tod_adjust_time(struct ptp_clock_info *ptp, s64 delta)
+{
+	struct intel_fpga_tod_private *priv =
+		container_of(ptp, struct intel_fpga_tod_private, ptp_clock_ops);
+	unsigned long flags;
+	u32 period, diff, rem, rem_period, adj_period;
+	u64 count;
+	int neg_adj = 0, ret = 0;
+
+	if (delta < 0) {
+		neg_adj = 1;
+		delta = -delta;
+	}
+
+	spin_lock_irqsave(&priv->tod_lock, flags);
+
+	/* Get the maximum possible value of the Period register offset
+	 * adjustment in nanoseconds scale. This depends on the current
+	 * Period register setting and the maximum and minimum possible
+	 * values of the Period register.
+	 */
+	period = csrrd32(priv->tod_ctrl, tod_csroffs(period));
+
+	if (neg_adj)
+		diff = (period - TOD_PERIOD_MIN) >> 16;
+	else
+		diff = (TOD_PERIOD_MAX - period) >> 16;
+
+	/* Find the number of cycles required for the
+	 * time adjustment
+	 */
+	count = div_u64_rem(delta, diff, &rem);
+
+	if (neg_adj) {
+		adj_period = period - (diff << 16);
+		rem_period = period - (rem << 16);
+	} else {
+		adj_period = period + (diff << 16);
+		rem_period = period + (rem << 16);
+	}
+
+	/* If count is larger than the maximum count,
+	 * just set the time.
+	 */
+	if (count > TOD_ADJUST_COUNT_MAX) {
+		/* Perform the coarse time offset adjustment */
+		ret = coarse_adjust_tod_clock(priv, delta);
+	} else {
+		/* Adjust the period for count cycles to adjust
+		 * the time.
+		 */
+		if (count)
+			ret = fine_adjust_tod_clock(priv, adj_period, count);
+
+		/* If there is a remainder, adjust the period for an
+		 * additional cycle
+		 */
+		if (rem)
+			ret = fine_adjust_tod_clock(priv, rem_period, 1);
+	}
+
+	spin_unlock_irqrestore(&priv->tod_lock, flags);
+
+	return ret;
+}
+
+static int intel_fpga_tod_get_time(struct ptp_clock_info *ptp,
+				   struct timespec64 *ts)
+{
+	struct intel_fpga_tod_private *priv =
+		container_of(ptp, struct intel_fpga_tod_private, ptp_clock_ops);
+	u32 seconds_msb, seconds_lsb, nanosec;
+	unsigned long flags;
+	u64 seconds;
+
+	spin_lock_irqsave(&priv->tod_lock, flags);
+	nanosec = csrrd32(priv->tod_ctrl, tod_csroffs(nanosec));
+	seconds_lsb = csrrd32(priv->tod_ctrl, tod_csroffs(seconds_lsb));
+	seconds_msb = csrrd32(priv->tod_ctrl, tod_csroffs(seconds_msb));
+	spin_unlock_irqrestore(&priv->tod_lock, flags);
+
+	seconds = (((u64)(seconds_msb & 0x0000ffff)) << 32) | seconds_lsb;
+
+	ts->tv_nsec = nanosec;
+	ts->tv_sec = (__kernel_old_time_t)seconds;
+
+	return 0;
+}
+
+static int intel_fpga_tod_set_time(struct ptp_clock_info *ptp,
+				   const struct timespec64 *ts)
+{
+	struct intel_fpga_tod_private *priv =
+		container_of(ptp, struct intel_fpga_tod_private, ptp_clock_ops);
+	u32 seconds_msb = upper_32_bits(ts->tv_sec) & 0x0000ffff;
+	u32 seconds_lsb = lower_32_bits(ts->tv_sec);
+	u32 nanosec = lower_32_bits(ts->tv_nsec);
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->tod_lock, flags);
+	csrwr32(seconds_msb, priv->tod_ctrl, tod_csroffs(seconds_msb));
+	csrwr32(seconds_lsb, priv->tod_ctrl, tod_csroffs(seconds_lsb));
+	csrwr32(nanosec, priv->tod_ctrl, tod_csroffs(nanosec));
+	spin_unlock_irqrestore(&priv->tod_lock, flags);
+
+	return 0;
+}
+
+static int intel_fpga_tod_enable_feature(struct ptp_clock_info *ptp,
+					 struct ptp_clock_request *request,
+					 int on)
+{
+	return -EOPNOTSUPP;
+}
+
+static struct ptp_clock_info intel_fpga_tod_clock_ops = {
+	.owner = THIS_MODULE,
+	.name = "intel_fpga_tod",
+	.max_adj = 500000000,
+	.n_alarm = 0,
+	.n_ext_ts = 0,
+	.n_per_out = 0,
+	.pps = 0,
+	.adjfine = intel_fpga_tod_adjust_fine,
+	.adjtime = intel_fpga_tod_adjust_time,
+	.gettime64 = intel_fpga_tod_get_time,
+	.settime64 = intel_fpga_tod_set_time,
+	.enable = intel_fpga_tod_enable_feature,
+};
+
+/* Initialize PTP control block registers */
+int intel_fpga_tod_init(struct intel_fpga_tod_private *priv)
+{
+	struct timespec64 now;
+	int ret = 0;
+
+	ret = intel_fpga_tod_adjust_fine(&priv->ptp_clock_ops, 0l);
+	if (ret != 0)
+		goto out;
+
+	/* Initialize the hardware clock to the system time */
+	ktime_get_real_ts64(&now);
+	intel_fpga_tod_set_time(&priv->ptp_clock_ops, &now);
+
+	spin_lock_init(&priv->tod_lock);
+
+out:
+	return ret;
+}
+
+/* Register the PTP clock driver to kernel */
+int intel_fpga_tod_register(struct intel_fpga_tod_private *priv,
+			    struct device *device)
+{
+	int ret = 0;
+
+	priv->ptp_clock_ops = intel_fpga_tod_clock_ops;
+
+	priv->ptp_clock = ptp_clock_register(&priv->ptp_clock_ops, device);
+	if (IS_ERR(priv->ptp_clock)) {
+		priv->ptp_clock = NULL;
+		ret = -ENODEV;
+	}
+
+	if (priv->tod_clk)
+		ret = clk_prepare_enable(priv->tod_clk);
+
+	return ret;
+}
+
+/* Remove/unregister the ptp clock driver from the kernel */
+void intel_fpga_tod_unregister(struct intel_fpga_tod_private *priv)
+{
+	if (priv->ptp_clock) {
+		ptp_clock_unregister(priv->ptp_clock);
+		priv->ptp_clock = NULL;
+	}
+
+	if (priv->tod_clk)
+		clk_disable_unprepare(priv->tod_clk);
+}
+
+/* Common PTP probe function */
+int intel_fpga_tod_probe(struct platform_device *pdev,
+			 struct intel_fpga_tod_private *priv)
+{
+	struct resource *ptp_res;
+	int ret = -ENODEV;
+
+	priv->dev = (struct net_device *)platform_get_drvdata(pdev);
+
+	/* Time-of-Day (ToD) Clock address space */
+	ret = request_and_map(pdev, "tod_ctrl", &ptp_res,
+			      (void __iomem **)&priv->tod_ctrl);
+	if (ret)
+		goto err;
+
+	dev_info(&pdev->dev, "\tTOD Ctrl at 0x%08lx\n",
+		 (unsigned long)ptp_res->start);
+
+	/* Time-of-Day (ToD) Clock period clock */
+	priv->tod_clk = devm_clk_get(&pdev->dev, "tod_clk");
+	if (IS_ERR(priv->tod_clk)) {
+		dev_err(&pdev->dev, "cannot obtain ToD period clock\n");
+		ret = -ENXIO;
+		goto err;
+	}
+err:
+	return ret;
+}
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/altera/intel_fpga_tod.h b/drivers/net/ethernet/altera/intel_fpga_tod.h
new file mode 100644
index 000000000000..064b97c2bf38
--- /dev/null
+++ b/drivers/net/ethernet/altera/intel_fpga_tod.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Altera PTP Hardware Clock (PHC) Linux driver
+ * Copyright (C) 2015-2016 Altera Corporation. All rights reserved.
+ * Copyright (C) 2017-2020 Intel Corporation. All rights reserved.
+ *
+ * Author(s):
+ *	Dalon Westergreen <dalon.westergreen@intel.com>
+ */
+
+#ifndef __INTEL_FPGA_TOD_H__
+#define __INTEL_FPGA_TOD_H__
+
+#include <linux/debugfs.h>
+#include <linux/netdevice.h>
+#include <linux/ptp_clock_kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+
+/* Altera Time-of-Day (ToD) clock register space. */
+struct intel_fpga_tod {
+	u32 seconds_msb;
+	u32 seconds_lsb;
+	u32 nanosec;
+	u32 reserved1[0x1];
+	u32 period;
+	u32 adjust_period;
+	u32 adjust_count;
+	u32 drift_adjust;
+	u32 drift_adjust_rate;
+};
+
+#define tod_csroffs(a)	(offsetof(struct intel_fpga_tod, a))
+
+struct intel_fpga_tod_private {
+	struct net_device *dev;
+
+	struct ptp_clock_info ptp_clock_ops;
+	struct ptp_clock *ptp_clock;
+
+	/* Time-of-Day (ToD) Clock address space */
+	struct intel_fpga_tod __iomem *tod_ctrl;
+	struct clk *tod_clk;
+
+	/* ToD clock registers protection */
+	spinlock_t tod_lock;
+};
+
+int intel_fpga_tod_init(struct intel_fpga_tod_private *priv);
+void intel_fpga_tod_uinit(struct intel_fpga_tod_private *priv);
+int intel_fpga_tod_register(struct intel_fpga_tod_private *priv,
+			    struct device *device);
+void intel_fpga_tod_unregister(struct intel_fpga_tod_private *priv);
+int intel_fpga_tod_probe(struct platform_device *pdev,
+			 struct intel_fpga_tod_private *priv);
+
+#endif /* __INTEL_FPGA_TOD_H__ */
-- 
2.13.0


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

* [PATCH v3 09/10] net: eth: altera: add msgdma prefetcher
  2020-06-04  7:32 [PATCH v3 00/10] net: eth: altera: tse: Add PTP and mSGDMA prefetcher Ooi, Joyce
                   ` (7 preceding siblings ...)
  2020-06-04  7:32 ` [PATCH v3 08/10] net: eth: altera: add support for ptp and timestamping Ooi, Joyce
@ 2020-06-04  7:32 ` Ooi, Joyce
  2020-06-04 11:02   ` kernel test robot
  2020-06-04 22:16   ` kernel test robot
  2020-06-04  7:32 ` [PATCH v3 10/10] net: eth: altera: update devicetree bindings documentation Ooi, Joyce
  2020-06-04 22:00 ` [PATCH v3 00/10] net: eth: altera: tse: Add PTP and mSGDMA prefetcher David Miller
  10 siblings, 2 replies; 16+ messages in thread
From: Ooi, Joyce @ 2020-06-04  7:32 UTC (permalink / raw)
  To: Thor Thayer, David S . Miller, Jakub Kicinski
  Cc: netdev, linux-kernel, Dalon Westergreen, Joyce Ooi, Tan Ley Foon,
	See Chin Liang, Dinh Nguyen, Dalon Westergreen

From: Dalon Westergreen <dalon.westergreen@intel.com>

Add support for the mSGDMA prefetcher.  The prefetcher adds support
for a linked list of descriptors in system memory.  The prefetcher
feeds these to the mSGDMA dispatcher.

The prefetcher is configured to poll for the next descriptor in the
list to be owned by hardware, then pass the descriptor to the
dispatcher.  It will then poll the next descriptor until it is
owned by hardware.

The dispatcher responses are written back to the appropriate
descriptor, and the owned by hardware bit is cleared.

The driver sets up a linked list twice the tx and rx ring sizes,
with the last descriptor pointing back to the first.  This ensures
that the ring of descriptors will always have inactive descriptors
preventing the prefetcher from looping over and reusing descriptors
inappropriately.  The prefetcher will continuously loop over these
descriptors.  The driver modifies descriptors as required to update
the skb address and length as well as the owned by hardware bit.

In addition to the above, the mSGDMA prefetcher can be used to
handle rx and tx timestamps coming from the ethernet ip.  These
can be included in the prefetcher response in the descriptor.

Signed-off-by: Dalon Westergreen <dalon.westergreen@intel.com>
Signed-off-by: Joyce Ooi <joyce.ooi@intel.com>
---
v2: minor fixes and suggested edits
v3: queue is stopped before returning NETDEV_TX_BUSY
---
 drivers/net/ethernet/altera/Makefile               |   2 +-
 .../net/ethernet/altera/altera_msgdma_prefetcher.c | 431 +++++++++++++++++++++
 .../net/ethernet/altera/altera_msgdma_prefetcher.h |  30 ++
 .../ethernet/altera/altera_msgdmahw_prefetcher.h   |  87 +++++
 drivers/net/ethernet/altera/altera_tse.h           |  14 +
 drivers/net/ethernet/altera/altera_tse_main.c      |  51 +++
 6 files changed, 614 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/ethernet/altera/altera_msgdma_prefetcher.c
 create mode 100644 drivers/net/ethernet/altera/altera_msgdma_prefetcher.h
 create mode 100644 drivers/net/ethernet/altera/altera_msgdmahw_prefetcher.h

diff --git a/drivers/net/ethernet/altera/Makefile b/drivers/net/ethernet/altera/Makefile
index fc2e460926b3..4834e972e906 100644
--- a/drivers/net/ethernet/altera/Makefile
+++ b/drivers/net/ethernet/altera/Makefile
@@ -6,4 +6,4 @@
 obj-$(CONFIG_ALTERA_TSE) += altera_tse.o
 altera_tse-objs := altera_tse_main.o altera_tse_ethtool.o \
 		   altera_msgdma.o altera_sgdma.o altera_utils.o \
-		   intel_fpga_tod.o
+		   intel_fpga_tod.o altera_msgdma_prefetcher.o
diff --git a/drivers/net/ethernet/altera/altera_msgdma_prefetcher.c b/drivers/net/ethernet/altera/altera_msgdma_prefetcher.c
new file mode 100644
index 000000000000..e8cd4d04730d
--- /dev/null
+++ b/drivers/net/ethernet/altera/altera_msgdma_prefetcher.c
@@ -0,0 +1,431 @@
+// SPDX-License-Identifier: GPL-2.0
+/* MSGDMA Prefetcher driver for Altera ethernet devices
+ *
+ * Copyright (C) 2020 Intel Corporation. All rights reserved.
+ * Author(s):
+ *   Dalon Westergreen <dalon.westergreen@intel.com>
+ */
+
+#include <linux/list.h>
+#include <linux/netdevice.h>
+#include <linux/net_tstamp.h>
+#include "altera_tse.h"
+#include "altera_msgdma.h"
+#include "altera_msgdmahw.h"
+#include "altera_msgdma_prefetcher.h"
+#include "altera_msgdmahw_prefetcher.h"
+#include "altera_utils.h"
+
+int msgdma_pref_initialize(struct altera_tse_private *priv)
+{
+	int i;
+	struct msgdma_pref_extended_desc *rx_descs;
+	struct msgdma_pref_extended_desc *tx_descs;
+	dma_addr_t rx_descsphys;
+	dma_addr_t tx_descsphys;
+
+	priv->pref_rxdescphys = (dma_addr_t)0;
+	priv->pref_txdescphys = (dma_addr_t)0;
+
+	/* we need to allocate more pref descriptors than ringsize to
+	 * prevent all of the descriptors being owned by hw.  To do this
+	 * we just allocate twice ring_size descriptors.
+	 * rx_ring_size = priv->rx_ring_size * 2
+	 * tx_ring_size = priv->tx_ring_size * 2
+	 */
+
+	/* The prefetcher requires the descriptors to be aligned to the
+	 * descriptor read/write master's data width which worst case is
+	 * 512 bits.  Currently we DO NOT CHECK THIS and only support 32-bit
+	 * prefetcher masters.
+	 */
+
+	/* allocate memory for rx descriptors */
+	priv->pref_rxdesc =
+		dma_alloc_coherent(priv->device,
+				   sizeof(struct msgdma_pref_extended_desc)
+				   * priv->rx_ring_size * 2,
+				   &priv->pref_rxdescphys, GFP_KERNEL);
+
+	if (!priv->pref_rxdesc)
+		goto err_rx;
+
+	/* allocate memory for tx descriptors */
+	priv->pref_txdesc =
+		dma_alloc_coherent(priv->device,
+				   sizeof(struct msgdma_pref_extended_desc)
+				   * priv->tx_ring_size * 2,
+				   &priv->pref_txdescphys, GFP_KERNEL);
+
+	if (!priv->pref_txdesc)
+		goto err_tx;
+
+	/* setup base descriptor ring for tx & rx */
+	rx_descs = (struct msgdma_pref_extended_desc *)priv->pref_rxdesc;
+	tx_descs = (struct msgdma_pref_extended_desc *)priv->pref_txdesc;
+	tx_descsphys = priv->pref_txdescphys;
+	rx_descsphys = priv->pref_rxdescphys;
+
+	/* setup RX descriptors */
+	priv->pref_rx_prod = 0;
+	for (i = 0; i < priv->rx_ring_size * 2; i++) {
+		rx_descsphys = priv->pref_rxdescphys +
+			(((i + 1) % (priv->rx_ring_size * 2)) *
+			sizeof(struct msgdma_pref_extended_desc));
+		rx_descs[i].next_desc_lo = lower_32_bits(rx_descsphys);
+		rx_descs[i].next_desc_hi = upper_32_bits(rx_descsphys);
+		rx_descs[i].stride = MSGDMA_DESC_RX_STRIDE;
+		/* burst set to 0 so it defaults to max configured */
+		/* set seq number to desc number */
+		rx_descs[i].burst_seq_num = i;
+	}
+
+	/* setup TX descriptors */
+	for (i = 0; i < priv->tx_ring_size * 2; i++) {
+		tx_descsphys = priv->pref_txdescphys +
+			(((i + 1) % (priv->tx_ring_size * 2)) *
+			sizeof(struct msgdma_pref_extended_desc));
+		tx_descs[i].next_desc_lo = lower_32_bits(tx_descsphys);
+		tx_descs[i].next_desc_hi = upper_32_bits(tx_descsphys);
+		tx_descs[i].stride = MSGDMA_DESC_TX_STRIDE;
+		/* burst set to 0 so it defaults to max configured */
+		/* set seq number to desc number */
+		tx_descs[i].burst_seq_num = i;
+	}
+
+	if (netif_msg_ifup(priv))
+		netdev_info(priv->dev, "%s: RX Desc mem at 0x%x\n", __func__,
+			    priv->pref_rxdescphys);
+
+	if (netif_msg_ifup(priv))
+		netdev_info(priv->dev, "%s: TX Desc mem at 0x%x\n", __func__,
+			    priv->pref_txdescphys);
+
+	return 0;
+
+err_tx:
+	dma_free_coherent(priv->device,
+			  sizeof(struct msgdma_pref_extended_desc)
+			  * priv->rx_ring_size * 2,
+			  priv->pref_rxdesc, priv->pref_rxdescphys);
+err_rx:
+	return -ENOMEM;
+}
+
+void msgdma_pref_uninitialize(struct altera_tse_private *priv)
+{
+	if (priv->pref_rxdesc)
+		dma_free_coherent(priv->device,
+				  sizeof(struct msgdma_pref_extended_desc)
+				  * priv->rx_ring_size * 2,
+				  priv->pref_rxdesc, priv->pref_rxdescphys);
+
+	if (priv->pref_txdesc)
+		dma_free_coherent(priv->device,
+				  sizeof(struct msgdma_pref_extended_desc)
+				  * priv->tx_ring_size * 2,
+				  priv->pref_txdesc, priv->pref_txdescphys);
+}
+
+void msgdma_pref_enable_txirq(struct altera_tse_private *priv)
+{
+	tse_set_bit(priv->tx_pref_csr, msgdma_pref_csroffs(control),
+		    MSGDMA_PREF_CTL_GLOBAL_INTR);
+}
+
+void msgdma_pref_disable_txirq(struct altera_tse_private *priv)
+{
+	tse_clear_bit(priv->tx_pref_csr, msgdma_pref_csroffs(control),
+		      MSGDMA_PREF_CTL_GLOBAL_INTR);
+}
+
+void msgdma_pref_clear_txirq(struct altera_tse_private *priv)
+{
+	csrwr32(MSGDMA_PREF_STAT_IRQ, priv->tx_pref_csr,
+		msgdma_pref_csroffs(status));
+}
+
+void msgdma_pref_enable_rxirq(struct altera_tse_private *priv)
+{
+	tse_set_bit(priv->rx_pref_csr, msgdma_pref_csroffs(control),
+		    MSGDMA_PREF_CTL_GLOBAL_INTR);
+}
+
+void msgdma_pref_disable_rxirq(struct altera_tse_private *priv)
+{
+	tse_clear_bit(priv->rx_pref_csr, msgdma_pref_csroffs(control),
+		      MSGDMA_PREF_CTL_GLOBAL_INTR);
+}
+
+void msgdma_pref_clear_rxirq(struct altera_tse_private *priv)
+{
+	csrwr32(MSGDMA_PREF_STAT_IRQ, priv->rx_pref_csr,
+		msgdma_pref_csroffs(status));
+}
+
+static u64 timestamp_to_ns(struct msgdma_pref_extended_desc *desc)
+{
+	u64 ns = 0;
+	u64 second;
+	u32 tmp;
+
+	tmp = desc->timestamp_96b[0] >> 16;
+	tmp |= (desc->timestamp_96b[1] << 16);
+
+	second = desc->timestamp_96b[2];
+	second <<= 16;
+	second |= ((desc->timestamp_96b[1] & 0xffff0000) >> 16);
+
+	ns = second * NSEC_PER_SEC + tmp;
+
+	return ns;
+}
+
+/* Setup TX descriptor
+ *   -> this should never be called when a descriptor isn't available
+ */
+
+netdev_tx_t msgdma_pref_tx_buffer(struct altera_tse_private *priv,
+				  struct tse_buffer *buffer)
+{
+	u32 desc_entry = priv->tx_prod % (priv->tx_ring_size * 2);
+	struct msgdma_pref_extended_desc *tx_descs = priv->pref_txdesc;
+
+	/* if for some reason the descriptor is still owned by hardware */
+	if (unlikely(tx_descs[desc_entry].desc_control
+		     & MSGDMA_PREF_DESC_CTL_OWNED_BY_HW)) {
+		if (!netif_queue_stopped(priv->dev))
+			netif_stop_queue(priv->dev);
+		return NETDEV_TX_BUSY;
+	}
+
+	/* write descriptor entries */
+	tx_descs[desc_entry].len = buffer->len;
+	tx_descs[desc_entry].read_addr_lo = lower_32_bits(buffer->dma_addr);
+	tx_descs[desc_entry].read_addr_hi = upper_32_bits(buffer->dma_addr);
+
+	/* set the control bits and set owned by hw */
+	tx_descs[desc_entry].desc_control = (MSGDMA_DESC_CTL_TX_SINGLE
+			| MSGDMA_PREF_DESC_CTL_OWNED_BY_HW);
+
+	if (netif_msg_tx_queued(priv))
+		netdev_info(priv->dev, "%s: cons: %d prod: %d",
+			    __func__, priv->tx_cons, priv->tx_prod);
+
+	return NETDEV_TX_OK;
+}
+
+u32 msgdma_pref_tx_completions(struct altera_tse_private *priv)
+{
+	u32 control;
+	u32 ready = 0;
+	u32 cons = priv->tx_cons;
+	u32 desc_ringsize = priv->tx_ring_size * 2;
+	u32 ringsize = priv->tx_ring_size;
+	u64 ns = 0;
+	struct msgdma_pref_extended_desc *cur;
+	struct tse_buffer *tx_buff;
+	struct skb_shared_hwtstamps shhwtstamp;
+	int i;
+
+	if (netif_msg_tx_done(priv))
+		for (i = 0; i < desc_ringsize; i++)
+			netdev_info(priv->dev, "%s: desc: %d control 0x%x\n",
+				    __func__, i,
+				    priv->pref_txdesc[i].desc_control);
+
+	cur = &priv->pref_txdesc[cons % desc_ringsize];
+	control = cur->desc_control;
+	tx_buff = &priv->tx_ring[cons % ringsize];
+
+	while (!(control & MSGDMA_PREF_DESC_CTL_OWNED_BY_HW) &&
+	       (priv->tx_prod != (cons + ready)) && control) {
+		if (skb_shinfo(tx_buff->skb)->tx_flags & SKBTX_IN_PROGRESS) {
+			/* Timestamping is enabled, pass timestamp back */
+			ns = timestamp_to_ns(cur);
+			memset(&shhwtstamp, 0,
+			       sizeof(struct skb_shared_hwtstamps));
+			shhwtstamp.hwtstamp = ns_to_ktime(ns);
+			skb_tstamp_tx(tx_buff->skb, &shhwtstamp);
+		}
+
+		if (netif_msg_tx_done(priv))
+			netdev_info(priv->dev, "%s: cur: %d ts: %lld ns\n",
+				    __func__,
+				    ((cons + ready) % desc_ringsize), ns);
+
+		/* clear data */
+		cur->desc_control = 0;
+		cur->timestamp_96b[0] = 0;
+		cur->timestamp_96b[1] = 0;
+		cur->timestamp_96b[2] = 0;
+
+		ready++;
+		cur = &priv->pref_txdesc[(cons + ready) % desc_ringsize];
+		tx_buff = &priv->tx_ring[(cons + ready) % ringsize];
+		control = cur->desc_control;
+	}
+
+	return ready;
+}
+
+void msgdma_pref_reset(struct altera_tse_private *priv)
+{
+	int counter;
+
+	/* turn off polling */
+	tse_clear_bit(priv->rx_pref_csr, msgdma_pref_csroffs(control),
+		      MSGDMA_PREF_CTL_DESC_POLL_EN);
+	tse_clear_bit(priv->tx_pref_csr, msgdma_pref_csroffs(control),
+		      MSGDMA_PREF_CTL_DESC_POLL_EN);
+
+	/* Reset the RX Prefetcher */
+	csrwr32(MSGDMA_PREF_STAT_IRQ, priv->rx_pref_csr,
+		msgdma_pref_csroffs(status));
+	csrwr32(MSGDMA_PREF_CTL_RESET, priv->rx_pref_csr,
+		msgdma_pref_csroffs(control));
+
+	counter = 0;
+	while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) {
+		if (tse_bit_is_clear(priv->rx_pref_csr,
+				     msgdma_pref_csroffs(control),
+				     MSGDMA_PREF_CTL_RESET))
+			break;
+		udelay(1);
+	}
+
+	if (counter >= ALTERA_TSE_SW_RESET_WATCHDOG_CNTR)
+		netif_warn(priv, drv, priv->dev,
+			   "TSE Rx Prefetcher reset bit never cleared!\n");
+
+	/* Reset the TX Prefetcher */
+	csrwr32(MSGDMA_PREF_STAT_IRQ, priv->tx_pref_csr,
+		msgdma_pref_csroffs(status));
+	csrwr32(MSGDMA_PREF_CTL_RESET, priv->tx_pref_csr,
+		msgdma_pref_csroffs(control));
+
+	counter = 0;
+	while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) {
+		if (tse_bit_is_clear(priv->tx_pref_csr,
+				     msgdma_pref_csroffs(control),
+				     MSGDMA_PREF_CTL_RESET))
+			break;
+		udelay(1);
+	}
+
+	if (counter >= ALTERA_TSE_SW_RESET_WATCHDOG_CNTR)
+		netif_warn(priv, drv, priv->dev,
+			   "TSE Tx Prefetcher reset bit never cleared!\n");
+
+	/* clear all status bits */
+	csrwr32(MSGDMA_PREF_STAT_IRQ, priv->tx_pref_csr,
+		msgdma_pref_csroffs(status));
+
+	/* Reset mSGDMA dispatchers*/
+	msgdma_reset(priv);
+}
+
+/* Setup the RX and TX prefetchers to poll the descriptor chain */
+void msgdma_pref_start_rxdma(struct altera_tse_private *priv)
+{
+	csrwr32(priv->rx_poll_freq, priv->rx_pref_csr,
+		msgdma_pref_csroffs(desc_poll_freq));
+	csrwr32(lower_32_bits(priv->pref_rxdescphys), priv->rx_pref_csr,
+		msgdma_pref_csroffs(next_desc_lo));
+	csrwr32(upper_32_bits(priv->pref_rxdescphys), priv->rx_pref_csr,
+		msgdma_pref_csroffs(next_desc_hi));
+	tse_set_bit(priv->rx_pref_csr, msgdma_pref_csroffs(control),
+		    MSGDMA_PREF_CTL_DESC_POLL_EN | MSGDMA_PREF_CTL_RUN);
+}
+
+void msgdma_pref_start_txdma(struct altera_tse_private *priv)
+{
+	csrwr32(priv->tx_poll_freq, priv->tx_pref_csr,
+		msgdma_pref_csroffs(desc_poll_freq));
+	csrwr32(lower_32_bits(priv->pref_txdescphys), priv->tx_pref_csr,
+		msgdma_pref_csroffs(next_desc_lo));
+	csrwr32(upper_32_bits(priv->pref_txdescphys), priv->tx_pref_csr,
+		msgdma_pref_csroffs(next_desc_hi));
+	tse_set_bit(priv->tx_pref_csr, msgdma_pref_csroffs(control),
+		    MSGDMA_PREF_CTL_DESC_POLL_EN | MSGDMA_PREF_CTL_RUN);
+}
+
+/* Add MSGDMA Prefetcher Descriptor to descriptor list
+ *   -> This should never be called when a descriptor isn't available
+ */
+void msgdma_pref_add_rx_desc(struct altera_tse_private *priv,
+			     struct tse_buffer *rxbuffer)
+{
+	struct msgdma_pref_extended_desc *rx_descs = priv->pref_rxdesc;
+	u32 desc_entry = priv->pref_rx_prod % (priv->rx_ring_size * 2);
+
+	/* write descriptor entries */
+	rx_descs[desc_entry].len = priv->rx_dma_buf_sz;
+	rx_descs[desc_entry].write_addr_lo = lower_32_bits(rxbuffer->dma_addr);
+	rx_descs[desc_entry].write_addr_hi = upper_32_bits(rxbuffer->dma_addr);
+
+	/* set the control bits and set owned by hw */
+	rx_descs[desc_entry].desc_control = (MSGDMA_DESC_CTL_END_ON_EOP
+			| MSGDMA_DESC_CTL_END_ON_LEN
+			| MSGDMA_DESC_CTL_TR_COMP_IRQ
+			| MSGDMA_DESC_CTL_EARLY_IRQ
+			| MSGDMA_DESC_CTL_TR_ERR_IRQ
+			| MSGDMA_DESC_CTL_GO
+			| MSGDMA_PREF_DESC_CTL_OWNED_BY_HW);
+
+	/* we need to keep a separate one for rx as RX_DESCRIPTORS are
+	 * pre-configured at startup
+	 */
+	priv->pref_rx_prod++;
+
+	if (netif_msg_rx_status(priv)) {
+		netdev_info(priv->dev, "%s: desc: %d buf: %d control 0x%x\n",
+			    __func__, desc_entry,
+			    priv->rx_prod % priv->rx_ring_size,
+			    priv->pref_rxdesc[desc_entry].desc_control);
+	}
+}
+
+u32 msgdma_pref_rx_status(struct altera_tse_private *priv)
+{
+	u32 rxstatus = 0;
+	u32 pktlength;
+	u32 pktstatus;
+	u64 ns = 0;
+	u32 entry = priv->rx_cons % priv->rx_ring_size;
+	u32 desc_entry = priv->rx_prod % (priv->rx_ring_size * 2);
+	struct msgdma_pref_extended_desc *rx_descs = priv->pref_rxdesc;
+	struct skb_shared_hwtstamps *shhwtstamp = NULL;
+	struct tse_buffer *rx_buff = priv->rx_ring;
+
+	/* if the current entry is not owned by hardware, process it */
+	if (!(rx_descs[desc_entry].desc_control
+	      & MSGDMA_PREF_DESC_CTL_OWNED_BY_HW) &&
+	      rx_descs[desc_entry].desc_control) {
+		pktlength = rx_descs[desc_entry].bytes_transferred;
+		pktstatus = rx_descs[desc_entry].desc_status;
+		rxstatus = pktstatus;
+		rxstatus = rxstatus << 16;
+		rxstatus |= (pktlength & 0xffff);
+
+		/* get the timestamp */
+		if (priv->hwts_rx_en) {
+			ns = timestamp_to_ns(&rx_descs[desc_entry]);
+			shhwtstamp = skb_hwtstamps(rx_buff[entry].skb);
+			memset(shhwtstamp, 0,
+			       sizeof(struct skb_shared_hwtstamps));
+			shhwtstamp->hwtstamp = ns_to_ktime(ns);
+		}
+
+		/* clear data */
+		rx_descs[desc_entry].desc_control = 0;
+		rx_descs[desc_entry].timestamp_96b[0] = 0;
+		rx_descs[desc_entry].timestamp_96b[1] = 0;
+		rx_descs[desc_entry].timestamp_96b[2] = 0;
+
+		if (netif_msg_rx_status(priv))
+			netdev_info(priv->dev, "%s: desc: %d buf: %d ts: %lld ns",
+				    __func__, desc_entry, entry, ns);
+	}
+	return rxstatus;
+}
diff --git a/drivers/net/ethernet/altera/altera_msgdma_prefetcher.h b/drivers/net/ethernet/altera/altera_msgdma_prefetcher.h
new file mode 100644
index 000000000000..6507c2805a05
--- /dev/null
+++ b/drivers/net/ethernet/altera/altera_msgdma_prefetcher.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* MSGDMA Prefetcher driver for Altera ethernet devices
+ *
+ * Copyright (C) 2020 Intel Corporation. All rights reserved.
+ * Author(s):
+ *   Dalon Westergreen <dalon.westergreen@intel.com>
+ */
+
+#ifndef __ALTERA_PREF_MSGDMA_H__
+#define __ALTERA_PREF_MSGDMA_H__
+
+void msgdma_pref_reset(struct altera_tse_private *priv);
+void msgdma_pref_enable_txirq(struct altera_tse_private *priv);
+void msgdma_pref_enable_rxirq(struct altera_tse_private *priv);
+void msgdma_pref_disable_rxirq(struct altera_tse_private *priv);
+void msgdma_pref_disable_txirq(struct altera_tse_private *priv);
+void msgdma_pref_clear_rxirq(struct altera_tse_private *priv);
+void msgdma_pref_clear_txirq(struct altera_tse_private *priv);
+u32 msgdma_pref_tx_completions(struct altera_tse_private *priv);
+void msgdma_pref_add_rx_desc(struct altera_tse_private *priv,
+			     struct tse_buffer *buffer);
+netdev_tx_t msgdma_pref_tx_buffer(struct altera_tse_private *priv,
+				  struct tse_buffer *buffer);
+u32 msgdma_pref_rx_status(struct altera_tse_private *priv);
+int msgdma_pref_initialize(struct altera_tse_private *priv);
+void msgdma_pref_uninitialize(struct altera_tse_private *priv);
+void msgdma_pref_start_rxdma(struct altera_tse_private *priv);
+void msgdma_pref_start_txdma(struct altera_tse_private *priv);
+
+#endif /*  __ALTERA_PREF_MSGDMA_H__ */
diff --git a/drivers/net/ethernet/altera/altera_msgdmahw_prefetcher.h b/drivers/net/ethernet/altera/altera_msgdmahw_prefetcher.h
new file mode 100644
index 000000000000..efda31e491ca
--- /dev/null
+++ b/drivers/net/ethernet/altera/altera_msgdmahw_prefetcher.h
@@ -0,0 +1,87 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* MSGDMA Prefetcher driver for Altera ethernet devices
+ *
+ * Copyright (C) 2020 Intel Corporation.
+ * Contributors:
+ *   Dalon Westergreen
+ *   Thomas Chou
+ *   Ian Abbott
+ *   Yuriy Kozlov
+ *   Tobias Klauser
+ *   Andriy Smolskyy
+ *   Roman Bulgakov
+ *   Dmytro Mytarchuk
+ *   Matthew Gerlach
+ */
+
+#ifndef __ALTERA_MSGDMAHW_PREFETCHER_H__
+#define __ALTERA_MSGDMAHW_PREFETCHER_H__
+
+/* mSGDMA prefetcher extended prefectcher descriptor format
+ */
+struct msgdma_pref_extended_desc {
+	/* data buffer source address low bits */
+	u32 read_addr_lo;
+	/* data buffer destination address low bits */
+	u32 write_addr_lo;
+	/* the number of bytes to transfer */
+	u32 len;
+	/* next descriptor low address */
+	u32 next_desc_lo;
+	/* number of bytes transferred */
+	u32 bytes_transferred;
+	u32 desc_status;
+	u32 reserved_18;
+	/* bit 31:24 write burst */
+	/* bit 23:16 read burst */
+	/* bit 15:0  sequence number */
+	u32 burst_seq_num;
+	/* bit 31:16 write stride */
+	/* bit 15:0  read stride */
+	u32 stride;
+	/* data buffer source address high bits */
+	u32 read_addr_hi;
+	/* data buffer destination address high bits */
+	u32 write_addr_hi;
+	/* next descriptor high address */
+	u32 next_desc_hi;
+	/* prefetcher mod now writes these reserved bits*/
+	/* Response bits [191:160] */
+	u32 timestamp_96b[3];
+	/* desc_control */
+	u32 desc_control;
+};
+
+/* mSGDMA Prefetcher Descriptor Status bits */
+#define MSGDMA_PREF_DESC_STAT_STOPPED_ON_EARLY		BIT(8)
+#define MSGDMA_PREF_DESC_STAT_MASK			0xFF
+
+/* mSGDMA Prefetcher Descriptor Control bits */
+/* bit 31 and bits 29-0 are the same as the normal dispatcher ctl flags */
+#define MSGDMA_PREF_DESC_CTL_OWNED_BY_HW		BIT(30)
+
+/* mSGDMA Prefetcher CSR */
+struct msgdma_prefetcher_csr {
+	u32 control;
+	u32 next_desc_lo;
+	u32 next_desc_hi;
+	u32 desc_poll_freq;
+	u32 status;
+};
+
+/* mSGDMA Prefetcher Control */
+#define MSGDMA_PREF_CTL_PARK				BIT(4)
+#define MSGDMA_PREF_CTL_GLOBAL_INTR			BIT(3)
+#define MSGDMA_PREF_CTL_RESET				BIT(2)
+#define MSGDMA_PREF_CTL_DESC_POLL_EN			BIT(1)
+#define MSGDMA_PREF_CTL_RUN				BIT(0)
+
+#define MSGDMA_PREF_POLL_FREQ_MASK			0xFFFF
+
+/* mSGDMA Prefetcher Status */
+#define MSGDMA_PREF_STAT_IRQ				BIT(0)
+
+#define msgdma_pref_csroffs(a) (offsetof(struct msgdma_prefetcher_csr, a))
+#define msgdma_pref_descroffs(a) (offsetof(struct msgdma_pref_extended_desc, a))
+
+#endif /* __ALTERA_MSGDMAHW_PREFETCHER_H__*/
diff --git a/drivers/net/ethernet/altera/altera_tse.h b/drivers/net/ethernet/altera/altera_tse.h
index b7c176a808ac..35f99bfce4ef 100644
--- a/drivers/net/ethernet/altera/altera_tse.h
+++ b/drivers/net/ethernet/altera/altera_tse.h
@@ -382,6 +382,7 @@ struct altera_tse_private;
 
 #define ALTERA_DTYPE_SGDMA 1
 #define ALTERA_DTYPE_MSGDMA 2
+#define ALTERA_DTYPE_MSGDMA_PREF 3
 
 /* standard DMA interface for SGDMA and MSGDMA */
 struct altera_dmaops {
@@ -434,6 +435,19 @@ struct altera_tse_private {
 	void __iomem *tx_dma_csr;
 	void __iomem *tx_dma_desc;
 
+	/* mSGDMA Rx Prefecher address space */
+	void __iomem *rx_pref_csr;
+	struct msgdma_pref_extended_desc *pref_rxdesc;
+	dma_addr_t pref_rxdescphys;
+	u32 pref_rx_prod;
+
+	/* mSGDMA Tx Prefecher address space */
+	void __iomem *tx_pref_csr;
+	struct msgdma_pref_extended_desc *pref_txdesc;
+	dma_addr_t pref_txdescphys;
+	u32 rx_poll_freq;
+	u32 tx_poll_freq;
+
 	/* Rx buffers queue */
 	struct tse_buffer *rx_ring;
 	u32 rx_cons;
diff --git a/drivers/net/ethernet/altera/altera_tse_main.c b/drivers/net/ethernet/altera/altera_tse_main.c
index c874b8c1dd48..d061381bd545 100644
--- a/drivers/net/ethernet/altera/altera_tse_main.c
+++ b/drivers/net/ethernet/altera/altera_tse_main.c
@@ -44,6 +44,7 @@
 #include "altera_sgdma.h"
 #include "altera_msgdma.h"
 #include "intel_fpga_tod.h"
+#include "altera_msgdma_prefetcher.h"
 
 static atomic_t instance_count = ATOMIC_INIT(~0);
 /* Module parameters */
@@ -1500,6 +1501,34 @@ static int altera_tse_probe(struct platform_device *pdev)
 		priv->rxdescmem = resource_size(dma_res);
 		priv->rxdescmem_busaddr = dma_res->start;
 
+	} else if (priv->dmaops &&
+			   priv->dmaops->altera_dtype ==
+			   ALTERA_DTYPE_MSGDMA_PREF) {
+		/* mSGDMA Rx Prefetcher address space */
+		ret = request_and_map(pdev, "rx_pref", &dma_res,
+				      &priv->rx_pref_csr);
+		if (ret)
+			goto err_free_netdev;
+
+		/* mSGDMA Tx Prefetcher address space */
+		ret = request_and_map(pdev, "tx_pref", &dma_res,
+				      &priv->tx_pref_csr);
+		if (ret)
+			goto err_free_netdev;
+
+		/* get prefetcher rx poll frequency from device tree */
+		if (of_property_read_u32(pdev->dev.of_node, "rx-poll-freq",
+					 &priv->rx_poll_freq)) {
+			dev_info(&pdev->dev, "Defaulting RX Poll Frequency to 128\n");
+			priv->rx_poll_freq = 128;
+		}
+
+		/* get prefetcher rx poll frequency from device tree */
+		if (of_property_read_u32(pdev->dev.of_node, "tx-poll-freq",
+					 &priv->tx_poll_freq)) {
+			dev_info(&pdev->dev, "Defaulting TX Poll Frequency to 128\n");
+			priv->tx_poll_freq = 128;
+		}
 	} else {
 		goto err_free_netdev;
 	}
@@ -1758,7 +1787,29 @@ static const struct altera_dmaops altera_dtype_msgdma = {
 	.start_txdma = NULL,
 };
 
+static const struct altera_dmaops altera_dtype_prefetcher = {
+	.altera_dtype = ALTERA_DTYPE_MSGDMA_PREF,
+	.dmamask = 64,
+	.reset_dma = msgdma_pref_reset,
+	.enable_txirq = msgdma_pref_enable_txirq,
+	.enable_rxirq = msgdma_pref_enable_rxirq,
+	.disable_txirq = msgdma_pref_disable_txirq,
+	.disable_rxirq = msgdma_pref_disable_rxirq,
+	.clear_txirq = msgdma_pref_clear_txirq,
+	.clear_rxirq = msgdma_pref_clear_rxirq,
+	.tx_buffer = msgdma_pref_tx_buffer,
+	.tx_completions = msgdma_pref_tx_completions,
+	.add_rx_desc = msgdma_pref_add_rx_desc,
+	.get_rx_status = msgdma_pref_rx_status,
+	.init_dma = msgdma_pref_initialize,
+	.uninit_dma = msgdma_pref_uninitialize,
+	.start_rxdma = msgdma_pref_start_rxdma,
+	.start_txdma = msgdma_pref_start_txdma,
+};
+
 static const struct of_device_id altera_tse_ids[] = {
+	{ .compatible = "altr,tse-msgdma-2.0",
+		.data = &altera_dtype_prefetcher, },
 	{ .compatible = "altr,tse-msgdma-1.0", .data = &altera_dtype_msgdma, },
 	{ .compatible = "altr,tse-1.0", .data = &altera_dtype_sgdma, },
 	{ .compatible = "ALTR,tse-1.0", .data = &altera_dtype_sgdma, },
-- 
2.13.0


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

* [PATCH v3 10/10] net: eth: altera: update devicetree bindings documentation
  2020-06-04  7:32 [PATCH v3 00/10] net: eth: altera: tse: Add PTP and mSGDMA prefetcher Ooi, Joyce
                   ` (8 preceding siblings ...)
  2020-06-04  7:32 ` [PATCH v3 09/10] net: eth: altera: add msgdma prefetcher Ooi, Joyce
@ 2020-06-04  7:32 ` Ooi, Joyce
  2020-06-04 22:23   ` Rob Herring
  2020-06-04 22:00 ` [PATCH v3 00/10] net: eth: altera: tse: Add PTP and mSGDMA prefetcher David Miller
  10 siblings, 1 reply; 16+ messages in thread
From: Ooi, Joyce @ 2020-06-04  7:32 UTC (permalink / raw)
  To: Thor Thayer, David S . Miller, Jakub Kicinski
  Cc: netdev, linux-kernel, Dalon Westergreen, Joyce Ooi, Tan Ley Foon,
	See Chin Liang, Dinh Nguyen, Dalon Westergreen, Rob Herring,
	devicetree

From: Dalon Westergreen <dalon.westergreen@intel.com>

Update devicetree bindings documentation to include msgdma
prefetcher and ptp bindings.

Cc: Rob Herring <robh+dt@kernel.org>
Cc: devicetree@vger.kernel.org
Signed-off-by: Dalon Westergreen <dalon.westergreen@intel.com>
Signed-off-by: Joyce Ooi <joyce.ooi@intel.com>
---
v2: no change
v3: no change
---
 .../devicetree/bindings/net/altera_tse.txt         | 103 +++++++++++++++++----
 1 file changed, 84 insertions(+), 19 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/altera_tse.txt b/Documentation/devicetree/bindings/net/altera_tse.txt
index 0b7d4d3758ea..2f2d12603907 100644
--- a/Documentation/devicetree/bindings/net/altera_tse.txt
+++ b/Documentation/devicetree/bindings/net/altera_tse.txt
@@ -2,53 +2,86 @@
 
 Required properties:
 - compatible: Should be "altr,tse-1.0" for legacy SGDMA based TSE, and should
-		be "altr,tse-msgdma-1.0" for the preferred MSGDMA based TSE.
+		be "altr,tse-msgdma-1.0" for the preferred MSGDMA based TSE,
+		and "altr,tse-msgdma-2.0" for MSGDMA with prefetcher based
+		implementations.
 		ALTR is supported for legacy device trees, but is deprecated.
 		altr should be used for all new designs.
 - reg: Address and length of the register set for the device. It contains
   the information of registers in the same order as described by reg-names
 - reg-names: Should contain the reg names
-  "control_port": MAC configuration space region
-  "tx_csr":       xDMA Tx dispatcher control and status space region
-  "tx_desc":      MSGDMA Tx dispatcher descriptor space region
-  "rx_csr" :      xDMA Rx dispatcher control and status space region
-  "rx_desc":      MSGDMA Rx dispatcher descriptor space region
-  "rx_resp":      MSGDMA Rx dispatcher response space region
-  "s1":		  SGDMA descriptor memory
 - interrupts: Should contain the TSE interrupts and it's mode.
 - interrupt-names: Should contain the interrupt names
-  "rx_irq":       xDMA Rx dispatcher interrupt
-  "tx_irq":       xDMA Tx dispatcher interrupt
+  "rx_irq":       DMA Rx dispatcher interrupt
+  "tx_irq":       DMA Tx dispatcher interrupt
 - rx-fifo-depth: MAC receive FIFO buffer depth in bytes
 - tx-fifo-depth: MAC transmit FIFO buffer depth in bytes
 - phy-mode: See ethernet.txt in the same directory.
 - phy-handle: See ethernet.txt in the same directory.
 - phy-addr: See ethernet.txt in the same directory. A configuration should
 		include phy-handle or phy-addr.
-- altr,has-supplementary-unicast:
-		If present, TSE supports additional unicast addresses.
-		Otherwise additional unicast addresses are not supported.
-- altr,has-hash-multicast-filter:
-		If present, TSE supports a hash based multicast filter.
-		Otherwise, hash-based multicast filtering is not supported.
-
 - mdio device tree subnode: When the TSE has a phy connected to its local
 		mdio, there must be device tree subnode with the following
 		required properties:
-
 	- compatible: Must be "altr,tse-mdio".
 	- #address-cells: Must be <1>.
 	- #size-cells: Must be <0>.
 
 	For each phy on the mdio bus, there must be a node with the following
 	fields:
-
 	- reg: phy id used to communicate to phy.
 	- device_type: Must be "ethernet-phy".
 
 The MAC address will be determined using the optional properties defined in
 ethernet.txt.
 
+- altr,has-supplementary-unicast:
+		If present, TSE supports additional unicast addresses.
+		Otherwise additional unicast addresses are not supported.
+- altr,has-hash-multicast-filter:
+		If present, TSE supports a hash based multicast filter.
+		Otherwise, hash-based multicast filtering is not supported.
+- altr,has-ptp:
+		If present, TSE supports 1588 timestamping.  Currently only
+		supported with the msgdma prefetcher.
+- altr,tx-poll-cnt:
+		Optional cycle count for Tx prefetcher to poll descriptor
+		list.  If not present, defaults to 128, which at 125MHz is
+		roughly 1usec. Only for "altr,tse-msgdma-2.0".
+- altr,rx-poll-cnt:
+		Optional cycle count for Tx prefetcher to poll descriptor
+		list.  If not present, defaults to 128, which at 125MHz is
+		roughly 1usec. Only for "altr,tse-msgdma-2.0".
+
+Required registers by compatibility string:
+ - "altr,tse-1.0"
+	"control_port": MAC configuration space region
+	"tx_csr":       DMA Tx dispatcher control and status space region
+	"rx_csr" :      DMA Rx dispatcher control and status space region
+	"s1":		DMA descriptor memory
+
+ - "altr,tse-msgdma-1.0"
+	"control_port": MAC configuration space region
+	"tx_csr":       DMA Tx dispatcher control and status space region
+	"tx_desc":      DMA Tx dispatcher descriptor space region
+	"rx_csr" :      DMA Rx dispatcher control and status space region
+	"rx_desc":      DMA Rx dispatcher descriptor space region
+	"rx_resp":      DMA Rx dispatcher response space region
+
+ - "altr,tse-msgdma-2.0"
+	"control_port": MAC configuration space region
+	"tx_csr":       DMA Tx dispatcher control and status space region
+	"tx_pref":      DMA Tx prefetcher configuration space region
+	"rx_csr" :      DMA Rx dispatcher control and status space region
+	"rx_pref":      DMA Rx prefetcher configuration space region
+	"tod_ctrl":     Time of Day Control register only required when
+			timestamping support is enabled.  Timestamping is
+			only supported with the msgdma-2.0 implementation.
+
+Optional properties:
+- local-mac-address: See ethernet.txt in the same directory.
+- max-frame-size: See ethernet.txt in the same directory.
+
 Example:
 
 	tse_sub_0_eth_tse_0: ethernet@1,00000000 {
@@ -86,6 +119,11 @@ Example:
 				device_type = "ethernet-phy";
 			};
 
+			phy2: ethernet-phy@2 {
+				reg = <0x2>;
+				device_type = "ethernet-phy";
+			};
+
 		};
 	};
 
@@ -111,3 +149,30 @@ Example:
 		altr,has-hash-multicast-filter;
 		phy-handle = <&phy1>;
 	};
+
+
+	tse_sub_2_eth_tse_0: ethernet@1,00002000 {
+		compatible = "altr,tse-msgdma-2.0";
+		reg = 	<0x00000001 0x00002000 0x00000400>,
+			<0x00000001 0x00002400 0x00000020>,
+			<0x00000001 0x00002420 0x00000020>,
+			<0x00000001 0x00002440 0x00000020>,
+			<0x00000001 0x00002460 0x00000020>,
+			<0x00000001 0x00002480 0x00000040>;
+		reg-names = "control_port", "rx_csr", "rx_pref","tx_csr", "tx_pref", "tod_ctrl";
+		interrupt-parent = <&hps_0_arm_gic_0>;
+		interrupts = <0 45 4>, <0 44 4>;
+		interrupt-names = "rx_irq", "tx_irq";
+		rx-fifo-depth = <2048>;
+		tx-fifo-depth = <2048>;
+		address-bits = <48>;
+		max-frame-size = <1500>;
+		local-mac-address = [ 00 00 00 00 00 00 ];
+		phy-mode = "sgmii";
+		altr,has-supplementary-unicast;
+		altr,has-hash-multicast-filter;
+		altr,has-ptp;
+		altr,tx-poll-cnt = <128>;
+		altr,rx-poll-cnt = <32>;
+		phy-handle = <&phy2>;
+	};
-- 
2.13.0


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

* Re: [PATCH v3 09/10] net: eth: altera: add msgdma prefetcher
  2020-06-04  7:32 ` [PATCH v3 09/10] net: eth: altera: add msgdma prefetcher Ooi, Joyce
@ 2020-06-04 11:02   ` kernel test robot
  2020-06-04 22:16   ` kernel test robot
  1 sibling, 0 replies; 16+ messages in thread
From: kernel test robot @ 2020-06-04 11:02 UTC (permalink / raw)
  To: Ooi, Joyce, Thor Thayer, David S . Miller, Jakub Kicinski
  Cc: kbuild-all, netdev, linux-kernel, Dalon Westergreen, Joyce Ooi,
	Tan Ley Foon, See Chin Liang, Dinh Nguyen

[-- Attachment #1: Type: text/plain, Size: 6550 bytes --]

Hi Joyce",

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on net/master]
[also build test WARNING on robh/for-next sparc-next/master linus/master v5.7 next-20200604]
[cannot apply to net-next/master]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Ooi-Joyce/net-eth-altera-tse-Add-PTP-and-mSGDMA-prefetcher/20200604-153632
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git bdc48fa11e46f867ea4d75fa59ee87a7f48be144
config: arc-allyesconfig (attached as .config)
compiler: arc-elf-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>, old ones prefixed by <<):

drivers/net/ethernet/altera/altera_msgdma_prefetcher.c: In function 'msgdma_pref_initialize':
>> drivers/net/ethernet/altera/altera_msgdma_prefetcher.c:97:49: warning: format '%x' expects argument of type 'unsigned int', but argument 4 has type 'dma_addr_t' {aka 'long long unsigned int'} [-Wformat=]
97 |   netdev_info(priv->dev, "%s: RX Desc mem at 0x%xn", __func__,
|                                                ~^
|                                                 |
|                                                 unsigned int
|                                                %llx
98 |        priv->pref_rxdescphys);
|        ~~~~~~~~~~~~~~~~~~~~~
|            |
|            dma_addr_t {aka long long unsigned int}
drivers/net/ethernet/altera/altera_msgdma_prefetcher.c:101:49: warning: format '%x' expects argument of type 'unsigned int', but argument 4 has type 'dma_addr_t' {aka 'long long unsigned int'} [-Wformat=]
101 |   netdev_info(priv->dev, "%s: TX Desc mem at 0x%xn", __func__,
|                                                ~^
|                                                 |
|                                                 unsigned int
|                                                %llx
102 |        priv->pref_txdescphys);
|        ~~~~~~~~~~~~~~~~~~~~~
|            |
|            dma_addr_t {aka long long unsigned int}

vim +97 drivers/net/ethernet/altera/altera_msgdma_prefetcher.c

    18	
    19	int msgdma_pref_initialize(struct altera_tse_private *priv)
    20	{
    21		int i;
    22		struct msgdma_pref_extended_desc *rx_descs;
    23		struct msgdma_pref_extended_desc *tx_descs;
    24		dma_addr_t rx_descsphys;
    25		dma_addr_t tx_descsphys;
    26	
    27		priv->pref_rxdescphys = (dma_addr_t)0;
    28		priv->pref_txdescphys = (dma_addr_t)0;
    29	
    30		/* we need to allocate more pref descriptors than ringsize to
    31		 * prevent all of the descriptors being owned by hw.  To do this
    32		 * we just allocate twice ring_size descriptors.
    33		 * rx_ring_size = priv->rx_ring_size * 2
    34		 * tx_ring_size = priv->tx_ring_size * 2
    35		 */
    36	
    37		/* The prefetcher requires the descriptors to be aligned to the
    38		 * descriptor read/write master's data width which worst case is
    39		 * 512 bits.  Currently we DO NOT CHECK THIS and only support 32-bit
    40		 * prefetcher masters.
    41		 */
    42	
    43		/* allocate memory for rx descriptors */
    44		priv->pref_rxdesc =
    45			dma_alloc_coherent(priv->device,
    46					   sizeof(struct msgdma_pref_extended_desc)
    47					   * priv->rx_ring_size * 2,
    48					   &priv->pref_rxdescphys, GFP_KERNEL);
    49	
    50		if (!priv->pref_rxdesc)
    51			goto err_rx;
    52	
    53		/* allocate memory for tx descriptors */
    54		priv->pref_txdesc =
    55			dma_alloc_coherent(priv->device,
    56					   sizeof(struct msgdma_pref_extended_desc)
    57					   * priv->tx_ring_size * 2,
    58					   &priv->pref_txdescphys, GFP_KERNEL);
    59	
    60		if (!priv->pref_txdesc)
    61			goto err_tx;
    62	
    63		/* setup base descriptor ring for tx & rx */
    64		rx_descs = (struct msgdma_pref_extended_desc *)priv->pref_rxdesc;
    65		tx_descs = (struct msgdma_pref_extended_desc *)priv->pref_txdesc;
    66		tx_descsphys = priv->pref_txdescphys;
    67		rx_descsphys = priv->pref_rxdescphys;
    68	
    69		/* setup RX descriptors */
    70		priv->pref_rx_prod = 0;
    71		for (i = 0; i < priv->rx_ring_size * 2; i++) {
    72			rx_descsphys = priv->pref_rxdescphys +
    73				(((i + 1) % (priv->rx_ring_size * 2)) *
    74				sizeof(struct msgdma_pref_extended_desc));
    75			rx_descs[i].next_desc_lo = lower_32_bits(rx_descsphys);
    76			rx_descs[i].next_desc_hi = upper_32_bits(rx_descsphys);
    77			rx_descs[i].stride = MSGDMA_DESC_RX_STRIDE;
    78			/* burst set to 0 so it defaults to max configured */
    79			/* set seq number to desc number */
    80			rx_descs[i].burst_seq_num = i;
    81		}
    82	
    83		/* setup TX descriptors */
    84		for (i = 0; i < priv->tx_ring_size * 2; i++) {
    85			tx_descsphys = priv->pref_txdescphys +
    86				(((i + 1) % (priv->tx_ring_size * 2)) *
    87				sizeof(struct msgdma_pref_extended_desc));
    88			tx_descs[i].next_desc_lo = lower_32_bits(tx_descsphys);
    89			tx_descs[i].next_desc_hi = upper_32_bits(tx_descsphys);
    90			tx_descs[i].stride = MSGDMA_DESC_TX_STRIDE;
    91			/* burst set to 0 so it defaults to max configured */
    92			/* set seq number to desc number */
    93			tx_descs[i].burst_seq_num = i;
    94		}
    95	
    96		if (netif_msg_ifup(priv))
  > 97			netdev_info(priv->dev, "%s: RX Desc mem at 0x%x\n", __func__,
    98				    priv->pref_rxdescphys);
    99	
   100		if (netif_msg_ifup(priv))
   101			netdev_info(priv->dev, "%s: TX Desc mem at 0x%x\n", __func__,
   102				    priv->pref_txdescphys);
   103	
   104		return 0;
   105	
   106	err_tx:
   107		dma_free_coherent(priv->device,
   108				  sizeof(struct msgdma_pref_extended_desc)
   109				  * priv->rx_ring_size * 2,
   110				  priv->pref_rxdesc, priv->pref_rxdescphys);
   111	err_rx:
   112		return -ENOMEM;
   113	}
   114	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 63048 bytes --]

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

* Re: [PATCH v3 00/10] net: eth: altera: tse: Add PTP and mSGDMA prefetcher
  2020-06-04  7:32 [PATCH v3 00/10] net: eth: altera: tse: Add PTP and mSGDMA prefetcher Ooi, Joyce
                   ` (9 preceding siblings ...)
  2020-06-04  7:32 ` [PATCH v3 10/10] net: eth: altera: update devicetree bindings documentation Ooi, Joyce
@ 2020-06-04 22:00 ` David Miller
  10 siblings, 0 replies; 16+ messages in thread
From: David Miller @ 2020-06-04 22:00 UTC (permalink / raw)
  To: joyce.ooi
  Cc: thor.thayer, kuba, netdev, linux-kernel, dalon.westergreen,
	ley.foon.tan, chin.liang.see, dinh.nguyen

From: "Ooi, Joyce" <joyce.ooi@intel.com>
Date: Thu,  4 Jun 2020 15:32:46 +0800

> From: Joyce Ooi <joyce.ooi@intel.com>
> 
> This patch series cleans up the Altera TSE driver and adds support
> for the newer msgdma prefetcher as well as ptp support when using
> the msgdma prefetcher.
> 
> v2: Rename altera_ptp to intel_fpga_tod, modify msgdma and sgdma tx_buffer
>     functions to be of type netdev_tx_t, and minor suggested edits
> v3: Modify tx_buffer to stop queue before returning NETDEV_TX_BUSY

net-next is closed at this time

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

* Re: [PATCH v3 09/10] net: eth: altera: add msgdma prefetcher
  2020-06-04  7:32 ` [PATCH v3 09/10] net: eth: altera: add msgdma prefetcher Ooi, Joyce
  2020-06-04 11:02   ` kernel test robot
@ 2020-06-04 22:16   ` kernel test robot
  1 sibling, 0 replies; 16+ messages in thread
From: kernel test robot @ 2020-06-04 22:16 UTC (permalink / raw)
  To: Ooi, Joyce, Thor Thayer, David S . Miller, Jakub Kicinski
  Cc: kbuild-all, netdev, linux-kernel, Dalon Westergreen, Joyce Ooi,
	Tan Ley Foon, See Chin Liang, Dinh Nguyen

[-- Attachment #1: Type: text/plain, Size: 5523 bytes --]

Hi Joyce",

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on net/master]
[also build test WARNING on robh/for-next sparc-next/master linus/master v5.7 next-20200604]
[cannot apply to net-next/master]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Ooi-Joyce/net-eth-altera-tse-Add-PTP-and-mSGDMA-prefetcher/20200604-153632
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git bdc48fa11e46f867ea4d75fa59ee87a7f48be144
config: i386-randconfig-a011-20200605 (attached as .config)
compiler: gcc-4.9 (Ubuntu 4.9.3-13ubuntu2) 4.9.3
reproduce (this is a W=1 build):
        # save the attached .config to linux build tree
        make W=1 ARCH=i386 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>, old ones prefixed by <<):

drivers/net/ethernet/altera/altera_msgdma_prefetcher.c: In function 'msgdma_pref_initialize':
>> drivers/net/ethernet/altera/altera_msgdma_prefetcher.c:98:8: warning: format '%x' expects argument of type 'unsigned int', but argument 4 has type 'dma_addr_t' [-Wformat=]
priv->pref_rxdescphys);
^
drivers/net/ethernet/altera/altera_msgdma_prefetcher.c:102:8: warning: format '%x' expects argument of type 'unsigned int', but argument 4 has type 'dma_addr_t' [-Wformat=]
priv->pref_txdescphys);
^

vim +98 drivers/net/ethernet/altera/altera_msgdma_prefetcher.c

    18	
    19	int msgdma_pref_initialize(struct altera_tse_private *priv)
    20	{
    21		int i;
    22		struct msgdma_pref_extended_desc *rx_descs;
    23		struct msgdma_pref_extended_desc *tx_descs;
    24		dma_addr_t rx_descsphys;
    25		dma_addr_t tx_descsphys;
    26	
    27		priv->pref_rxdescphys = (dma_addr_t)0;
    28		priv->pref_txdescphys = (dma_addr_t)0;
    29	
    30		/* we need to allocate more pref descriptors than ringsize to
    31		 * prevent all of the descriptors being owned by hw.  To do this
    32		 * we just allocate twice ring_size descriptors.
    33		 * rx_ring_size = priv->rx_ring_size * 2
    34		 * tx_ring_size = priv->tx_ring_size * 2
    35		 */
    36	
    37		/* The prefetcher requires the descriptors to be aligned to the
    38		 * descriptor read/write master's data width which worst case is
    39		 * 512 bits.  Currently we DO NOT CHECK THIS and only support 32-bit
    40		 * prefetcher masters.
    41		 */
    42	
    43		/* allocate memory for rx descriptors */
    44		priv->pref_rxdesc =
    45			dma_alloc_coherent(priv->device,
    46					   sizeof(struct msgdma_pref_extended_desc)
    47					   * priv->rx_ring_size * 2,
    48					   &priv->pref_rxdescphys, GFP_KERNEL);
    49	
    50		if (!priv->pref_rxdesc)
    51			goto err_rx;
    52	
    53		/* allocate memory for tx descriptors */
    54		priv->pref_txdesc =
    55			dma_alloc_coherent(priv->device,
    56					   sizeof(struct msgdma_pref_extended_desc)
    57					   * priv->tx_ring_size * 2,
    58					   &priv->pref_txdescphys, GFP_KERNEL);
    59	
    60		if (!priv->pref_txdesc)
    61			goto err_tx;
    62	
    63		/* setup base descriptor ring for tx & rx */
    64		rx_descs = (struct msgdma_pref_extended_desc *)priv->pref_rxdesc;
    65		tx_descs = (struct msgdma_pref_extended_desc *)priv->pref_txdesc;
    66		tx_descsphys = priv->pref_txdescphys;
    67		rx_descsphys = priv->pref_rxdescphys;
    68	
    69		/* setup RX descriptors */
    70		priv->pref_rx_prod = 0;
    71		for (i = 0; i < priv->rx_ring_size * 2; i++) {
    72			rx_descsphys = priv->pref_rxdescphys +
    73				(((i + 1) % (priv->rx_ring_size * 2)) *
    74				sizeof(struct msgdma_pref_extended_desc));
    75			rx_descs[i].next_desc_lo = lower_32_bits(rx_descsphys);
    76			rx_descs[i].next_desc_hi = upper_32_bits(rx_descsphys);
    77			rx_descs[i].stride = MSGDMA_DESC_RX_STRIDE;
    78			/* burst set to 0 so it defaults to max configured */
    79			/* set seq number to desc number */
    80			rx_descs[i].burst_seq_num = i;
    81		}
    82	
    83		/* setup TX descriptors */
    84		for (i = 0; i < priv->tx_ring_size * 2; i++) {
    85			tx_descsphys = priv->pref_txdescphys +
    86				(((i + 1) % (priv->tx_ring_size * 2)) *
    87				sizeof(struct msgdma_pref_extended_desc));
    88			tx_descs[i].next_desc_lo = lower_32_bits(tx_descsphys);
    89			tx_descs[i].next_desc_hi = upper_32_bits(tx_descsphys);
    90			tx_descs[i].stride = MSGDMA_DESC_TX_STRIDE;
    91			/* burst set to 0 so it defaults to max configured */
    92			/* set seq number to desc number */
    93			tx_descs[i].burst_seq_num = i;
    94		}
    95	
    96		if (netif_msg_ifup(priv))
    97			netdev_info(priv->dev, "%s: RX Desc mem at 0x%x\n", __func__,
  > 98				    priv->pref_rxdescphys);
    99	
   100		if (netif_msg_ifup(priv))
   101			netdev_info(priv->dev, "%s: TX Desc mem at 0x%x\n", __func__,
   102				    priv->pref_txdescphys);
   103	
   104		return 0;
   105	
   106	err_tx:
   107		dma_free_coherent(priv->device,
   108				  sizeof(struct msgdma_pref_extended_desc)
   109				  * priv->rx_ring_size * 2,
   110				  priv->pref_rxdesc, priv->pref_rxdescphys);
   111	err_rx:
   112		return -ENOMEM;
   113	}
   114	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 37400 bytes --]

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

* Re: [PATCH v3 10/10] net: eth: altera: update devicetree bindings documentation
  2020-06-04  7:32 ` [PATCH v3 10/10] net: eth: altera: update devicetree bindings documentation Ooi, Joyce
@ 2020-06-04 22:23   ` Rob Herring
  2020-06-05  6:36     ` Ooi, Joyce
  0 siblings, 1 reply; 16+ messages in thread
From: Rob Herring @ 2020-06-04 22:23 UTC (permalink / raw)
  To: Ooi, Joyce
  Cc: David S . Miller, Jakub Kicinski, Thor Thayer, netdev,
	Rob Herring, See Chin Liang, linux-kernel, Dinh Nguyen,
	Dalon Westergreen, devicetree, Dalon Westergreen, Tan Ley Foon

On Thu, 04 Jun 2020 15:32:56 +0800, Ooi, Joyce wrote:
> From: Dalon Westergreen <dalon.westergreen@intel.com>
> 
> Update devicetree bindings documentation to include msgdma
> prefetcher and ptp bindings.
> 
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Dalon Westergreen <dalon.westergreen@intel.com>
> Signed-off-by: Joyce Ooi <joyce.ooi@intel.com>
> ---
> v2: no change
> v3: no change
> ---
>  .../devicetree/bindings/net/altera_tse.txt         | 103 +++++++++++++++++----
>  1 file changed, 84 insertions(+), 19 deletions(-)
> 


Please add Acked-by/Reviewed-by tags when posting new versions. However,
there's no need to repost patches *only* to add the tags. The upstream
maintainer will do that for acks received on the version they apply.

If a tag was not added on purpose, please state why and what changed.


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

* RE: [PATCH v3 10/10] net: eth: altera: update devicetree bindings documentation
  2020-06-04 22:23   ` Rob Herring
@ 2020-06-05  6:36     ` Ooi, Joyce
  0 siblings, 0 replies; 16+ messages in thread
From: Ooi, Joyce @ 2020-06-05  6:36 UTC (permalink / raw)
  To: Rob Herring
  Cc: David S . Miller, Jakub Kicinski, Thor Thayer, netdev,
	Rob Herring, See, Chin Liang, linux-kernel, Nguyen, Dinh,
	Westergreen, Dalon, devicetree, Dalon Westergreen, Tan, Ley Foon

> -----Original Message-----
> From: Rob Herring <robh@kernel.org>
> Sent: Friday, June 5, 2020 6:23 AM
> To: Ooi, Joyce <joyce.ooi@intel.com>
> Cc: David S . Miller <davem@davemloft.net>; Jakub Kicinski
> <kuba@kernel.org>; Thor Thayer <thor.thayer@linux.intel.com>;
> netdev@vger.kernel.org; Rob Herring <robh+dt@kernel.org>; See, Chin
> Liang <chin.liang.see@intel.com>; linux-kernel@vger.kernel.org; Nguyen,
> Dinh <dinh.nguyen@intel.com>; Westergreen, Dalon
> <dalon.westergreen@intel.com>; devicetree@vger.kernel.org; Dalon
> Westergreen <dalon.westergreen@linux.intel.com>; Tan, Ley Foon
> <ley.foon.tan@intel.com>
> Subject: Re: [PATCH v3 10/10] net: eth: altera: update devicetree bindings
> documentation
> 
> On Thu, 04 Jun 2020 15:32:56 +0800, Ooi, Joyce wrote:
> > From: Dalon Westergreen <dalon.westergreen@intel.com>
> >
> > Update devicetree bindings documentation to include msgdma prefetcher
> > and ptp bindings.
> >
> > Cc: Rob Herring <robh+dt@kernel.org>
> > Cc: devicetree@vger.kernel.org
> > Signed-off-by: Dalon Westergreen <dalon.westergreen@intel.com>
> > Signed-off-by: Joyce Ooi <joyce.ooi@intel.com>
> > ---
> > v2: no change
> > v3: no change
> > ---
> >  .../devicetree/bindings/net/altera_tse.txt         | 103
> +++++++++++++++++----
> >  1 file changed, 84 insertions(+), 19 deletions(-)
> >
> 
> 
> Please add Acked-by/Reviewed-by tags when posting new versions.
> However, there's no need to repost patches *only* to add the tags. The
> upstream maintainer will do that for acks received on the version they apply.
> 
> If a tag was not added on purpose, please state why and what changed.

Noted, will do that next time.


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

end of thread, other threads:[~2020-06-05  6:36 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-04  7:32 [PATCH v3 00/10] net: eth: altera: tse: Add PTP and mSGDMA prefetcher Ooi, Joyce
2020-06-04  7:32 ` [PATCH v3 01/10] net: eth: altera: tse_start_xmit ignores tx_buffer call response Ooi, Joyce
2020-06-04  7:32 ` [PATCH v3 02/10] net: eth: altera: set rx and tx ring size before init_dma call Ooi, Joyce
2020-06-04  7:32 ` [PATCH v3 03/10] net: eth: altera: fix altera_dmaops declaration Ooi, Joyce
2020-06-04  7:32 ` [PATCH v3 04/10] net: eth: altera: add optional function to start tx dma Ooi, Joyce
2020-06-04  7:32 ` [PATCH v3 05/10] net: eth: altera: Move common functions to altera_utils Ooi, Joyce
2020-06-04  7:32 ` [PATCH v3 06/10] net: eth: altera: Add missing identifier names to function declarations Ooi, Joyce
2020-06-04  7:32 ` [PATCH v3 07/10] net: eth: altera: change tx functions to type netdev_tx_t Ooi, Joyce
2020-06-04  7:32 ` [PATCH v3 08/10] net: eth: altera: add support for ptp and timestamping Ooi, Joyce
2020-06-04  7:32 ` [PATCH v3 09/10] net: eth: altera: add msgdma prefetcher Ooi, Joyce
2020-06-04 11:02   ` kernel test robot
2020-06-04 22:16   ` kernel test robot
2020-06-04  7:32 ` [PATCH v3 10/10] net: eth: altera: update devicetree bindings documentation Ooi, Joyce
2020-06-04 22:23   ` Rob Herring
2020-06-05  6:36     ` Ooi, Joyce
2020-06-04 22:00 ` [PATCH v3 00/10] net: eth: altera: tse: Add PTP and mSGDMA prefetcher 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).