All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4] sun4i-emac.c: add dma support
@ 2021-12-24 14:44 conleylee
  2021-12-28  2:35 ` Jakub Kicinski
  2021-12-28 11:42 ` [PATCH v5] " conleylee
  0 siblings, 2 replies; 33+ messages in thread
From: conleylee @ 2021-12-24 14:44 UTC (permalink / raw)
  To: davem, kuba, mripard, wens; +Cc: netdev, Conley Lee

From: Conley Lee <conleylee@foxmail.com>

This patch adds support for the emac rx dma present on sun4i.
The emac is able to move packets from rx fifo to RAM by using dma.

Signed-off-by: Conley Lee <conleylee@foxmail.com>
---
 drivers/net/ethernet/allwinner/sun4i-emac.c | 209 +++++++++++++++++++-
 1 file changed, 200 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
index cccf8a3ead5e..b17d2df17335 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -29,6 +29,7 @@
 #include <linux/platform_device.h>
 #include <linux/phy.h>
 #include <linux/soc/sunxi/sunxi_sram.h>
+#include <linux/dmaengine.h>
 
 #include "sun4i-emac.h"
 
@@ -86,6 +87,16 @@ struct emac_board_info {
 	unsigned int		duplex;
 
 	phy_interface_t		phy_interface;
+	struct dma_chan	*rx_chan;
+	phys_addr_t emac_rx_fifo;
+};
+
+struct emac_dma_req {
+	struct emac_board_info *db;
+	struct dma_async_tx_descriptor *desc;
+	struct sk_buff *sbk;
+	dma_addr_t rxbuf;
+	int count;
 };
 
 static void emac_update_speed(struct net_device *dev)
@@ -205,6 +216,113 @@ static void emac_inblk_32bit(void __iomem *reg, void *data, int count)
 	readsl(reg, data, round_up(count, 4) / 4);
 }
 
+static struct emac_dma_req *
+alloc_emac_dma_req(struct emac_board_info *db,
+		   struct dma_async_tx_descriptor *desc, struct sk_buff *skb,
+		   dma_addr_t rxbuf, int count)
+{
+	struct emac_dma_req *req =
+		kzalloc(sizeof(struct emac_dma_req), GFP_KERNEL);
+	if (!req)
+		return NULL;
+
+	req->db = db;
+	req->desc = desc;
+	req->sbk = skb;
+	req->rxbuf = rxbuf;
+	req->count = count;
+	return req;
+}
+
+static void free_emac_dma_req(struct emac_dma_req *req)
+{
+	kfree(req);
+}
+
+static void emac_dma_done_callback(void *arg)
+{
+	struct emac_dma_req *req = arg;
+	struct emac_board_info *db = req->db;
+	struct sk_buff *skb = req->sbk;
+	struct net_device *dev = db->ndev;
+	int rxlen = req->count;
+	u32 reg_val;
+
+	dma_unmap_single(db->dev, req->rxbuf, rxlen, DMA_FROM_DEVICE);
+
+	skb->protocol = eth_type_trans(skb, dev);
+	netif_rx(skb);
+	dev->stats.rx_bytes += rxlen;
+	/* Pass to upper layer */
+	dev->stats.rx_packets++;
+
+	//re enable cpu receive
+	reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+	reg_val &= ~EMAC_RX_CTL_DMA_EN;
+	writel(reg_val, db->membase + EMAC_RX_CTL_REG);
+
+	//re enable interrupt
+	reg_val = readl(db->membase + EMAC_INT_CTL_REG);
+	reg_val |= (0x01 << 8);
+	writel(reg_val, db->membase + EMAC_INT_CTL_REG);
+
+	db->emacrx_completed_flag = 1;
+	free_emac_dma_req(req);
+}
+
+static void emac_dma_inblk_32bit(struct emac_board_info *db,
+				 struct sk_buff *skb, int count)
+{
+	struct dma_async_tx_descriptor *desc;
+	dma_cookie_t cookie;
+	dma_addr_t rxbuf;
+	void *rdptr;
+	struct emac_dma_req *req;
+
+	rdptr = skb_put(skb, count - 4);
+	rxbuf = dma_map_single(db->dev, rdptr, count, DMA_FROM_DEVICE);
+
+	if (dma_mapping_error(db->dev, rxbuf)) {
+		dev_err(db->dev, "dma mapping error.\n");
+		return;
+	}
+
+	desc = dmaengine_prep_slave_single(db->rx_chan, rxbuf, count,
+					   DMA_DEV_TO_MEM,
+					   DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!desc) {
+		dev_err(db->dev, "prepare slave single failed\n");
+		goto prepare_err;
+	}
+
+	req = alloc_emac_dma_req(db, desc, skb, rxbuf, count);
+	if (!req) {
+		dev_err(db->dev, "alloc emac dma req error.\n");
+		goto alloc_req_err;
+	}
+
+	desc->callback_param = req;
+	desc->callback = emac_dma_done_callback;
+
+	cookie = dmaengine_submit(desc);
+	if (dma_submit_error(cookie)) {
+		dev_err(db->dev, "dma submit error.\n");
+		goto submit_err;
+	}
+
+	dma_async_issue_pending(db->rx_chan);
+	return;
+
+submit_err:
+	free_emac_dma_req(req);
+
+alloc_req_err:
+	dmaengine_desc_free(desc);
+
+prepare_err:
+	dma_unmap_single(db->dev, rxbuf, count, DMA_FROM_DEVICE);
+}
+
 /* ethtool ops */
 static void emac_get_drvinfo(struct net_device *dev,
 			      struct ethtool_drvinfo *info)
@@ -599,20 +717,28 @@ static void emac_rx(struct net_device *dev)
 			if (!skb)
 				continue;
 			skb_reserve(skb, 2);
-			rdptr = skb_put(skb, rxlen - 4);
 
 			/* Read received packet from RX SRAM */
 			if (netif_msg_rx_status(db))
 				dev_dbg(db->dev, "RxLen %x\n", rxlen);
 
-			emac_inblk_32bit(db->membase + EMAC_RX_IO_DATA_REG,
-					rdptr, rxlen);
-			dev->stats.rx_bytes += rxlen;
-
-			/* Pass to upper layer */
-			skb->protocol = eth_type_trans(skb, dev);
-			netif_rx(skb);
-			dev->stats.rx_packets++;
+			if (rxlen < dev->mtu || !db->rx_chan) {
+				rdptr = skb_put(skb, rxlen - 4);
+				emac_inblk_32bit(db->membase + EMAC_RX_IO_DATA_REG,
+						rdptr, rxlen);
+				dev->stats.rx_bytes += rxlen;
+
+				/* Pass to upper layer */
+				skb->protocol = eth_type_trans(skb, dev);
+				netif_rx(skb);
+				dev->stats.rx_packets++;
+			} else {
+				reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+				reg_val |= EMAC_RX_CTL_DMA_EN;
+				writel(reg_val, db->membase + EMAC_RX_CTL_REG);
+				emac_dma_inblk_32bit(db, skb, rxlen);
+				break;
+			}
 		}
 	}
 }
@@ -659,7 +785,12 @@ static irqreturn_t emac_interrupt(int irq, void *dev_id)
 		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
 		reg_val |= (0xf << 0) | (0x01 << 8);
 		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
+	} else {
+		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
+		reg_val |= (0xf << 0);
+		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 	}
+
 	spin_unlock(&db->lock);
 
 	return IRQ_HANDLED;
@@ -764,6 +895,58 @@ static const struct net_device_ops emac_netdev_ops = {
 #endif
 };
 
+static int emac_configure_dma(struct emac_board_info *db)
+{
+	struct platform_device *pdev = db->pdev;
+	struct net_device *ndev = db->ndev;
+	struct dma_slave_config conf = {};
+	struct resource *regs;
+	int err = 0;
+
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!regs) {
+		netdev_err(ndev, "get io resource from device failed.\n");
+		err = -ENOMEM;
+		goto out_clear_chan;
+	}
+
+	netdev_info(ndev, "get io resource from device: 0x%x, size = %u\n",
+		    regs->start, resource_size(regs));
+	db->emac_rx_fifo = regs->start + EMAC_RX_IO_DATA_REG;
+
+	db->rx_chan = dma_request_chan(&pdev->dev, "rx");
+	if (IS_ERR(db->rx_chan)) {
+		netdev_err(ndev,
+			   "failed to request dma channel. dma is disabled");
+		err = PTR_ERR(db->rx_chan);
+		goto out_clear_chan;
+	}
+
+	conf.direction = DMA_DEV_TO_MEM;
+	conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	conf.src_addr = db->emac_rx_fifo;
+	conf.dst_maxburst = 4;
+	conf.src_maxburst = 4;
+	conf.device_fc = false;
+
+	err = dmaengine_slave_config(db->rx_chan, &conf);
+	if (err) {
+		netdev_err(ndev, "config dma slave failed\n");
+		err = -EINVAL;
+		goto out_slave_configure_err;
+	}
+
+	return err;
+
+out_slave_configure_err:
+	dma_release_channel(db->rx_chan);
+
+out_clear_chan:
+	db->rx_chan = NULL;
+	return err;
+}
+
 /* Search EMAC board, allocate space and register it
  */
 static int emac_probe(struct platform_device *pdev)
@@ -806,6 +989,9 @@ static int emac_probe(struct platform_device *pdev)
 		goto out_iounmap;
 	}
 
+	if (emac_configure_dma(db))
+		netdev_info(ndev, "configure dma failed. disable dma.\n");
+
 	db->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(db->clk)) {
 		ret = PTR_ERR(db->clk);
@@ -888,6 +1074,11 @@ static int emac_remove(struct platform_device *pdev)
 	struct net_device *ndev = platform_get_drvdata(pdev);
 	struct emac_board_info *db = netdev_priv(ndev);
 
+	if (db->rx_chan) {
+		dmaengine_terminate_all(db->rx_chan);
+		dma_release_channel(db->rx_chan);
+	}
+
 	unregister_netdev(ndev);
 	sunxi_sram_release(&pdev->dev);
 	clk_disable_unprepare(db->clk);
-- 
2.34.1


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

* Re: [PATCH v4] sun4i-emac.c: add dma support
  2021-12-24 14:44 [PATCH v4] sun4i-emac.c: add dma support conleylee
@ 2021-12-28  2:35 ` Jakub Kicinski
  2021-12-28 11:42 ` [PATCH v5] " conleylee
  1 sibling, 0 replies; 33+ messages in thread
From: Jakub Kicinski @ 2021-12-28  2:35 UTC (permalink / raw)
  To: conleylee; +Cc: davem, mripard, wens, netdev

On Fri, 24 Dec 2021 22:44:31 +0800 conleylee@foxmail.com wrote:
> From: Conley Lee <conleylee@foxmail.com>
> 
> This patch adds support for the emac rx dma present on sun4i.
> The emac is able to move packets from rx fifo to RAM by using dma.
> 
> Signed-off-by: Conley Lee <conleylee@foxmail.com>
> ---
>  drivers/net/ethernet/allwinner/sun4i-emac.c | 209 +++++++++++++++++++-
>  1 file changed, 200 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
> index cccf8a3ead5e..b17d2df17335 100644
> --- a/drivers/net/ethernet/allwinner/sun4i-emac.c
> +++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
> @@ -29,6 +29,7 @@
>  #include <linux/platform_device.h>
>  #include <linux/phy.h>
>  #include <linux/soc/sunxi/sunxi_sram.h>
> +#include <linux/dmaengine.h>
>  
>  #include "sun4i-emac.h"
>  
> @@ -86,6 +87,16 @@ struct emac_board_info {
>  	unsigned int		duplex;
>  
>  	phy_interface_t		phy_interface;
> +	struct dma_chan	*rx_chan;
> +	phys_addr_t emac_rx_fifo;
> +};
> +
> +struct emac_dma_req {
> +	struct emac_board_info *db;
> +	struct dma_async_tx_descriptor *desc;
> +	struct sk_buff *sbk;

sbk -> skb ?

> +	dma_addr_t rxbuf;
> +	int count;
>  };
>  
>  static void emac_update_speed(struct net_device *dev)
> @@ -205,6 +216,113 @@ static void emac_inblk_32bit(void __iomem *reg, void *data, int count)
>  	readsl(reg, data, round_up(count, 4) / 4);
>  }
>  
> +static struct emac_dma_req *
> +alloc_emac_dma_req(struct emac_board_info *db,

nit: please use "emac" as a prefix of the name, instead of putting it
     inside the name.

> +		   struct dma_async_tx_descriptor *desc, struct sk_buff *skb,
> +		   dma_addr_t rxbuf, int count)
> +{
> +	struct emac_dma_req *req =
> +		kzalloc(sizeof(struct emac_dma_req), GFP_KERNEL);

Please don't put complex initializers inline, also missing an empty
line between variable declaration and code. Should be:

	struct emac_dma_req *req;

	req = kzalloc(...);
	if (!req)
		...

You seem to call this from an IRQ handler, shouldn't the flags be
GFP_ATOMIC? Please test with CONFIG_DEBUG_ATOMIC_SLEEP=y.

> +	if (!req)
> +		return NULL;
> +
> +	req->db = db;
> +	req->desc = desc;
> +	req->sbk = skb;
> +	req->rxbuf = rxbuf;
> +	req->count = count;
> +	return req;
> +}
> +
> +static void free_emac_dma_req(struct emac_dma_req *req)
> +{
> +	kfree(req);
> +}
> +
> +static void emac_dma_done_callback(void *arg)
> +{
> +	struct emac_dma_req *req = arg;
> +	struct emac_board_info *db = req->db;
> +	struct sk_buff *skb = req->sbk;
> +	struct net_device *dev = db->ndev;
> +	int rxlen = req->count;
> +	u32 reg_val;
> +
> +	dma_unmap_single(db->dev, req->rxbuf, rxlen, DMA_FROM_DEVICE);
> +
> +	skb->protocol = eth_type_trans(skb, dev);
> +	netif_rx(skb);
> +	dev->stats.rx_bytes += rxlen;
> +	/* Pass to upper layer */
> +	dev->stats.rx_packets++;
> +
> +	//re enable cpu receive

Please use the /**/ comment style consistently

> +	reg_val = readl(db->membase + EMAC_RX_CTL_REG);
> +	reg_val &= ~EMAC_RX_CTL_DMA_EN;
> +	writel(reg_val, db->membase + EMAC_RX_CTL_REG);
> +
> +	//re enable interrupt
> +	reg_val = readl(db->membase + EMAC_INT_CTL_REG);
> +	reg_val |= (0x01 << 8);
> +	writel(reg_val, db->membase + EMAC_INT_CTL_REG);
> +
> +	db->emacrx_completed_flag = 1;
> +	free_emac_dma_req(req);
> +}
> +
> +static void emac_dma_inblk_32bit(struct emac_board_info *db,
> +				 struct sk_buff *skb, int count)
> +{
> +	struct dma_async_tx_descriptor *desc;
> +	dma_cookie_t cookie;
> +	dma_addr_t rxbuf;
> +	void *rdptr;
> +	struct emac_dma_req *req;
> +
> +	rdptr = skb_put(skb, count - 4);

The skb_put can be factored out from both branches it seems.

> +	rxbuf = dma_map_single(db->dev, rdptr, count, DMA_FROM_DEVICE);
> +
> +	if (dma_mapping_error(db->dev, rxbuf)) {
> +		dev_err(db->dev, "dma mapping error.\n");
> +		return;

You seem to leak the skb if this function fails, no?

> +	}
> +
> +	desc = dmaengine_prep_slave_single(db->rx_chan, rxbuf, count,
> +					   DMA_DEV_TO_MEM,
> +					   DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> +	if (!desc) {
> +		dev_err(db->dev, "prepare slave single failed\n");
> +		goto prepare_err;
> +	}
> +
> +	req = alloc_emac_dma_req(db, desc, skb, rxbuf, count);
> +	if (!req) {
> +		dev_err(db->dev, "alloc emac dma req error.\n");
> +		goto alloc_req_err;
> +	}
> +
> +	desc->callback_param = req;
> +	desc->callback = emac_dma_done_callback;
> +
> +	cookie = dmaengine_submit(desc);
> +	if (dma_submit_error(cookie)) {
> +		dev_err(db->dev, "dma submit error.\n");
> +		goto submit_err;
> +	}
> +
> +	dma_async_issue_pending(db->rx_chan);
> +	return;
> +
> +submit_err:
> +	free_emac_dma_req(req);
> +
> +alloc_req_err:
> +	dmaengine_desc_free(desc);
> +
> +prepare_err:
> +	dma_unmap_single(db->dev, rxbuf, count, DMA_FROM_DEVICE);
> +}

> -			/* Pass to upper layer */
> -			skb->protocol = eth_type_trans(skb, dev);
> -			netif_rx(skb);
> -			dev->stats.rx_packets++;
> +			if (rxlen < dev->mtu || !db->rx_chan) {
> +				rdptr = skb_put(skb, rxlen - 4);
> +				emac_inblk_32bit(db->membase + EMAC_RX_IO_DATA_REG,
> +						rdptr, rxlen);
> +				dev->stats.rx_bytes += rxlen;
> +
> +				/* Pass to upper layer */
> +				skb->protocol = eth_type_trans(skb, dev);
> +				netif_rx(skb);
> +				dev->stats.rx_packets++;
> +			} else {
> +				reg_val = readl(db->membase + EMAC_RX_CTL_REG);
> +				reg_val |= EMAC_RX_CTL_DMA_EN;
> +				writel(reg_val, db->membase + EMAC_RX_CTL_REG);
> +				emac_dma_inblk_32bit(db, skb, rxlen);
> +				break;
> +			}
>  		}

> +static int emac_configure_dma(struct emac_board_info *db)
> +{
> +	struct platform_device *pdev = db->pdev;
> +	struct net_device *ndev = db->ndev;
> +	struct dma_slave_config conf = {};
> +	struct resource *regs;
> +	int err = 0;
> +
> +	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!regs) {
> +		netdev_err(ndev, "get io resource from device failed.\n");
> +		err = -ENOMEM;
> +		goto out_clear_chan;
> +	}
> +
> +	netdev_info(ndev, "get io resource from device: 0x%x, size = %u\n",
> +		    regs->start, resource_size(regs));
> +	db->emac_rx_fifo = regs->start + EMAC_RX_IO_DATA_REG;
> +
> +	db->rx_chan = dma_request_chan(&pdev->dev, "rx");
> +	if (IS_ERR(db->rx_chan)) {
> +		netdev_err(ndev,
> +			   "failed to request dma channel. dma is disabled");

nit: this message lacks '\n' at the end

> +		err = PTR_ERR(db->rx_chan);
> +		goto out_clear_chan;
> +	}


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

