Skip to content

Commit 93763e6

Browse files
committed
Merge branch 'net-renesas-rswitch-several-fixes'
Nikita Yushchenko says: ==================== net: renesas: rswitch: several fixes This series fixes several glitches found in the rswitch driver. Repost of https://lore.kernel.org/20241206190015.4194153-1-nikita.yoush@cogentembedded.com ==================== Link: https://patch.msgid.link/20241208095004.69468-1-nikita.yoush@cogentembedded.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents d02af27 + 66b7e9f commit 93763e6

File tree

1 file changed

+14
-11
lines changed

1 file changed

+14
-11
lines changed

drivers/net/ethernet/renesas/rswitch.c

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -862,13 +862,10 @@ static void rswitch_tx_free(struct net_device *ndev)
862862
struct rswitch_ext_desc *desc;
863863
struct sk_buff *skb;
864864

865-
for (; rswitch_get_num_cur_queues(gq) > 0;
866-
gq->dirty = rswitch_next_queue_index(gq, false, 1)) {
867-
desc = &gq->tx_ring[gq->dirty];
868-
if ((desc->desc.die_dt & DT_MASK) != DT_FEMPTY)
869-
break;
870-
865+
desc = &gq->tx_ring[gq->dirty];
866+
while ((desc->desc.die_dt & DT_MASK) == DT_FEMPTY) {
871867
dma_rmb();
868+
872869
skb = gq->skbs[gq->dirty];
873870
if (skb) {
874871
rdev->ndev->stats.tx_packets++;
@@ -879,7 +876,10 @@ static void rswitch_tx_free(struct net_device *ndev)
879876
dev_kfree_skb_any(gq->skbs[gq->dirty]);
880877
gq->skbs[gq->dirty] = NULL;
881878
}
879+
882880
desc->desc.die_dt = DT_EEMPTY;
881+
gq->dirty = rswitch_next_queue_index(gq, false, 1);
882+
desc = &gq->tx_ring[gq->dirty];
883883
}
884884
}
885885

@@ -1681,8 +1681,11 @@ static netdev_tx_t rswitch_start_xmit(struct sk_buff *skb, struct net_device *nd
16811681
if (dma_mapping_error(ndev->dev.parent, dma_addr_orig))
16821682
goto err_kfree;
16831683

1684-
gq->skbs[gq->cur] = skb;
1685-
gq->unmap_addrs[gq->cur] = dma_addr_orig;
1684+
/* Stored the skb at the last descriptor to avoid skb free before hardware completes send */
1685+
gq->skbs[(gq->cur + nr_desc - 1) % gq->ring_size] = skb;
1686+
gq->unmap_addrs[(gq->cur + nr_desc - 1) % gq->ring_size] = dma_addr_orig;
1687+
1688+
dma_wmb();
16861689

16871690
/* DT_FSTART should be set at last. So, this is reverse order. */
16881691
for (i = nr_desc; i-- > 0; ) {
@@ -1694,14 +1697,13 @@ static netdev_tx_t rswitch_start_xmit(struct sk_buff *skb, struct net_device *nd
16941697
goto err_unmap;
16951698
}
16961699

1697-
wmb(); /* gq->cur must be incremented after die_dt was set */
1698-
16991700
gq->cur = rswitch_next_queue_index(gq, true, nr_desc);
17001701
rswitch_modify(rdev->addr, GWTRC(gq->index), 0, BIT(gq->index % 32));
17011702

17021703
return ret;
17031704

17041705
err_unmap:
1706+
gq->skbs[(gq->cur + nr_desc - 1) % gq->ring_size] = NULL;
17051707
dma_unmap_single(ndev->dev.parent, dma_addr_orig, skb->len, DMA_TO_DEVICE);
17061708

17071709
err_kfree:
@@ -1889,7 +1891,6 @@ static int rswitch_device_alloc(struct rswitch_private *priv, unsigned int index
18891891
rdev->np_port = rswitch_get_port_node(rdev);
18901892
rdev->disabled = !rdev->np_port;
18911893
err = of_get_ethdev_address(rdev->np_port, ndev);
1892-
of_node_put(rdev->np_port);
18931894
if (err) {
18941895
if (is_valid_ether_addr(rdev->etha->mac_addr))
18951896
eth_hw_addr_set(ndev, rdev->etha->mac_addr);
@@ -1919,6 +1920,7 @@ static int rswitch_device_alloc(struct rswitch_private *priv, unsigned int index
19191920

19201921
out_rxdmac:
19211922
out_get_params:
1923+
of_node_put(rdev->np_port);
19221924
netif_napi_del(&rdev->napi);
19231925
free_netdev(ndev);
19241926

@@ -1932,6 +1934,7 @@ static void rswitch_device_free(struct rswitch_private *priv, unsigned int index
19321934

19331935
rswitch_txdmac_free(ndev);
19341936
rswitch_rxdmac_free(ndev);
1937+
of_node_put(rdev->np_port);
19351938
netif_napi_del(&rdev->napi);
19361939
free_netdev(ndev);
19371940
}

0 commit comments

Comments
 (0)