[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20231127115334.3670790-5-yoshihiro.shimoda.uh@renesas.com>
Date: Mon, 27 Nov 2023 20:53:29 +0900
From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@...esas.com>
To: s.shtylyov@....ru,
davem@...emloft.net,
edumazet@...gle.com,
kuba@...nel.org,
pabeni@...hat.com
Cc: netdev@...r.kernel.org,
linux-renesas-soc@...r.kernel.org,
Yoshihiro Shimoda <yoshihiro.shimoda.uh@...esas.com>
Subject: [PATCH net-next 4/9] net: rswitch: Add unmap_addrs instead of dma address in each desc
If the driver would like to transmit a jumbo frame like 2KiB or more,
it should be split into multiple queues. In near the future, to support
this, add unmap_addrs array to unmap dma mapping address instead of dma
address in each TX descriptor because the descriptors may not have
the top dma address.
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@...esas.com>
---
drivers/net/ethernet/renesas/rswitch.c | 19 +++++++++++--------
drivers/net/ethernet/renesas/rswitch.h | 1 +
2 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/renesas/rswitch.c b/drivers/net/ethernet/renesas/rswitch.c
index 8337c860eb9a..4774130c417b 100644
--- a/drivers/net/ethernet/renesas/rswitch.c
+++ b/drivers/net/ethernet/renesas/rswitch.c
@@ -284,6 +284,8 @@ static void rswitch_gwca_queue_free(struct net_device *ndev,
gq->tx_ring = NULL;
kfree(gq->skbs);
gq->skbs = NULL;
+ kfree(gq->unmap_addrs);
+ gq->unmap_addrs = NULL;
}
}
@@ -321,6 +323,9 @@ static int rswitch_gwca_queue_alloc(struct net_device *ndev,
gq->skbs = kcalloc(gq->ring_size, sizeof(*gq->skbs), GFP_KERNEL);
if (!gq->skbs)
return -ENOMEM;
+ gq->unmap_addrs = kcalloc(gq->ring_size, sizeof(*gq->unmap_addrs), GFP_KERNEL);
+ if (!gq->unmap_addrs)
+ goto out;
gq->tx_ring = dma_alloc_coherent(ndev->dev.parent,
sizeof(struct rswitch_ext_desc) *
(gq->ring_size + 1), &gq->ring_dma, GFP_KERNEL);
@@ -786,9 +791,7 @@ static void rswitch_tx_free(struct net_device *ndev)
struct rswitch_device *rdev = netdev_priv(ndev);
struct rswitch_gwca_queue *gq = rdev->tx_queue;
struct rswitch_ext_desc *desc;
- dma_addr_t dma_addr;
struct sk_buff *skb;
- unsigned int size;
for (; rswitch_get_num_cur_queues(gq) > 0;
gq->dirty = rswitch_next_queue_index(gq, false, 1)) {
@@ -797,18 +800,17 @@ static void rswitch_tx_free(struct net_device *ndev)
break;
dma_rmb();
- size = le16_to_cpu(desc->desc.info_ds) & TX_DS;
skb = gq->skbs[gq->dirty];
if (skb) {
- dma_addr = rswitch_desc_get_dptr(&desc->desc);
- dma_unmap_single(ndev->dev.parent, dma_addr,
- size, DMA_TO_DEVICE);
+ dma_unmap_single(ndev->dev.parent,
+ gq->unmap_addrs[gq->dirty],
+ skb->len, DMA_TO_DEVICE);
dev_kfree_skb_any(gq->skbs[gq->dirty]);
gq->skbs[gq->dirty] = NULL;
+ rdev->ndev->stats.tx_packets++;
+ rdev->ndev->stats.tx_bytes += skb->len;
}
desc->desc.die_dt = DT_EEMPTY;
- rdev->ndev->stats.tx_packets++;
- rdev->ndev->stats.tx_bytes += size;
}
}
@@ -1537,6 +1539,7 @@ static netdev_tx_t rswitch_start_xmit(struct sk_buff *skb, struct net_device *nd
goto err_kfree;
gq->skbs[gq->cur] = skb;
+ gq->unmap_addrs[gq->cur] = dma_addr;
desc = &gq->tx_ring[gq->cur];
rswitch_desc_set_dptr(&desc->desc, dma_addr);
desc->desc.info_ds = cpu_to_le16(skb->len);
diff --git a/drivers/net/ethernet/renesas/rswitch.h b/drivers/net/ethernet/renesas/rswitch.h
index a407d85dcfad..2ac9a86b6238 100644
--- a/drivers/net/ethernet/renesas/rswitch.h
+++ b/drivers/net/ethernet/renesas/rswitch.h
@@ -956,6 +956,7 @@ struct rswitch_gwca_queue {
/* For TX */
struct {
struct sk_buff **skbs;
+ dma_addr_t *unmap_addrs;
};
/* For RX */
struct {
--
2.34.1
Powered by blists - more mailing lists