* [PATCH v5] sun4i-emac.c: add dma support
  2021-12-24 14:44 [PATCH v4] sun4i-emac.c: add dma support conleylee
  2021-12-28  2:35 ` Jakub Kicinski
@ 2021-12-28 11:42 ` conleylee
  2021-12-29  0:48     ` Jakub Kicinski
  1 sibling, 1 reply; 33+ messages in thread
From: conleylee @ 2021-12-28 11:42 UTC (permalink / raw)
  To: davem, kuba, mripard, wens
  Cc: netdev, linux-arm-kernel, linux-kernel, Conley Lee

From: Conley Lee <conleylee@foxmail.com>

Thanks for your review. Here is the new version for this patch.

This patch adds support for the emac rx dma present on sun4i. The emac
is able to move packets from rx fifo to RAM by using dma.

Change since v4.
  - rename sbk field to skb
  - rename alloc_emac_dma_req to emac_alloc_dma_req
  - using kzalloc(..., GPF_ATOMIC) in interrupt context to avoid
    sleeping
  - retry by using emac_inblk_32bit when emac_dma_inblk_32bit fails
  - fix some code style issues 


Signed-off-by: Conley Lee <conleylee@foxmail.com>
---
 drivers/net/ethernet/allwinner/sun4i-emac.c | 202 +++++++++++++++++++-
 1 file changed, 201 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
index cccf8a3ead5e..ec8184196377 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -29,6 +29,7 @@
 #include <linux/platform_device.h>
 #include <linux/phy.h>
 #include <linux/soc/sunxi/sunxi_sram.h>
+#include <linux/dmaengine.h>
 
 #include "sun4i-emac.h"
 
@@ -86,6 +87,16 @@ struct emac_board_info {
 	unsigned int		duplex;
 
 	phy_interface_t		phy_interface;
+	struct dma_chan	*rx_chan;
+	phys_addr_t emac_rx_fifo;
+};
+
+struct emac_dma_req {
+	struct emac_board_info *db;
+	struct dma_async_tx_descriptor *desc;
+	struct sk_buff *skb;
+	dma_addr_t rxbuf;
+	int count;
 };
 
 static void emac_update_speed(struct net_device *dev)
@@ -205,6 +216,117 @@ static void emac_inblk_32bit(void __iomem *reg, void *data, int count)
 	readsl(reg, data, round_up(count, 4) / 4);
 }
 
+static struct emac_dma_req *
+emac_alloc_dma_req(struct emac_board_info *db,
+		   struct dma_async_tx_descriptor *desc, struct sk_buff *skb,
+		   dma_addr_t rxbuf, int count)
+{
+	struct emac_dma_req *req;
+
+	req = kzalloc(sizeof(struct emac_dma_req), GFP_ATOMIC);
+	if (!req)
+		return NULL;
+
+	req->db = db;
+	req->desc = desc;
+	req->skb = skb;
+	req->rxbuf = rxbuf;
+	req->count = count;
+	return req;
+}
+
+static void free_emac_dma_req(struct emac_dma_req *req)
+{
+	kfree(req);
+}
+
+static void emac_dma_done_callback(void *arg)
+{
+	struct emac_dma_req *req = arg;
+	struct emac_board_info *db = req->db;
+	struct sk_buff *skb = req->skb;
+	struct net_device *dev = db->ndev;
+	int rxlen = req->count;
+	u32 reg_val;
+
+	dma_unmap_single(db->dev, req->rxbuf, rxlen, DMA_FROM_DEVICE);
+
+	skb->protocol = eth_type_trans(skb, dev);
+	netif_rx(skb);
+	dev->stats.rx_bytes += rxlen;
+	/* Pass to upper layer */
+	dev->stats.rx_packets++;
+
+	/* re enable cpu receive */
+	reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+	reg_val &= ~EMAC_RX_CTL_DMA_EN;
+	writel(reg_val, db->membase + EMAC_RX_CTL_REG);
+
+	/* re enable interrupt */
+	reg_val = readl(db->membase + EMAC_INT_CTL_REG);
+	reg_val |= (0x01 << 8);
+	writel(reg_val, db->membase + EMAC_INT_CTL_REG);
+
+	db->emacrx_completed_flag = 1;
+	free_emac_dma_req(req);
+}
+
+static int emac_dma_inblk_32bit(struct emac_board_info *db,
+		struct sk_buff *skb, void *rdptr, int count)
+{
+	struct dma_async_tx_descriptor *desc;
+	dma_cookie_t cookie;
+	dma_addr_t rxbuf;
+	struct emac_dma_req *req;
+	int ret = 0;
+
+	rxbuf = dma_map_single(db->dev, rdptr, count, DMA_FROM_DEVICE);
+	ret = dma_mapping_error(db->dev, rxbuf);
+	if (ret) {
+		dev_err(db->dev, "dma mapping error.\n");
+		return ret;
+	}
+
+	desc = dmaengine_prep_slave_single(db->rx_chan, rxbuf, count,
+					   DMA_DEV_TO_MEM,
+					   DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!desc) {
+		dev_err(db->dev, "prepare slave single failed\n");
+		ret = -ENOMEM;
+		goto prepare_err;
+	}
+
+	req = emac_alloc_dma_req(db, desc, skb, rxbuf, count);
+	if (!req) {
+		dev_err(db->dev, "alloc emac dma req error.\n");
+		ret = -ENOMEM;
+		goto alloc_req_err;
+	}
+
+	desc->callback_param = req;
+	desc->callback = emac_dma_done_callback;
+
+	cookie = dmaengine_submit(desc);
+	ret = dma_submit_error(cookie);
+	if (ret) {
+		dev_err(db->dev, "dma submit error.\n");
+		goto submit_err;
+	}
+
+	dma_async_issue_pending(db->rx_chan);
+	return ret;
+
+submit_err:
+	free_emac_dma_req(req);
+
+alloc_req_err:
+	dmaengine_desc_free(desc);
+
+prepare_err:
+	dma_unmap_single(db->dev, rxbuf, count, DMA_FROM_DEVICE);
+    return ret;
+}
+
 /* ethtool ops */
 static void emac_get_drvinfo(struct net_device *dev,
 			      struct ethtool_drvinfo *info)
@@ -599,12 +721,25 @@ static void emac_rx(struct net_device *dev)
 			if (!skb)
 				continue;
 			skb_reserve(skb, 2);
-			rdptr = skb_put(skb, rxlen - 4);
 
 			/* Read received packet from RX SRAM */
 			if (netif_msg_rx_status(db))
 				dev_dbg(db->dev, "RxLen %x\n", rxlen);
 
+			rdptr = skb_put(skb, rxlen - 4);
+			if (rxlen >= dev->mtu && db->rx_chan) {
+				reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+				reg_val |= EMAC_RX_CTL_DMA_EN;
+				writel(reg_val, db->membase + EMAC_RX_CTL_REG);
+				if (!emac_dma_inblk_32bit(db, skb, rdptr, rxlen))
+					break;
+
+				/* re enable cpu receive. then try to receive by emac_inblk_32bit */
+				reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+				reg_val &= ~EMAC_RX_CTL_DMA_EN;
+				writel(reg_val, db->membase + EMAC_RX_CTL_REG);
+			}
+
 			emac_inblk_32bit(db->membase + EMAC_RX_IO_DATA_REG,
 					rdptr, rxlen);
 			dev->stats.rx_bytes += rxlen;
@@ -659,7 +794,12 @@ static irqreturn_t emac_interrupt(int irq, void *dev_id)
 		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
 		reg_val |= (0xf << 0) | (0x01 << 8);
 		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
+	} else {
+		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
+		reg_val |= (0xf << 0);
+		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 	}
+
 	spin_unlock(&db->lock);
 
 	return IRQ_HANDLED;
@@ -764,6 +904,58 @@ static const struct net_device_ops emac_netdev_ops = {
 #endif
 };
 
+static int emac_configure_dma(struct emac_board_info *db)
+{
+	struct platform_device *pdev = db->pdev;
+	struct net_device *ndev = db->ndev;
+	struct dma_slave_config conf = {};
+	struct resource *regs;
+	int err = 0;
+
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!regs) {
+		netdev_err(ndev, "get io resource from device failed.\n");
+		err = -ENOMEM;
+		goto out_clear_chan;
+	}
+
+	netdev_info(ndev, "get io resource from device: 0x%x, size = %u\n",
+		    regs->start, resource_size(regs));
+	db->emac_rx_fifo = regs->start + EMAC_RX_IO_DATA_REG;
+
+	db->rx_chan = dma_request_chan(&pdev->dev, "rx");
+	if (IS_ERR(db->rx_chan)) {
+		netdev_err(ndev,
+			   "failed to request dma channel. dma is disabled\n");
+		err = PTR_ERR(db->rx_chan);
+		goto out_clear_chan;
+	}
+
+	conf.direction = DMA_DEV_TO_MEM;
+	conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	conf.src_addr = db->emac_rx_fifo;
+	conf.dst_maxburst = 4;
+	conf.src_maxburst = 4;
+	conf.device_fc = false;
+
+	err = dmaengine_slave_config(db->rx_chan, &conf);
+	if (err) {
+		netdev_err(ndev, "config dma slave failed\n");
+		err = -EINVAL;
+		goto out_slave_configure_err;
+	}
+
+	return err;
+
+out_slave_configure_err:
+	dma_release_channel(db->rx_chan);
+
+out_clear_chan:
+	db->rx_chan = NULL;
+	return err;
+}
+
 /* Search EMAC board, allocate space and register it
  */
 static int emac_probe(struct platform_device *pdev)
@@ -806,6 +998,9 @@ static int emac_probe(struct platform_device *pdev)
 		goto out_iounmap;
 	}
 
+	if (emac_configure_dma(db))
+		netdev_info(ndev, "configure dma failed. disable dma.\n");
+
 	db->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(db->clk)) {
 		ret = PTR_ERR(db->clk);
@@ -888,6 +1083,11 @@ static int emac_remove(struct platform_device *pdev)
 	struct net_device *ndev = platform_get_drvdata(pdev);
 	struct emac_board_info *db = netdev_priv(ndev);
 
+	if (db->rx_chan) {
+		dmaengine_terminate_all(db->rx_chan);
+		dma_release_channel(db->rx_chan);
+	}
+
 	unregister_netdev(ndev);
 	sunxi_sram_release(&pdev->dev);
 	clk_disable_unprepare(db->clk);
-- 
2.31.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5] sun4i-emac.c: add dma support
  2021-12-28 11:42 ` [PATCH v5] " conleylee
@ 2021-12-29  0:48     ` Jakub Kicinski
  0 siblings, 0 replies; 33+ messages in thread
From: Jakub Kicinski @ 2021-12-29  0:48 UTC (permalink / raw)
  To: conleylee; +Cc: davem, mripard, wens, netdev, linux-arm-kernel, linux-kernel

On Tue, 28 Dec 2021 19:42:04 +0800 conleylee@foxmail.com wrote:
> +static void free_emac_dma_req(struct emac_dma_req *req)

emac_free_dma_req

> +prepare_err:
> +	dma_unmap_single(db->dev, rxbuf, count, DMA_FROM_DEVICE);
> +    return ret;

incorrect whitespace here

> @@ -599,12 +721,25 @@ static void emac_rx(struct net_device *dev)
>  			if (!skb)
>  				continue;
>  			skb_reserve(skb, 2);
> -			rdptr = skb_put(skb, rxlen - 4);
>  
>  			/* Read received packet from RX SRAM */
>  			if (netif_msg_rx_status(db))
>  				dev_dbg(db->dev, "RxLen %x\n", rxlen);
>  
> +			rdptr = skb_put(skb, rxlen - 4);

no reason to move this line

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

* Re: [PATCH v5] sun4i-emac.c: add dma support
@ 2021-12-29  0:48     ` Jakub Kicinski
  0 siblings, 0 replies; 33+ messages in thread
From: Jakub Kicinski @ 2021-12-29  0:48 UTC (permalink / raw)
  To: conleylee; +Cc: davem, mripard, wens, netdev, linux-arm-kernel, linux-kernel

On Tue, 28 Dec 2021 19:42:04 +0800 conleylee@foxmail.com wrote:
> +static void free_emac_dma_req(struct emac_dma_req *req)

emac_free_dma_req

> +prepare_err:
> +	dma_unmap_single(db->dev, rxbuf, count, DMA_FROM_DEVICE);
> +    return ret;

incorrect whitespace here

> @@ -599,12 +721,25 @@ static void emac_rx(struct net_device *dev)
>  			if (!skb)
>  				continue;
>  			skb_reserve(skb, 2);
> -			rdptr = skb_put(skb, rxlen - 4);
>  
>  			/* Read received packet from RX SRAM */
>  			if (netif_msg_rx_status(db))
>  				dev_dbg(db->dev, "RxLen %x\n", rxlen);
>  
> +			rdptr = skb_put(skb, rxlen - 4);

no reason to move this line

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v6] sun4i-emac.c: add dma support
  2021-12-29  0:48     ` Jakub Kicinski
@ 2021-12-29  1:43       ` conleylee
  -1 siblings, 0 replies; 33+ messages in thread
From: conleylee @ 2021-12-29  1:43 UTC (permalink / raw)
  To: davem, kuba, mripard, wens
  Cc: netdev, linux-arm-kernel, linux-kernel, Conley Lee

From: Conley Lee <conleylee@foxmail.com>

Thanks for your review. Here is the new version for this patch.

This patch adds support for the emac rx dma present on sun4i. The emac
is able to move packets from rx fifo to RAM by using dma.

Change since v4.
  - rename sbk field to skb
  - rename alloc_emac_dma_req to emac_alloc_dma_req
  - using kzalloc(..., GPF_ATOMIC) in interrupt context to avoid
    sleeping
  - retry by using emac_inblk_32bit when emac_dma_inblk_32bit fails
  - fix some code style issues 

Change since v5.
  - fix some code style issue

Signed-off-by: Conley Lee <conleylee@foxmail.com>
---
 drivers/net/ethernet/allwinner/sun4i-emac.c | 200 ++++++++++++++++++++
 1 file changed, 200 insertions(+)

diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
index cccf8a3ead5e..964227e342ee 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -29,6 +29,7 @@
 #include <linux/platform_device.h>
 #include <linux/phy.h>
 #include <linux/soc/sunxi/sunxi_sram.h>
+#include <linux/dmaengine.h>
 
 #include "sun4i-emac.h"
 
@@ -86,6 +87,16 @@ struct emac_board_info {
 	unsigned int		duplex;
 
 	phy_interface_t		phy_interface;
+	struct dma_chan	*rx_chan;
+	phys_addr_t emac_rx_fifo;
+};
+
+struct emac_dma_req {
+	struct emac_board_info *db;
+	struct dma_async_tx_descriptor *desc;
+	struct sk_buff *skb;
+	dma_addr_t rxbuf;
+	int count;
 };
 
 static void emac_update_speed(struct net_device *dev)
@@ -205,6 +216,117 @@ static void emac_inblk_32bit(void __iomem *reg, void *data, int count)
 	readsl(reg, data, round_up(count, 4) / 4);
 }
 
+static struct emac_dma_req *
+emac_alloc_dma_req(struct emac_board_info *db,
+		   struct dma_async_tx_descriptor *desc, struct sk_buff *skb,
+		   dma_addr_t rxbuf, int count)
+{
+	struct emac_dma_req *req;
+
+	req = kzalloc(sizeof(struct emac_dma_req), GFP_ATOMIC);
+	if (!req)
+		return NULL;
+
+	req->db = db;
+	req->desc = desc;
+	req->skb = skb;
+	req->rxbuf = rxbuf;
+	req->count = count;
+	return req;
+}
+
+static void emac_free_dma_req(struct emac_dma_req *req)
+{
+	kfree(req);
+}
+
+static void emac_dma_done_callback(void *arg)
+{
+	struct emac_dma_req *req = arg;
+	struct emac_board_info *db = req->db;
+	struct sk_buff *skb = req->skb;
+	struct net_device *dev = db->ndev;
+	int rxlen = req->count;
+	u32 reg_val;
+
+	dma_unmap_single(db->dev, req->rxbuf, rxlen, DMA_FROM_DEVICE);
+
+	skb->protocol = eth_type_trans(skb, dev);
+	netif_rx(skb);
+	dev->stats.rx_bytes += rxlen;
+	/* Pass to upper layer */
+	dev->stats.rx_packets++;
+
+	/* re enable cpu receive */
+	reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+	reg_val &= ~EMAC_RX_CTL_DMA_EN;
+	writel(reg_val, db->membase + EMAC_RX_CTL_REG);
+
+	/* re enable interrupt */
+	reg_val = readl(db->membase + EMAC_INT_CTL_REG);
+	reg_val |= (0x01 << 8);
+	writel(reg_val, db->membase + EMAC_INT_CTL_REG);
+
+	db->emacrx_completed_flag = 1;
+	emac_free_dma_req(req);
+}
+
+static int emac_dma_inblk_32bit(struct emac_board_info *db,
+		struct sk_buff *skb, void *rdptr, int count)
+{
+	struct dma_async_tx_descriptor *desc;
+	dma_cookie_t cookie;
+	dma_addr_t rxbuf;
+	struct emac_dma_req *req;
+	int ret = 0;
+
+	rxbuf = dma_map_single(db->dev, rdptr, count, DMA_FROM_DEVICE);
+	ret = dma_mapping_error(db->dev, rxbuf);
+	if (ret) {
+		dev_err(db->dev, "dma mapping error.\n");
+		return ret;
+	}
+
+	desc = dmaengine_prep_slave_single(db->rx_chan, rxbuf, count,
+					   DMA_DEV_TO_MEM,
+					   DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!desc) {
+		dev_err(db->dev, "prepare slave single failed\n");
+		ret = -ENOMEM;
+		goto prepare_err;
+	}
+
+	req = emac_alloc_dma_req(db, desc, skb, rxbuf, count);
+	if (!req) {
+		dev_err(db->dev, "alloc emac dma req error.\n");
+		ret = -ENOMEM;
+		goto alloc_req_err;
+	}
+
+	desc->callback_param = req;
+	desc->callback = emac_dma_done_callback;
+
+	cookie = dmaengine_submit(desc);
+	ret = dma_submit_error(cookie);
+	if (ret) {
+		dev_err(db->dev, "dma submit error.\n");
+		goto submit_err;
+	}
+
+	dma_async_issue_pending(db->rx_chan);
+	return ret;
+
+submit_err:
+	emac_free_dma_req(req);
+
+alloc_req_err:
+	dmaengine_desc_free(desc);
+
+prepare_err:
+	dma_unmap_single(db->dev, rxbuf, count, DMA_FROM_DEVICE);
+	return ret;
+}
+
 /* ethtool ops */
 static void emac_get_drvinfo(struct net_device *dev,
 			      struct ethtool_drvinfo *info)
@@ -605,6 +727,19 @@ static void emac_rx(struct net_device *dev)
 			if (netif_msg_rx_status(db))
 				dev_dbg(db->dev, "RxLen %x\n", rxlen);
 
+			if (rxlen >= dev->mtu && db->rx_chan) {
+				reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+				reg_val |= EMAC_RX_CTL_DMA_EN;
+				writel(reg_val, db->membase + EMAC_RX_CTL_REG);
+				if (!emac_dma_inblk_32bit(db, skb, rdptr, rxlen))
+					break;
+
+				/* re enable cpu receive. then try to receive by emac_inblk_32bit */
+				reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+				reg_val &= ~EMAC_RX_CTL_DMA_EN;
+				writel(reg_val, db->membase + EMAC_RX_CTL_REG);
+			}
+
 			emac_inblk_32bit(db->membase + EMAC_RX_IO_DATA_REG,
 					rdptr, rxlen);
 			dev->stats.rx_bytes += rxlen;
@@ -659,7 +794,12 @@ static irqreturn_t emac_interrupt(int irq, void *dev_id)
 		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
 		reg_val |= (0xf << 0) | (0x01 << 8);
 		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
+	} else {
+		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
+		reg_val |= (0xf << 0);
+		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 	}
+
 	spin_unlock(&db->lock);
 
 	return IRQ_HANDLED;
@@ -764,6 +904,58 @@ static const struct net_device_ops emac_netdev_ops = {
 #endif
 };
 
+static int emac_configure_dma(struct emac_board_info *db)
+{
+	struct platform_device *pdev = db->pdev;
+	struct net_device *ndev = db->ndev;
+	struct dma_slave_config conf = {};
+	struct resource *regs;
+	int err = 0;
+
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!regs) {
+		netdev_err(ndev, "get io resource from device failed.\n");
+		err = -ENOMEM;
+		goto out_clear_chan;
+	}
+
+	netdev_info(ndev, "get io resource from device: 0x%x, size = %u\n",
+		    regs->start, resource_size(regs));
+	db->emac_rx_fifo = regs->start + EMAC_RX_IO_DATA_REG;
+
+	db->rx_chan = dma_request_chan(&pdev->dev, "rx");
+	if (IS_ERR(db->rx_chan)) {
+		netdev_err(ndev,
+			   "failed to request dma channel. dma is disabled\n");
+		err = PTR_ERR(db->rx_chan);
+		goto out_clear_chan;
+	}
+
+	conf.direction = DMA_DEV_TO_MEM;
+	conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	conf.src_addr = db->emac_rx_fifo;
+	conf.dst_maxburst = 4;
+	conf.src_maxburst = 4;
+	conf.device_fc = false;
+
+	err = dmaengine_slave_config(db->rx_chan, &conf);
+	if (err) {
+		netdev_err(ndev, "config dma slave failed\n");
+		err = -EINVAL;
+		goto out_slave_configure_err;
+	}
+
+	return err;
+
+out_slave_configure_err:
+	dma_release_channel(db->rx_chan);
+
+out_clear_chan:
+	db->rx_chan = NULL;
+	return err;
+}
+
 /* Search EMAC board, allocate space and register it
  */
 static int emac_probe(struct platform_device *pdev)
