All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] net: smc911x: convert pxa dma to dmaengine
@ 2015-11-30 21:40 Robert Jarzmik
  2015-12-03  4:52 ` David Miller
  0 siblings, 1 reply; 15+ messages in thread
From: Robert Jarzmik @ 2015-11-30 21:40 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, linux-kernel, Robert Jarzmik

Convert the dma transfers to be dmaengine based, now pxa has a dmaengine
slave driver. This makes this driver a bit more PXA agnostic.

The driver was only compile tested. The risk is quite small as no
current PXA platform I'm aware of is using smc911x driver.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 drivers/net/ethernet/smsc/smc911x.c | 85 ++++++++++++++++++++++++-------------
 drivers/net/ethernet/smsc/smc911x.h | 63 ++++++++++++---------------
 2 files changed, 82 insertions(+), 66 deletions(-)

diff --git a/drivers/net/ethernet/smsc/smc911x.c b/drivers/net/ethernet/smsc/smc911x.c
index bd64eb982e52..3f5711061432 100644
--- a/drivers/net/ethernet/smsc/smc911x.c
+++ b/drivers/net/ethernet/smsc/smc911x.c
@@ -73,6 +73,9 @@ static const char version[] =
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
+#include <linux/dmaengine.h>
+#include <linux/dma/pxa-dma.h>
+
 #include <asm/io.h>
 
 #include "smc911x.h"
@@ -1174,18 +1177,16 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id)
 
 #ifdef SMC_USE_DMA
 static void
-smc911x_tx_dma_irq(int dma, void *data)
+smc911x_tx_dma_irq(void *data)
 {
-	struct net_device *dev = (struct net_device *)data;
-	struct smc911x_local *lp = netdev_priv(dev);
+	struct smc911x_local *lp = data;
+	struct net_device *dev = lp->netdev;
 	struct sk_buff *skb = lp->current_tx_skb;
 	unsigned long flags;
 
 	DBG(SMC_DEBUG_FUNC, dev, "--> %s\n", __func__);
 
 	DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA, dev, "TX DMA irq handler\n");
-	/* Clear the DMA interrupt sources */
-	SMC_DMA_ACK_IRQ(dev, dma);
 	BUG_ON(skb == NULL);
 	dma_unmap_single(NULL, tx_dmabuf, tx_dmalen, DMA_TO_DEVICE);
 	dev->trans_start = jiffies;
@@ -1208,18 +1209,16 @@ smc911x_tx_dma_irq(int dma, void *data)
 	    "TX DMA irq completed\n");
 }
 static void
-smc911x_rx_dma_irq(int dma, void *data)
+smc911x_rx_dma_irq(void *data)
 {
-	struct net_device *dev = (struct net_device *)data;
-	struct smc911x_local *lp = netdev_priv(dev);
+	struct smc911x_local *lp = data;
+	struct net_device *dev = lp->netdev;
 	struct sk_buff *skb = lp->current_rx_skb;
 	unsigned long flags;
 	unsigned int pkts;
 
 	DBG(SMC_DEBUG_FUNC, dev, "--> %s\n", __func__);
 	DBG(SMC_DEBUG_RX | SMC_DEBUG_DMA, dev, "RX DMA irq handler\n");
-	/* Clear the DMA interrupt sources */
-	SMC_DMA_ACK_IRQ(dev, dma);
 	dma_unmap_single(NULL, rx_dmabuf, rx_dmalen, DMA_FROM_DEVICE);
 	BUG_ON(skb == NULL);
 	lp->current_rx_skb = NULL;
@@ -1792,6 +1791,9 @@ static int smc911x_probe(struct net_device *dev)
 	unsigned int val, chip_id, revision;
 	const char *version_string;
 	unsigned long irq_flags;
+	struct dma_slave_config	config;
+	dma_cap_mask_t mask;
+	struct pxad_param param;
 
 	DBG(SMC_DEBUG_FUNC, dev, "--> %s\n", __func__);
 
@@ -1963,11 +1965,40 @@ static int smc911x_probe(struct net_device *dev)
 		goto err_out;
 
 #ifdef SMC_USE_DMA
-	lp->rxdma = SMC_DMA_REQUEST(dev, smc911x_rx_dma_irq);
-	lp->txdma = SMC_DMA_REQUEST(dev, smc911x_tx_dma_irq);
+
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+	param.prio = PXAD_PRIO_LOWEST;
+	param.drcmr = -1UL;
+
+	lp->rxdma =
+		dma_request_slave_channel_compat(mask, pxad_filter_fn,
+						 &param, &dev->dev, "rx");
+	lp->txdma =
+		dma_request_slave_channel_compat(mask, pxad_filter_fn,
+						 &param, &dev->dev, "tx");
 	lp->rxdma_active = 0;
 	lp->txdma_active = 0;
-	dev->dma = lp->rxdma;
+
+	memset(&config, 0, sizeof(config));
+	config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	config.src_addr = lp->physaddr + RX_DATA_FIFO;
+	config.dst_addr = lp->physaddr + TX_DATA_FIFO;
+	config.src_maxburst = 32;
+	config.dst_maxburst = 32;
+	retval = dmaengine_slave_config(lp->rxdma, &config);
+	if (retval) {
+		dev_err(lp->dev, "dma rx channel configuration failed: %d\n",
+			retval);
+		goto err_out;
+	}
+	retval = dmaengine_slave_config(lp->txdma, &config);
+	if (retval) {
+		dev_err(lp->dev, "dma tx channel configuration failed: %d\n",
+			retval);
+		goto err_out;
+	}
 #endif
 
 	retval = register_netdev(dev);
@@ -1978,11 +2009,11 @@ static int smc911x_probe(struct net_device *dev)
 			    dev->base_addr, dev->irq);
 
 #ifdef SMC_USE_DMA
-		if (lp->rxdma != -1)
-			pr_cont(" RXDMA %d", lp->rxdma);
+		if (lp->rxdma)
+			pr_cont(" RXDMA %p", lp->rxdma);
 
-		if (lp->txdma != -1)
-			pr_cont(" TXDMA %d", lp->txdma);
+		if (lp->txdma)
+			pr_cont(" TXDMA %p", lp->txdma);
 #endif
 		pr_cont("\n");
 		if (!is_valid_ether_addr(dev->dev_addr)) {
@@ -2005,12 +2036,10 @@ static int smc911x_probe(struct net_device *dev)
 err_out:
 #ifdef SMC_USE_DMA
 	if (retval) {
-		if (lp->rxdma != -1) {
-			SMC_DMA_FREE(dev, lp->rxdma);
-		}
-		if (lp->txdma != -1) {
-			SMC_DMA_FREE(dev, lp->txdma);
-		}
+		if (lp->rxdma)
+			dma_release_channel(lp->rxdma);
+		if (lp->txdma)
+			dma_release_channel(lp->txdma);
 	}
 #endif
 	return retval;
@@ -2112,12 +2141,10 @@ static int smc911x_drv_remove(struct platform_device *pdev)
 
 #ifdef SMC_USE_DMA
 	{
-		if (lp->rxdma != -1) {
-			SMC_DMA_FREE(dev, lp->rxdma);
-		}
-		if (lp->txdma != -1) {
-			SMC_DMA_FREE(dev, lp->txdma);
-		}
+		if (lp->rxdma)
+			dma_release_channel(lp->rxdma);
+		if (lp->txdma)
+			dma_release_channel(lp->txdma);
 	}
 #endif
 	iounmap(lp->base);
diff --git a/drivers/net/ethernet/smsc/smc911x.h b/drivers/net/ethernet/smsc/smc911x.h
index 04b35f55df97..fa528ea0ea51 100644
--- a/drivers/net/ethernet/smsc/smc911x.h
+++ b/drivers/net/ethernet/smsc/smc911x.h
@@ -101,8 +101,8 @@ struct smc911x_local {
 #ifdef SMC_USE_DMA
 	/* DMA needs the physical address of the chip */
 	u_long physaddr;
-	int rxdma;
-	int txdma;
+	struct dma_chan *rxdma;
+	struct dma_chan *txdma;
 	int rxdma_active;
 	int txdma_active;
 	struct sk_buff *current_rx_skb;
@@ -210,27 +210,6 @@ static inline void SMC_outsl(struct smc911x_local *lp, int reg,
 
 #ifdef SMC_USE_PXA_DMA
 
-#include <mach/dma.h>
-
-/*
- * Define the request and free functions
- * These are unfortunately architecture specific as no generic allocation
- * mechanism exits
- */
-#define SMC_DMA_REQUEST(dev, handler) \
-	 pxa_request_dma(dev->name, DMA_PRIO_LOW, handler, dev)
-
-#define SMC_DMA_FREE(dev, dma) \
-	 pxa_free_dma(dma)
-
-#define SMC_DMA_ACK_IRQ(dev, dma)					\
-{									\
-	if (DCSR(dma) & DCSR_BUSERR) {					\
-		netdev_err(dev, "DMA %d bus error!\n", dma);		\
-	}								\
-	DCSR(dma) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;		\
-}
-
 /*
  * Use a DMA for RX and TX packets.
  */
@@ -238,6 +217,8 @@ static inline void SMC_outsl(struct smc911x_local *lp, int reg,
 
 static dma_addr_t rx_dmabuf, tx_dmabuf;
 static int rx_dmalen, tx_dmalen;
+static void smc911x_rx_dma_irq(void *data);
+static void smc911x_tx_dma_irq(void *data);
 
 #ifdef SMC_insl
 #undef SMC_insl
@@ -246,8 +227,10 @@ static int rx_dmalen, tx_dmalen;
 
 static inline void
 smc_pxa_dma_insl(struct smc911x_local *lp, u_long physaddr,
-		int reg, int dma, u_char *buf, int len)
+		int reg, struct dma_chan *dma, u_char *buf, int len)
 {
+	struct dma_async_tx_descriptor *tx;
+
 	/* 64 bit alignment is required for memory to memory DMA */
 	if ((long)buf & 4) {
 		*((u32 *)buf) = SMC_inl(lp, reg);
@@ -258,12 +241,14 @@ smc_pxa_dma_insl(struct smc911x_local *lp, u_long physaddr,
 	len *= 4;
 	rx_dmabuf = dma_map_single(lp->dev, buf, len, DMA_FROM_DEVICE);
 	rx_dmalen = len;
-	DCSR(dma) = DCSR_NODESC;
-	DTADR(dma) = rx_dmabuf;
-	DSADR(dma) = physaddr + reg;
-	DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 |
-		DCMD_WIDTH4 | DCMD_ENDIRQEN | (DCMD_LENGTH & rx_dmalen));
-	DCSR(dma) = DCSR_NODESC | DCSR_RUN;
+	tx = dmaengine_prep_slave_single(dma, rx_dmabuf, rx_dmalen,
+					 DMA_DEV_TO_MEM, 0);
+	if (tx) {
+		tx->callback = smc911x_rx_dma_irq;
+		tx->callback_param = lp;
+		dmaengine_submit(tx);
+		dma_async_issue_pending(dma);
+	}
 }
 #endif
 
@@ -274,8 +259,10 @@ smc_pxa_dma_insl(struct smc911x_local *lp, u_long physaddr,
 
 static inline void
 smc_pxa_dma_outsl(struct smc911x_local *lp, u_long physaddr,
-		int reg, int dma, u_char *buf, int len)
+		int reg, struct dma_chan *dma, u_char *buf, int len)
 {
+	struct dma_async_tx_descriptor *tx;
+
 	/* 64 bit alignment is required for memory to memory DMA */
 	if ((long)buf & 4) {
 		SMC_outl(*((u32 *)buf), lp, reg);
@@ -286,12 +273,14 @@ smc_pxa_dma_outsl(struct smc911x_local *lp, u_long physaddr,
 	len *= 4;
 	tx_dmabuf = dma_map_single(lp->dev, buf, len, DMA_TO_DEVICE);
 	tx_dmalen = len;
-	DCSR(dma) = DCSR_NODESC;
-	DSADR(dma) = tx_dmabuf;
-	DTADR(dma) = physaddr + reg;
-	DCMD(dma) = (DCMD_INCSRCADDR | DCMD_BURST32 |
-		DCMD_WIDTH4 | DCMD_ENDIRQEN | (DCMD_LENGTH & tx_dmalen));
-	DCSR(dma) = DCSR_NODESC | DCSR_RUN;
+	tx = dmaengine_prep_slave_single(dma, tx_dmabuf, tx_dmalen,
+					 DMA_DEV_TO_MEM, 0);
+	if (tx) {
+		tx->callback = smc911x_tx_dma_irq;
+		tx->callback_param = lp;
+		dmaengine_submit(tx);
+		dma_async_issue_pending(dma);
+	}
 }
 #endif
 #endif	 /* SMC_USE_PXA_DMA */
-- 
2.1.4


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

* Re: [PATCH] net: smc911x: convert pxa dma to dmaengine
  2015-11-30 21:40 [PATCH] net: smc911x: convert pxa dma to dmaengine Robert Jarzmik
@ 2015-12-03  4:52 ` David Miller
  2015-12-03 18:46   ` Robert Jarzmik
  0 siblings, 1 reply; 15+ messages in thread
From: David Miller @ 2015-12-03  4:52 UTC (permalink / raw)
  To: robert.jarzmik; +Cc: netdev, linux-kernel

From: Robert Jarzmik <robert.jarzmik@free.fr>
Date: Mon, 30 Nov 2015 22:40:28 +0100

> Convert the dma transfers to be dmaengine based, now pxa has a dmaengine
> slave driver. This makes this driver a bit more PXA agnostic.
> 
> The driver was only compile tested. The risk is quite small as no
> current PXA platform I'm aware of is using smc911x driver.
> 
> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>

I've marked this 'deferred' in patchwork until someone tests
these changes and says they should be good on all platforms
this chip is used.

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

* Re: [PATCH] net: smc911x: convert pxa dma to dmaengine
  2015-12-03  4:52 ` David Miller
