Commit 93763e68 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

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: default avatarJakub Kicinski <kuba@kernel.org>
parents d02af27f 66b7e9f8
Loading
Loading
Loading
Loading
+14 −11
Original line number Diff line number Diff line
@@ -862,13 +862,10 @@ static void rswitch_tx_free(struct net_device *ndev)
	struct rswitch_ext_desc *desc;
	struct sk_buff *skb;

	for (; rswitch_get_num_cur_queues(gq) > 0;
	     gq->dirty = rswitch_next_queue_index(gq, false, 1)) {
	desc = &gq->tx_ring[gq->dirty];
		if ((desc->desc.die_dt & DT_MASK) != DT_FEMPTY)
			break;

	while ((desc->desc.die_dt & DT_MASK) == DT_FEMPTY) {
		dma_rmb();

		skb = gq->skbs[gq->dirty];
		if (skb) {
			rdev->ndev->stats.tx_packets++;
@@ -879,7 +876,10 @@ static void rswitch_tx_free(struct net_device *ndev)
			dev_kfree_skb_any(gq->skbs[gq->dirty]);
			gq->skbs[gq->dirty] = NULL;
		}

		desc->desc.die_dt = DT_EEMPTY;
		gq->dirty = rswitch_next_queue_index(gq, false, 1);
		desc = &gq->tx_ring[gq->dirty];
	}
}

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

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

	dma_wmb();

	/* DT_FSTART should be set at last. So, this is reverse order. */
	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
			goto err_unmap;
	}

	wmb();	/* gq->cur must be incremented after die_dt was set */

	gq->cur = rswitch_next_queue_index(gq, true, nr_desc);
	rswitch_modify(rdev->addr, GWTRC(gq->index), 0, BIT(gq->index % 32));

	return ret;

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

err_kfree:
@@ -1889,7 +1891,6 @@ static int rswitch_device_alloc(struct rswitch_private *priv, unsigned int index
	rdev->np_port = rswitch_get_port_node(rdev);
	rdev->disabled = !rdev->np_port;
	err = of_get_ethdev_address(rdev->np_port, ndev);
	of_node_put(rdev->np_port);
	if (err) {
		if (is_valid_ether_addr(rdev->etha->mac_addr))
			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

out_rxdmac:
out_get_params:
	of_node_put(rdev->np_port);
	netif_napi_del(&rdev->napi);
	free_netdev(ndev);

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

	rswitch_txdmac_free(ndev);
	rswitch_rxdmac_free(ndev);
	of_node_put(rdev->np_port);
	netif_napi_del(&rdev->napi);
	free_netdev(ndev);
}