@@ -806,6 +998,9 @@ static int emac_probe(struct platform_device *pdev)
 		goto out_iounmap;
 	}
 
+	if (emac_configure_dma(db))
+		netdev_info(ndev, "configure dma failed. disable dma.\n");
+
 	db->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(db->clk)) {
 		ret = PTR_ERR(db->clk);
@@ -888,6 +1083,11 @@ static int emac_remove(struct platform_device *pdev)
 	struct net_device *ndev = platform_get_drvdata(pdev);
 	struct emac_board_info *db = netdev_priv(ndev);
 
+	if (db->rx_chan) {
+		dmaengine_terminate_all(db->rx_chan);
+		dma_release_channel(db->rx_chan);
+	}
+
 	unregister_netdev(ndev);
 	sunxi_sram_release(&pdev->dev);
 	clk_disable_unprepare(db->clk);
-- 
2.31.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v6] sun4i-emac.c: add dma support
@ 2021-12-29  1:43       ` conleylee
  0 siblings, 0 replies; 33+ messages in thread
From: conleylee @ 2021-12-29  1:43 UTC (permalink / raw)
  To: davem, kuba, mripard, wens
  Cc: netdev, linux-arm-kernel, linux-kernel, Conley Lee

From: Conley Lee <conleylee@foxmail.com>

Thanks for your review. Here is the new version for this patch.

This patch adds support for the emac rx dma present on sun4i. The emac
is able to move packets from rx fifo to RAM by using dma.

Change since v4.
  - rename sbk field to skb
  - rename alloc_emac_dma_req to emac_alloc_dma_req
  - using kzalloc(..., GPF_ATOMIC) in interrupt context to avoid
    sleeping
  - retry by using emac_inblk_32bit when emac_dma_inblk_32bit fails
  - fix some code style issues 

Change since v5.
  - fix some code style issue

Signed-off-by: Conley Lee <conleylee@foxmail.com>
---
 drivers/net/ethernet/allwinner/sun4i-emac.c | 200 ++++++++++++++++++++
 1 file changed, 200 insertions(+)

diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
index cccf8a3ead5e..964227e342ee 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -29,6 +29,7 @@
 #include <linux/platform_device.h>
 #include <linux/phy.h>
 #include <linux/soc/sunxi/sunxi_sram.h>
+#include <linux/dmaengine.h>
 
 #include "sun4i-emac.h"
 
@@ -86,6 +87,16 @@ struct emac_board_info {
 	unsigned int		duplex;
 
 	phy_interface_t		phy_interface;
+	struct dma_chan	*rx_chan;
+	phys_addr_t emac_rx_fifo;
+};
+
+struct emac_dma_req {
+	struct emac_board_info *db;
+	struct dma_async_tx_descriptor *desc;
+	struct sk_buff *skb;
+	dma_addr_t rxbuf;
+	int count;
 };
 
 static void emac_update_speed(struct net_device *dev)
@@ -205,6 +216,117 @@ static void emac_inblk_32bit(void __iomem *reg, void *data, int count)
 	readsl(reg, data, round_up(count, 4) / 4);
 }
 
+static struct emac_dma_req *
+emac_alloc_dma_req(struct emac_board_info *db,
+		   struct dma_async_tx_descriptor *desc, struct sk_buff *skb,
+		   dma_addr_t rxbuf, int count)
+{
+	struct emac_dma_req *req;
+
+	req = kzalloc(sizeof(struct emac_dma_req), GFP_ATOMIC);
+	if (!req)
+		return NULL;
+
+	req->db = db;
+	req->desc = desc;
+	req->skb = skb;
+	req->rxbuf = rxbuf;
+	req->count = count;
+	return req;
+}
+
+static void emac_free_dma_req(struct emac_dma_req *req)
+{
+	kfree(req);
+}
+
+static void emac_dma_done_callback(void *arg)
+{
+	struct emac_dma_req *req = arg;
+	struct emac_board_info *db = req->db;
+	struct sk_buff *skb = req->skb;
+	struct net_device *dev = db->ndev;
+	int rxlen = req->count;
+	u32 reg_val;
+
+	dma_unmap_single(db->dev, req->rxbuf, rxlen, DMA_FROM_DEVICE);
+
+	skb->protocol = eth_type_trans(skb, dev);
+	netif_rx(skb);
+	dev->stats.rx_bytes += rxlen;
+	/* Pass to upper layer */
+	dev->stats.rx_packets++;
+
+	/* re enable cpu receive */
+	reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+	reg_val &= ~EMAC_RX_CTL_DMA_EN;
+	writel(reg_val, db->membase + EMAC_RX_CTL_REG);
+
+	/* re enable interrupt */
+	reg_val = readl(db->membase + EMAC_INT_CTL_REG);
+	reg_val |= (0x01 << 8);
+	writel(reg_val, db->membase + EMAC_INT_CTL_REG);
+
+	db->emacrx_completed_flag = 1;
+	emac_free_dma_req(req);
+}
+
+static int emac_dma_inblk_32bit(struct emac_board_info *db,
+		struct sk_buff *skb, void *rdptr, int count)
+{
+	struct dma_async_tx_descriptor *desc;
+	dma_cookie_t cookie;
+	dma_addr_t rxbuf;
+	struct emac_dma_req *req;
+	int ret = 0;
+
+	rxbuf = dma_map_single(db->dev, rdptr, count, DMA_FROM_DEVICE);
+	ret = dma_mapping_error(db->dev, rxbuf);
+	if (ret) {
+		dev_err(db->dev, "dma mapping error.\n");
+		return ret;
+	}
+
+	desc = dmaengine_prep_slave_single(db->rx_chan, rxbuf, count,
+					   DMA_DEV_TO_MEM,
+					   DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!desc) {
+		dev_err(db->dev, "prepare slave single failed\n");
+		ret = -ENOMEM;
+		goto prepare_err;
+	}
+
+	req = emac_alloc_dma_req(db, desc, skb, rxbuf, count);
+	if (!req) {
+		dev_err(db->dev, "alloc emac dma req error.\n");
+		ret = -ENOMEM;
+		goto alloc_req_err;
+	}
+
+	desc->callback_param = req;
+	desc->callback = emac_dma_done_callback;
+
+	cookie = dmaengine_submit(desc);
+	ret = dma_submit_error(cookie);
+	if (ret) {
+		dev_err(db->dev, "dma submit error.\n");
+		goto submit_err;
+	}
+
+	dma_async_issue_pending(db->rx_chan);
+	return ret;
+
+submit_err:
+	emac_free_dma_req(req);
+
+alloc_req_err:
+	dmaengine_desc_free(desc);
+
+prepare_err:
+	dma_unmap_single(db->dev, rxbuf, count, DMA_FROM_DEVICE);
+	return ret;
+}
+
 /* ethtool ops */
 static void emac_get_drvinfo(struct net_device *dev,
 			      struct ethtool_drvinfo *info)
@@ -605,6 +727,19 @@ static void emac_rx(struct net_device *dev)
 			if (netif_msg_rx_status(db))
 				dev_dbg(db->dev, "RxLen %x\n", rxlen);
 
+			if (rxlen >= dev->mtu && db->rx_chan) {
+				reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+				reg_val |= EMAC_RX_CTL_DMA_EN;
+				writel(reg_val, db->membase + EMAC_RX_CTL_REG);
+				if (!emac_dma_inblk_32bit(db, skb, rdptr, rxlen))
+					break;
+
+				/* re enable cpu receive. then try to receive by emac_inblk_32bit */
+				reg_val = readl(db->membase + EMAC_RX_CTL_REG);
+				reg_val &= ~EMAC_RX_CTL_DMA_EN;
+				writel(reg_val, db->membase + EMAC_RX_CTL_REG);
+			}
+
 			emac_inblk_32bit(db->membase + EMAC_RX_IO_DATA_REG,
 					rdptr, rxlen);
 			dev->stats.rx_bytes += rxlen;
@@ -659,7 +794,12 @@ static irqreturn_t emac_interrupt(int irq, void *dev_id)
 		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
 		reg_val |= (0xf << 0) | (0x01 << 8);
 		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
+	} else {
+		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
+		reg_val |= (0xf << 0);
+		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 	}
+
 	spin_unlock(&db->lock);
 
 	return IRQ_HANDLED;
@@ -764,6 +904,58 @@ static const struct net_device_ops emac_netdev_ops = {
 #endif
 };
 
+static int emac_configure_dma(struct emac_board_info *db)
+{
+	struct platform_device *pdev = db->pdev;
+	struct net_device *ndev = db->ndev;
+	struct dma_slave_config conf = {};
+	struct resource *regs;
+	int err = 0;
+
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!regs) {
+		netdev_err(ndev, "get io resource from device failed.\n");
+		err = -ENOMEM;
+		goto out_clear_chan;
+	}
+
+	netdev_info(ndev, "get io resource from device: 0x%x, size = %u\n",
+		    regs->start, resource_size(regs));
+	db->emac_rx_fifo = regs->start + EMAC_RX_IO_DATA_REG;
+
+	db->rx_chan = dma_request_chan(&pdev->dev, "rx");
+	if (IS_ERR(db->rx_chan)) {
+		netdev_err(ndev,
+			   "failed to request dma channel. dma is disabled\n");
+		err = PTR_ERR(db->rx_chan);
+		goto out_clear_chan;
+	}
+
+	conf.direction = DMA_DEV_TO_MEM;
+	conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	conf.src_addr = db->emac_rx_fifo;
+	conf.dst_maxburst = 4;
+	conf.src_maxburst = 4;
+	conf.device_fc = false;
+
+	err = dmaengine_slave_config(db->rx_chan, &conf);
+	if (err) {
+		netdev_err(ndev, "config dma slave failed\n");
+		err = -EINVAL;
+		goto out_slave_configure_err;
+	}
+
+	return err;
+
+out_slave_configure_err:
+	dma_release_channel(db->rx_chan);
+
+out_clear_chan:
+	db->rx_chan = NULL;
+	return err;
+}
+
 /* Search EMAC board, allocate space and register it
  */
 static int emac_probe(struct platform_device *pdev)
@@ -806,6 +998,9 @@ static int emac_probe(struct platform_device *pdev)
 		goto out_iounmap;
 	}
 
+	if (emac_configure_dma(db))
+		netdev_info(ndev, "configure dma failed. disable dma.\n");
+
 	db->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(db->clk)) {
 		ret = PTR_ERR(db->clk);
@@ -888,6 +1083,11 @@ static int emac_remove(struct platform_device *pdev)
 	struct net_device *ndev = platform_get_drvdata(pdev);
 	struct emac_board_info *db = netdev_priv(ndev);
 
+	if (db->rx_chan) {
+		dmaengine_terminate_all(db->rx_chan);
+		dma_release_channel(db->rx_chan);
+	}
+
 	unregister_netdev(ndev);
 	sunxi_sram_release(&pdev->dev);
 	clk_disable_unprepare(db->clk);
-- 
2.31.1


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

* Re: [PATCH v6] sun4i-emac.c: add dma support
  2021-12-29  1:43       ` conleylee
@ 2021-12-30  2:00         ` patchwork-bot+netdevbpf
  -1 siblings, 0 replies; 33+ messages in thread
From: patchwork-bot+netdevbpf @ 2021-12-30  2:00 UTC (permalink / raw)
  To: None; +Cc: davem, kuba, mripard, wens, netdev, linux-arm-kernel, linux-kernel

Hello:

This patch was applied to netdev/net-next.git (master)
by Jakub Kicinski <kuba@kernel.org>:

On Wed, 29 Dec 2021 09:43:51 +0800 you wrote:
> From: Conley Lee <conleylee@foxmail.com>
> 
> Thanks for your review. Here is the new version for this patch.
> 
> This patch adds support for the emac rx dma present on sun4i. The emac
> is able to move packets from rx fifo to RAM by using dma.
> 
> [...]

Here is the summary with links:
  - [v6] sun4i-emac.c: add dma support
    https://git.kernel.org/netdev/net-next/c/47869e82c8b8

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



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

* Re: [PATCH v6] sun4i-emac.c: add dma support
@ 2021-12-30  2:00         ` patchwork-bot+netdevbpf
  0 siblings, 0 replies; 33+ messages in thread
From: patchwork-bot+netdevbpf @ 2021-12-30  2:00 UTC (permalink / raw)
  To: None; +Cc: davem, kuba, mripard, wens, netdev, linux-arm-kernel, linux-kernel

Hello:

This patch was applied to netdev/net-next.git (master)
by Jakub Kicinski <kuba@kernel.org>:

On Wed, 29 Dec 2021 09:43:51 +0800 you wrote:
> From: Conley Lee <conleylee@foxmail.com>
> 
> Thanks for your review. Here is the new version for this patch.
> 
> This patch adds support for the emac rx dma present on sun4i. The emac
> is able to move packets from rx fifo to RAM by using dma.
> 
> [...]

Here is the summary with links:
  - [v6] sun4i-emac.c: add dma support
    https://git.kernel.org/netdev/net-next/c/47869e82c8b8

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6] sun4i-emac.c: add dma support
  2021-12-29  1:43       ` conleylee
@ 2021-12-31 10:43         ` Corentin Labbe
  -1 siblings, 0 replies; 33+ messages in thread
From: Corentin Labbe @ 2021-12-31 10:43 UTC (permalink / raw)
  To: conleylee
  Cc: davem, kuba, mripard, wens, netdev, linux-arm-kernel, linux-kernel

Le Wed, Dec 29, 2021 at 09:43:51AM +0800, conleylee@foxmail.com a écrit :
> From: Conley Lee <conleylee@foxmail.com>
> 
> Thanks for your review. Here is the new version for this patch.
> 
> This patch adds support for the emac rx dma present on sun4i. The emac
> is able to move packets from rx fifo to RAM by using dma.
> 
> Change since v4.
>   - rename sbk field to skb
>   - rename alloc_emac_dma_req to emac_alloc_dma_req
>   - using kzalloc(..., GPF_ATOMIC) in interrupt context to avoid
>     sleeping
>   - retry by using emac_inblk_32bit when emac_dma_inblk_32bit fails
>   - fix some code style issues 
> 
> Change since v5.
>   - fix some code style issue
> 

Hello

I just tested this on a sun4i-a10-olinuxino-lime

I got:
[    2.922812] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): get io resource from device: 0x1c0b000, size = 4096
[    2.934512] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): failed to request dma channel. dma is disabled
[    2.945740] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): configure dma failed. disable dma.
[    2.957887] sun4i-emac 1c0b000.ethernet: eth0: at (ptrval), IRQ 19 MAC: 02:49:09:40:ab:3d

On which board did you test it and how ?

Regards

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

* Re: [PATCH v6] sun4i-emac.c: add dma support
@ 2021-12-31 10:43         ` Corentin Labbe
  0 siblings, 0 replies; 33+ messages in thread
From: Corentin Labbe @ 2021-12-31 10:43 UTC (permalink / raw)
  To: conleylee
  Cc: davem, kuba, mripard, wens, netdev, linux-arm-kernel, linux-kernel

Le Wed, Dec 29, 2021 at 09:43:51AM +0800, conleylee@foxmail.com a écrit :
> From: Conley Lee <conleylee@foxmail.com>
> 
> Thanks for your review. Here is the new version for this patch.
> 
> This patch adds support for the emac rx dma present on sun4i. The emac
> is able to move packets from rx fifo to RAM by using dma.
> 
> Change since v4.
>   - rename sbk field to skb
>   - rename alloc_emac_dma_req to emac_alloc_dma_req
>   - using kzalloc(..., GPF_ATOMIC) in interrupt context to avoid
>     sleeping
>   - retry by using emac_inblk_32bit when emac_dma_inblk_32bit fails
>   - fix some code style issues 
> 
> Change since v5.
>   - fix some code style issue
> 

Hello

I just tested this on a sun4i-a10-olinuxino-lime

I got:
[    2.922812] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): get io resource from device: 0x1c0b000, size = 4096
[    2.934512] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): failed to request dma channel. dma is disabled
[    2.945740] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): configure dma failed. disable dma.
[    2.957887] sun4i-emac 1c0b000.ethernet: eth0: at (ptrval), IRQ 19 MAC: 02:49:09:40:ab:3d

On which board did you test it and how ?

Regards

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6] sun4i-emac.c: add dma support
       [not found]         ` <tencent_57960DDC83F43DA3E0A2F47DEBAD69A4A005@qq.com>
@ 2022-01-02 17:38             ` Corentin Labbe
  0 siblings, 0 replies; 33+ messages in thread
From: Corentin Labbe @ 2022-01-02 17:38 UTC (permalink / raw)
  To: Conley Lee
  Cc: davem, kuba, mripard, wens, netdev, linux-arm-kernel,
	linux-kernel, linux-sunxi, jernej.skrabec

Le Sat, Jan 01, 2022 at 03:09:01PM +0800, Conley Lee a écrit :
> On 12/31/21 at 11:43上午, Corentin Labbe wrote:
> > Date: Fri, 31 Dec 2021 11:43:53 +0100
> > From: Corentin Labbe <clabbe.montjoie@gmail.com>
> > To: conleylee@foxmail.com
> > Cc: davem@davemloft.net, kuba@kernel.org, mripard@kernel.org,
> >  wens@csie.org, netdev@vger.kernel.org,
> >  linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org
> > Subject: Re: [PATCH v6] sun4i-emac.c: add dma support
> > 
> > Le Wed, Dec 29, 2021 at 09:43:51AM +0800, conleylee@foxmail.com a écrit :
> > > From: Conley Lee <conleylee@foxmail.com>
> > > 
> > > Thanks for your review. Here is the new version for this patch.
> > > 
> > > This patch adds support for the emac rx dma present on sun4i. The emac
> > > is able to move packets from rx fifo to RAM by using dma.
> > > 
> > > Change since v4.
> > >   - rename sbk field to skb
> > >   - rename alloc_emac_dma_req to emac_alloc_dma_req
> > >   - using kzalloc(..., GPF_ATOMIC) in interrupt context to avoid
> > >     sleeping
> > >   - retry by using emac_inblk_32bit when emac_dma_inblk_32bit fails
> > >   - fix some code style issues 
> > > 
> > > Change since v5.
> > >   - fix some code style issue
> > > 
> > 
> > Hello
> > 
> > I just tested this on a sun4i-a10-olinuxino-lime
> > 
> > I got:
> > [    2.922812] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): get io resource from device: 0x1c0b000, size = 4096
> > [    2.934512] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): failed to request dma channel. dma is disabled
> > [    2.945740] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): configure dma failed. disable dma.
> > [    2.957887] sun4i-emac 1c0b000.ethernet: eth0: at (ptrval), IRQ 19 MAC: 02:49:09:40:ab:3d
> > 
> > On which board did you test it and how ?
> > 
> > Regards
> 
> Sorry. I sent the email with text/html format. This email is an clean version.
> 
> In order to enable dma rx channel. `dmas` and `dma-names` properties
> should be added to emac section in dts:
> 
> emac: ethernet@1c0b000 {
> 	...
> 	dmas = <&dma SUN4I_DMA_DEDICATED 7>;
> 	dma-names = "rx";
> 	...
> }

Helo

Yes I figured that out. But you should have done a patch serie adding this.
Your patch is now applied but it is a useless change without the dtb change.
You should also probably update the driver binding (Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml) since you add new members to DT node.

Furthermore, why did you add RX only and not TX dma also ?

Probably it is too late since patch is applied but it is:
Tested-by: Corentin Labbe <clabbe.montjoie@gmail.com>
Tested-on: sun4i-a10-olinuxino-lime

Regards

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

* Re: [PATCH v6] sun4i-emac.c: add dma support
@ 2022-01-02 17:38             ` Corentin Labbe
  0 siblings, 0 replies; 33+ messages in thread
From: Corentin Labbe @ 2022-01-02 17:38 UTC (permalink / raw)
  To: Conley Lee
  Cc: davem, kuba, mripard, wens, netdev, linux-arm-kernel,
	linux-kernel, linux-sunxi, jernej.skrabec