@ 2015-12-03 18:46   ` Robert Jarzmik
  2016-02-05 21:44     ` Robert Jarzmik
  0 siblings, 1 reply; 15+ messages in thread
From: Robert Jarzmik @ 2015-12-03 18:46 UTC (permalink / raw)
  To: David Miller, Alberto Panizzo, Guennadi Liakhovetski,
	Hitoshi Mitake, Fabio Estevam
  Cc: netdev, linux-kernel

David Miller <davem@davemloft.net> writes:

> From: Robert Jarzmik <robert.jarzmik@free.fr>
> Date: Mon, 30 Nov 2015 22:40:28 +0100
>
>> Convert the dma transfers to be dmaengine based, now pxa has a dmaengine
>> slave driver. This makes this driver a bit more PXA agnostic.
>> 
>> The driver was only compile tested. The risk is quite small as no
>> current PXA platform I'm aware of is using smc911x driver.
>> 
>> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
>
> I've marked this 'deferred' in patchwork until someone tests
> these changes and says they should be good on all platforms
> this chip is used.

Okay, so would any maintainer of non pxa boards give a feedback for this patch ?
The ones I have found are :
 - sh2007: Guennadi and Hitoshi
 - armadillo5x0: Alberto
 - imx v6 and imx v7: Fabio
I've added the patch at the end of this mail for easier handling.

Now, if no maintainer gives it a test, what do we do, David ? I'm intending to
remove "arch/arm/mach-pxa/include/mach/dma.h" in the near future, which will
break this driver somehow (at least for PXA boards, even if none is identified
so far).
So could we agree on a deadline, and what you wish to do : either drop the patch
or apply, or something else.

Cheers.

-- 
Robert

--8>--
>From 9b7e996fe92d81d417f59a4eed92b3472594a2e8 Mon Sep 17 00:00:00 2001
From: Robert Jarzmik <robert.jarzmik@free.fr>
Date: Thu, 10 Sep 2015 14:48:09 +0200
Subject: [PATCH] net: smc911x: convert pxa dma to dmaengine

Convert the dma transfers to be dmaengine based, now pxa has a dmaengine
slave driver. This makes this driver a bit more PXA agnostic.

The driver was only compile tested. The risk is quite small as no
current PXA platform I'm aware of is using smc911x driver.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 drivers/net/ethernet/smsc/smc911x.c | 85 ++++++++++++++++++++++++-------------
 drivers/net/ethernet/smsc/smc911x.h | 63 ++++++++++++---------------
 2 files changed, 82 insertions(+), 66 deletions(-)

diff --git a/drivers/net/ethernet/smsc/smc911x.c b/drivers/net/ethernet/smsc/smc911x.c
index bd64eb982e52..3f5711061432 100644
--- a/drivers/net/ethernet/smsc/smc911x.c
+++ b/drivers/net/ethernet/smsc/smc911x.c
@@ -73,6 +73,9 @@ static const char version[] =
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
+#include <linux/dmaengine.h>
+#include <linux/dma/pxa-dma.h>
+
 #include <asm/io.h>
 
 #include "smc911x.h"
@@ -1174,18 +1177,16 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id)
 
 #ifdef SMC_USE_DMA
 static void
-smc911x_tx_dma_irq(int dma, void *data)
+smc911x_tx_dma_irq(void *data)
 {
-	struct net_device *dev = (struct net_device *)data;
-	struct smc911x_local *lp = netdev_priv(dev);
+	struct smc911x_local *lp = data;
+	struct net_device *dev = lp->netdev;
 	struct sk_buff *skb = lp->current_tx_skb;
 	unsigned long flags;
 
 	DBG(SMC_DEBUG_FUNC, dev, "--> %s\n", __func__);
 
 	DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA, dev, "TX DMA irq handler\n");
-	/* Clear the DMA interrupt sources */
-	SMC_DMA_ACK_IRQ(dev, dma);
 	BUG_ON(skb == NULL);
 	dma_unmap_single(NULL, tx_dmabuf, tx_dmalen, DMA_TO_DEVICE);
 	dev->trans_start = jiffies;
@@ -1208,18 +1209,16 @@ smc911x_tx_dma_irq(int dma, void *data)
 	    "TX DMA irq completed\n");
 }
 static void
-smc911x_rx_dma_irq(int dma, void *data)
+smc911x_rx_dma_irq(void *data)
 {
-	struct net_device *dev = (struct net_device *)data;
-	struct smc911x_local *lp = netdev_priv(dev);
+	struct smc911x_local *lp = data;
+	struct net_device *dev = lp->netdev;
 	struct sk_buff *skb = lp->current_rx_skb;
 	unsigned long flags;
 	unsigned int pkts;
 
 	DBG(SMC_DEBUG_FUNC, dev, "--> %s\n", __func__);
 	DBG(SMC_DEBUG_RX | SMC_DEBUG_DMA, dev, "RX DMA irq handler\n");
-	/* Clear the DMA interrupt sources */
-	SMC_DMA_ACK_IRQ(dev, dma);
 	dma_unmap_single(NULL, rx_dmabuf, rx_dmalen, DMA_FROM_DEVICE);
 	BUG_ON(skb == NULL);
 	lp->current_rx_skb = NULL;
@@ -1792,6 +1791,9 @@ static int smc911x_probe(struct net_device *dev)
 	unsigned int val, chip_id, revision;
 	const char *version_string;
 	unsigned long irq_flags;
+	struct dma_slave_config	config;
+	dma_cap_mask_t mask;
+	struct pxad_param param;
 
 	DBG(SMC_DEBUG_FUNC, dev, "--> %s\n", __func__);
 
@@ -1963,11 +1965,40 @@ static int smc911x_probe(struct net_device *dev)
 		goto err_out;
 
 #ifdef SMC_USE_DMA
-	lp->rxdma = SMC_DMA_REQUEST(dev, smc911x_rx_dma_irq);
-	lp->txdma = SMC_DMA_REQUEST(dev, smc911x_tx_dma_irq);
+
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+	param.prio = PXAD_PRIO_LOWEST;
+	param.drcmr = -1UL;
+
+	lp->rxdma =
+		dma_request_slave_channel_compat(mask, pxad_filter_fn,
+						 &param, &dev->dev, "rx");
+	lp->txdma =
+		dma_request_slave_channel_compat(mask, pxad_filter_fn,
+						 &param, &dev->dev, "tx");
 	lp->rxdma_active = 0;
 	lp->txdma_active = 0;
-	dev->dma = lp->rxdma;
+
+	memset(&config, 0, sizeof(config));
+	config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	config.src_addr = lp->physaddr + RX_DATA_FIFO;
+	config.dst_addr = lp->physaddr + TX_DATA_FIFO;
+	config.src_maxburst = 32;
+	config.dst_maxburst = 32;
+	retval = dmaengine_slave_config(lp->rxdma, &config);
+	if (retval) {
+		dev_err(lp->dev, "dma rx channel configuration failed: %d\n",
+			retval);
+		goto err_out;
+	}
+	retval = dmaengine_slave_config(lp->txdma, &config);
+	if (retval) {
+		dev_err(lp->dev, "dma tx channel configuration failed: %d\n",
+			retval);
+		goto err_out;
+	}
 #endif
 
 	retval = register_netdev(dev);
@@ -1978,11 +2009,11 @@ static int smc911x_probe(struct net_device *dev)
 			    dev->base_addr, dev->irq);
 
 #ifdef SMC_USE_DMA
-		if (lp->rxdma != -1)
-			pr_cont(" RXDMA %d", lp->rxdma);
+		if (lp->rxdma)
+			pr_cont(" RXDMA %p", lp->rxdma);
 
