Skip to content

Commit 0aeec4b

Browse files
shimodaygregkh
authored andcommitted
net: rswitch: Add unmap_addrs instead of dma address in each desc
[ Upstream commit 271e015 ] If the driver would like to transmit a jumbo frame like 2KiB or more, it should be split into multiple queues. In the near 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 <[email protected]> Signed-off-by: David S. Miller <[email protected]> Stable-dep-of: 0c9547e ("net: renesas: rswitch: fix race window between tx start and complete") Signed-off-by: Sasha Levin <[email protected]>
1 parent 99ee2eb commit 0aeec4b

File tree

2 files changed

+12
-8
lines changed

2 files changed

+12
-8
lines changed

drivers/net/ethernet/renesas/rswitch.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,8 @@ static void rswitch_gwca_queue_free(struct net_device *ndev,
283283
gq->tx_ring = NULL;
284284
kfree(gq->skbs);
285285
gq->skbs = NULL;
286+
kfree(gq->unmap_addrs);
287+
gq->unmap_addrs = NULL;
286288
}
287289
}
288290

@@ -321,6 +323,9 @@ static int rswitch_gwca_queue_alloc(struct net_device *ndev,
321323
gq->skbs = kcalloc(gq->ring_size, sizeof(*gq->skbs), GFP_KERNEL);
322324
if (!gq->skbs)
323325
return -ENOMEM;
326+
gq->unmap_addrs = kcalloc(gq->ring_size, sizeof(*gq->unmap_addrs), GFP_KERNEL);
327+
if (!gq->unmap_addrs)
328+
goto out;
324329
gq->tx_ring = dma_alloc_coherent(ndev->dev.parent,
325330
sizeof(struct rswitch_ext_desc) *
326331
(gq->ring_size + 1), &gq->ring_dma, GFP_KERNEL);
@@ -786,9 +791,7 @@ static void rswitch_tx_free(struct net_device *ndev)
786791
struct rswitch_device *rdev = netdev_priv(ndev);
787792
struct rswitch_gwca_queue *gq = rdev->tx_queue;
788793
struct rswitch_ext_desc *desc;
789-
dma_addr_t dma_addr;
790794
struct sk_buff *skb;
791-
unsigned int size;
792795

793796
for (; rswitch_get_num_cur_queues(gq) > 0;
794797
gq->dirty = rswitch_next_queue_index(gq, false, 1)) {
@@ -797,18 +800,17 @@ static void rswitch_tx_free(struct net_device *ndev)
797800
break;
798801

799802
dma_rmb();
800-
size = le16_to_cpu(desc->desc.info_ds) & TX_DS;
801803
skb = gq->skbs[gq->dirty];
802804
if (skb) {
803-
dma_addr = rswitch_desc_get_dptr(&desc->desc);
804-
dma_unmap_single(ndev->dev.parent, dma_addr,
805-
size, DMA_TO_DEVICE);
805+
dma_unmap_single(ndev->dev.parent,
806+
gq->unmap_addrs[gq->dirty],
807+
skb->len, DMA_TO_DEVICE);
806808
dev_kfree_skb_any(gq->skbs[gq->dirty]);
807809
gq->skbs[gq->dirty] = NULL;
810+
rdev->ndev->stats.tx_packets++;
811+
rdev->ndev->stats.tx_bytes += skb->len;
808812
}
809813
desc->desc.die_dt = DT_EEMPTY;
810-
rdev->ndev->stats.tx_packets++;
811-
rdev->ndev->stats.tx_bytes += size;
812814
}
813815
}
814816

@@ -1535,6 +1537,7 @@ static netdev_tx_t rswitch_start_xmit(struct sk_buff *skb, struct net_device *nd
15351537
goto err_kfree;
15361538

15371539
gq->skbs[gq->cur] = skb;
1540+
gq->unmap_addrs[gq->cur] = dma_addr;
15381541
desc = &gq->tx_ring[gq->cur];
15391542
rswitch_desc_set_dptr(&desc->desc, dma_addr);
15401543
desc->desc.info_ds = cpu_to_le16(skb->len);

drivers/net/ethernet/renesas/rswitch.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -956,6 +956,7 @@ struct rswitch_gwca_queue {
956956
/* For TX */
957957
struct {
958958
struct sk_buff **skbs;
959+
dma_addr_t *unmap_addrs;
959960
};
960961
/* For RX */
961962
struct {

0 commit comments

Comments
 (0)