Le Sat, Jan 01, 2022 at 03:09:01PM +0800, Conley Lee a écrit :
> On 12/31/21 at 11:43上午, Corentin Labbe wrote:
> > Date: Fri, 31 Dec 2021 11:43:53 +0100
> > From: Corentin Labbe <clabbe.montjoie@gmail.com>
> > To: conleylee@foxmail.com
> > Cc: davem@davemloft.net, kuba@kernel.org, mripard@kernel.org,
> >  wens@csie.org, netdev@vger.kernel.org,
> >  linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org
> > Subject: Re: [PATCH v6] sun4i-emac.c: add dma support
> > 
> > Le Wed, Dec 29, 2021 at 09:43:51AM +0800, conleylee@foxmail.com a écrit :
> > > From: Conley Lee <conleylee@foxmail.com>
> > > 
> > > Thanks for your review. Here is the new version for this patch.
> > > 
> > > This patch adds support for the emac rx dma present on sun4i. The emac
> > > is able to move packets from rx fifo to RAM by using dma.
> > > 
> > > Change since v4.
> > >   - rename sbk field to skb
> > >   - rename alloc_emac_dma_req to emac_alloc_dma_req
> > >   - using kzalloc(..., GPF_ATOMIC) in interrupt context to avoid
> > >     sleeping
> > >   - retry by using emac_inblk_32bit when emac_dma_inblk_32bit fails
> > >   - fix some code style issues 
> > > 
> > > Change since v5.
> > >   - fix some code style issue
> > > 
> > 
> > Hello
> > 
> > I just tested this on a sun4i-a10-olinuxino-lime
> > 
> > I got:
> > [    2.922812] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): get io resource from device: 0x1c0b000, size = 4096
> > [    2.934512] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): failed to request dma channel. dma is disabled
> > [    2.945740] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): configure dma failed. disable dma.
> > [    2.957887] sun4i-emac 1c0b000.ethernet: eth0: at (ptrval), IRQ 19 MAC: 02:49:09:40:ab:3d
> > 
> > On which board did you test it and how ?
> > 
> > Regards
> 
> Sorry. I sent the email with text/html format. This email is an clean version.
> 
> In order to enable dma rx channel. `dmas` and `dma-names` properties
> should be added to emac section in dts:
> 
> emac: ethernet@1c0b000 {
> 	...
> 	dmas = <&dma SUN4I_DMA_DEDICATED 7>;
> 	dma-names = "rx";
> 	...
> }

Helo

Yes I figured that out. But you should have done a patch serie adding this.
Your patch is now applied but it is a useless change without the dtb change.
You should also probably update the driver binding (Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml) since you add new members to DT node.

Furthermore, why did you add RX only and not TX dma also ?

Probably it is too late since patch is applied but it is:
Tested-by: Corentin Labbe <clabbe.montjoie@gmail.com>
Tested-on: sun4i-a10-olinuxino-lime

Regards

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6] sun4i-emac.c: add dma support
       [not found]             ` <tencent_67023336008FE777A58293D2D32DEFA69107@qq.com>
@ 2022-01-03 11:42                 ` Corentin Labbe
  0 siblings, 0 replies; 33+ messages in thread
From: Corentin Labbe @ 2022-01-03 11:42 UTC (permalink / raw)
  To: Conley Lee
  Cc: davem, mripard, wens, jernej.skrabec, netdev, linux-arm-kernel,
	linux-sunxi, linux-kernel

Le Mon, Jan 03, 2022 at 10:55:04AM +0800, Conley Lee a écrit :
> On 01/02/22 at 06:38下午, Corentin Labbe wrote:
> > Date: Sun, 2 Jan 2022 18:38:51 +0100
> > From: Corentin Labbe <clabbe.montjoie@gmail.com>
> > To: Conley Lee <conleylee@foxmail.com>
> > Cc: davem@davemloft.net, kuba@kernel.org, mripard@kernel.org,
> >  wens@csie.org, netdev@vger.kernel.org,
> >  linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org,
> >  linux-sunxi@lists.linux.dev, jernej.skrabec@gmail.com
> > Subject: Re: [PATCH v6] sun4i-emac.c: add dma support
> > 
> > Le Sat, Jan 01, 2022 at 03:09:01PM +0800, Conley Lee a écrit :
> > > On 12/31/21 at 11:43上午, Corentin Labbe wrote:
> > > > Date: Fri, 31 Dec 2021 11:43:53 +0100
> > > > From: Corentin Labbe <clabbe.montjoie@gmail.com>
> > > > To: conleylee@foxmail.com
> > > > Cc: davem@davemloft.net, kuba@kernel.org, mripard@kernel.org,
> > > >  wens@csie.org, netdev@vger.kernel.org,
> > > >  linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org
> > > > Subject: Re: [PATCH v6] sun4i-emac.c: add dma support
> > > > 
> > > > Le Wed, Dec 29, 2021 at 09:43:51AM +0800, conleylee@foxmail.com a écrit :
> > > > > From: Conley Lee <conleylee@foxmail.com>
> > > > > 
> > > > > Thanks for your review. Here is the new version for this patch.
> > > > > 
> > > > > This patch adds support for the emac rx dma present on sun4i. The emac
> > > > > is able to move packets from rx fifo to RAM by using dma.
> > > > > 
> > > > > Change since v4.
> > > > >   - rename sbk field to skb
> > > > >   - rename alloc_emac_dma_req to emac_alloc_dma_req
> > > > >   - using kzalloc(..., GPF_ATOMIC) in interrupt context to avoid
> > > > >     sleeping
> > > > >   - retry by using emac_inblk_32bit when emac_dma_inblk_32bit fails
> > > > >   - fix some code style issues 
> > > > > 
> > > > > Change since v5.
> > > > >   - fix some code style issue
> > > > > 
> > > > 
> > > > Hello
> > > > 
> > > > I just tested this on a sun4i-a10-olinuxino-lime
> > > > 
> > > > I got:
> > > > [    2.922812] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): get io resource from device: 0x1c0b000, size = 4096
> > > > [    2.934512] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): failed to request dma channel. dma is disabled
> > > > [    2.945740] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): configure dma failed. disable dma.
> > > > [    2.957887] sun4i-emac 1c0b000.ethernet: eth0: at (ptrval), IRQ 19 MAC: 02:49:09:40:ab:3d
> > > > 
> > > > On which board did you test it and how ?
> > > > 
> > > > Regards
> > > 
> > > Sorry. I sent the email with text/html format. This email is an clean version.
> > > 
> > > In order to enable dma rx channel. `dmas` and `dma-names` properties
> > > should be added to emac section in dts:
> > > 
> > > emac: ethernet@1c0b000 {
> > > 	...
> > > 	dmas = <&dma SUN4I_DMA_DEDICATED 7>;
> > > 	dma-names = "rx";
> > > 	...
> > > }
> > 
> > Helo
> > 
> > Yes I figured that out. But you should have done a patch serie adding this.
> > Your patch is now applied but it is a useless change without the dtb change.
> > You should also probably update the driver binding (Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml) since you add new members to DT node.
> > 
> > Furthermore, why did you add RX only and not TX dma also ?
> > 
> > Probably it is too late since patch is applied but it is:
> > Tested-by: Corentin Labbe <clabbe.montjoie@gmail.com>
> > Tested-on: sun4i-a10-olinuxino-lime
> > 
> > Regards
> 
> Thanks for your suggestion. I will submit a patch to add those changes
> later. 
> 
> And the reason why I didn't add TX support is becasuse there is no any
> public page to describe sun4i emac TX DMA register map. So, I don't known
> how to enable TX DMA at hardware level. If you has any page or datasheet
> about EMAC TX DMA, can you share with me ? Thanks.

Hello

You can find TX DMA info on the R40 Use manual (8.10.5.2 Register Name: EMAC_TX_MODE)

You should keep all people in CC when you answer to someone.

Regards

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

* Re: [PATCH v6] sun4i-emac.c: add dma support
@ 2022-01-03 11:42                 ` Corentin Labbe
  0 siblings, 0 replies; 33+ messages in thread
From: Corentin Labbe @ 2022-01-03 11:42 UTC (permalink / raw)
  To: Conley Lee
  Cc: davem, mripard, wens, jernej.skrabec, netdev, linux-arm-kernel,
	linux-sunxi, linux-kernel

Le Mon, Jan 03, 2022 at 10:55:04AM +0800, Conley Lee a écrit :
> On 01/02/22 at 06:38下午, Corentin Labbe wrote:
> > Date: Sun, 2 Jan 2022 18:38:51 +0100
> > From: Corentin Labbe <clabbe.montjoie@gmail.com>
> > To: Conley Lee <conleylee@foxmail.com>
> > Cc: davem@davemloft.net, kuba@kernel.org, mripard@kernel.org,
> >  wens@csie.org, netdev@vger.kernel.org,
> >  linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org,
> >  linux-sunxi@lists.linux.dev, jernej.skrabec@gmail.com
> > Subject: Re: [PATCH v6] sun4i-emac.c: add dma support
> > 
> > Le Sat, Jan 01, 2022 at 03:09:01PM +0800, Conley Lee a écrit :
> > > On 12/31/21 at 11:43上午, Corentin Labbe wrote:
> > > > Date: Fri, 31 Dec 2021 11:43:53 +0100
> > > > From: Corentin Labbe <clabbe.montjoie@gmail.com>
> > > > To: conleylee@foxmail.com
> > > > Cc: davem@davemloft.net, kuba@kernel.org, mripard@kernel.org,
> > > >  wens@csie.org, netdev@vger.kernel.org,
> > > >  linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org
> > > > Subject: Re: [PATCH v6] sun4i-emac.c: add dma support
> > > > 
> > > > Le Wed, Dec 29, 2021 at 09:43:51AM +0800, conleylee@foxmail.com a écrit :
> > > > > From: Conley Lee <conleylee@foxmail.com>
> > > > > 
> > > > > Thanks for your review. Here is the new version for this patch.
> > > > > 
> > > > > This patch adds support for the emac rx dma present on sun4i. The emac
> > > > > is able to move packets from rx fifo to RAM by using dma.
> > > > > 
> > > > > Change since v4.
> > > > >   - rename sbk field to skb
> > > > >   - rename alloc_emac_dma_req to emac_alloc_dma_req
> > > > >   - using kzalloc(..., GPF_ATOMIC) in interrupt context to avoid
> > > > >     sleeping
> > > > >   - retry by using emac_inblk_32bit when emac_dma_inblk_32bit fails
> > > > >   - fix some code style issues 
> > > > > 
> > > > > Change since v5.
> > > > >   - fix some code style issue
> > > > > 
> > > > 
> > > > Hello
> > > > 
> > > > I just tested this on a sun4i-a10-olinuxino-lime
> > > > 
> > > > I got:
> > > > [    2.922812] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): get io resource from device: 0x1c0b000, size = 4096
> > > > [    2.934512] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): failed to request dma channel. dma is disabled
> > > > [    2.945740] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): configure dma failed. disable dma.
> > > > [    2.957887] sun4i-emac 1c0b000.ethernet: eth0: at (ptrval), IRQ 19 MAC: 02:49:09:40:ab:3d
> > > > 
> > > > On which board did you test it and how ?
> > > > 
> > > > Regards
> > > 
> > > Sorry. I sent the email with text/html format. This email is an clean version.
> > > 
> > > In order to enable dma rx channel. `dmas` and `dma-names` properties
> > > should be added to emac section in dts:
> > > 
> > > emac: ethernet@1c0b000 {
> > > 	...
> > > 	dmas = <&dma SUN4I_DMA_DEDICATED 7>;
> > > 	dma-names = "rx";
> > > 	...
> > > }
> > 
> > Helo
> > 
> > Yes I figured that out. But you should have done a patch serie adding this.
> > Your patch is now applied but it is a useless change without the dtb change.
> > You should also probably update the driver binding (Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml) since you add new members to DT node.
> > 
> > Furthermore, why did you add RX only and not TX dma also ?
> > 
> > Probably it is too late since patch is applied but it is:
> > Tested-by: Corentin Labbe <clabbe.montjoie@gmail.com>
> > Tested-on: sun4i-a10-olinuxino-lime
> > 
> > Regards
> 
> Thanks for your suggestion. I will submit a patch to add those changes
> later. 
> 
> And the reason why I didn't add TX support is becasuse there is no any
> public page to describe sun4i emac TX DMA register map. So, I don't known
> how to enable TX DMA at hardware level. If you has any page or datasheet
> about EMAC TX DMA, can you share with me ? Thanks.

Hello

You can find TX DMA info on the R40 Use manual (8.10.5.2 Register Name: EMAC_TX_MODE)

You should keep all people in CC when you answer to someone.

Regards

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6] sun4i-emac.c: add dma support
  2022-01-03 11:42                 ` Corentin Labbe
@ 2022-01-03 12:21                   ` Conley Lee
  -1 siblings, 0 replies; 33+ messages in thread
From: Conley Lee @ 2022-01-03 12:21 UTC (permalink / raw)
  To: Corentin Labbe
  Cc: davem, mripard, wens, jernej.skrabec, netdev, linux-arm-kernel,
	linux-sunxi, linux-kernel

On 01/03/22 at 12:42下午, Corentin Labbe wrote:
> Date: Mon, 3 Jan 2022 12:42:58 +0100
> From: Corentin Labbe <clabbe.montjoie@gmail.com>
> To: Conley Lee <conleylee@foxmail.com>
> Cc: davem@davemloft.net, mripard@kernel.org, wens@csie.org,
>  jernej.skrabec@gmail.com, netdev@vger.kernel.org,
>  linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev,
>  linux-kernel@vger.kernel.org
> Subject: Re: [PATCH v6] sun4i-emac.c: add dma support
> 
> Le Mon, Jan 03, 2022 at 10:55:04AM +0800, Conley Lee a écrit :
> > On 01/02/22 at 06:38下午, Corentin Labbe wrote:
> > > Date: Sun, 2 Jan 2022 18:38:51 +0100
> > > From: Corentin Labbe <clabbe.montjoie@gmail.com>
> > > To: Conley Lee <conleylee@foxmail.com>
> > > Cc: davem@davemloft.net, kuba@kernel.org, mripard@kernel.org,
> > >  wens@csie.org, netdev@vger.kernel.org,
> > >  linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org,
> > >  linux-sunxi@lists.linux.dev, jernej.skrabec@gmail.com
> > > Subject: Re: [PATCH v6] sun4i-emac.c: add dma support
> > > 
> > > Le Sat, Jan 01, 2022 at 03:09:01PM +0800, Conley Lee a écrit :
> > > > On 12/31/21 at 11:43上午, Corentin Labbe wrote:
> > > > > Date: Fri, 31 Dec 2021 11:43:53 +0100
> > > > > From: Corentin Labbe <clabbe.montjoie@gmail.com>
> > > > > To: conleylee@foxmail.com
> > > > > Cc: davem@davemloft.net, kuba@kernel.org, mripard@kernel.org,
> > > > >  wens@csie.org, netdev@vger.kernel.org,
> > > > >  linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org
> > > > > Subject: Re: [PATCH v6] sun4i-emac.c: add dma support
> > > > > 
> > > > > Le Wed, Dec 29, 2021 at 09:43:51AM +0800, conleylee@foxmail.com a écrit :
> > > > > > From: Conley Lee <conleylee@foxmail.com>
> > > > > > 
> > > > > > Thanks for your review. Here is the new version for this patch.
> > > > > > 
> > > > > > This patch adds support for the emac rx dma present on sun4i. The emac
> > > > > > is able to move packets from rx fifo to RAM by using dma.
> > > > > > 
> > > > > > Change since v4.
> > > > > >   - rename sbk field to skb
> > > > > >   - rename alloc_emac_dma_req to emac_alloc_dma_req
> > > > > >   - using kzalloc(..., GPF_ATOMIC) in interrupt context to avoid
> > > > > >     sleeping
> > > > > >   - retry by using emac_inblk_32bit when emac_dma_inblk_32bit fails
> > > > > >   - fix some code style issues 
> > > > > > 
> > > > > > Change since v5.
> > > > > >   - fix some code style issue
> > > > > > 
> > > > > 
> > > > > Hello
> > > > > 
> > > > > I just tested this on a sun4i-a10-olinuxino-lime
> > > > > 
> > > > > I got:
> > > > > [    2.922812] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): get io resource from device: 0x1c0b000, size = 4096
> > > > > [    2.934512] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): failed to request dma channel. dma is disabled
> > > > > [    2.945740] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): configure dma failed. disable dma.
> > > > > [    2.957887] sun4i-emac 1c0b000.ethernet: eth0: at (ptrval), IRQ 19 MAC: 02:49:09:40:ab:3d
> > > > > 
> > > > > On which board did you test it and how ?
> > > > > 
> > > > > Regards
> > > > 
> > > > Sorry. I sent the email with text/html format. This email is an clean version.
> > > > 
> > > > In order to enable dma rx channel. `dmas` and `dma-names` properties
> > > > should be added to emac section in dts:
> > > > 
> > > > emac: ethernet@1c0b000 {
> > > > 	...
> > > > 	dmas = <&dma SUN4I_DMA_DEDICATED 7>;
> > > > 	dma-names = "rx";
> > > > 	...
> > > > }
> > > 
> > > Helo
> > > 
> > > Yes I figured that out. But you should have done a patch serie adding this.
> > > Your patch is now applied but it is a useless change without the dtb change.
> > > You should also probably update the driver binding (Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml) since you add new members to DT node.
> > > 
> > > Furthermore, why did you add RX only and not TX dma also ?
> > > 
> > > Probably it is too late since patch is applied but it is:
> > > Tested-by: Corentin Labbe <clabbe.montjoie@gmail.com>
> > > Tested-on: sun4i-a10-olinuxino-lime
> > > 
> > > Regards
> > 
> > Thanks for your suggestion. I will submit a patch to add those changes
> > later. 
> > 
> > And the reason why I didn't add TX support is becasuse there is no any
> > public page to describe sun4i emac TX DMA register map. So, I don't known
> > how to enable TX DMA at hardware level. If you has any page or datasheet
> > about EMAC TX DMA, can you share with me ? Thanks.
> 
> Hello
> 
> You can find TX DMA info on the R40 Use manual (8.10.5.2 Register Name: EMAC_TX_MODE)
> 
> You should keep all people in CC when you answer to someone.
> 
> Regards

Haha, got it! I have been looking for the docs about emac register map
for a long time. You really help me a lot. I will submit a new patch to
add driver bidding and enable both RX and TX channels. Thanks ~

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6] sun4i-emac.c: add dma support
@ 2022-01-03 12:21                   ` Conley Lee
  0 siblings, 0 replies; 33+ messages in thread
From: Conley Lee @ 2022-01-03 12:21 UTC (permalink / raw)
  To: Corentin Labbe
  Cc: davem, mripard, wens, jernej.skrabec, netdev, linux-arm-kernel,
	linux-sunxi, linux-kernel