-		if (lp->txdma != -1)
-			pr_cont(" TXDMA %d", lp->txdma);
+		if (lp->txdma)
+			pr_cont(" TXDMA %p", lp->txdma);
 #endif
 		pr_cont("\n");
 		if (!is_valid_ether_addr(dev->dev_addr)) {
@@ -2005,12 +2036,10 @@ static int smc911x_probe(struct net_device *dev)
 err_out:
 #ifdef SMC_USE_DMA
 	if (retval) {
-		if (lp->rxdma != -1) {
-			SMC_DMA_FREE(dev, lp->rxdma);
-		}
-		if (lp->txdma != -1) {
-			SMC_DMA_FREE(dev, lp->txdma);
-		}
+		if (lp->rxdma)
+			dma_release_channel(lp->rxdma);
+		if (lp->txdma)
+			dma_release_channel(lp->txdma);
 	}
 #endif
 	return retval;
@@ -2112,12 +2141,10 @@ static int smc911x_drv_remove(struct platform_device *pdev)
 
 #ifdef SMC_USE_DMA
 	{
-		if (lp->rxdma != -1) {
-			SMC_DMA_FREE(dev, lp->rxdma);
-		}
-		if (lp->txdma != -1) {
-			SMC_DMA_FREE(dev, lp->txdma);
-		}
+		if (lp->rxdma)
+			dma_release_channel(lp->rxdma);
+		if (lp->txdma)
+			dma_release_channel(lp->txdma);
 	}
 #endif
 	iounmap(lp->base);
diff --git a/drivers/net/ethernet/smsc/smc911x.h b/drivers/net/ethernet/smsc/smc911x.h
index 04b35f55df97..fa528ea0ea51 100644
--- a/drivers/net/ethernet/smsc/smc911x.h
+++ b/drivers/net/ethernet/smsc/smc911x.h
@@ -101,8 +101,8 @@ struct smc911x_local {
 #ifdef SMC_USE_DMA
 	/* DMA needs the physical address of the chip */
 	u_long physaddr;
-	int rxdma;
-	int txdma;
+	struct dma_chan *rxdma;
+	struct dma_chan *txdma;
 	int rxdma_active;
 	int txdma_active;
 	struct sk_buff *current_rx_skb;
@@ -210,27 +210,6 @@ static inline void SMC_outsl(struct smc911x_local *lp, int reg,
 
 #ifdef SMC_USE_PXA_DMA
 
-#include <mach/dma.h>
-
-/*
- * Define the request and free functions
- * These are unfortunately architecture specific as no generic allocation
- * mechanism exits
- */
-#define SMC_DMA_REQUEST(dev, handler) \
-	 pxa_request_dma(dev->name, DMA_PRIO_LOW, handler, dev)
-
-#define SMC_DMA_FREE(dev, dma) \
-	 pxa_free_dma(dma)
-
-#define SMC_DMA_ACK_IRQ(dev, dma)					\
-{									\
-	if (DCSR(dma) & DCSR_BUSERR) {					\
-		netdev_err(dev, "DMA %d bus error!\n", dma);		\
-	}								\
-	DCSR(dma) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;		\
-}
-
 /*
  * Use a DMA for RX and TX packets.
  */
@@ -238,6 +217,8 @@ static inline void SMC_outsl(struct smc911x_local *lp, int reg,
 
 static dma_addr_t rx_dmabuf, tx_dmabuf;
 static int rx_dmalen, tx_dmalen;
+static void smc911x_rx_dma_irq(void *data);
+static void smc911x_tx_dma_irq(void *data);
 
 #ifdef SMC_insl
 #undef SMC_insl
@@ -246,8 +227,10 @@ static int rx_dmalen, tx_dmalen;
 
 static inline void
 smc_pxa_dma_insl(struct smc911x_local *lp, u_long physaddr,
-		int reg, int dma, u_char *buf, int len)
+		int reg, struct dma_chan *dma, u_char *buf, int len)
 {
+	struct dma_async_tx_descriptor *tx;
+
 	/* 64 bit alignment is required for memory to memory DMA */
 	if ((long)buf & 4) {
 		*((u32 *)buf) = SMC_inl(lp, reg);
@@ -258,12 +241,14 @@ smc_pxa_dma_insl(struct smc911x_local *lp, u_long physaddr,
 	len *= 4;
 	rx_dmabuf = dma_map_single(lp->dev, buf, len, DMA_FROM_DEVICE);
 	rx_dmalen = len;
-	DCSR(dma) = DCSR_NODESC;
-	DTADR(dma) = rx_dmabuf;
-	DSADR(dma) = physaddr + reg;
-	DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 |
-		DCMD_WIDTH4 | DCMD_ENDIRQEN | (DCMD_LENGTH & rx_dmalen));
-	DCSR(dma) = DCSR_NODESC | DCSR_RUN;
+	tx = dmaengine_prep_slave_single(dma, rx_dmabuf, rx_dmalen,
+					 DMA_DEV_TO_MEM, 0);
+	if (tx) {
+		tx->callback = smc911x_rx_dma_irq;
+		tx->callback_param = lp;
+		dmaengine_submit(tx);
+		dma_async_issue_pending(dma);
+	}
 }
 #endif
 
@@ -274,8 +259,10 @@ smc_pxa_dma_insl(struct smc911x_local *lp, u_long physaddr,
 
 static inline void
 smc_pxa_dma_outsl(struct smc911x_local *lp, u_long physaddr,
-		int reg, int dma, u_char *buf, int len)
+		int reg, struct dma_chan *dma, u_char *buf, int len)
 {
+	struct dma_async_tx_descriptor *tx;
+
 	/* 64 bit alignment is required for memory to memory DMA */
 	if ((long)buf & 4) {
 		SMC_outl(*((u32 *)buf), lp, reg);
@@ -286,12 +273,14 @@ smc_pxa_dma_outsl(struct smc911x_local *lp, u_long physaddr,
 	len *= 4;
 	tx_dmabuf = dma_map_single(lp->dev, buf, len, DMA_TO_DEVICE);
 	tx_dmalen = len;
-	DCSR(dma) = DCSR_NODESC;
-	DSADR(dma) = tx_dmabuf;
-	DTADR(dma) = physaddr + reg;
-	DCMD(dma) = (DCMD_INCSRCADDR | DCMD_BURST32 |
-		DCMD_WIDTH4 | DCMD_ENDIRQEN | (DCMD_LENGTH & tx_dmalen));
-	DCSR(dma) = DCSR_NODESC | DCSR_RUN;
+	tx = dmaengine_prep_slave_single(dma, tx_dmabuf, tx_dmalen,
+					 DMA_DEV_TO_MEM, 0);
+	if (tx) {
+		tx->callback = smc911x_tx_dma_irq;
+		tx->callback_param = lp;
+		dmaengine_submit(tx);
+		dma_async_issue_pending(dma);
+	}
 }
 #endif
 #endif	 /* SMC_USE_PXA_DMA */
-- 
2.1.4


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

* Re: [PATCH] net: smc911x: convert pxa dma to dmaengine
  2015-12-03 18:46   ` Robert Jarzmik
@ 2016-02-05 21:44     ` Robert Jarzmik
  2016-02-05 22:30       ` David Miller
  0 siblings, 1 reply; 15+ messages in thread
From: Robert Jarzmik @ 2016-02-05 21:44 UTC (permalink / raw)
  To: David Miller
  Cc: Alberto Panizzo, Guennadi Liakhovetski, Hitoshi Mitake,
	Fabio Estevam, netdev, linux-kernel

Robert Jarzmik <robert.jarzmik@free.fr> writes:

> David Miller <davem@davemloft.net> writes:
>
>> From: Robert Jarzmik <robert.jarzmik@free.fr>
>> Date: Mon, 30 Nov 2015 22:40:28 +0100
>>
>>> Convert the dma transfers to be dmaengine based, now pxa has a dmaengine
>>> slave driver. This makes this driver a bit more PXA agnostic.
>>> 
>>> The driver was only compile tested. The risk is quite small as no
>>> current PXA platform I'm aware of is using smc911x driver.
>>> 
>>> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
>>
>> I've marked this 'deferred' in patchwork until someone tests
>> these changes and says they should be good on all platforms
>> this chip is used.
>
> Okay, so would any maintainer of non pxa boards give a feedback for this patch ?
> The ones I have found are :
>  - sh2007: Guennadi and Hitoshi
>  - armadillo5x0: Alberto
>  - imx v6 and imx v7: Fabio
> I've added the patch at the end of this mail for easier handling.
>
> Now, if no maintainer gives it a test, what do we do, David ? I'm intending to
> remove "arch/arm/mach-pxa/include/mach/dma.h" in the near future, which will
> break this driver somehow (at least for PXA boards, even if none is identified
> so far).
> So could we agree on a deadline, and what you wish to do : either drop the patch
> or apply, or something else.

Hi David,

Apart from Alberto who answered he cannot test it by lack of hardware, the
others didn't answer.

So how can I move forward ? Would you want me to amend the KConfig to add a "&&
!ARCH_PXA" on the "depend" line ?

Cheers.

-- 
Robert

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

* Re: [PATCH] net: smc911x: convert pxa dma to dmaengine
  2016-02-05 21:44     ` Robert Jarzmik
@ 2016-02-05 22:30       ` David Miller
  2016-02-06  9:05         ` Robert Jarzmik
  0 siblings, 1 reply; 15+ messages in thread
From: David Miller @ 2016-02-05 22:30 UTC (permalink / raw)
  To: robert.jarzmik
  Cc: maramaopercheseimorto, g.liakhovetski, mitake, fabio.estevam,
	netdev, linux-kernel

From: Robert Jarzmik <robert.jarzmik@free.fr>
Date: Fri, 05 Feb 2016 22:44:56 +0100

> Apart from Alberto who answered he cannot test it by lack of hardware, the
> others didn't answer.
> 
> So how can I move forward ? Would you want me to amend the KConfig to add a "&&
> !ARCH_PXA" on the "depend" line ?

Please just keep pinging people to properly test this.

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

* Re: [PATCH] net: smc911x: convert pxa dma to dmaengine
  2016-02-05 22:30       ` David Miller
@ 2016-02-06  9:05         ` Robert Jarzmik
  2016-02-20 13:29           ` Hitoshi Mitake
       [not found]           ` <CAE1WaKK2DqYYOTLmprbLuZVN-8--sZVyZVHgkcT4Jg7797S7HQ@mail.gmail.com>
  0 siblings, 2 replies; 15+ messages in thread
From: Robert Jarzmik @ 2016-02-06  9:05 UTC (permalink / raw)
  To: g.liakhovetski, mitake, fabio.estevam; +Cc: netdev, linux-kernel, David Miller

David Miller <davem@davemloft.net> writes:

> From: Robert Jarzmik <robert.jarzmik@free.fr>
> Date: Fri, 05 Feb 2016 22:44:56 +0100
>
>> Apart from Alberto who answered he cannot test it by lack of hardware, the
>> others didn't answer.
>> 
>> So how can I move forward ? Would you want me to amend the KConfig to add a "&&
>> !ARCH_PXA" on the "depend" line ?
>
> Please just keep pinging people to properly test this.
Okay, let's have another try.

Hi Guennadi, Hitoshi, Fabio,

Could any of you try this patch to ensure your board is not broken please ?
I've re-added the patch at the end of this mail for easier handling. Normally no
code path in non-PXA board is changed, so the test should be straightforward.

It's also available in : https://lkml.org/lkml/2015/11/30/768

You're the maintainers of the following boards using smc911x AFAIK:
 - sh2007: Guennadi and Hitoshi
 - armadillo5x0: Alberto
 - imx v6 and imx v7: Fabio

Cheers.

-- 
Robert


---8<---
From: Robert Jarzmik <robert.jarzmik@free.fr>
Subject: [PATCH] net: smc911x: convert pxa dma to dmaengine
To: "David S. Miller" <davem@davemloft.net>
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Robert Jarzmik <robert.jarzmik@free.fr>
Date: Mon, 30 Nov 2015 22:40:28 +0100 (9 weeks, 4 days, 11 hours ago)
Message-Id: <1448919628-13273-1-git-send-email-robert.jarzmik@free.fr>
X-Mailer: git-send-email 2.1.4

Convert the dma transfers to be dmaengine based, now pxa has a dmaengine
slave driver. This makes this driver a bit more PXA agnostic.

The driver was only compile tested. The risk is quite small as no
current PXA platform I'm aware of is using smc911x driver.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 drivers/net/ethernet/smsc/smc911x.c | 85 ++++++++++++++++++++++++-------------
 drivers/net/ethernet/smsc/smc911x.h | 63 ++++++++++++---------------
 2 files changed, 82 insertions(+), 66 deletions(-)

diff --git a/drivers/net/ethernet/smsc/smc911x.c b/drivers/net/ethernet/smsc/smc911x.c
index bd64eb982e52..3f5711061432 100644
--- a/drivers/net/ethernet/smsc/smc911x.c
+++ b/drivers/net/ethernet/smsc/smc911x.c
@@ -73,6 +73,9 @@ static const char version[] =
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
+#include <linux/dmaengine.h>
+#include <linux/dma/pxa-dma.h>
+
 #include <asm/io.h>
 
 #include "smc911x.h"
@@ -1174,18 +1177,16 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id)
 
 #ifdef SMC_USE_DMA
 static void
-smc911x_tx_dma_irq(int dma, void *data)
+smc911x_tx_dma_irq(void *data)
 {
-	struct net_device *dev = (struct net_device *)data;
-	struct smc911x_local *lp = netdev_priv(dev);
+	struct smc911x_local *lp = data;
+	struct net_device *dev = lp->netdev;
 	struct sk_buff *skb = lp->current_tx_skb;
 	unsigned long flags;
 
 	DBG(SMC_DEBUG_FUNC, dev, "--> %s\n", __func__);
 
 	DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA, dev, "TX DMA irq handler\n");
-	/* Clear the DMA interrupt sources */
-	SMC_DMA_ACK_IRQ(dev, dma);
 	BUG_ON(skb == NULL);
 	dma_unmap_single(NULL, tx_dmabuf, tx_dmalen, DMA_TO_DEVICE);
 	dev->trans_start = jiffies;
@@ -1208,18 +1209,16 @@ smc911x_tx_dma_irq(int dma, void *data)
 	    "TX DMA irq completed\n");
 }
 static void
-smc911x_rx_dma_irq(int dma, void *data)
+smc911x_rx_dma_irq(void *data)
 {
-	struct net_device *dev = (struct net_device *)data;
-	struct smc911x_local *lp = netdev_priv(dev);
+	struct smc911x_local *lp = data;
+	struct net_device *dev = lp->netdev;
 	struct sk_buff *skb = lp->current_rx_skb;
 	unsigned long flags;
 	unsigned int pkts;
 
 	DBG(SMC_DEBUG_FUNC, dev, "--> %s\n", __func__);
 	DBG(SMC_DEBUG_RX | SMC_DEBUG_DMA, dev, "RX DMA irq handler\n");
-	/* Clear the DMA interrupt sources */
-	SMC_DMA_ACK_IRQ(dev, dma);
 	dma_unmap_single(NULL, rx_dmabuf, rx_dmalen, DMA_FROM_DEVICE);
 	BUG_ON(skb == NULL);
 	lp->current_rx_skb = NULL;
@@ -1792,6 +1791,9 @@ static int smc911x_probe(struct net_device *dev)
 	unsigned int val, chip_id, revision;
 	const char *version_string;
 	unsigned long irq_flags;
+	struct dma_slave_config	config;
+	dma_cap_mask_t mask;
+	struct pxad_param param;
 
 	DBG(SMC_DEBUG_FUNC, dev, "--> %s\n", __func__);
 
@@ -1963,11 +1965,40 @@ static int smc911x_probe(struct net_device *dev)
 		goto err_out;
 
 #ifdef SMC_USE_DMA
-	lp->rxdma = SMC_DMA_REQUEST(dev, smc911x_rx_dma_irq);
-	lp->txdma = SMC_DMA_REQUEST(dev, smc911x_tx_dma_irq);
+
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+	param.prio = PXAD_PRIO_LOWEST;
+	param.drcmr = -1UL;
+
+	lp->rxdma =
+		dma_request_slave_channel_compat(mask, pxad_filter_fn,
+						 &param, &dev->dev, "rx");
+	lp->txdma =
+		dma_request_slave_channel_compat(mask, pxad_filter_fn,
+						 &param, &dev->dev, "tx");
 	lp->rxdma_active = 0;
 	lp->txdma_active = 0;
-	dev->dma = lp->rxdma;
+
+	memset(&config, 0, sizeof(config));
+	config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	config.src_addr = lp->physaddr + RX_DATA_FIFO;
+	config.dst_addr = lp->physaddr + TX_DATA_FIFO;
+	config.src_maxburst = 32;
+	config.dst_maxburst = 32;
+	retval = dmaengine_slave_config(lp->rxdma, &config);
+	if (retval) {
+		dev_err(lp->dev, "dma rx channel configuration failed: %d\n",
+			retval);
+		goto err_out;
+	}
+	retval = dmaengine_slave_config(lp->txdma, &config);
+	if (retval) {
+		dev_err(lp->dev, "dma tx channel configuration failed: %d\n",
+			retval);
+		goto err_out;
+	}
 #endif
 
 	retval = register_netdev(dev);
@@ -1978,11 +2009,11 @@ static int smc911x_probe(struct net_device *dev)
 			    dev->base_addr, dev->irq);
 
 #ifdef SMC_USE_DMA
-		if (lp->rxdma != -1)
-			pr_cont(" RXDMA %d", lp->rxdma);
+		if (lp->rxdma)
+			pr_cont(" RXDMA %p", lp->rxdma);
 
-		if (lp->txdma != -1)
-			pr_cont(" TXDMA %d", lp->txdma);
+		if (lp->txdma)
+			pr_cont(" TXDMA %p", lp->txdma);
 #endif
 		pr_cont("\n");
 		if (!is_valid_ether_addr(dev->dev_addr)) {
@@ -2005,12 +2036,10 @@ static int smc911x_probe(struct net_device *dev)
 err_out:
 #ifdef SMC_USE_DMA
 	if (retval) {
-		if (lp->rxdma != -1) {
-			SMC_DMA_FREE(dev, lp->rxdma);
-		}
-		if (lp->txdma != -1) {
-			SMC_DMA_FREE(dev, lp->txdma);
-		}
+		if (lp->rxdma)
+			dma_release_channel(lp->rxdma);
+		if (lp->txdma)
+			dma_release_channel(lp->txdma);
 	}
 #endif
 	return retval;
@@ -2112,12 +2141,10 @@ static int smc911x_drv_remove(struct platform_device *pdev)
 
 #ifdef SMC_USE_DMA
 	{
-		if (lp->rxdma != -1) {
-			SMC_DMA_FREE(dev, lp->rxdma);
-		}
-		if (lp->txdma != -1) {
-			SMC_DMA_FREE(dev, lp->txdma);
-		}
+		if (lp->rxdma)
+			dma_release_channel(lp->rxdma);
+		if (lp->txdma)
+			dma_release_channel(lp->txdma);
 	}
 #endif
 	iounmap(lp->base);
diff --git a/drivers/net/ethernet/smsc/smc911x.h b/drivers/net/ethernet/smsc/smc911x.h
index 04b35f55df97..fa528ea0ea51 100644
--- a/drivers/net/ethernet/smsc/smc911x.h
+++ b/drivers/net/ethernet/smsc/smc911x.h
@@ -101,8 +101,8 @@ struct smc911x_local {
 #ifdef SMC_USE_DMA
 	/* DMA needs the physical address of the chip */
 	u_long physaddr;
-	int rxdma;
-	int txdma;
+	struct dma_chan *rxdma;
+	struct dma_chan *txdma;
 	int rxdma_active;
 	int txdma_active;
 	struct sk_buff *current_rx_skb;
@@ -210,27 +210,6 @@ static inline void SMC_outsl(struct smc911x_local *lp, int reg,
 
 #ifdef SMC_USE_PXA_DMA
 
-#include <mach/dma.h>
-
-/*
- * Define the request and free functions
- * These are unfortunately architecture specific as no generic allocation
- * mechanism exits
- */
-#define SMC_DMA_REQUEST(dev, handler) \
-	 pxa_request_dma(dev->name, DMA_PRIO_LOW, handler, dev)
-
-#define SMC_DMA_FREE(dev, dma) \
-	 pxa_free_dma(dma)
-
-#define SMC_DMA_ACK_IRQ(dev, dma)					\
-{									\
-	if (DCSR(dma) & DCSR_BUSERR) {					\
-		netdev_err(dev, "DMA %d bus error!\n", dma);		\
-	}								\
-	DCSR(dma) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;		\
-}
-
 /*
  * Use a DMA for RX and TX packets.
  */
@@ -238,6 +217,8 @@ static inline void SMC_outsl(struct smc911x_local *lp, int reg,
 
 static dma_addr_t rx_dmabuf, tx_dmabuf;
 static int rx_dmalen, tx_dmalen;
+static void smc911x_rx_dma_irq(void *data);
+static void smc911x_tx_dma_irq(void *data);
 
 #ifdef SMC_insl
 #undef SMC_insl
@@ -246,8 +227,10 @@ static int rx_dmalen, tx_dmalen;
 
 static inline void
 smc_pxa_dma_insl(struct smc911x_local *lp, u_long physaddr,
-		int reg, int dma, u_char *buf, int len)
+		int reg, struct dma_chan *dma, u_char *buf, int len)
 {
+	struct dma_async_tx_descriptor *tx;
+
 	/* 64 bit alignment is required for memory to memory DMA */
 	if ((long)buf & 4) {
 		*((u32 *)buf) = SMC_inl(lp, reg);
@@ -258,12 +241,14 @@ smc_pxa_dma_insl(struct smc911x_local *lp, u_long physaddr,
 	len *= 4;
 	rx_dmabuf = dma_map_single(lp->dev, buf, len, DMA_FROM_DEVICE);
 	rx_dmalen = len;
-	DCSR(dma) = DCSR_NODESC;
-	DTADR(dma) = rx_dmabuf;
-	DSADR(dma) = physaddr + reg;
-	DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 |
-		DCMD_WIDTH4 | DCMD_ENDIRQEN | (DCMD_LENGTH & rx_dmalen));
-	DCSR(dma) = DCSR_NODESC | DCSR_RUN;
+	tx = dmaengine_prep_slave_single(dma, rx_dmabuf, rx_dmalen,
+					 DMA_DEV_TO_MEM, 0);
+	if (tx) {
+		tx->callback = smc911x_rx_dma_irq;
+		tx->callback_param = lp;
+		dmaengine_submit(tx);
+		dma_async_issue_pending(dma);
+	}
 }
 #endif
 
@@ -274,8 +259,10 @@ smc_pxa_dma_insl(struct smc911x_local *lp, u_long physaddr,
 
 static inline void
 smc_pxa_dma_outsl(struct smc911x_local *lp, u_long physaddr,
-		int reg, int dma, u_char *buf, int len)
+		int reg, struct dma_chan *dma, u_char *buf, int len)
 {
+	struct dma_async_tx_descriptor *tx;
+
 	/* 64 bit alignment is required for memory to memory DMA */
 	if ((long)buf & 4) {
 		SMC_outl(*((u32 *)buf), lp, reg);
@@ -286,12 +273,14 @@ smc_pxa_dma_outsl(struct smc911x_local *lp, u_long physaddr,
 	len *= 4;
 	tx_dmabuf = dma_map_single(lp->dev, buf, len, DMA_TO_DEVICE);
 	tx_dmalen = len;
-	DCSR(dma) = DCSR_NODESC;
-	DSADR(dma) = tx_dmabuf;
-	DTADR(dma) = physaddr + reg;
-	DCMD(dma) = (DCMD_INCSRCADDR | DCMD_BURST32 |
-		DCMD_WIDTH4 | DCMD_ENDIRQEN | (DCMD_LENGTH & tx_dmalen));
-	DCSR(dma) = DCSR_NODESC | DCSR_RUN;
+	tx = dmaengine_prep_slave_single(dma, tx_dmabuf, tx_dmalen,
+					 DMA_DEV_TO_MEM, 0);
+	if (tx) {
+		tx->callback = smc911x_tx_dma_irq;
+		tx->callback_param = lp;
+		dmaengine_submit(tx);
+		dma_async_issue_pending(dma);
+	}
 }
 #endif
 #endif	 /* SMC_USE_PXA_DMA */
-- 
2.1.4

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

* Re: [PATCH] net: smc911x: convert pxa dma to dmaengine
  2016-02-06  9:05         ` Robert Jarzmik
@ 2016-02-20 13:29           ` Hitoshi Mitake
  2016-02-20 15:46             ` Guennadi Liakhovetski
       [not found]           ` <CAE1WaKK2DqYYOTLmprbLuZVN-8--sZVyZVHgkcT4Jg7797S7HQ@mail.gmail.com>
  1 sibling, 1 reply; 15+ messages in thread
From: Hitoshi Mitake @ 2016-02-20 13:29 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: g.liakhovetski, mitake, fabio.estevam, netdev, linux-kernel,
	David Miller


Hi Robert,

At Sat, 06 Feb 2016 10:05:51 +0100,
Robert Jarzmik wrote:
> 
> David Miller <davem@davemloft.net> writes:
> 
> > From: Robert Jarzmik <robert.jarzmik@free.fr>
> > Date: Fri, 05 Feb 2016 22:44:56 +0100
> >
> >> Apart from Alberto who answered he cannot test it by lack of hardware, the
> >> others didn't answer.
> >> 
> >> So how can I move forward ? Would you want me to amend the KConfig to add a "&&
> >> !ARCH_PXA" on the "depend" line ?
> >
> > Please just keep pinging people to properly test this.
> Okay, let's have another try.
> 
> Hi Guennadi, Hitoshi, Fabio,
> 
> Could any of you try this patch to ensure your board is not broken please ?
> I've re-added the patch at the end of this mail for easier handling. Normally no
> code path in non-PXA board is changed, so the test should be straightforward.
> 
> It's also available in : https://lkml.org/lkml/2015/11/30/768
> 
> You're the maintainers of the following boards using smc911x AFAIK:
>  - sh2007: Guennadi and Hitoshi

(I noticed my previous mail was bounced, so sending it again)

Really sorry, currently I don't have the board :(
Do you have a working board that can be used for testing, Guennadi?

Thanks,
Hitoshi

>  - armadillo5x0: Alberto
>  - imx v6 and imx v7: Fabio
> 
> Cheers.
> 
> -- 
> Robert
> 
> 
> ---8<---
> From: Robert Jarzmik <robert.jarzmik@free.fr>
> Subject: [PATCH] net: smc911x: convert pxa dma to dmaengine
> To: "David S. Miller" <davem@davemloft.net>
> Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Robert Jarzmik <robert.jarzmik@free.fr>
> Date: Mon, 30 Nov 2015 22:40:28 +0100 (9 weeks, 4 days, 11 hours ago)
> Message-Id: <1448919628-13273-1-git-send-email-robert.jarzmik@free.fr>
> X-Mailer: git-send-email 2.1.4
> 
> Convert the dma transfers to be dmaengine based, now pxa has a dmaengine
> slave driver. This makes this driver a bit more PXA agnostic.
> 
> The driver was only compile tested. The risk is quite small as no
> current PXA platform I'm aware of is using smc911x driver.
> 
> Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
> ---
>  drivers/net/ethernet/smsc/smc911x.c | 85 ++++++++++++++++++++++++-------------
>  drivers/net/ethernet/smsc/smc911x.h | 63 ++++++++++++---------------
>  2 files changed, 82 insertions(+), 66 deletions(-)
> 
> diff --git a/drivers/net/ethernet/smsc/smc911x.c b/drivers/net/ethernet/smsc/smc911x.c
> index bd64eb982e52..3f5711061432 100644
> --- a/drivers/net/ethernet/smsc/smc911x.c
> +++ b/drivers/net/ethernet/smsc/smc911x.c
> @@ -73,6 +73,9 @@ static const char version[] =
>  #include <linux/etherdevice.h>
>  #include <linux/skbuff.h>
>  
> +#include <linux/dmaengine.h>
> +#include <linux/dma/pxa-dma.h>
> +
>  #include <asm/io.h>
>  
>  #include "smc911x.h"
> @@ -1174,18 +1177,16 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id)
>  
>  #ifdef SMC_USE_DMA
>  static void
> -smc911x_tx_dma_irq(int dma, void *data)
> +smc911x_tx_dma_irq(void *data)
>  {
> -	struct net_device *dev = (struct net_device *)data;
> -	struct smc911x_local *lp = netdev_priv(dev);
> +	struct smc911x_local *lp = data;
> +	struct net_device *dev = lp->netdev;
>  	struct sk_buff *skb = lp->current_tx_skb;
>  	unsigned long flags;
>  
>  	DBG(SMC_DEBUG_FUNC, dev, "--> %s\n", __func__);
>  
>  	DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA, dev, "TX DMA irq handler\n");
> -	/* Clear the DMA interrupt sources */
> -	SMC_DMA_ACK_IRQ(dev, dma);
>  	BUG_ON(skb == NULL);
>  	dma_unmap_single(NULL, tx_dmabuf, tx_dmalen, DMA_TO_DEVICE);
>  	dev->trans_start = jiffies;
> @@ -1208,18 +1209,16 @@ smc911x_tx_dma_irq(int dma, void *data)
>  	    "TX DMA irq completed\n");
>  }
>  static void
> -smc911x_rx_dma_irq(int dma, void *data)
> +smc911x_rx_dma_irq(void *data)
>  {
> -	struct net_device *dev = (struct net_device *)data;
> -	struct smc911x_local *lp = netdev_priv(dev);
> +	struct smc911x_local *lp = data;
> +	struct net_device *dev = lp->netdev;
>  	struct sk_buff *skb = lp->current_rx_skb;
>  	unsigned long flags;
>  	unsigned int pkts;
>  
>  	DBG(SMC_DEBUG_FUNC, dev, "--> %s\n", __func__);
>  	DBG(SMC_DEBUG_RX | SMC_DEBUG_DMA, dev, "RX DMA irq handler\n");
> -	/* Clear the DMA interrupt sources */
> -	SMC_DMA_ACK_IRQ(dev, dma);
>  	dma_unmap_single(NULL, rx_dmabuf, rx_dmalen, DMA_FROM_DEVICE);
>  	BUG_ON(skb == NULL);
>  	lp->current_rx_skb = NULL;
> @@ -1792,6 +1791,9 @@ static int smc911x_probe(struct net_device *dev)
>  	unsigned int val, chip_id, revision;
>  	const char *version_string;
>  	unsigned long irq_flags;
> +	struct dma_slave_config	config;
> +	dma_cap_mask_t mask;
> +	struct pxad_param param;
>  
>  	DBG(SMC_DEBUG_FUNC, dev, "--> %s\n", __func__);
>  
> @@ -1963,11 +1965,40 @@ static int smc911x_probe(struct net_device *dev)
>  		goto err_out;
>  
>  #ifdef SMC_USE_DMA
> -	lp->rxdma = SMC_DMA_REQUEST(dev, smc911x_rx_dma_irq);
> -	lp->txdma = SMC_DMA_REQUEST(dev, smc911x_tx_dma_irq);
> +
> +	dma_cap_zero(mask);
> +	dma_cap_set(DMA_SLAVE, mask);
> +	param.prio = PXAD_PRIO_LOWEST;
> +	param.drcmr = -1UL;
> +
> +	lp->rxdma =
> +		dma_request_slave_channel_compat(mask, pxad_filter_fn,
> +						 &param, &dev->dev, "rx");
> +	lp->txdma =
> +		dma_request_slave_channel_compat(mask, pxad_filter_fn,
> +						 &param, &dev->dev, "tx");
>  	lp->rxdma_active = 0;
>  	lp->txdma_active = 0;
> -	dev->dma = lp->rxdma;
> +
> +	memset(&config, 0, sizeof(config));
> +	config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
> +	config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
> +	config.src_addr = lp->physaddr + RX_DATA_FIFO;
> +	config.dst_addr = lp->physaddr + TX_DATA_FIFO;
> +	config.src_maxburst = 32;
> +	config.dst_maxburst = 32;
> +	retval = dmaengine_slave_config(lp->rxdma, &config);
> +	if (retval) {
> +		dev_err(lp->dev, "dma rx channel configuration failed: %d\n",
> +			retval);
> +		goto err_out;
> +	}
> +	retval = dmaengine_slave_config(lp->txdma, &config);
> +	if (retval) {
> +		dev_err(lp->dev, "dma tx channel configuration failed: %d\n",
> +			retval);
> +		goto err_out;
> +	}
>  #endif
>  
>  	retval = register_netdev(dev);
> @@ -1978,11 +2009,11 @@ static int smc911x_probe(struct net_device *dev)
>  			    dev->base_addr, dev->irq);
>  
>  #ifdef SMC_USE_DMA
> -		if (lp->rxdma != -1)
> -			pr_cont(" RXDMA %d", lp->rxdma);
> +		if (lp->rxdma)
> +			pr_cont(" RXDMA %p", lp->rxdma);
>  
> -		if (lp->txdma != -1)
> -			pr_cont(" TXDMA %d", lp->txdma);
> +		if (lp->txdma)
> +			pr_cont(" TXDMA %p", lp->txdma);
>  #endif
>  		pr_cont("\n");
>  		if (!is_valid_ether_addr(dev->dev_addr)) {
> @@ -2005,12 +2036,10 @@ static int smc911x_probe(struct net_device *dev)
>  err_out:
>  #ifdef SMC_USE_DMA
>  	if (retval) {
> -		if (lp->rxdma != -1) {
> -			SMC_DMA_FREE(dev, lp->rxdma);
> -		}
> -		if (lp->txdma != -1) {
> -			SMC_DMA_FREE(dev, lp->txdma);
> -		}
> +		if (lp->rxdma)
> +			dma_release_channel(lp->rxdma);
> +		if (lp->txdma)
> +			dma_release_channel(lp->txdma);
>  	}
>  #endif
>  	return retval;
> @@ -2112,12 +2141,10 @@ static int smc911x_drv_remove(struct platform_device *pdev)
>  
>  #ifdef SMC_USE_DMA
>  	{
> -		if (lp->rxdma != -1) {
> -			SMC_DMA_FREE(dev, lp->rxdma);
> -		}
> -		if (lp->txdma != -1) {
> -			SMC_DMA_FREE(dev, lp->txdma);
> -		}
> +		if (lp->rxdma)
> +			dma_release_channel(lp->rxdma);
> +		if (lp->txdma)
> +			dma_release_channel(lp->txdma);
>  	}
>  #endif
>  	iounmap(lp->base);
> diff --git a/drivers/net/ethernet/smsc/smc911x.h b/drivers/net/ethernet/smsc/smc911x.h
> index 04b35f55df97..fa528ea0ea51 100644
> --- a/drivers/net/ethernet/smsc/smc911x.h
> +++ b/drivers/net/ethernet/smsc/smc911x.h
> @@ -101,8 +101,8 @@ struct smc911x_local {
>  #ifdef SMC_USE_DMA
>  	/* DMA needs the physical address of the chip */
>  	u_long physaddr;
> -	int rxdma;
> -	int txdma;
> +	struct dma_chan *rxdma;
> +	struct dma_chan *txdma;
>  	int rxdma_active;
>  	int txdma_active;
>  	struct sk_buff *current_rx_skb;
> @@ -210,27 +210,6 @@ static inline void SMC_outsl(struct smc911x_local *lp, int reg,
>  
>  #ifdef SMC_USE_PXA_DMA
>  
> -#include <mach/dma.h>
> -
> -/*
> - * Define the request and free functions
> - * These are unfortunately architecture specific as no generic allocation
> - * mechanism exits
> - */
> -#define SMC_DMA_REQUEST(dev, handler) \
> -	 pxa_request_dma(dev->name, DMA_PRIO_LOW, handler, dev)
> -
> -#define SMC_DMA_FREE(dev, dma) \
> -	 pxa_free_dma(dma)
> -
> -#define SMC_DMA_ACK_IRQ(dev, dma)					\
> -{									\
> -	if (DCSR(dma) & DCSR_BUSERR) {					\
> -		netdev_err(dev, "DMA %d bus error!\n", dma);		\
> -	}								\
> -	DCSR(dma) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;		\
> -}
> -
>  /*
>   * Use a DMA for RX and TX packets.
>   */
> @@ -238,6 +217,8 @@ static inline void SMC_outsl(struct smc911x_local *lp, int reg,
>  
>  static dma_addr_t rx_dmabuf, tx_dmabuf;
>  static int rx_dmalen, tx_dmalen;
> +static void smc911x_rx_dma_irq(void *data);
> +static void smc911x_tx_dma_irq(void *data);
>  
>  #ifdef SMC_insl
>  #undef SMC_insl
> @@ -246,8 +227,10 @@ static int rx_dmalen, tx_dmalen;
>  
>  static inline void
>  smc_pxa_dma_insl(struct smc911x_local *lp, u_long physaddr,
> -		int reg, int dma, u_char *buf, int len)
> +		int reg, struct dma_chan *dma, u_char *buf, int len)
>  {
> +	struct dma_async_tx_descriptor *tx;
> +
>  	/* 64 bit alignment is required for memory to memory DMA */
>  	if ((long)buf & 4) {
>  		*((u32 *)buf) = SMC_inl(lp, reg);
> @@ -258,12 +241,14 @@ smc_pxa_dma_insl(struct smc911x_local *lp, u_long physaddr,
>  	len *= 4;
>  	rx_dmabuf = dma_map_single(lp->dev, buf, len, DMA_FROM_DEVICE);
>  	rx_dmalen = len;
> -	DCSR(dma) = DCSR_NODESC;
> -	DTADR(dma) = rx_dmabuf;
> -	DSADR(dma) = physaddr + reg;
> -	DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 |
> -		DCMD_WIDTH4 | DCMD_ENDIRQEN | (DCMD_LENGTH & rx_dmalen));
> -	DCSR(dma) = DCSR_NODESC | DCSR_RUN;
> +	tx = dmaengine_prep_slave_single(dma, rx_dmabuf, rx_dmalen,
> +					 DMA_DEV_TO_MEM, 0);
> +	if (tx) {
> +		tx->callback = smc911x_rx_dma_irq;
> +		tx->callback_param = lp;
> +		dmaengine_submit(tx);
> +		dma_async_issue_pending(dma);
> +	}
>  }
>  #endif
>  
> @@ -274,8 +259,10 @@ smc_pxa_dma_insl(struct smc911x_local *lp, u_long physaddr,
>  
>  static inline void
>  smc_pxa_dma_outsl(struct smc911x_local *lp, u_long physaddr,
> -		int reg, int dma, u_char *buf, int len)
> +		int reg, struct dma_chan *dma, u_char *buf, int len)
>  {
> +	struct dma_async_tx_descriptor *tx;
> +
>  	/* 64 bit alignment is required for memory to memory DMA */
>  	if ((long)buf & 4) {
>  		SMC_outl(*((u32 *)buf), lp, reg);
> @@ -286,12 +273,14 @@ smc_pxa_dma_outsl(struct smc911x_local *lp, u_long physaddr,
>  	len *= 4;
>  	tx_dmabuf = dma_map_single(lp->dev, buf, len, DMA_TO_DEVICE);
>  	tx_dmalen = len;
> -	DCSR(dma) = DCSR_NODESC;
> -	DSADR(dma) = tx_dmabuf;
> -	DTADR(dma) = physaddr + reg;
> -	DCMD(dma) = (DCMD_INCSRCADDR | DCMD_BURST32 |
> -		DCMD_WIDTH4 | DCMD_ENDIRQEN | (DCMD_LENGTH & tx_dmalen));
> -	DCSR(dma) = DCSR_NODESC | DCSR_RUN;
> +	tx = dmaengine_prep_slave_single(dma, tx_dmabuf, tx_dmalen,
> +					 DMA_DEV_TO_MEM, 0);
> +	if (tx) {
> +		tx->callback = smc911x_tx_dma_irq;
> +		tx->callback_param = lp;
> +		dmaengine_submit(tx);
> +		dma_async_issue_pending(dma);
> +	}
>  }
>  #endif
>  #endif	 /* SMC_USE_PXA_DMA */
> -- 
> 2.1.4
> 

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

* Re: [PATCH] net: smc911x: convert pxa dma to dmaengine
       [not found]           ` <CAE1WaKK2DqYYOTLmprbLuZVN-8--sZVyZVHgkcT4Jg7797S7HQ@mail.gmail.com>
@ 2016-02-20 14:48               ` Robert Jarzmik
  0 siblings, 0 replies; 15+ messages in thread
From: Robert Jarzmik @ 2016-02-20 14:48 UTC (permalink / raw)
  To: g.liakhovetski, Hitoshi Mitake, fabio.estevam, Hitoshi Mitake
  Cc: netdev, LKML, David Miller

Hitoshi Mitake <mitake.hitoshi@gmail.com> writes:

> Hi Robert,
>
> On Sat, Feb 6, 2016 at 6:05 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:
>     > Please just keep pinging people to properly test this.
>     
>     Okay, let's have another try.
>     
>     Hi Guennadi, Hitoshi, Fabio,
>     
>     Could any of you try this patch to ensure your board is not broken please ?
>     I've re-added the patch at the end of this mail for easier handling.
>     Normally no
>     code path in non-PXA board is changed, so the test should be
>     straightforward.
>     
>     It's also available in : https://lkml.org/lkml/2015/11/30/768
>     
>     You're the maintainers of the following boards using smc911x AFAIK:
>     - sh2007: Guennadi and Hitoshi
>
> Really sorry, currently I don't have the board :(
> Do you have a working board that can be used for testing, Guennadi?
>
> Thanks,
> Hitoshi

Hello,

I'll reping once more, to see if any of you could give this patch a try.
So far Hitoshi doesn't have the hardware anymore, so it leaves only Guennadi and
Fabio.

If you could give it a try it would be great.

For reference, the patch is here : https://lkml.org/lkml/2015/11/30/768

Cheers.

--
Robert

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

* Re: [PATCH] net: smc911x: convert pxa dma to dmaengine
@ 2016-02-20 14:48               ` Robert Jarzmik
  0 siblings, 0 replies; 15+ messages in thread
From: Robert Jarzmik @ 2016-02-20 14:48 UTC (permalink / raw)
  To: g.liakhovetski, Hitoshi Mitake, fabio.estevam, Hitoshi Mitake
  Cc: netdev, LKML, David Miller

Hitoshi Mitake <mitake.hitoshi@gmail.com> writes:

> Hi Robert,
>
> On Sat, Feb 6, 2016 at 6:05 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:
>     > Please just keep pinging people to properly test this.
>     
>     Okay, let's have another try.
>     
>     Hi Guennadi, Hitoshi, Fabio,
>     
>     Could any of you try this patch to ensure your board is not broken please ?
>     I've re-added the patch at the end of this mail for easier handling.
>     Normally no
>     code path in non-PXA board is changed, so the test should be
>     straightforward.
>     
>     It's also available in : https://lkml.org/lkml/2015/11/30/768
>     
>     You're the maintainers of the following boards using smc911x AFAIK:
>     - sh2007: Guennadi and Hitoshi
>
> Really sorry, currently I don't have the board :(
> Do you have a working board that can be used for testing, Guennadi?
>
> Thanks,
> Hitoshi

Hello,

I'll reping once more, to see if any of you could give this patch a try.
So far Hitoshi doesn't have the hardware anymore, so it leaves only Guennadi and
Fabio.

If you could give it a try it would be great.

For reference, the patch is here : https://lkml.org/lkml/2015/11/30/768

Cheers.

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

* Re: [PATCH] net: smc911x: convert pxa dma to dmaengine
  2016-02-20 13:29           ` Hitoshi Mitake
@ 2016-02-20 15:46             ` Guennadi Liakhovetski
  0 siblings, 0 replies; 15+ messages in thread
From: Guennadi Liakhovetski @ 2016-02-20 15:46 UTC (permalink / raw)
  To: Hitoshi Mitake
  Cc: Robert Jarzmik, mitake, fabio.estevam, netdev, linux-kernel,
	David Miller

Hi,

On Sat, 20 Feb 2016, Hitoshi Mitake wrote:

> 
> Hi Robert,
> 
> At Sat, 06 Feb 2016 10:05:51 +0100,
> Robert Jarzmik wrote:
> > 
> > David Miller <davem@davemloft.net> writes:
> > 
> > > From: Robert Jarzmik <robert.jarzmik@free.fr>
> > > Date: Fri, 05 Feb 2016 22:44:56 +0100
> > >
> > >> Apart from Alberto who answered he cannot test it by lack of hardware, the
> > >> others didn't answer.
> > >> 
> > >> So how can I move forward ? Would you want me to amend the KConfig to add a "&&
> > >> !ARCH_PXA" on the "depend" line ?
> > >
> > > Please just keep pinging people to properly test this.
> > Okay, let's have another try.
> > 
> > Hi Guennadi, Hitoshi, Fabio,
> > 
> > Could any of you try this patch to ensure your board is not broken please ?
> > I've re-added the patch at the end of this mail for easier handling. Normally no
> > code path in non-PXA board is changed, so the test should be straightforward.
> > 
> > It's also available in : https://lkml.org/lkml/2015/11/30/768
> > 
> > You're the maintainers of the following boards using smc911x AFAIK:
> >  - sh2007: Guennadi and Hitoshi
> 
> (I noticed my previous mail was bounced, so sending it again)
> 
> Really sorry, currently I don't have the board :(
> Do you have a working board that can be used for testing, Guennadi?

Don't think I have anything, that I could use for testing with a 
reasonable effort.

Thanks
Guennadi

> 
> Thanks,
> Hitoshi
> 
> >  - armadillo5x0: Alberto
> >  - imx v6 and imx v7: Fabio
> > 
> > Cheers.
> > 
> > -- 
> > Robert
> > 
> > 
> > ---8<---
> > From: Robert Jarzmik <robert.jarzmik@free.fr>
> > Subject: [PATCH] net: smc911x: convert pxa dma to dmaengine
> > To: "David S. Miller" <davem@davemloft.net>
> > Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Robert Jarzmik <robert.jarzmik@free.fr>
> > Date: Mon, 30 Nov 2015 22:40:28 +0100 (9 weeks, 4 days, 11 hours ago)
> > Message-Id: <1448919628-13273-1-git-send-email-robert.jarzmik@free.fr>
> > X-Mailer: git-send-email 2.1.4
> > 
> > Convert the dma transfers to be dmaengine based, now pxa has a dmaengine
> > slave driver. This makes this driver a bit more PXA agnostic.
> > 
> > The driver was only compile tested. The risk is quite small as no
> > current PXA platform I'm aware of is using smc911x driver.
> > 
> > Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
> > ---
> >  drivers/net/ethernet/smsc/smc911x.c | 85 ++++++++++++++++++++++++-------------
> >  drivers/net/ethernet/smsc/smc911x.h | 63 ++++++++++++---------------
> >  2 files changed, 82 insertions(+), 66 deletions(-)
> > 
> > diff --git a/drivers/net/ethernet/smsc/smc911x.c b/drivers/net/ethernet/smsc/smc911x.c
> > index bd64eb982e52..3f5711061432 100644
> > --- a/drivers/net/ethernet/smsc/smc911x.c
> > +++ b/drivers/net/ethernet/smsc/smc911x.c
> > @@ -73,6 +73,9 @@ static const char version[] =
> >  #include <linux/etherdevice.h>
> >  #include <linux/skbuff.h>
> >  
> > +#include <linux/dmaengine.h>
> > +#include <linux/dma/pxa-dma.h>
> > +
> >  #include <asm/io.h>
> >  
> >  #include "smc911x.h"
> > @@ -1174,18 +1177,16 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id)
> >  
> >  #ifdef SMC_USE_DMA
> >  static void
> > -smc911x_tx_dma_irq(int dma, void *data)
> > +smc911x_tx_dma_irq(void *data)
> >  {
> > -	struct net_device *dev = (struct net_device *)data;
> > -	struct smc911x_local *lp = netdev_priv(dev);
> > +	struct smc911x_local *lp = data;
> > +	struct net_device *dev = lp->netdev;
> >  	struct sk_buff *skb = lp->current_tx_skb;
> >  	unsigned long flags;
> >  
> >  	DBG(SMC_DEBUG_FUNC, dev, "--> %s\n", __func__);
> >  
> >  	DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA, dev, "TX DMA irq handler\n");
> > -	/* Clear the DMA interrupt sources */
> > -	SMC_DMA_ACK_IRQ(dev, dma);
> >  	BUG_ON(skb == NULL);
> >  	dma_unmap_single(NULL, tx_dmabuf, tx_dmalen, DMA_TO_DEVICE);
> >  	dev->trans_start = jiffies;
> > @@ -1208,18 +1209,16 @@ smc911x_tx_dma_irq(int dma, void *data)
> >  	    "TX DMA irq completed\n");
> >  }
> >  static void
> > -smc911x_rx_dma_irq(int dma, void *data)
> > +smc911x_rx_dma_irq(void *data)
> >  {
> > -	struct net_device *dev = (struct net_device *)data;
> > -	struct smc911x_local *lp = netdev_priv(dev);
> > +	struct smc911x_local *lp = data;
> > +	struct net_device *dev = lp->netdev;
> >  	struct sk_buff *skb = lp->current_rx_skb;
> >  	unsigned long flags;
> >  	unsigned int pkts;
> >  
> >  	DBG(SMC_DEBUG_FUNC, dev, "--> %s\n", __func__);
> >  	DBG(SMC_DEBUG_RX | SMC_DEBUG_DMA, dev, "RX DMA irq handler\n");
> > -	/* Clear the DMA interrupt sources */
> > -	SMC_DMA_ACK_IRQ(dev, dma);
> >  	dma_unmap_single(NULL, rx_dmabuf, rx_dmalen, DMA_FROM_DEVICE);
> >  	BUG_ON(skb == NULL);
> >  	lp->current_rx_skb = NULL;
> > @@ -1792,6 +1791,9 @@ static int smc911x_probe(struct net_device *dev)
> >  	unsigned int val, chip_id, revision;
> >  	const char *version_string;
> >  	unsigned long irq_flags;
> > +	struct dma_slave_config	config;
> > +	dma_cap_mask_t mask;
> > +	struct pxad_param param;
> >  
> >  	DBG(SMC_DEBUG_FUNC, dev, "--> %s\n", __func__);
> >  
> > @@ -1963,11 +1965,40 @@ static int smc911x_probe(struct net_device *dev)
> >  		goto err_out;
> >  
> >  #ifdef SMC_USE_DMA
> > -	lp->rxdma = SMC_DMA_REQUEST(dev, smc911x_rx_dma_irq);
> > -	lp->txdma = SMC_DMA_REQUEST(dev, smc911x_tx_dma_irq);
> > +
> > +	dma_cap_zero(mask);
> > +	dma_cap_set(DMA_SLAVE, mask);
> > +	param.prio = PXAD_PRIO_LOWEST;
> > +	param.drcmr = -1UL;
> > +
> > +	lp->rxdma =
> > +		dma_request_slave_channel_compat(mask, pxad_filter_fn,
> > +						 &param, &dev->dev, "rx");
> > +	lp->txdma =
> > +		dma_request_slave_channel_compat(mask, pxad_filter_fn,
> > +						 &param, &dev->dev, "tx");
> >  	lp->rxdma_active = 0;
> >  	lp->txdma_active = 0;
> > -	dev->dma = lp->rxdma;
> > +
> > +	memset(&config, 0, sizeof(config));
> > +	config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
> > +	config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
> > +	config.src_addr = lp->physaddr + RX_DATA_FIFO;
> > +	config.dst_addr = lp->physaddr + TX_DATA_FIFO;
> > +	config.src_maxburst = 32;
> > +	config.dst_maxburst = 32;
> > +	retval = dmaengine_slave_config(lp->rxdma, &config);
> > +	if (retval) {
> > +		dev_err(lp->dev, "dma rx channel configuration failed: %d\n",
> > +			retval);
> > +		goto err_out;
> > +	}
> > +	retval = dmaengine_slave_config(lp->txdma, &config);
> > +	if (retval) {
> > +		dev_err(lp->dev, "dma tx channel configuration failed: %d\n",
> > +			retval);
> > +		goto err_out;
> > +	}
> >  #endif
> >  
> >  	retval = register_netdev(dev);
> > @@ -1978,11 +2009,11 @@ static int smc911x_probe(struct net_device *dev)
> >  			    dev->base_addr, dev->irq);
> >  
> >  #ifdef SMC_USE_DMA
> > -		if (lp->rxdma != -1)
> > -			pr_cont(" RXDMA %d", lp->rxdma);
> > +		if (lp->rxdma)
> > +			pr_cont(" RXDMA %p", lp->rxdma);
> >  
> > -		if (lp->txdma != -1)
> > -			pr_cont(" TXDMA %d", lp->txdma);
> > +		if (lp->txdma)
> > +			pr_cont(" TXDMA %p", lp->txdma);
> >  #endif
> >  		pr_cont("\n");
> >  		if (!is_valid_ether_addr(dev->dev_addr)) {
> > @@ -2005,12 +2036,10 @@ static int smc911x_probe(struct net_device *dev)
> >  err_out:
> >  #ifdef SMC_USE_DMA
> >  	if (retval) {
> > -		if (lp->rxdma != -1) {
> > -			SMC_DMA_FREE(dev, lp->rxdma);
> > -		}
> > -		if (lp->txdma != -1) {
> > -			SMC_DMA_FREE(dev, lp->txdma);
> > -		}
> > +		if (lp->rxdma)
> > +			dma_release_channel(lp->rxdma);
> > +		if (lp->txdma)
> > +			dma_release_channel(lp->txdma);
> >  	}
> >  #endif
> >  	return retval;
> > @@ -2112,12 +2141,10 @@ static int smc911x_drv_remove(struct platform_device *pdev)
> >  
> >  #ifdef SMC_USE_DMA
> >  	{
> > -		if (lp->rxdma != -1) {
> > -			SMC_DMA_FREE(dev, lp->rxdma);
> > -		}
> > -		if (lp->txdma != -1) {
> > -			SMC_DMA_FREE(dev, lp->txdma);
> > -		}
> > +		if (lp->rxdma)
> > +			dma_release_channel(lp->rxdma);
> > +		if (lp->txdma)
> > +			dma_release_channel(lp->txdma);
> >  	}
> >  #endif
> >  	iounmap(lp->base);
> > diff --git a/drivers/net/ethernet/smsc/smc911x.h b/drivers/net/ethernet/smsc/smc911x.h
> > index 04b35f55df97..fa528ea0ea51 100644
> > --- a/drivers/net/ethernet/smsc/smc911x.h
> > +++ b/drivers/net/ethernet/smsc/smc911x.h
> > @@ -101,8 +101,8 @@ struct smc911x_local {
> >  #ifdef SMC_USE_DMA
> >  	/* DMA needs the physical address of the chip */
> >  	u_long physaddr;
> > -	int rxdma;
> > -	int txdma;
> > +	struct dma_chan *rxdma;
> > +	struct dma_chan *txdma;
> >  	int rxdma_active;
> >  	int txdma_active;
> >  	struct sk_buff *current_rx_skb;
> > @@ -210,27 +210,6 @@ static inline void SMC_outsl(struct smc911x_local *lp, int reg,
> >  
> >  #ifdef SMC_USE_PXA_DMA
> >  
> > -#include <mach/dma.h>
> > -
> > -/*
> > - * Define the request and free functions
> > - * These are unfortunately architecture specific as no generic allocation
> > - * mechanism exits
> > - */
> > -#define SMC_DMA_REQUEST(dev, handler) \
> > -	 pxa_request_dma(dev->name, DMA_PRIO_LOW, handler, dev)
> > -
> > -#define SMC_DMA_FREE(dev, dma) \
> > -	 pxa_free_dma(dma)
> > -
> > -#define SMC_DMA_ACK_IRQ(dev, dma)					\
> > -{									\
> > -	if (DCSR(dma) & DCSR_BUSERR) {					\
> > -		netdev_err(dev, "DMA %d bus error!\n", dma);		\
> > -	}								\
> > -	DCSR(dma) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;		\
> > -}
> > -
> >  /*
> >   * Use a DMA for RX and TX packets.
> >   */
> > @@ -238,6 +217,8 @@ static inline void SMC_outsl(struct smc911x_local *lp, int reg,
> >  
> >  static dma_addr_t rx_dmabuf, tx_dmabuf;
> >  static int rx_dmalen, tx_dmalen;
> > +static void smc911x_rx_dma_irq(void *data);
> > +static void smc911x_tx_dma_irq(void *data);
> >  
> >  #ifdef SMC_insl
> >  #undef SMC_insl
> > @@ -246,8 +227,10 @@ static int rx_dmalen, tx_dmalen;
> >  
> >  static inline void
> >  smc_pxa_dma_insl(struct smc911x_local *lp, u_long physaddr,
> > -		int reg, int dma, u_char *buf, int len)
> > +		int reg, struct dma_chan *dma, u_char *buf, int len)
> >  {
> > +	struct dma_async_tx_descriptor *tx;
> > +
> >  	/* 64 bit alignment is required for memory to memory DMA */
> >  	if ((long)buf & 4) {
> >  		*((u32 *)buf) = SMC_inl(lp, reg);
> > @@ -258,12 +241,14 @@ smc_pxa_dma_insl(struct smc911x_local *lp, u_long physaddr,
> >  	len *= 4;
> >  	rx_dmabuf = dma_map_single(lp->dev, buf, len, DMA_FROM_DEVICE);
> >  	rx_dmalen = len;
> > -	DCSR(dma) = DCSR_NODESC;
> > -	DTADR(dma) = rx_dmabuf;
> > -	DSADR(dma) = physaddr + reg;
> > -	DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 |
> > -		DCMD_WIDTH4 | DCMD_ENDIRQEN | (DCMD_LENGTH & rx_dmalen));
> > -	DCSR(dma) = DCSR_NODESC | DCSR_RUN;
> > +	tx = dmaengine_prep_slave_single(dma, rx_dmabuf, rx_dmalen,
> > +					 DMA_DEV_TO_MEM, 0);
> > +	if (tx) {
> > +		tx->callback = smc911x_rx_dma_irq;
> > +		tx->callback_param = lp;
> > +		dmaengine_submit(tx);
> > +		dma_async_issue_pending(dma);
> > +	}
> >  }
> >  #endif
> >  
> > @@ -274,8 +259,10 @@ smc_pxa_dma_insl(struct smc911x_local *lp, u_long physaddr,
> >  
> >  static inline void
> >  smc_pxa_dma_outsl(struct smc911x_local *lp, u_long physaddr,
> > -		int reg, int dma, u_char *buf, int len)
> > +		int reg, struct dma_chan *dma, u_char *buf, int len)
> >  {
> > +	struct dma_async_tx_descriptor *tx;
> > +
> >  	/* 64 bit alignment is required for memory to memory DMA */
> >  	if ((long)buf & 4) {
> >  		SMC_outl(*((u32 *)buf), lp, reg);
> > @@ -286,12 +273,14 @@ smc_pxa_dma_outsl(struct smc911x_local *lp, u_long physaddr,
> >  	len *= 4;
> >  	tx_dmabuf = dma_map_single(lp->dev, buf, len, DMA_TO_DEVICE);
> >  	tx_dmalen = len;
> > -	DCSR(dma) = DCSR_NODESC;
> > -	DSADR(dma) = tx_dmabuf;
> > -	DTADR(dma) = physaddr + reg;
> > -	DCMD(dma) = (DCMD_INCSRCADDR | DCMD_BURST32 |
> > -		DCMD_WIDTH4 | DCMD_ENDIRQEN | (DCMD_LENGTH & tx_dmalen));
> > -	DCSR(dma) = DCSR_NODESC | DCSR_RUN;
> > +	tx = dmaengine_prep_slave_single(dma, tx_dmabuf, tx_dmalen,
> > +					 DMA_DEV_TO_MEM, 0);
> > +	if (tx) {
> > +		tx->callback = smc911x_tx_dma_irq;
> > +		tx->callback_param = lp;
> > +		dmaengine_submit(tx);
> > +		dma_async_issue_pending(dma);
> > +	}
> >  }
> >  #endif
> >  #endif	 /* SMC_USE_PXA_DMA */
> > -- 
> > 2.1.4
> > 
> 

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

* Re: [PATCH] net: smc911x: convert pxa dma to dmaengine
  2016-02-20 14:48               ` Robert Jarzmik
  (?)
@ 2016-02-23 18:15               ` Fabio Estevam
  2016-03-03 20:16                 ` Robert Jarzmik
  -1 siblings, 1 reply; 15+ messages in thread
From: Fabio Estevam @ 2016-02-23 18:15 UTC (permalink / raw)
  To: Robert Jarzmik
  Cc: Guennadi Liakhovetski, Hitoshi Mitake, Fabio Estevam,
	Hitoshi Mitake, netdev, LKML, David Miller

On Sat, Feb 20, 2016 at 12:48 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:

> Hello,
>
> I'll reping once more, to see if any of you could give this patch a try.
> So far Hitoshi doesn't have the hardware anymore, so it leaves only Guennadi and
> Fabio.
>
> If you could give it a try it would be great.
>
> For reference, the patch is here : https://lkml.org/lkml/2015/11/30/768

I finally got access to a mx53ard board, applied your patch and
managed to NFS boot without issues:

[    1.739281] smsc911x f4000000.lan9220 eth0: SMSC911x/921x
identified at 0xe0a80000, IRQ: 207

Tested-by: Fabio Estevam <fabio.estevam@nxp.com>

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

* Re: [PATCH] net: smc911x: convert pxa dma to dmaengine
  2016-02-23 18:15               ` Fabio Estevam
@ 2016-03-03 20:16                 ` Robert Jarzmik
  2016-03-15 22:56                     ` Robert Jarzmik
  0 siblings, 1 reply; 15+ messages in thread
From: Robert Jarzmik @ 2016-03-03 20:16 UTC (permalink / raw)
  To: David Miller, Fabio Estevam
  Cc: Guennadi Liakhovetski, Hitoshi Mitake, Fabio Estevam,
	Hitoshi Mitake, netdev, LKML

Fabio Estevam <festevam@gmail.com> writes:

> On Sat, Feb 20, 2016 at 12:48 PM, Robert Jarzmik <robert.jarzmik@free.fr> wrote:
>
>> Hello,
>>
>> I'll reping once more, to see if any of you could give this patch a try.
>> So far Hitoshi doesn't have the hardware anymore, so it leaves only Guennadi and
>> Fabio.
>>
>> If you could give it a try it would be great.
>>
>> For reference, the patch is here : https://lkml.org/lkml/2015/11/30/768
>
> I finally got access to a mx53ard board, applied your patch and
> managed to NFS boot without issues:
>
> [    1.739281] smsc911x f4000000.lan9220 eth0: SMSC911x/921x
> identified at 0xe0a80000, IRQ: 207
>
> Tested-by: Fabio Estevam <fabio.estevam@nxp.com>

Thanks Fabio for the test.

I also tried with a different different approach.

I built the different platforms (imx v6, etc ...) :
 - one version (a) on a vanilla v4.5-rc2
 - one version (b) on a vaniall v4.5-rc2 + this patch

For each of the builds, I took the preprocessed output of smc911x.c, and made a
diff between (a) and (b). The commands used were :
 - building in [1]
 - diffing in [2]

The result is [3]. I conclude from [3] that the driver cannot break for non PXA
platforms.

With Fabio's test and this demonstration, is enough to convince you to apply
this patch David ?

Cheers.

--
Robert

[1] Building
arm-linux-gnueabi-gcc -Wp,-MD,drivers/net/ethernet/smsc/.smc911x.o.d  -nostdinc
-isystem /usr/lib/gcc/arm-linux-gnueabi/4.9/include -I./arch/arm/include
-Iarch/arm/include/generated/uapi -Iarch/arm/include/generated  -Iinclude
-I./arch/arm/include/uapi -Iarch/arm/include/generated/uapi -I./include/uapi
-Iinclude/generated/uapi -include ./include/linux/kconfig.h -D__KERNEL__
-mlittle-endian -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs
-fno-strict-aliasing -fno-common -Werror-implicit-function-declaration
-Wno-format-security -std=gnu89 -fno-dwarf2-cfi-asm -fno-omit-frame-pointer
-mapcs -mno-sched-prolog -fno-ipa-sra -mabi=aapcs-linux -mno-thumb-interwork
-mfpu=vfp -marm -D__LINUX_ARM_ARCH__=6 -march=armv6k -mtune=arm1136j-s
-msoft-float -Uarm -fno-delete-null-pointer-checks -O2
--param=allow-store-data-races=0 -Wframe-larger-than=1024 -fno-stack-protector
-Wno-unused-but-set-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls
-fno-var-tracking-assignments -Wdeclaration-after-statement -Wno-pointer-sign
-fno-strict-overflow -fconserve-stack -Werror=implicit-int
-Werror=strict-prototypes -Werror=date-time -DCC_HAVE_ASM_GOTO
-D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(smc911x)"
-D"KBUILD_MODNAME=KBUILD_STR(smc911x)" -E -o
drivers/net/ethernet/smsc/smc911x_with_rjk_patch.E
drivers/net/ethernet/smsc/smc911x.c

[2] Diffing
rj@belgarion:~/mio_linux/kernel$ diff -I "#.*" -u
 drivers/net/ethernet/smsc/smc911x_without_rjk_patch.E
 drivers/net/ethernet/smsc/smc911x_with_rjk_patch.E >
 drivers/net/ethernet/smsc/smc911x_sdiff.diff

[3] Result of diffing
--- drivers/net/ethernet/smsc/smc911x_without_rjk_patch.E	2016-02-21 16:19:27.882425010 +0100
+++ drivers/net/ethernet/smsc/smc911x_with_rjk_patch.E	2016-02-21 16:19:59.250424159 +0100
@@ -49141,6 +49141,34 @@
 
 
 
+# 1 "include/linux/dma/pxa-dma.h" 1
+
+
+
+enum pxad_chan_prio {
+ PXAD_PRIO_HIGHEST = 0,
+ PXAD_PRIO_NORMAL,
+ PXAD_PRIO_LOW,
+ PXAD_PRIO_LOWEST,
+};
+
+struct pxad_param {
+ unsigned int drcmr;
+ enum pxad_chan_prio prio;
+};
+
+struct dma_chan;
+
+
+
+
+static inline __attribute__((always_inline)) __attribute__((no_instrument_function)) bool pxad_filter_fn(struct dma_chan *chan, void *param)
+{
+ return false;
+}
+# 78 "drivers/net/ethernet/smsc/smc911x.c" 2
+
+
 
 # 1 "drivers/net/ethernet/smsc/smc911x.h" 1
 # 31 "drivers/net/ethernet/smsc/smc911x.h"
@@ -50670,6 +50698,9 @@
  unsigned int val, chip_id, revision;
  const char *version_string;
  unsigned long irq_flags;
+ struct dma_slave_config config;
+ dma_cap_mask_t mask;
+ struct pxad_param param;
 
  do { } while (0);

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

* Re: [PATCH] net: smc911x: convert pxa dma to dmaengine
  2016-03-03 20:16                 ` Robert Jarzmik
@ 2016-03-15 22:56                     ` Robert Jarzmik
  0 siblings, 0 replies; 15+ messages in thread
From: Robert Jarzmik @ 2016-03-15 22:56 UTC (permalink / raw)
  To: David Miller
  Cc: Fabio Estevam, Guennadi Liakhovetski, Hitoshi Mitake,
	Fabio Estevam, Hitoshi Mitake, netdev, LKML

Robert Jarzmik <robert.jarzmik@free.fr> writes:

> Fabio Estevam <festevam@gmail.com> writes:
>> Tested-by: Fabio Estevam <fabio.estevam@nxp.com>
>
> Thanks Fabio for the test.
>
> I also tried with a different different approach.
>
> I built the different platforms (imx v6, etc ...) :
>  - one version (a) on a vanilla v4.5-rc2
>  - one version (b) on a vaniall v4.5-rc2 + this patch
>
> For each of the builds, I took the preprocessed output of smc911x.c, and made a
> diff between (a) and (b). The commands used were :
>  - building in [1]
>  - diffing in [2]
>
> The result is [3]. I conclude from [3] that the driver cannot break for non PXA
> platforms.
>
> With Fabio's test and this demonstration, is enough to convince you to apply
> this patch David ?
Hi David,

Can you consider this patch now it is tested please ?

--
Robert

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

* Re: [PATCH] net: smc911x: convert pxa dma to dmaengine
@ 2016-03-15 22:56                     ` Robert Jarzmik
  0 siblings, 0 replies; 15+ messages in thread
From: Robert Jarzmik @ 2016-03-15 22:56 UTC (permalink / raw)
  To: David Miller
  Cc: Fabio Estevam, Guennadi Liakhovetski, Hitoshi Mitake,
	Fabio Estevam, Hitoshi Mitake, netdev, LKML

Robert Jarzmik <robert.jarzmik@free.fr> writes:

> Fabio Estevam <festevam@gmail.com> writes:
>> Tested-by: Fabio Estevam <fabio.estevam@nxp.com>
>
> Thanks Fabio for the test.
>
> I also tried with a different different approach.
>
> I built the different platforms (imx v6, etc ...) :
>  - one version (a) on a vanilla v4.5-rc2
>  - one version (b) on a vaniall v4.5-rc2 + this patch
>
> For each of the builds, I took the preprocessed output of smc911x.c, and made a
> diff between (a) and (b). The commands used were :
>  - building in [1]
>  - diffing in [2]
>
> The result is [3]. I conclude from [3] that the driver cannot break for non PXA
> platforms.
>
> With Fabio's test and this demonstration, is enough to convince you to apply
> this patch David ?
Hi David,

Can you consider this patch now it is tested please ?

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

* Re: [PATCH] net: smc911x: convert pxa dma to dmaengine
  2016-03-15 22:56                     ` Robert Jarzmik
  (?)
@ 2016-03-16  2:57                     ` David Miller
  -1 siblings, 0 replies; 15+ messages in thread
From: David Miller @ 2016-03-16  2:57 UTC (permalink / raw)
  To: robert.jarzmik
  Cc: festevam, g.liakhovetski, mitake, fabio.estevam, mitake.hitoshi,
	netdev, linux-kernel

From: Robert Jarzmik <robert.jarzmik@free.fr>
Date: Tue, 15 Mar 2016 23:56:58 +0100

> Robert Jarzmik <robert.jarzmik@free.fr> writes:
> 
>> Fabio Estevam <festevam@gmail.com> writes:
>>> Tested-by: Fabio Estevam <fabio.estevam@nxp.com>
>>
>> Thanks Fabio for the test.
>>
>> I also tried with a different different approach.
>>
>> I built the different platforms (imx v6, etc ...) :
>>  - one version (a) on a vanilla v4.5-rc2
>>  - one version (b) on a vaniall v4.5-rc2 + this patch
>>
>> For each of the builds, I took the preprocessed output of smc911x.c, and made a
>> diff between (a) and (b). The commands used were :
>>  - building in [1]
>>  - diffing in [2]
>>
>> The result is [3]. I conclude from [3] that the driver cannot break for non PXA
>> platforms.
>>
>> With Fabio's test and this demonstration, is enough to convince you to apply
>> this patch David ?
> Hi David,
> 
> Can you consider this patch now it is tested please ?

Please resubmit the patch fresh with the appropriate Tested-by: tags
added, thanks.

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

end of thread, other threads:[~2016-03-16  2:57 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-30 21:40 [PATCH] net: smc911x: convert pxa dma to dmaengine Robert Jarzmik
2015-12-03  4:52 ` David Miller
2015-12-03 18:46   ` Robert Jarzmik
2016-02-05 21:44     ` Robert Jarzmik
2016-02-05 22:30       ` David Miller
2016-02-06  9:05         ` Robert Jarzmik
2016-02-20 13:29           ` Hitoshi Mitake
2016-02-20 15:46             ` Guennadi Liakhovetski
     [not found]           ` <CAE1WaKK2DqYYOTLmprbLuZVN-8--sZVyZVHgkcT4Jg7797S7HQ@mail.gmail.com>
2016-02-20 14:48             ` Robert Jarzmik
2016-02-20 14:48               ` Robert Jarzmik
2016-02-23 18:15               ` Fabio Estevam
2016-03-03 20:16                 ` Robert Jarzmik
2016-03-15 22:56                   ` Robert Jarzmik
2016-03-15 22:56                     ` Robert Jarzmik
2016-03-16  2:57                     ` David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.