On 01/03/22 at 12:42下午, Corentin Labbe wrote:
> Date: Mon, 3 Jan 2022 12:42:58 +0100
> From: Corentin Labbe <clabbe.montjoie@gmail.com>
> To: Conley Lee <conleylee@foxmail.com>
> Cc: davem@davemloft.net, mripard@kernel.org, wens@csie.org,
>  jernej.skrabec@gmail.com, netdev@vger.kernel.org,
>  linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev,
>  linux-kernel@vger.kernel.org
> Subject: Re: [PATCH v6] sun4i-emac.c: add dma support
> 
> Le Mon, Jan 03, 2022 at 10:55:04AM +0800, Conley Lee a écrit :
> > On 01/02/22 at 06:38下午, Corentin Labbe wrote:
> > > Date: Sun, 2 Jan 2022 18:38:51 +0100
> > > From: Corentin Labbe <clabbe.montjoie@gmail.com>
> > > To: Conley Lee <conleylee@foxmail.com>
> > > Cc: davem@davemloft.net, kuba@kernel.org, mripard@kernel.org,
> > >  wens@csie.org, netdev@vger.kernel.org,
> > >  linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org,
> > >  linux-sunxi@lists.linux.dev, jernej.skrabec@gmail.com
> > > Subject: Re: [PATCH v6] sun4i-emac.c: add dma support
> > > 
> > > Le Sat, Jan 01, 2022 at 03:09:01PM +0800, Conley Lee a écrit :
> > > > On 12/31/21 at 11:43上午, Corentin Labbe wrote:
> > > > > Date: Fri, 31 Dec 2021 11:43:53 +0100
> > > > > From: Corentin Labbe <clabbe.montjoie@gmail.com>
> > > > > To: conleylee@foxmail.com
> > > > > Cc: davem@davemloft.net, kuba@kernel.org, mripard@kernel.org,
> > > > >  wens@csie.org, netdev@vger.kernel.org,
> > > > >  linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org
> > > > > Subject: Re: [PATCH v6] sun4i-emac.c: add dma support
> > > > > 
> > > > > Le Wed, Dec 29, 2021 at 09:43:51AM +0800, conleylee@foxmail.com a écrit :
> > > > > > From: Conley Lee <conleylee@foxmail.com>
> > > > > > 
> > > > > > Thanks for your review. Here is the new version for this patch.
> > > > > > 
> > > > > > This patch adds support for the emac rx dma present on sun4i. The emac
> > > > > > is able to move packets from rx fifo to RAM by using dma.
> > > > > > 
> > > > > > Change since v4.
> > > > > >   - rename sbk field to skb
> > > > > >   - rename alloc_emac_dma_req to emac_alloc_dma_req
> > > > > >   - using kzalloc(..., GPF_ATOMIC) in interrupt context to avoid
> > > > > >     sleeping
> > > > > >   - retry by using emac_inblk_32bit when emac_dma_inblk_32bit fails
> > > > > >   - fix some code style issues 
> > > > > > 
> > > > > > Change since v5.
> > > > > >   - fix some code style issue
> > > > > > 
> > > > > 
> > > > > Hello
> > > > > 
> > > > > I just tested this on a sun4i-a10-olinuxino-lime
> > > > > 
> > > > > I got:
> > > > > [    2.922812] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): get io resource from device: 0x1c0b000, size = 4096
> > > > > [    2.934512] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): failed to request dma channel. dma is disabled
> > > > > [    2.945740] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): configure dma failed. disable dma.
> > > > > [    2.957887] sun4i-emac 1c0b000.ethernet: eth0: at (ptrval), IRQ 19 MAC: 02:49:09:40:ab:3d
> > > > > 
> > > > > On which board did you test it and how ?
> > > > > 
> > > > > Regards
> > > > 
> > > > Sorry. I sent the email with text/html format. This email is an clean version.
> > > > 
> > > > In order to enable dma rx channel. `dmas` and `dma-names` properties
> > > > should be added to emac section in dts:
> > > > 
> > > > emac: ethernet@1c0b000 {
> > > > 	...
> > > > 	dmas = <&dma SUN4I_DMA_DEDICATED 7>;
> > > > 	dma-names = "rx";
> > > > 	...
> > > > }
> > > 
> > > Helo
> > > 
> > > Yes I figured that out. But you should have done a patch serie adding this.
> > > Your patch is now applied but it is a useless change without the dtb change.
> > > You should also probably update the driver binding (Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml) since you add new members to DT node.
> > > 
> > > Furthermore, why did you add RX only and not TX dma also ?
> > > 
> > > Probably it is too late since patch is applied but it is:
> > > Tested-by: Corentin Labbe <clabbe.montjoie@gmail.com>
> > > Tested-on: sun4i-a10-olinuxino-lime
> > > 
> > > Regards
> > 
> > Thanks for your suggestion. I will submit a patch to add those changes
> > later. 
> > 
> > And the reason why I didn't add TX support is becasuse there is no any
> > public page to describe sun4i emac TX DMA register map. So, I don't known
> > how to enable TX DMA at hardware level. If you has any page or datasheet
> > about EMAC TX DMA, can you share with me ? Thanks.
> 
> Hello
> 
> You can find TX DMA info on the R40 Use manual (8.10.5.2 Register Name: EMAC_TX_MODE)
> 
> You should keep all people in CC when you answer to someone.
> 
> Regards

Haha, got it! I have been looking for the docs about emac register map
for a long time. You really help me a lot. I will submit a new patch to
add driver bidding and enable both RX and TX channels. Thanks ~

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

* Re: [PATCH v6] sun4i-emac.c: add dma support
  2021-12-29  1:43       ` conleylee
@ 2022-01-07 23:34         ` Kees Cook
  -1 siblings, 0 replies; 33+ messages in thread
From: Kees Cook @ 2022-01-07 23:34 UTC (permalink / raw)
  To: conleylee
  Cc: davem, kuba, mripard, wens, netdev, linux-arm-kernel, linux-kernel

On Wed, Dec 29, 2021 at 09:43:51AM +0800, conleylee@foxmail.com wrote:
> From: Conley Lee <conleylee@foxmail.com>
>
> Thanks for your review. Here is the new version for this patch.
>
> This patch adds support for the emac rx dma present on sun4i. The emac
> is able to move packets from rx fifo to RAM by using dma.
>
> Change since v4.
>   - rename sbk field to skb
>   - rename alloc_emac_dma_req to emac_alloc_dma_req
>   - using kzalloc(..., GPF_ATOMIC) in interrupt context to avoid
>     sleeping
>   - retry by using emac_inblk_32bit when emac_dma_inblk_32bit fails
>   - fix some code style issues
>
> Change since v5.
>   - fix some code style issue
>
> Signed-off-by: Conley Lee <conleylee@foxmail.com>
> ---
>  drivers/net/ethernet/allwinner/sun4i-emac.c | 200 ++++++++++++++++++++
>  1 file changed, 200 insertions(+)

This is causing build failures:

$ make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 allmodconfig
$ make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 -j... -k -s
drivers/net/ethernet/allwinner/sun4i-emac.c: In function 'emac_configure_dma':
drivers/net/ethernet/allwinner/sun4i-emac.c:922:60: error: format '%x' expects argument of type 'unsigned int', but argument 3 has type 'resource_size_t' {aka 'long long unsigned int'} [-Werror=format=]
  922 |         netdev_info(ndev, "get io resource from device: 0x%x, size = %u\n",
      |                                                           ~^
      |                                                            |                                      |                                                            unsigned int
      |                                                           %llx
  923 |                     regs->start, resource_size(regs));
      |                     ~~~~~~~~~~~
      |                         |
      |                         resource_size_t {aka long long unsigned int}
drivers/net/ethernet/allwinner/sun4i-emac.c:922:71: error: format '%u' expects argument of type 'unsigned int', but argument 4 has type 'resource_size_t' {aka 'long long unsigned int'} [-Werror=format=]
  922 |         netdev_info(ndev, "get io resource from device: 0x%x, size = %u\n",
      |                                                                      ~^
      |                                                                       |
      |                                                                       unsigned int
      |                                                                      %llu
  923 |                     regs->start, resource_size(regs));
      |                                  ~~~~~~~~~~~~~~~~~~~
      |                                  |
      |                                  resource_size_t {aka long long unsigned int}


--
Kees Cook

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

* Re: [PATCH v6] sun4i-emac.c: add dma support
@ 2022-01-07 23:34         ` Kees Cook
  0 siblings, 0 replies; 33+ messages in thread
From: Kees Cook @ 2022-01-07 23:34 UTC (permalink / raw)
  To: conleylee
  Cc: davem, kuba, mripard, wens, netdev, linux-arm-kernel, linux-kernel

On Wed, Dec 29, 2021 at 09:43:51AM +0800, conleylee@foxmail.com wrote:
> From: Conley Lee <conleylee@foxmail.com>
>
> Thanks for your review. Here is the new version for this patch.
>
> This patch adds support for the emac rx dma present on sun4i. The emac
> is able to move packets from rx fifo to RAM by using dma.
>
> Change since v4.
>   - rename sbk field to skb
>   - rename alloc_emac_dma_req to emac_alloc_dma_req
>   - using kzalloc(..., GPF_ATOMIC) in interrupt context to avoid
>     sleeping
>   - retry by using emac_inblk_32bit when emac_dma_inblk_32bit fails
>   - fix some code style issues
>
> Change since v5.
>   - fix some code style issue
>
> Signed-off-by: Conley Lee <conleylee@foxmail.com>
> ---
>  drivers/net/ethernet/allwinner/sun4i-emac.c | 200 ++++++++++++++++++++
>  1 file changed, 200 insertions(+)

This is causing build failures:

$ make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 allmodconfig
$ make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 -j... -k -s
drivers/net/ethernet/allwinner/sun4i-emac.c: In function 'emac_configure_dma':
drivers/net/ethernet/allwinner/sun4i-emac.c:922:60: error: format '%x' expects argument of type 'unsigned int', but argument 3 has type 'resource_size_t' {aka 'long long unsigned int'} [-Werror=format=]
  922 |         netdev_info(ndev, "get io resource from device: 0x%x, size = %u\n",
      |                                                           ~^
      |                                                            |                                      |                                                            unsigned int
      |                                                           %llx
  923 |                     regs->start, resource_size(regs));
      |                     ~~~~~~~~~~~
      |                         |
      |                         resource_size_t {aka long long unsigned int}
drivers/net/ethernet/allwinner/sun4i-emac.c:922:71: error: format '%u' expects argument of type 'unsigned int', but argument 4 has type 'resource_size_t' {aka 'long long unsigned int'} [-Werror=format=]
  922 |         netdev_info(ndev, "get io resource from device: 0x%x, size = %u\n",
      |                                                                      ~^
      |                                                                       |
      |                                                                       unsigned int
      |                                                                      %llu
  923 |                     regs->start, resource_size(regs));
      |                                  ~~~~~~~~~~~~~~~~~~~
      |                                  |
      |                                  resource_size_t {aka long long unsigned int}


--
Kees Cook

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6] sun4i-emac.c: add dma support
  2022-01-07 23:34         ` Kees Cook
@ 2022-01-08  2:34           ` Jakub Kicinski
  -1 siblings, 0 replies; 33+ messages in thread
From: Jakub Kicinski @ 2022-01-08  2:34 UTC (permalink / raw)
  To: Kees Cook
  Cc: conleylee, davem, mripard, wens, netdev, linux-arm-kernel, linux-kernel

On Fri, 7 Jan 2022 15:34:18 -0800 Kees Cook wrote:
> On Wed, Dec 29, 2021 at 09:43:51AM +0800, conleylee@foxmail.com wrote:
> > From: Conley Lee <conleylee@foxmail.com>
> >
> > Thanks for your review. Here is the new version for this patch.
> >
> > This patch adds support for the emac rx dma present on sun4i. The emac
> > is able to move packets from rx fifo to RAM by using dma.
> >
> > Change since v4.
> >   - rename sbk field to skb
> >   - rename alloc_emac_dma_req to emac_alloc_dma_req
> >   - using kzalloc(..., GPF_ATOMIC) in interrupt context to avoid
> >     sleeping
> >   - retry by using emac_inblk_32bit when emac_dma_inblk_32bit fails
> >   - fix some code style issues
> >
> > Change since v5.
> >   - fix some code style issue
> >
> > Signed-off-by: Conley Lee <conleylee@foxmail.com>
>
> This is causing build failures:
> 
> $ make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 allmodconfig
> $ make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 -j... -k -s
> drivers/net/ethernet/allwinner/sun4i-emac.c: In function 'emac_configure_dma':
> drivers/net/ethernet/allwinner/sun4i-emac.c:922:60: error: format '%x' expects argument of type 'unsigned int', but argument 3 has type 'resource_size_t' {aka 'long long unsigned int'} [-Werror=format=]
>   922 |         netdev_info(ndev, "get io resource from device: 0x%x, size = %u\n",
>       |                                                           ~^
>       |                                                            |                                      |                                                            unsigned int
>       |                                                           %llx
>   923 |                     regs->start, resource_size(regs));
>       |                     ~~~~~~~~~~~
>       |                         |
>       |                         resource_size_t {aka long long unsigned int}
> drivers/net/ethernet/allwinner/sun4i-emac.c:922:71: error: format '%u' expects argument of type 'unsigned int', but argument 4 has type 'resource_size_t' {aka 'long long unsigned int'} [-Werror=format=]
>   922 |         netdev_info(ndev, "get io resource from device: 0x%x, size = %u\n",
>       |                                                                      ~^
>       |                                                                       |
>       |                                                                       unsigned int
>       |                                                                      %llu
>   923 |                     regs->start, resource_size(regs));
>       |                                  ~~~~~~~~~~~~~~~~~~~
>       |                                  |
>       |                                  resource_size_t {aka long long unsigned int}
> 

Ugh, I saw this and somehow it didn't enter my brain that it's new.
%pa right? Let me test that and send a fix before we close net-next..

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

* Re: [PATCH v6] sun4i-emac.c: add dma support
@ 2022-01-08  2:34           ` Jakub Kicinski
  0 siblings, 0 replies; 33+ messages in thread
From: Jakub Kicinski @ 2022-01-08  2:34 UTC (permalink / raw)
  To: Kees Cook
  Cc: conleylee, davem, mripard, wens, netdev, linux-arm-kernel, linux-kernel

On Fri, 7 Jan 2022 15:34:18 -0800 Kees Cook wrote:
> On Wed, Dec 29, 2021 at 09:43:51AM +0800, conleylee@foxmail.com wrote:
> > From: Conley Lee <conleylee@foxmail.com>
> >
> > Thanks for your review. Here is the new version for this patch.
> >
> > This patch adds support for the emac rx dma present on sun4i. The emac
> > is able to move packets from rx fifo to RAM by using dma.
> >
> > Change since v4.
> >   - rename sbk field to skb
> >   - rename alloc_emac_dma_req to emac_alloc_dma_req
> >   - using kzalloc(..., GPF_ATOMIC) in interrupt context to avoid
> >     sleeping
> >   - retry by using emac_inblk_32bit when emac_dma_inblk_32bit fails
> >   - fix some code style issues
> >
> > Change since v5.
> >   - fix some code style issue
> >
> > Signed-off-by: Conley Lee <conleylee@foxmail.com>
>
> This is causing build failures:
> 
> $ make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 allmodconfig
> $ make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 -j... -k -s
> drivers/net/ethernet/allwinner/sun4i-emac.c: In function 'emac_configure_dma':
> drivers/net/ethernet/allwinner/sun4i-emac.c:922:60: error: format '%x' expects argument of type 'unsigned int', but argument 3 has type 'resource_size_t' {aka 'long long unsigned int'} [-Werror=format=]
>   922 |         netdev_info(ndev, "get io resource from device: 0x%x, size = %u\n",
>       |                                                           ~^
>       |                                                            |                                      |                                                            unsigned int
>       |                                                           %llx
>   923 |                     regs->start, resource_size(regs));
>       |                     ~~~~~~~~~~~
>       |                         |
>       |                         resource_size_t {aka long long unsigned int}
> drivers/net/ethernet/allwinner/sun4i-emac.c:922:71: error: format '%u' expects argument of type 'unsigned int', but argument 4 has type 'resource_size_t' {aka 'long long unsigned int'} [-Werror=format=]
>   922 |         netdev_info(ndev, "get io resource from device: 0x%x, size = %u\n",
>       |                                                                      ~^
>       |                                                                       |
>       |                                                                       unsigned int
>       |                                                                      %llu
>   923 |                     regs->start, resource_size(regs));
>       |                                  ~~~~~~~~~~~~~~~~~~~
>       |                                  |
>       |                                  resource_size_t {aka long long unsigned int}
> 

Ugh, I saw this and somehow it didn't enter my brain that it's new.
%pa right? Let me test that and send a fix before we close net-next..

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v1] sun4i-emac.c: enable emac tx dma
  2022-01-03 11:42                 ` Corentin Labbe
@ 2022-01-09  9:17                   ` conleylee
  -1 siblings, 0 replies; 33+ messages in thread
From: conleylee @ 2022-01-09  9:17 UTC (permalink / raw)
  To: clabbe.montjoie
  Cc: davem, mripard, wens, jernej.skrabec, netdev, linux-arm-kernel,
	linux-sunxi, linux-kernel, conley

From: conley <conleylee@foxmail.com>

Hello
I am reading the R40 user manual and trying to create a new path to enable
emac tx dma channel. According to the figure 8-21(TX Operation Diagram),
I try to enable emac tx dma channel by the follow steps:
1. enable tx dma mode
2. set packet lengths
2. move data from skb to tx fifo by using dma in xmit function.
3. start transfer from tx fifo to phy in dma tx done callback

But it doesn't work. emac tx interrupt and dma finished interrupt are
raised, but no packets are transmitted (I test it by tcpdump).
Do you know how to configure the emac tx dma correctly? Thanks ~

Signed-off-by: conley <conleylee@foxmail.com>
---
 drivers/net/ethernet/allwinner/sun4i-emac.c | 324 +++++++++++++-------
 drivers/net/ethernet/allwinner/sun4i-emac.h |  14 +
 2 files changed, 221 insertions(+), 117 deletions(-)

diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
index 964227e342ee..fcd7848f64a0 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -80,6 +80,7 @@ struct emac_board_info {
 	u16			tx_fifo_stat;
 
 	int			emacrx_completed_flag;
+	int 			emactx_completed_flag;
 
 	struct device_node	*phy_node;
 	unsigned int		link;
@@ -88,15 +89,20 @@ struct emac_board_info {
 
 	phy_interface_t		phy_interface;
 	struct dma_chan	*rx_chan;
+	struct dma_chan	*tx_chan;
 	phys_addr_t emac_rx_fifo;
+	phys_addr_t emac_tx_fifo;
 };
 
 struct emac_dma_req {
 	struct emac_board_info *db;
-	struct dma_async_tx_descriptor *desc;
+	struct dma_chan *chan;
 	struct sk_buff *skb;
-	dma_addr_t rxbuf;
+	void* buf;
+	dma_addr_t mapped_buf;
 	int count;
+	enum dma_data_direction dir;
+	int channel; // for tx
 };
 
 static void emac_update_speed(struct net_device *dev)
@@ -218,8 +224,9 @@ static void emac_inblk_32bit(void __iomem *reg, void *data, int count)
 
 static struct emac_dma_req *
 emac_alloc_dma_req(struct emac_board_info *db,
-		   struct dma_async_tx_descriptor *desc, struct sk_buff *skb,
-		   dma_addr_t rxbuf, int count)
+		struct dma_chan* chan,
+		struct sk_buff *skb, void* buf,
+		dma_addr_t mapped_buf, int count, int channel)
 {
 	struct emac_dma_req *req;
 
@@ -228,9 +235,10 @@ emac_alloc_dma_req(struct emac_board_info *db,
 		return NULL;
 
 	req->db = db;
-	req->desc = desc;
+	req->chan = chan;
 	req->skb = skb;
-	req->rxbuf = rxbuf;
+	req->buf = buf;
+	req->mapped_buf = mapped_buf;
 	req->count = count;
 	return req;
 }
@@ -240,22 +248,22 @@ static void emac_free_dma_req(struct emac_dma_req *req)
 	kfree(req);
 }
 
-static void emac_dma_done_callback(void *arg)
+static void emac_dma_rx_done_callback(void *arg)
 {
 	struct emac_dma_req *req = arg;
 	struct emac_board_info *db = req->db;
 	struct sk_buff *skb = req->skb;
-	struct net_device *dev = db->ndev;
+	struct net_device *ndev = db->ndev;
 	int rxlen = req->count;
 	u32 reg_val;
 
-	dma_unmap_single(db->dev, req->rxbuf, rxlen, DMA_FROM_DEVICE);
+	dma_unmap_single(db->dev, req->mapped_buf, rxlen, DMA_FROM_DEVICE);
 
-	skb->protocol = eth_type_trans(skb, dev);
+	skb->protocol = eth_type_trans(skb, ndev);
 	netif_rx(skb);
-	dev->stats.rx_bytes += rxlen;
+	ndev->stats.rx_bytes += rxlen;
 	/* Pass to upper layer */
-	dev->stats.rx_packets++;
+	ndev->stats.rx_packets++;
 
 	/* re enable cpu receive */
 	reg_val = readl(db->membase + EMAC_RX_CTL_REG);
@@ -264,48 +272,92 @@ static void emac_dma_done_callback(void *arg)
 
 	/* re enable interrupt */
 	reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-	reg_val |= (0x01 << 8);
+	reg_val |= EMAC_INT_CTL_RX_EN;
 	writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 
 	db->emacrx_completed_flag = 1;
 	emac_free_dma_req(req);
 }
 
-static int emac_dma_inblk_32bit(struct emac_board_info *db,
-		struct sk_buff *skb, void *rdptr, int count)
+
+static void emac_transfer_to_phy(struct emac_board_info* db, int channel)
+{
+	u32 reg = channel == 0 ? EMAC_TX_CTL0_REG : EMAC_TX_CTL1_REG;
+	writel(readl(db->membase + reg) | 1, db->membase + reg);
+	netif_trans_update(db->ndev);
+}
+
+
+static void emac_dma_tx_done_callback(void* arg)
+{
+	struct emac_dma_req *req = arg;
+	struct emac_board_info *db = req->db;
+	struct sk_buff *skb = req->skb;
+
+	emac_transfer_to_phy(db, req->channel);
+	dev_consume_skb_any(skb);
+
+	db->emactx_completed_flag = 1;
+	dev_info(db->dev, "emac xmit with dma done: channel = %d, len = %d\n", req->channel, req->count);
+	
+	emac_free_dma_req(req);
+}
+
+static int emac_dma_submit_request(
+		struct emac_board_info *db,
+		struct sk_buff *skb, void *buf,
+		int count, enum dma_transfer_direction dir,
+		int channel)
 {
+	int ret = 0;
 	struct dma_async_tx_descriptor *desc;
 	dma_cookie_t cookie;
-	dma_addr_t rxbuf;
+	dma_addr_t mapped_buf;
+	enum dma_data_direction data_dir;
+	struct dma_chan *chan;
 	struct emac_dma_req *req;
-	int ret = 0;
+	dma_async_tx_callback callback;
+	
+	if (dir == DMA_DEV_TO_MEM){
+		data_dir = DMA_FROM_DEVICE;
+		chan = db->rx_chan;
+		callback = emac_dma_rx_done_callback;
+	}else if (dir == DMA_MEM_TO_DEV){
+		data_dir = DMA_TO_DEVICE;
+		chan = db->tx_chan;
+		callback = emac_dma_tx_done_callback;
+	}else{
+		dev_err(db->dev, "emac dma transfer direction must be"
+				"DMA_FROM_DEVICE or DMA_TO_DEVICE\n");
+		return -EINVAL;
+	}
 
-	rxbuf = dma_map_single(db->dev, rdptr, count, DMA_FROM_DEVICE);
-	ret = dma_mapping_error(db->dev, rxbuf);
-	if (ret) {
-		dev_err(db->dev, "dma mapping error.\n");
+	mapped_buf = dma_map_single(db->dev, buf, count, data_dir);
+	ret = dma_mapping_error(db->dev, mapped_buf);
+	if (ret){
+		dev_err(db->dev, "dma mapping error\n");
 		return ret;
+	}	
+	
+	req = emac_alloc_dma_req(db, chan, skb, buf, mapped_buf, count, channel);
+	if (!req) {
+		dev_err(db->dev, "alloc emac dma req error.\n");
+		ret = -ENOMEM;
+		goto alloc_req_err;
 	}
 
-	desc = dmaengine_prep_slave_single(db->rx_chan, rxbuf, count,
-					   DMA_DEV_TO_MEM,
-					   DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	desc = dmaengine_prep_slave_single(chan, mapped_buf, count, dir,
+						DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+
 	if (!desc) {
 		dev_err(db->dev, "prepare slave single failed\n");
 		ret = -ENOMEM;
 		goto prepare_err;
 	}
 
-	req = emac_alloc_dma_req(db, desc, skb, rxbuf, count);
-	if (!req) {
-		dev_err(db->dev, "alloc emac dma req error.\n");
-		ret = -ENOMEM;
-		goto alloc_req_err;
-	}
-
 	desc->callback_param = req;
-	desc->callback = emac_dma_done_callback;
-
+	desc->callback = callback;
+	
 	cookie = dmaengine_submit(desc);
 	ret = dma_submit_error(cookie);
 	if (ret) {
@@ -313,20 +365,31 @@ static int emac_dma_inblk_32bit(struct emac_board_info *db,
 		goto submit_err;
 	}
 
-	dma_async_issue_pending(db->rx_chan);
+	dma_async_issue_pending(chan);
 	return ret;
 
 submit_err:
-	emac_free_dma_req(req);
-
-alloc_req_err:
 	dmaengine_desc_free(desc);
 
 prepare_err:
-	dma_unmap_single(db->dev, rxbuf, count, DMA_FROM_DEVICE);
+	dma_unmap_single(db->dev, req->mapped_buf, req->count, req->dir);
+
+alloc_req_err:
+	emac_free_dma_req(req);
 	return ret;
 }
 
+static int emac_dma_inblk_32bit(struct emac_board_info *db,
+		struct sk_buff *skb, void *rdptr, int count)
+{
+	return emac_dma_submit_request(db, skb, rdptr, count, DMA_DEV_TO_MEM, -1);
+}
+
+static int emac_dma_outblk_32bit(struct emac_board_info *db, struct sk_buff *skb, int channel)
+{
+	return emac_dma_submit_request(db, skb, skb->data, skb->len, DMA_MEM_TO_DEV, channel);
+}
+
 /* ethtool ops */
 static void emac_get_drvinfo(struct net_device *dev,
 			      struct ethtool_drvinfo *info)
@@ -506,7 +569,7 @@ static void emac_init_device(struct net_device *dev)
 
 	/* enable RX/TX0/RX Hlevel interrup */
 	reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-	reg_val |= (0xf << 0) | (0x01 << 8);
+	reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
 	writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 
 	spin_unlock_irqrestore(&db->lock, flags);
@@ -535,6 +598,13 @@ static void emac_timeout(struct net_device *dev, unsigned int txqueue)
 	spin_unlock_irqrestore(&db->lock, flags);
 }
 
+static void emac_set_packet_len(struct emac_board_info* db, int channel, int len)
+{
+	u32 reg = channel == 0 ? EMAC_TX_PL0_REG : EMAC_TX_PL1_REG;
+	/* set TX len */
+	writel(len, db->membase + reg);
+}
+
 /* Hardware start transmission.
  * Send a packet to media from the upper layer.
  */
@@ -543,9 +613,11 @@ static netdev_tx_t emac_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	struct emac_board_info *db = netdev_priv(dev);
 	unsigned long channel;
 	unsigned long flags;
+	u32 reg_val;
+	int len = skb->len;
 
 	channel = db->tx_fifo_stat & 3;
-	if (channel == 3)
+	if (channel == 3 || !db->emactx_completed_flag)
 		return NETDEV_TX_BUSY;
 
 	channel = (channel == 1 ? 1 : 0);
@@ -553,32 +625,27 @@ static netdev_tx_t emac_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	spin_lock_irqsave(&db->lock, flags);
 
 	writel(channel, db->membase + EMAC_TX_INS_REG);
+	
+	emac_set_packet_len(db, channel, len);
+
+	if (db->tx_chan){
+		reg_val = readl(db->membase + EMAC_TX_MODE_REG);
+		writel(reg_val | EMAC_TX_MODE_DMA_EN, db->membase + EMAC_TX_MODE_REG);
+		emac_dma_outblk_32bit(db, skb, channel);
+		db->emactx_completed_flag = 0;
+		dev_info(db->dev, "xmit with dma: channel = %lu, len = %d\n", channel, len);
+	}else{
+		reg_val = readl(db->membase + EMAC_TX_MODE_REG);
+		writel(reg_val & ~EMAC_TX_MODE_DMA_EN, db->membase + EMAC_TX_MODE_REG);
+		emac_outblk_32bit(db->membase + EMAC_TX_IO_DATA_REG, skb->data, len);
+
+		emac_transfer_to_phy(db, channel);
+		/* free this SKB */
+		dev_consume_skb_any(skb);
+	}
 
-	emac_outblk_32bit(db->membase + EMAC_TX_IO_DATA_REG,
-			skb->data, skb->len);
-	dev->stats.tx_bytes += skb->len;
-
+	dev->stats.tx_bytes += len;
 	db->tx_fifo_stat |= 1 << channel;
-	/* TX control: First packet immediately send, second packet queue */
-	if (channel == 0) {
-		/* set TX len */
-		writel(skb->len, db->membase + EMAC_TX_PL0_REG);
-		/* start translate from fifo to phy */
-		writel(readl(db->membase + EMAC_TX_CTL0_REG) | 1,
-		       db->membase + EMAC_TX_CTL0_REG);
-
-		/* save the time stamp */
-		netif_trans_update(dev);
-	} else if (channel == 1) {
-		/* set TX len */
-		writel(skb->len, db->membase + EMAC_TX_PL1_REG);
-		/* start translate from fifo to phy */
-		writel(readl(db->membase + EMAC_TX_CTL1_REG) | 1,
-		       db->membase + EMAC_TX_CTL1_REG);
-
-		/* save the time stamp */
-		netif_trans_update(dev);
-	}
 
 	if ((db->tx_fifo_stat & 3) == 3) {
 		/* Second packet */
@@ -587,9 +654,6 @@ static netdev_tx_t emac_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	spin_unlock_irqrestore(&db->lock, flags);
 
-	/* free this SKB */
-	dev_consume_skb_any(skb);
-
 	return NETDEV_TX_OK;
 }
 
@@ -637,7 +701,7 @@ static void emac_rx(struct net_device *dev)
 		if (!rxcount) {
 			db->emacrx_completed_flag = 1;
 			reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-			reg_val |= (0xf << 0) | (0x01 << 8);
+			reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
 			writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 
 			/* had one stuck? */
@@ -669,7 +733,7 @@ static void emac_rx(struct net_device *dev)
 			writel(reg_val | EMAC_CTL_RX_EN,
 			       db->membase + EMAC_CTL_REG);
 			reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-			reg_val |= (0xf << 0) | (0x01 << 8);
+			reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
 			writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 
 			db->emacrx_completed_flag = 1;
@@ -753,14 +817,14 @@ static void emac_rx(struct net_device *dev)
 }
 
 static irqreturn_t emac_interrupt(int irq, void *dev_id)
-{
+{	
 	struct net_device *dev = dev_id;
 	struct emac_board_info *db = netdev_priv(dev);
 	int int_status;
 	unsigned int reg_val;
 
 	/* A real interrupt coming */
-
+	
 	spin_lock(&db->lock);
 
 	/* Disable all interrupts */
@@ -776,27 +840,29 @@ static irqreturn_t emac_interrupt(int irq, void *dev_id)
 		dev_dbg(db->dev, "emac interrupt %02x\n", int_status);
 
 	/* Received the coming packet */
-	if ((int_status & 0x100) && (db->emacrx_completed_flag == 1)) {
+	if ((int_status & EMAC_INT_STA_RX_COMPLETE) && (db->emacrx_completed_flag == 1)) {
 		/* carrier lost */
 		db->emacrx_completed_flag = 0;
 		emac_rx(dev);
 	}
 
 	/* Transmit Interrupt check */
-	if (int_status & (0x01 | 0x02))
+	if (int_status & EMAC_INT_STA_TX_COMPLETE){
+		dev_info(db->dev, "emac tx interrupt, int_status = 0x%x\n", int_status);
 		emac_tx_done(dev, db, int_status);
+	}
 
-	if (int_status & (0x04 | 0x08))
+	if (int_status & EMAC_INT_STA_TX_ABRT)
 		netdev_info(dev, " ab : %x\n", int_status);
 
 	/* Re-enable interrupt mask */
 	if (db->emacrx_completed_flag == 1) {
 		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-		reg_val |= (0xf << 0) | (0x01 << 8);
+		reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
 		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 	} else {
 		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-		reg_val |= (0xf << 0);
+		reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN);
 		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 	}
 
@@ -904,56 +970,75 @@ static const struct net_device_ops emac_netdev_ops = {
 #endif
 };
 
-static int emac_configure_dma(struct emac_board_info *db)
+static int emac_configure_dma_channel(
+				struct device *dev,
+				const char *name,
+				phys_addr_t const fifo,
+				struct dma_chan **chan)
+{
+	int ret = 0;
+	struct dma_slave_config conf = {
+		.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
+		.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
+		.dst_maxburst = 4,
+		.src_maxburst = 4,
+		.device_fc = false
+	};
+
+	if (!strcmp(name, "rx")){
+		conf.direction = DMA_DEV_TO_MEM;
+		conf.src_addr = fifo;
+	} else if (!strcmp(name, "tx")) {
+		conf.direction = DMA_MEM_TO_DEV;
+		conf.dst_addr = fifo;
+	} else {
+		dev_err(dev, "emac dma channel must be rx or tx\n");
+		return -EINVAL;
+	}
+
+	*chan = dma_request_chan(dev, name);
+	ret = IS_ERR(*chan);
+	if (ret){
+		dev_err(dev, "request dma channel %s failed, ret = %d."
+				" dma %s channel is disabled\n", name, ret, name);
+		*chan = NULL;
+		return ret;
+	}
+
+	ret = dmaengine_slave_config(*chan, &conf);
+	if (ret) {
+		dev_err(dev, "config %s dma slave failed, ret = %d."
+				" dma %s channel is disabled\n", name, ret, name);
+		dma_release_channel(*chan);
+		*chan = NULL;
+	}
+
+	return ret;
+}
+
+static void emac_configure_dma(struct emac_board_info *db)
 {
 	struct platform_device *pdev = db->pdev;
-	struct net_device *ndev = db->ndev;
-	struct dma_slave_config conf = {};
+	struct device* dev = db->dev;
 	struct resource *regs;
-	int err = 0;
+
+	db->rx_chan = NULL;
+	db->tx_chan = NULL;
 
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!regs) {
-		netdev_err(ndev, "get io resource from device failed.\n");
-		err = -ENOMEM;
-		goto out_clear_chan;
+		dev_err(dev, "get io resource from device failed.\n");
+		return;
 	}
 
-	netdev_info(ndev, "get io resource from device: 0x%x, size = %u\n",
+	dev_info(dev, "get io resource from device: 0x%x, size = %u\n",
 		    regs->start, resource_size(regs));
-	db->emac_rx_fifo = regs->start + EMAC_RX_IO_DATA_REG;
-
-	db->rx_chan = dma_request_chan(&pdev->dev, "rx");
-	if (IS_ERR(db->rx_chan)) {
-		netdev_err(ndev,
-			   "failed to request dma channel. dma is disabled\n");
-		err = PTR_ERR(db->rx_chan);
-		goto out_clear_chan;
-	}
-
-	conf.direction = DMA_DEV_TO_MEM;
-	conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
-	conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
-	conf.src_addr = db->emac_rx_fifo;
-	conf.dst_maxburst = 4;
-	conf.src_maxburst = 4;
-	conf.device_fc = false;
-
-	err = dmaengine_slave_config(db->rx_chan, &conf);
-	if (err) {
-		netdev_err(ndev, "config dma slave failed\n");
-		err = -EINVAL;
-		goto out_slave_configure_err;
-	}
 
-	return err;
-
-out_slave_configure_err:
-	dma_release_channel(db->rx_chan);
+	db->emac_rx_fifo = regs->start + EMAC_RX_IO_DATA_REG;
+	db->emac_tx_fifo = regs->start + EMAC_TX_IO_DATA_REG;
 
-out_clear_chan:
-	db->rx_chan = NULL;
-	return err;
+	emac_configure_dma_channel(dev, "rx", db->emac_rx_fifo, &db->rx_chan);
+	emac_configure_dma_channel(dev, "tx", db->emac_tx_fifo, &db->tx_chan);
 }
 
 /* Search EMAC board, allocate space and register it
@@ -998,8 +1083,7 @@ static int emac_probe(struct platform_device *pdev)
 		goto out_iounmap;
 	}
 
-	if (emac_configure_dma(db))
-		netdev_info(ndev, "configure dma failed. disable dma.\n");
+	emac_configure_dma(db);
 
 	db->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(db->clk)) {
@@ -1038,6 +1122,7 @@ static int emac_probe(struct platform_device *pdev)
 	}
 
 	db->emacrx_completed_flag = 1;
+	db->emactx_completed_flag = 1;
 	emac_powerup(ndev);
 	emac_reset(db);
 
@@ -1088,6 +1173,11 @@ static int emac_remove(struct platform_device *pdev)
 		dma_release_channel(db->rx_chan);
 	}
 
+	if (db->tx_chan){
+		dmaengine_terminate_all(db->tx_chan);
+		dma_release_channel(db->tx_chan);
+	}
+
 	unregister_netdev(ndev);
 	sunxi_sram_release(&pdev->dev);
 	clk_disable_unprepare(db->clk);
diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.h b/drivers/net/ethernet/allwinner/sun4i-emac.h
index 38c72d9ec600..14914110d9b0 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.h
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.h
@@ -61,7 +61,21 @@
 #define EMAC_RX_IO_DATA_STATUS_OK	(1 << 7)
 #define EMAC_RX_FBC_REG		(0x50)
 #define EMAC_INT_CTL_REG	(0x54)
+#define EMAC_INT_CTL_RX_EN	(1 << 8)
+#define EMAC_INT_CTL_TX0_EN	(1)
+#define EMAC_INT_CTL_TX1_EN	(1 << 1)
+#define EMAC_INT_CTL_TX_EN	(EMAC_INT_CTL_TX0_EN | EMAC_INT_CTL_TX1_EN)
+#define EMAC_INT_CTL_TX0_ABRT_EN	(0x1 << 2)
+#define EMAC_INT_CTL_TX1_ABRT_EN	(0x1 << 3)
+#define EMAC_INT_CTL_TX_ABRT_EN	(EMAC_INT_CTL_TX0_ABRT_EN | EMAC_INT_CTL_TX1_ABRT_EN)
 #define EMAC_INT_STA_REG	(0x58)
+#define EMAC_INT_STA_TX0_COMPLETE	(0x1)
+#define EMAC_INT_STA_TX1_COMPLETE	(0x1 << 1)
+#define EMAC_INT_STA_TX_COMPLETE	(EMAC_INT_STA_TX0_COMPLETE | EMAC_INT_STA_TX1_COMPLETE)
+#define EMAC_INT_STA_TX0_ABRT	(0x1 << 2)
+#define EMAC_INT_STA_TX1_ABRT	(0x1 << 3)
+#define EMAC_INT_STA_TX_ABRT	(EMAC_INT_STA_TX0_ABRT | EMAC_INT_STA_TX1_ABRT)
+#define EMAC_INT_STA_RX_COMPLETE	(0x1 << 8)
 #define EMAC_MAC_CTL0_REG	(0x5c)
 #define EMAC_MAC_CTL0_RX_FLOW_CTL_EN	(1 << 2)
 #define EMAC_MAC_CTL0_TX_FLOW_CTL_EN	(1 << 3)
-- 
2.31.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v1] sun4i-emac.c: enable emac tx dma
@ 2022-01-09  9:17                   ` conleylee
  0 siblings, 0 replies; 33+ messages in thread
From: conleylee @ 2022-01-09  9:17 UTC (permalink / raw)
  To: clabbe.montjoie
  Cc: davem, mripard, wens, jernej.skrabec, netdev, linux-arm-kernel,
	linux-sunxi, linux-kernel, conley

From: conley <conleylee@foxmail.com>

Hello
I am reading the R40 user manual and trying to create a new path to enable
emac tx dma channel. According to the figure 8-21(TX Operation Diagram),
I try to enable emac tx dma channel by the follow steps:
1. enable tx dma mode
2. set packet lengths
2. move data from skb to tx fifo by using dma in xmit function.
3. start transfer from tx fifo to phy in dma tx done callback

But it doesn't work. emac tx interrupt and dma finished interrupt are
raised, but no packets are transmitted (I test it by tcpdump).
Do you know how to configure the emac tx dma correctly? Thanks ~

Signed-off-by: conley <conleylee@foxmail.com>
---
 drivers/net/ethernet/allwinner/sun4i-emac.c | 324 +++++++++++++-------
 drivers/net/ethernet/allwinner/sun4i-emac.h |  14 +
 2 files changed, 221 insertions(+), 117 deletions(-)

diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
index 964227e342ee..fcd7848f64a0 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -80,6 +80,7 @@ struct emac_board_info {
 	u16			tx_fifo_stat;
 
 	int			emacrx_completed_flag;
+	int 			emactx_completed_flag;
 
 	struct device_node	*phy_node;
 	unsigned int		link;
@@ -88,15 +89,20 @@ struct emac_board_info {
 
 	phy_interface_t		phy_interface;
 	struct dma_chan	*rx_chan;
+	struct dma_chan	*tx_chan;
 	phys_addr_t emac_rx_fifo;
+	phys_addr_t emac_tx_fifo;
 };
 
 struct emac_dma_req {
 	struct emac_board_info *db;
-	struct dma_async_tx_descriptor *desc;
+	struct dma_chan *chan;
 	struct sk_buff *skb;
-	dma_addr_t rxbuf;
+	void* buf;
+	dma_addr_t mapped_buf;
 	int count;
+	enum dma_data_direction dir;
+	int channel; // for tx
 };
 
 static void emac_update_speed(struct net_device *dev)
@@ -218,8 +224,9 @@ static void emac_inblk_32bit(void __iomem *reg, void *data, int count)
 
 static struct emac_dma_req *
 emac_alloc_dma_req(struct emac_board_info *db,
-		   struct dma_async_tx_descriptor *desc, struct sk_buff *skb,
-		   dma_addr_t rxbuf, int count)
+		struct dma_chan* chan,
+		struct sk_buff *skb, void* buf,
+		dma_addr_t mapped_buf, int count, int channel)
 {
 	struct emac_dma_req *req;
 
@@ -228,9 +235,10 @@ emac_alloc_dma_req(struct emac_board_info *db,
 		return NULL;
 
 	req->db = db;
-	req->desc = desc;
+	req->chan = chan;
 	req->skb = skb;
-	req->rxbuf = rxbuf;
+	req->buf = buf;
+	req->mapped_buf = mapped_buf;
 	req->count = count;
 	return req;
 }
@@ -240,22 +248,22 @@ static void emac_free_dma_req(struct emac_dma_req *req)
 	kfree(req);
 }
 
-static void emac_dma_done_callback(void *arg)
+static void emac_dma_rx_done_callback(void *arg)
 {
 	struct emac_dma_req *req = arg;
 	struct emac_board_info *db = req->db;
 	struct sk_buff *skb = req->skb;
-	struct net_device *dev = db->ndev;
+	struct net_device *ndev = db->ndev;
 	int rxlen = req->count;
 	u32 reg_val;
 
-	dma_unmap_single(db->dev, req->rxbuf, rxlen, DMA_FROM_DEVICE);
+	dma_unmap_single(db->dev, req->mapped_buf, rxlen, DMA_FROM_DEVICE);
 
-	skb->protocol = eth_type_trans(skb, dev);
+	skb->protocol = eth_type_trans(skb, ndev);
 	netif_rx(skb);
-	dev->stats.rx_bytes += rxlen;
+	ndev->stats.rx_bytes += rxlen;
 	/* Pass to upper layer */
-	dev->stats.rx_packets++;
+	ndev->stats.rx_packets++;
 
 	/* re enable cpu receive */
 	reg_val = readl(db->membase + EMAC_RX_CTL_REG);
@@ -264,48 +272,92 @@ static void emac_dma_done_callback(void *arg)
 
 	/* re enable interrupt */
 	reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-	reg_val |= (0x01 << 8);
+	reg_val |= EMAC_INT_CTL_RX_EN;
 	writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 
 	db->emacrx_completed_flag = 1;
 	emac_free_dma_req(req);
 }
 
-static int emac_dma_inblk_32bit(struct emac_board_info *db,
-		struct sk_buff *skb, void *rdptr, int count)
+
+static void emac_transfer_to_phy(struct emac_board_info* db, int channel)
+{
+	u32 reg = channel == 0 ? EMAC_TX_CTL0_REG : EMAC_TX_CTL1_REG;
+	writel(readl(db->membase + reg) | 1, db->membase + reg);
+	netif_trans_update(db->ndev);
+}
+
+
+static void emac_dma_tx_done_callback(void* arg)
+{
+	struct emac_dma_req *req = arg;
+	struct emac_board_info *db = req->db;
+	struct sk_buff *skb = req->skb;
+
+	emac_transfer_to_phy(db, req->channel);
+	dev_consume_skb_any(skb);
+
+	db->emactx_completed_flag = 1;
+	dev_info(db->dev, "emac xmit with dma done: channel = %d, len = %d\n", req->channel, req->count);
+	
+	emac_free_dma_req(req);
+}
+
+static int emac_dma_submit_request(
+		struct emac_board_info *db,
+		struct sk_buff *skb, void *buf,
+		int count, enum dma_transfer_direction dir,
+		int channel)
 {
+	int ret = 0;
 	struct dma_async_tx_descriptor *desc;
 	dma_cookie_t cookie;
-	dma_addr_t rxbuf;
+	dma_addr_t mapped_buf;
+	enum dma_data_direction data_dir;
+	struct dma_chan *chan;
 	struct emac_dma_req *req;
-	int ret = 0;
+	dma_async_tx_callback callback;
+	
+	if (dir == DMA_DEV_TO_MEM){
+		data_dir = DMA_FROM_DEVICE;
+		chan = db->rx_chan;
+		callback = emac_dma_rx_done_callback;
+	}else if (dir == DMA_MEM_TO_DEV){
+		data_dir = DMA_TO_DEVICE;
+		chan = db->tx_chan;
+		callback = emac_dma_tx_done_callback;
+	}else{
+		dev_err(db->dev, "emac dma transfer direction must be"
+				"DMA_FROM_DEVICE or DMA_TO_DEVICE\n");
+		return -EINVAL;
+	}
 
-	rxbuf = dma_map_single(db->dev, rdptr, count, DMA_FROM_DEVICE);
-	ret = dma_mapping_error(db->dev, rxbuf);
-	if (ret) {
-		dev_err(db->dev, "dma mapping error.\n");
+	mapped_buf = dma_map_single(db->dev, buf, count, data_dir);
+	ret = dma_mapping_error(db->dev, mapped_buf);
+	if (ret){
+		dev_err(db->dev, "dma mapping error\n");
 		return ret;
+	}	
+	
+	req = emac_alloc_dma_req(db, chan, skb, buf, mapped_buf, count, channel);
+	if (!req) {
+		dev_err(db->dev, "alloc emac dma req error.\n");
+		ret = -ENOMEM;
+		goto alloc_req_err;
 	}
 
-	desc = dmaengine_prep_slave_single(db->rx_chan, rxbuf, count,
-					   DMA_DEV_TO_MEM,
-					   DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	desc = dmaengine_prep_slave_single(chan, mapped_buf, count, dir,
+						DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+
 	if (!desc) {
 		dev_err(db->dev, "prepare slave single failed\n");
 		ret = -ENOMEM;
 		goto prepare_err;
 	}
 
-	req = emac_alloc_dma_req(db, desc, skb, rxbuf, count);
-	if (!req) {
-		dev_err(db->dev, "alloc emac dma req error.\n");
-		ret = -ENOMEM;
-		goto alloc_req_err;
-	}
-
 	desc->callback_param = req;
-	desc->callback = emac_dma_done_callback;
-
+	desc->callback = callback;
+	
 	cookie = dmaengine_submit(desc);
 	ret = dma_submit_error(cookie);
 	if (ret) {
@@ -313,20 +365,31 @@ static int emac_dma_inblk_32bit(struct emac_board_info *db,
 		goto submit_err;
 	}
 
-	dma_async_issue_pending(db->rx_chan);
+	dma_async_issue_pending(chan);
 	return ret;
 
 submit_err:
-	emac_free_dma_req(req);
-
-alloc_req_err:
 	dmaengine_desc_free(desc);
 
 prepare_err:
-	dma_unmap_single(db->dev, rxbuf, count, DMA_FROM_DEVICE);
+	dma_unmap_single(db->dev, req->mapped_buf, req->count, req->dir);
+
+alloc_req_err:
+	emac_free_dma_req(req);
 	return ret;
 }
 
+static int emac_dma_inblk_32bit(struct emac_board_info *db,
+		struct sk_buff *skb, void *rdptr, int count)
+{
+	return emac_dma_submit_request(db, skb, rdptr, count, DMA_DEV_TO_MEM, -1);
+}
+
+static int emac_dma_outblk_32bit(struct emac_board_info *db, struct sk_buff *skb, int channel)
+{
+	return emac_dma_submit_request(db, skb, skb->data, skb->len, DMA_MEM_TO_DEV, channel);
+}
+
 /* ethtool ops */
 static void emac_get_drvinfo(struct net_device *dev,
 			      struct ethtool_drvinfo *info)
@@ -506,7 +569,7 @@ static void emac_init_device(struct net_device *dev)
 
 	/* enable RX/TX0/RX Hlevel interrup */
 	reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-	reg_val |= (0xf << 0) | (0x01 << 8);
+	reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
 	writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 
 	spin_unlock_irqrestore(&db->lock, flags);
@@ -535,6 +598,13 @@ static void emac_timeout(struct net_device *dev, unsigned int txqueue)
 	spin_unlock_irqrestore(&db->lock, flags);
 }
 
+static void emac_set_packet_len(struct emac_board_info* db, int channel, int len)
+{
+	u32 reg = channel == 0 ? EMAC_TX_PL0_REG : EMAC_TX_PL1_REG;
+	/* set TX len */
+	writel(len, db->membase + reg);
+}
+
 /* Hardware start transmission.
  * Send a packet to media from the upper layer.
  */
@@ -543,9 +613,11 @@ static netdev_tx_t emac_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	struct emac_board_info *db = netdev_priv(dev);
 	unsigned long channel;
 	unsigned long flags;
+	u32 reg_val;
+	int len = skb->len;
 
 	channel = db->tx_fifo_stat & 3;
-	if (channel == 3)
+	if (channel == 3 || !db->emactx_completed_flag)
 		return NETDEV_TX_BUSY;
 
 	channel = (channel == 1 ? 1 : 0);
@@ -553,32 +625,27 @@ static netdev_tx_t emac_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	spin_lock_irqsave(&db->lock, flags);
 
 	writel(channel, db->membase + EMAC_TX_INS_REG);
+	
+	emac_set_packet_len(db, channel, len);
+
+	if (db->tx_chan){
+		reg_val = readl(db->membase + EMAC_TX_MODE_REG);
+		writel(reg_val | EMAC_TX_MODE_DMA_EN, db->membase + EMAC_TX_MODE_REG);
+		emac_dma_outblk_32bit(db, skb, channel);
+		db->emactx_completed_flag = 0;
+		dev_info(db->dev, "xmit with dma: channel = %lu, len = %d\n", channel, len);
+	}else{
+		reg_val = readl(db->membase + EMAC_TX_MODE_REG);
+		writel(reg_val & ~EMAC_TX_MODE_DMA_EN, db->membase + EMAC_TX_MODE_REG);
+		emac_outblk_32bit(db->membase + EMAC_TX_IO_DATA_REG, skb->data, len);
+
+		emac_transfer_to_phy(db, channel);
+		/* free this SKB */
+		dev_consume_skb_any(skb);
+	}
 
-	emac_outblk_32bit(db->membase + EMAC_TX_IO_DATA_REG,
-			skb->data, skb->len);
-	dev->stats.tx_bytes += skb->len;
-
+	dev->stats.tx_bytes += len;
 	db->tx_fifo_stat |= 1 << channel;
-	/* TX control: First packet immediately send, second packet queue */
-	if (channel == 0) {
-		/* set TX len */
-		writel(skb->len, db->membase + EMAC_TX_PL0_REG);
-		/* start translate from fifo to phy */
-		writel(readl(db->membase + EMAC_TX_CTL0_REG) | 1,
-		       db->membase + EMAC_TX_CTL0_REG);
-
-		/* save the time stamp */
-		netif_trans_update(dev);
-	} else if (channel == 1) {
-		/* set TX len */
-		writel(skb->len, db->membase + EMAC_TX_PL1_REG);
-		/* start translate from fifo to phy */
-		writel(readl(db->membase + EMAC_TX_CTL1_REG) | 1,
-		       db->membase + EMAC_TX_CTL1_REG);
-
-		/* save the time stamp */
-		netif_trans_update(dev);
-	}
 
 	if ((db->tx_fifo_stat & 3) == 3) {
 		/* Second packet */
@@ -587,9 +654,6 @@ static netdev_tx_t emac_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	spin_unlock_irqrestore(&db->lock, flags);
 
-	/* free this SKB */
-	dev_consume_skb_any(skb);
-
 	return NETDEV_TX_OK;
 }
 
@@ -637,7 +701,7 @@ static void emac_rx(struct net_device *dev)
 		if (!rxcount) {
 			db->emacrx_completed_flag = 1;
 			reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-			reg_val |= (0xf << 0) | (0x01 << 8);
+			reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
 			writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 
 			/* had one stuck? */
@@ -669,7 +733,7 @@ static void emac_rx(struct net_device *dev)
 			writel(reg_val | EMAC_CTL_RX_EN,
 			       db->membase + EMAC_CTL_REG);
 			reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-			reg_val |= (0xf << 0) | (0x01 << 8);
+			reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
 			writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 
 			db->emacrx_completed_flag = 1;
@@ -753,14 +817,14 @@ static void emac_rx(struct net_device *dev)
 }
 
 static irqreturn_t emac_interrupt(int irq, void *dev_id)
-{
+{	
 	struct net_device *dev = dev_id;
 	struct emac_board_info *db = netdev_priv(dev);
 	int int_status;
 	unsigned int reg_val;
 
 	/* A real interrupt coming */
-
+	
 	spin_lock(&db->lock);
 
 	/* Disable all interrupts */
@@ -776,27 +840,29 @@ static irqreturn_t emac_interrupt(int irq, void *dev_id)
 		dev_dbg(db->dev, "emac interrupt %02x\n", int_status);
 
 	/* Received the coming packet */
-	if ((int_status & 0x100) && (db->emacrx_completed_flag == 1)) {
+	if ((int_status & EMAC_INT_STA_RX_COMPLETE) && (db->emacrx_completed_flag == 1)) {
 		/* carrier lost */
 		db->emacrx_completed_flag = 0;
 		emac_rx(dev);
 	}
 
 	/* Transmit Interrupt check */
-	if (int_status & (0x01 | 0x02))
+	if (int_status & EMAC_INT_STA_TX_COMPLETE){
+		dev_info(db->dev, "emac tx interrupt, int_status = 0x%x\n", int_status);
 		emac_tx_done(dev, db, int_status);
+	}
 
-	if (int_status & (0x04 | 0x08))
+	if (int_status & EMAC_INT_STA_TX_ABRT)
 		netdev_info(dev, " ab : %x\n", int_status);
 
 	/* Re-enable interrupt mask */
 	if (db->emacrx_completed_flag == 1) {
 		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-		reg_val |= (0xf << 0) | (0x01 << 8);
+		reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
 		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 	} else {
 		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-		reg_val |= (0xf << 0);
+		reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN);
 		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 	}
 
@@ -904,56 +970,75 @@ static const struct net_device_ops emac_netdev_ops = {
 #endif
 };
 
-static int emac_configure_dma(struct emac_board_info *db)
+static int emac_configure_dma_channel(
+				struct device *dev,
+				const char *name,
+				phys_addr_t const fifo,
+				struct dma_chan **chan)
+{
+	int ret = 0;
+	struct dma_slave_config conf = {
+		.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
+		.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
+		.dst_maxburst = 4,
+		.src_maxburst = 4,
+		.device_fc = false
+	};
+
+	if (!strcmp(name, "rx")){
+		conf.direction = DMA_DEV_TO_MEM;
+		conf.src_addr = fifo;
+	} else if (!strcmp(name, "tx")) {
+		conf.direction = DMA_MEM_TO_DEV;
+		conf.dst_addr = fifo;
+	} else {
+		dev_err(dev, "emac dma channel must be rx or tx\n");
+		return -EINVAL;
+	}
+
+	*chan = dma_request_chan(dev, name);
+	ret = IS_ERR(*chan);
+	if (ret){
+		dev_err(dev, "request dma channel %s failed, ret = %d."
+				" dma %s channel is disabled\n", name, ret, name);
+		*chan = NULL;
+		return ret;
+	}
+
+	ret = dmaengine_slave_config(*chan, &conf);
+	if (ret) {
+		dev_err(dev, "config %s dma slave failed, ret = %d."
+				" dma %s channel is disabled\n", name, ret, name);
+		dma_release_channel(*chan);
+		*chan = NULL;
+	}
+
+	return ret;
+}
+
+static void emac_configure_dma(struct emac_board_info *db)
 {
 	struct platform_device *pdev = db->pdev;
-	struct net_device *ndev = db->ndev;
-	struct dma_slave_config conf = {};
+	struct device* dev = db->dev;
 	struct resource *regs;
-	int err = 0;
+
+	db->rx_chan = NULL;
+	db->tx_chan = NULL;
 
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!regs) {
-		netdev_err(ndev, "get io resource from device failed.\n");
-		err = -ENOMEM;
-		goto out_clear_chan;
+		dev_err(dev, "get io resource from device failed.\n");
+		return;
 	}
 
-	netdev_info(ndev, "get io resource from device: 0x%x, size = %u\n",
+	dev_info(dev, "get io resource from device: 0x%x, size = %u\n",
 		    regs->start, resource_size(regs));
-	db->emac_rx_fifo = regs->start + EMAC_RX_IO_DATA_REG;
-
-	db->rx_chan = dma_request_chan(&pdev->dev, "rx");
-	if (IS_ERR(db->rx_chan)) {
-		netdev_err(ndev,
-			   "failed to request dma channel. dma is disabled\n");
-		err = PTR_ERR(db->rx_chan);
-		goto out_clear_chan;
-	}
-
-	conf.direction = DMA_DEV_TO_MEM;
-	conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
-	conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
-	conf.src_addr = db->emac_rx_fifo;
-	conf.dst_maxburst = 4;
-	conf.src_maxburst = 4;
-	conf.device_fc = false;
-
-	err = dmaengine_slave_config(db->rx_chan, &conf);
-	if (err) {
-		netdev_err(ndev, "config dma slave failed\n");
-		err = -EINVAL;
-		goto out_slave_configure_err;
-	}
 
-	return err;
-
-out_slave_configure_err:
-	dma_release_channel(db->rx_chan);
+	db->emac_rx_fifo = regs->start + EMAC_RX_IO_DATA_REG;
+	db->emac_tx_fifo = regs->start + EMAC_TX_IO_DATA_REG;
 
-out_clear_chan:
-	db->rx_chan = NULL;
-	return err;
+	emac_configure_dma_channel(dev, "rx", db->emac_rx_fifo, &db->rx_chan);
+	emac_configure_dma_channel(dev, "tx", db->emac_tx_fifo, &db->tx_chan);
 }
 
 /* Search EMAC board, allocate space and register it
@@ -998,8 +1083,7 @@ static int emac_probe(struct platform_device *pdev)
 		goto out_iounmap;
 	}
 
-	if (emac_configure_dma(db))
-		netdev_info(ndev, "configure dma failed. disable dma.\n");
+	emac_configure_dma(db);
 
 	db->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(db->clk)) {
@@ -1038,6 +1122,7 @@ static int emac_probe(struct platform_device *pdev)
 	}
 
 	db->emacrx_completed_flag = 1;
+	db->emactx_completed_flag = 1;
 	emac_powerup(ndev);
 	emac_reset(db);
 
@@ -1088,6 +1173,11 @@ static int emac_remove(struct platform_device *pdev)
 		dma_release_channel(db->rx_chan);
 	}
 
+	if (db->tx_chan){
+		dmaengine_terminate_all(db->tx_chan);
+		dma_release_channel(db->tx_chan);
+	}
+
 	unregister_netdev(ndev);
 	sunxi_sram_release(&pdev->dev);
 	clk_disable_unprepare(db->clk);
diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.h b/drivers/net/ethernet/allwinner/sun4i-emac.h
index 38c72d9ec600..14914110d9b0 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.h
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.h
@@ -61,7 +61,21 @@
 #define EMAC_RX_IO_DATA_STATUS_OK	(1 << 7)
 #define EMAC_RX_FBC_REG		(0x50)
 #define EMAC_INT_CTL_REG	(0x54)
+#define EMAC_INT_CTL_RX_EN	(1 << 8)
+#define EMAC_INT_CTL_TX0_EN	(1)
+#define EMAC_INT_CTL_TX1_EN	(1 << 1)
+#define EMAC_INT_CTL_TX_EN	(EMAC_INT_CTL_TX0_EN | EMAC_INT_CTL_TX1_EN)
+#define EMAC_INT_CTL_TX0_ABRT_EN	(0x1 << 2)
+#define EMAC_INT_CTL_TX1_ABRT_EN	(0x1 << 3)
+#define EMAC_INT_CTL_TX_ABRT_EN	(EMAC_INT_CTL_TX0_ABRT_EN | EMAC_INT_CTL_TX1_ABRT_EN)
 #define EMAC_INT_STA_REG	(0x58)
+#define EMAC_INT_STA_TX0_COMPLETE	(0x1)
+#define EMAC_INT_STA_TX1_COMPLETE	(0x1 << 1)
+#define EMAC_INT_STA_TX_COMPLETE	(EMAC_INT_STA_TX0_COMPLETE | EMAC_INT_STA_TX1_COMPLETE)
+#define EMAC_INT_STA_TX0_ABRT	(0x1 << 2)
+#define EMAC_INT_STA_TX1_ABRT	(0x1 << 3)
+#define EMAC_INT_STA_TX_ABRT	(EMAC_INT_STA_TX0_ABRT | EMAC_INT_STA_TX1_ABRT)
+#define EMAC_INT_STA_RX_COMPLETE	(0x1 << 8)
 #define EMAC_MAC_CTL0_REG	(0x5c)
 #define EMAC_MAC_CTL0_RX_FLOW_CTL_EN	(1 << 2)
 #define EMAC_MAC_CTL0_TX_FLOW_CTL_EN	(1 << 3)
-- 
2.31.1


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

* Re: [PATCH v1] sun4i-emac.c: enable emac tx dma
  2022-01-09  9:17                   ` conleylee
@ 2022-01-09 20:45                     ` Corentin Labbe
  -1 siblings, 0 replies; 33+ messages in thread
From: Corentin Labbe @ 2022-01-09 20:45 UTC (permalink / raw)
  To: conleylee
  Cc: davem, mripard, wens, jernej.skrabec, netdev, linux-arm-kernel,
	linux-sunxi, linux-kernel

Le Sun, Jan 09, 2022 at 05:17:55PM +0800, conleylee@foxmail.com a écrit :
> From: conley <conleylee@foxmail.com>
> 
> Hello
> I am reading the R40 user manual and trying to create a new path to enable
> emac tx dma channel. According to the figure 8-21(TX Operation Diagram),
> I try to enable emac tx dma channel by the follow steps:
> 1. enable tx dma mode
> 2. set packet lengths
> 2. move data from skb to tx fifo by using dma in xmit function.
> 3. start transfer from tx fifo to phy in dma tx done callback
> 
> But it doesn't work. emac tx interrupt and dma finished interrupt are
> raised, but no packets are transmitted (I test it by tcpdump).
> Do you know how to configure the emac tx dma correctly? Thanks ~
> 

Hello

Here are my thoughts to help you:
- Your email is not a real patch, but an ask for help, so you should not use [ PATCH ] in the subject.
- If it was a patch, "v1" is not necessary
- Your patch below is doing too many unrelated different things, it is hard to see the DMA TX enable part
- I think you could first send a preliminary patch which adds all EMAC_INT_CTL_TX_xxx which are already used by the driver (to reduce the diff)
- Without the DTB change, it is hard to see the whole picture, did you correctly use the right dma number for an easy example.
- Knowing also the board (and so PHY, modes etc...) could help
- I think your priority should not to add TX, but to fix reported problems to your initial patch (build warnings/error https://marc.info/?l=linux-arm-kernel&m=164159846213585&w=2) since your work on TX will need to be applied after this.
- For the previous point, always build test with at least 2 different 32/64 arch. And if possible a total different arch (like x86_64).

Anyway, I will try to test your patch on my a10 board

Regards

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

* Re: [PATCH v1] sun4i-emac.c: enable emac tx dma
@ 2022-01-09 20:45                     ` Corentin Labbe
  0 siblings, 0 replies; 33+ messages in thread
From: Corentin Labbe @ 2022-01-09 20:45 UTC (permalink / raw)
  To: conleylee
  Cc: davem, mripard, wens, jernej.skrabec, netdev, linux-arm-kernel,
	linux-sunxi, linux-kernel

Le Sun, Jan 09, 2022 at 05:17:55PM +0800, conleylee@foxmail.com a écrit :
> From: conley <conleylee@foxmail.com>
> 
> Hello
> I am reading the R40 user manual and trying to create a new path to enable
> emac tx dma channel. According to the figure 8-21(TX Operation Diagram),
> I try to enable emac tx dma channel by the follow steps:
> 1. enable tx dma mode
> 2. set packet lengths
> 2. move data from skb to tx fifo by using dma in xmit function.
> 3. start transfer from tx fifo to phy in dma tx done callback
> 
> But it doesn't work. emac tx interrupt and dma finished interrupt are
> raised, but no packets are transmitted (I test it by tcpdump).
> Do you know how to configure the emac tx dma correctly? Thanks ~
> 

Hello

Here are my thoughts to help you:
- Your email is not a real patch, but an ask for help, so you should not use [ PATCH ] in the subject.
- If it was a patch, "v1" is not necessary
- Your patch below is doing too many unrelated different things, it is hard to see the DMA TX enable part
- I think you could first send a preliminary patch which adds all EMAC_INT_CTL_TX_xxx which are already used by the driver (to reduce the diff)
- Without the DTB change, it is hard to see the whole picture, did you correctly use the right dma number for an easy example.
- Knowing also the board (and so PHY, modes etc...) could help
- I think your priority should not to add TX, but to fix reported problems to your initial patch (build warnings/error https://marc.info/?l=linux-arm-kernel&m=164159846213585&w=2) since your work on TX will need to be applied after this.
- For the previous point, always build test with at least 2 different 32/64 arch. And if possible a total different arch (like x86_64).

Anyway, I will try to test your patch on my a10 board

Regards

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v1] sun4i-emac.c: enable emac tx dma
  2022-01-09 20:45                     ` Corentin Labbe
@ 2022-01-10  7:47                       ` Conley Lee
  -1 siblings, 0 replies; 33+ messages in thread
From: Conley Lee @ 2022-01-10  7:47 UTC (permalink / raw)
  To: Corentin Labbe
  Cc: davem, mripard, wens, jernej.skrabec, netdev, linux-arm-kernel,
	linux-sunxi, linux-kernel

On 01/09/22 at 09:45下午, Corentin Labbe wrote:
> Date: Sun, 9 Jan 2022 21:45:01 +0100
> From: Corentin Labbe <clabbe.montjoie@gmail.com>
> To: conleylee@foxmail.com
> Cc: davem@davemloft.net, mripard@kernel.org, wens@csie.org,
>  jernej.skrabec@gmail.com, netdev@vger.kernel.org,
>  linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev,
>  linux-kernel@vger.kernel.org
> Subject: Re: [PATCH v1] sun4i-emac.c: enable emac tx dma
> 
> Le Sun, Jan 09, 2022 at 05:17:55PM +0800, conleylee@foxmail.com a écrit :
> > From: conley <conleylee@foxmail.com>
> > 
> > Hello
> > I am reading the R40 user manual and trying to create a new path to enable
> > emac tx dma channel. According to the figure 8-21(TX Operation Diagram),
> > I try to enable emac tx dma channel by the follow steps:
> > 1. enable tx dma mode
> > 2. set packet lengths
> > 2. move data from skb to tx fifo by using dma in xmit function.
> > 3. start transfer from tx fifo to phy in dma tx done callback
> > 
> > But it doesn't work. emac tx interrupt and dma finished interrupt are
> > raised, but no packets are transmitted (I test it by tcpdump).
> > Do you know how to configure the emac tx dma correctly? Thanks ~
> > 
> 
> Hello
> 
> Here are my thoughts to help you:
> - Your email is not a real patch, but an ask for help, so you should not use [ PATCH ] in the subject.
> - If it was a patch, "v1" is not necessary
> - Your patch below is doing too many unrelated different things, it is hard to see the DMA TX enable part
> - I think you could first send a preliminary patch which adds all EMAC_INT_CTL_TX_xxx which are already used by the driver (to reduce the diff)
> - Without the DTB change, it is hard to see the whole picture, did you correctly use the right dma number for an easy example.
> - Knowing also the board (and so PHY, modes etc...) could help
> - I think your priority should not to add TX, but to fix reported problems to your initial patch (build warnings/error https://marc.info/?l=linux-arm-kernel&m=164159846213585&w=2) since your work on TX will need to be applied after this.
> - For the previous point, always build test with at least 2 different 32/64 arch. And if possible a total different arch (like x86_64).
> 
> Anyway, I will try to test your patch on my a10 board
> 
> Regards
Thanks a lot for your help ~ I will submit an patch which add all
register related. By the way, the build warnings problems have been fixed
by Jakub Kicinski <kuba@kernel.org>.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v1] sun4i-emac.c: enable emac tx dma
@ 2022-01-10  7:47                       ` Conley Lee
  0 siblings, 0 replies; 33+ messages in thread
From: Conley Lee @ 2022-01-10  7:47 UTC (permalink / raw)
  To: Corentin Labbe
  Cc: davem, mripard, wens, jernej.skrabec, netdev, linux-arm-kernel,
	linux-sunxi, linux-kernel

On 01/09/22 at 09:45下午, Corentin Labbe wrote:
> Date: Sun, 9 Jan 2022 21:45:01 +0100
> From: Corentin Labbe <clabbe.montjoie@gmail.com>
> To: conleylee@foxmail.com
> Cc: davem@davemloft.net, mripard@kernel.org, wens@csie.org,
>  jernej.skrabec@gmail.com, netdev@vger.kernel.org,
>  linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev,
>  linux-kernel@vger.kernel.org
> Subject: Re: [PATCH v1] sun4i-emac.c: enable emac tx dma
> 
> Le Sun, Jan 09, 2022 at 05:17:55PM +0800, conleylee@foxmail.com a écrit :
> > From: conley <conleylee@foxmail.com>
> > 
> > Hello
> > I am reading the R40 user manual and trying to create a new path to enable
> > emac tx dma channel. According to the figure 8-21(TX Operation Diagram),
> > I try to enable emac tx dma channel by the follow steps:
> > 1. enable tx dma mode
> > 2. set packet lengths
> > 2. move data from skb to tx fifo by using dma in xmit function.
> > 3. start transfer from tx fifo to phy in dma tx done callback
> > 
> > But it doesn't work. emac tx interrupt and dma finished interrupt are
> > raised, but no packets are transmitted (I test it by tcpdump).
> > Do you know how to configure the emac tx dma correctly? Thanks ~
> > 
> 
> Hello
> 
> Here are my thoughts to help you:
> - Your email is not a real patch, but an ask for help, so you should not use [ PATCH ] in the subject.
> - If it was a patch, "v1" is not necessary
> - Your patch below is doing too many unrelated different things, it is hard to see the DMA TX enable part
> - I think you could first send a preliminary patch which adds all EMAC_INT_CTL_TX_xxx which are already used by the driver (to reduce the diff)
> - Without the DTB change, it is hard to see the whole picture, did you correctly use the right dma number for an easy example.
> - Knowing also the board (and so PHY, modes etc...) could help
> - I think your priority should not to add TX, but to fix reported problems to your initial patch (build warnings/error https://marc.info/?l=linux-arm-kernel&m=164159846213585&w=2) since your work on TX will need to be applied after this.
> - For the previous point, always build test with at least 2 different 32/64 arch. And if possible a total different arch (like x86_64).
> 
> Anyway, I will try to test your patch on my a10 board
> 
> Regards
Thanks a lot for your help ~ I will submit an patch which add all
register related. By the way, the build warnings problems have been fixed
by Jakub Kicinski <kuba@kernel.org>.

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

* Re: [PATCH v6] sun4i-emac.c: add dma support
  2021-12-30  2:00         ` patchwork-bot+netdevbpf
@ 2022-05-30  4:51           ` Corentin Labbe
  -1 siblings, 0 replies; 33+ messages in thread
From: Corentin Labbe @ 2022-05-30  4:51 UTC (permalink / raw)
  To: patchwork-bot+netdevbpf
  Cc: None, davem, kuba, mripard, wens, netdev, linux-arm-kernel, linux-kernel

Le Thu, Dec 30, 2021 at 02:00:11AM +0000, patchwork-bot+netdevbpf@kernel.org a écrit :
> Hello:
> 
> This patch was applied to netdev/net-next.git (master)
> by Jakub Kicinski <kuba@kernel.org>:
> 
> On Wed, 29 Dec 2021 09:43:51 +0800 you wrote:
> > From: Conley Lee <conleylee@foxmail.com>
> > 
> > Thanks for your review. Here is the new version for this patch.
> > 
> > This patch adds support for the emac rx dma present on sun4i. The emac
> > is able to move packets from rx fifo to RAM by using dma.
> > 
> > [...]
> 
> Here is the summary with links:
>   - [v6] sun4i-emac.c: add dma support
>     https://git.kernel.org/netdev/net-next/c/47869e82c8b8
> 
> You are awesome, thank you!
> -- 
> Deet-doot-dot, I am a bot.
> https://korg.docs.kernel.org/patchwork/pwbot.html
> 

Hello

Any news on patch which enable sun4i-emac DMA in DT ?

Regards

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

* Re: [PATCH v6] sun4i-emac.c: add dma support
@ 2022-05-30  4:51           ` Corentin Labbe
  0 siblings, 0 replies; 33+ messages in thread
From: Corentin Labbe @ 2022-05-30  4:51 UTC (permalink / raw)
  To: patchwork-bot+netdevbpf
  Cc: None, davem, kuba, mripard, wens, netdev, linux-arm-kernel, linux-kernel

Le Thu, Dec 30, 2021 at 02:00:11AM +0000, patchwork-bot+netdevbpf@kernel.org a écrit :
> Hello:
> 
> This patch was applied to netdev/net-next.git (master)
> by Jakub Kicinski <kuba@kernel.org>:
> 
> On Wed, 29 Dec 2021 09:43:51 +0800 you wrote:
> > From: Conley Lee <conleylee@foxmail.com>
> > 
> > Thanks for your review. Here is the new version for this patch.
> > 
> > This patch adds support for the emac rx dma present on sun4i. The emac
> > is able to move packets from rx fifo to RAM by using dma.
> > 
> > [...]
> 
> Here is the summary with links:
>   - [v6] sun4i-emac.c: add dma support
>     https://git.kernel.org/netdev/net-next/c/47869e82c8b8
> 
> You are awesome, thank you!
> -- 
> Deet-doot-dot, I am a bot.
> https://korg.docs.kernel.org/patchwork/pwbot.html
> 

Hello

Any news on patch which enable sun4i-emac DMA in DT ?

Regards

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6] sun4i-emac.c: add dma support
  2022-05-30  4:51           ` Corentin Labbe
@ 2022-05-30 18:48             ` Jakub Kicinski
  -1 siblings, 0 replies; 33+ messages in thread
From: Jakub Kicinski @ 2022-05-30 18:48 UTC (permalink / raw)
  To: Corentin Labbe
  Cc: patchwork-bot+netdevbpf, None, davem, mripard, wens, netdev,
	linux-arm-kernel, linux-kernel

On Mon, 30 May 2022 06:51:14 +0200 Corentin Labbe wrote:
> Any news on patch which enable sun4i-emac DMA in DT ?

Who are you directing this question to and where's that patch posted?

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

* Re: [PATCH v6] sun4i-emac.c: add dma support
@ 2022-05-30 18:48             ` Jakub Kicinski
  0 siblings, 0 replies; 33+ messages in thread
From: Jakub Kicinski @ 2022-05-30 18:48 UTC (permalink / raw)
  To: Corentin Labbe
  Cc: patchwork-bot+netdevbpf, None, davem, mripard, wens, netdev,
	linux-arm-kernel, linux-kernel

On Mon, 30 May 2022 06:51:14 +0200 Corentin Labbe wrote:
> Any news on patch which enable sun4i-emac DMA in DT ?

Who are you directing this question to and where's that patch posted?

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v6] sun4i-emac.c: add dma support
  2022-05-30 18:48             ` Jakub Kicinski
@ 2022-05-30 18:55               ` Corentin Labbe
  -1 siblings, 0 replies; 33+ messages in thread
From: Corentin Labbe @ 2022-05-30 18:55 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: None, davem, mripard, wens, netdev, linux-arm-kernel, linux-kernel

Le Mon, May 30, 2022 at 11:48:19AM -0700, Jakub Kicinski a écrit :
> On Mon, 30 May 2022 06:51:14 +0200 Corentin Labbe wrote:
> > Any news on patch which enable sun4i-emac DMA in DT ?
> 
> Who are you directing this question to and where's that patch posted?

I am sorry, I fail to set the right "to:"
My question was for Conley Lee.

This serie was applied but the DT part was never posted.
So sun4i-emac can handle DMA but is not enabled at all.

The DT patch is easy, so without answer, I will send it.

Regards

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

* Re: [PATCH v6] sun4i-emac.c: add dma support
@ 2022-05-30 18:55               ` Corentin Labbe
  0 siblings, 0 replies; 33+ messages in thread
From: Corentin Labbe @ 2022-05-30 18:55 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: None, davem, mripard, wens, netdev, linux-arm-kernel, linux-kernel

Le Mon, May 30, 2022 at 11:48:19AM -0700, Jakub Kicinski a écrit :
> On Mon, 30 May 2022 06:51:14 +0200 Corentin Labbe wrote:
> > Any news on patch which enable sun4i-emac DMA in DT ?
> 
> Who are you directing this question to and where's that patch posted?

I am sorry, I fail to set the right "to:"
My question was for Conley Lee.

This serie was applied but the DT part was never posted.
So sun4i-emac can handle DMA but is not enabled at all.

The DT patch is easy, so without answer, I will send it.

Regards

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

end of thread, other threads:[~2022-05-30 18:56 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-24 14:44 [PATCH v4] sun4i-emac.c: add dma support conleylee
2021-12-28  2:35 ` Jakub Kicinski
2021-12-28 11:42 ` [PATCH v5] " conleylee
2021-12-29  0:48   ` Jakub Kicinski
2021-12-29  0:48     ` Jakub Kicinski
2021-12-29  1:43     ` [PATCH v6] " conleylee
2021-12-29  1:43       ` conleylee
2021-12-30  2:00       ` patchwork-bot+netdevbpf
2021-12-30  2:00         ` patchwork-bot+netdevbpf
2022-05-30  4:51         ` Corentin Labbe
2022-05-30  4:51           ` Corentin Labbe
2022-05-30 18:48           ` Jakub Kicinski
2022-05-30 18:48             ` Jakub Kicinski
2022-05-30 18:55             ` Corentin Labbe
2022-05-30 18:55               ` Corentin Labbe
2021-12-31 10:43       ` Corentin Labbe
2021-12-31 10:43         ` Corentin Labbe
     [not found]         ` <tencent_57960DDC83F43DA3E0A2F47DEBAD69A4A005@qq.com>
2022-01-02 17:38           ` Corentin Labbe
2022-01-02 17:38             ` Corentin Labbe
     [not found]             ` <tencent_67023336008FE777A58293D2D32DEFA69107@qq.com>
2022-01-03 11:42               ` Corentin Labbe
2022-01-03 11:42                 ` Corentin Labbe
2022-01-03 12:21                 ` Conley Lee
2022-01-03 12:21                   ` Conley Lee
2022-01-09  9:17                 ` [PATCH v1] sun4i-emac.c: enable emac tx dma conleylee
2022-01-09  9:17                   ` conleylee
2022-01-09 20:45                   ` Corentin Labbe
2022-01-09 20:45                     ` Corentin Labbe
2022-01-10  7:47                     ` Conley Lee
2022-01-10  7:47                       ` Conley Lee
2022-01-07 23:34       ` [PATCH v6] sun4i-emac.c: add dma support Kees Cook
2022-01-07 23:34         ` Kees Cook
2022-01-08  2:34         ` Jakub Kicinski
2022-01-08  2:34           ` Jakub Kicinski

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.