devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Clément Léger" <clement.leger@bootlin.com>
To: "David S. Miller" <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>,
	Rob Herring <robh+dt@kernel.org>,
	Vladimir Oltean <vladimir.oltean@nxp.com>,
	Claudiu Manoil <claudiu.manoil@nxp.com>,
	Alexandre Belloni <alexandre.belloni@bootlin.com>,
	UNGLinuxDriver@microchip.com, Andrew Lunn <andrew@lunn.ch>
Cc: "Clément Léger" <clement.leger@bootlin.com>,
	netdev@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	"Thomas Petazzoni" <thomas.petazzoni@bootlin.com>
Subject: [PATCH v2 6/6] net: ocelot: add jumbo frame support for FDMA
Date: Wed,  3 Nov 2021 10:19:43 +0100	[thread overview]
Message-ID: <20211103091943.3878621-7-clement.leger@bootlin.com> (raw)
In-Reply-To: <20211103091943.3878621-1-clement.leger@bootlin.com>

When using the FDMA, using jumbo frames can lead to a large performance
improvement. When changing the MTU, the RX buffer size must be
increased to be large enough to receive jumbo frame. Since the FDMA is
shared amongst all interfaces, all the ports must be down before
changing the MTU. Buffers are sized to accept the maximum MTU supported
by each port.

Signed-off-by: Clément Léger <clement.leger@bootlin.com>
---
 drivers/net/ethernet/mscc/ocelot_fdma.c | 61 +++++++++++++++++++++++++
 drivers/net/ethernet/mscc/ocelot_fdma.h |  1 +
 drivers/net/ethernet/mscc/ocelot_net.c  |  7 +++
 3 files changed, 69 insertions(+)

diff --git a/drivers/net/ethernet/mscc/ocelot_fdma.c b/drivers/net/ethernet/mscc/ocelot_fdma.c
index d8cdf022bbee..bee1a310caa6 100644
--- a/drivers/net/ethernet/mscc/ocelot_fdma.c
+++ b/drivers/net/ethernet/mscc/ocelot_fdma.c
@@ -530,6 +530,67 @@ static void fdma_free_skbs_list(struct ocelot_fdma *fdma,
 	}
 }
 
+int ocelot_fdma_change_mtu(struct net_device *dev, int new_mtu)
+{
+	struct ocelot_port_private *priv = netdev_priv(dev);
+	struct ocelot_port *port = &priv->port;
+	struct ocelot *ocelot = port->ocelot;
+	struct ocelot_fdma *fdma = ocelot->fdma;
+	struct ocelot_fdma_dcb *dcb, *dcb_temp;
+	struct list_head tmp = LIST_HEAD_INIT(tmp);
+	size_t old_rx_buf_size = fdma->rx_buf_size;
+	bool all_ports_down = true;
+	u8 port_num;
+
+	/* The FDMA RX list is shared amongst all the port, get the max MTU from
+	 * all of them
+	 */
+	for (port_num = 0; port_num < ocelot->num_phys_ports; port_num++) {
+		port = ocelot->ports[port_num];
+		if (!port)
+			continue;
+
+		priv = container_of(port, struct ocelot_port_private, port);
+
+		if (READ_ONCE(priv->dev->mtu) > new_mtu)
+			new_mtu = READ_ONCE(priv->dev->mtu);
+
+		/* All ports must be down to change the RX buffer length */
+		if (netif_running(priv->dev))
+			all_ports_down = false;
+	}
+
+	fdma->rx_buf_size = fdma_rx_compute_buffer_size(new_mtu);
+	if (fdma->rx_buf_size == old_rx_buf_size)
+		return 0;
+
+	if (!all_ports_down)
+		return -EBUSY;
+
+	priv = netdev_priv(dev);
+
+	fdma_stop_channel(fdma, MSCC_FDMA_INJ_CHAN);
+
+	/* Discard all pending RX software and hardware descriptor */
+	fdma_free_skbs_list(fdma, &fdma->rx_hw, DMA_FROM_DEVICE);
+	fdma_free_skbs_list(fdma, &fdma->rx_sw, DMA_FROM_DEVICE);
+
+	/* Move all DCBs to a temporary list that will be injected in sw list */
+	if (!list_empty(&fdma->rx_hw))
+		list_splice_tail_init(&fdma->rx_hw, &tmp);
+	if (!list_empty(&fdma->rx_sw))
+		list_splice_tail_init(&fdma->rx_sw, &tmp);
+
+	list_for_each_entry_safe(dcb, dcb_temp, &tmp, node) {
+		list_del(&dcb->node);
+		ocelot_fdma_rx_add_dcb_sw(fdma, dcb);
+	}
+
+	ocelot_fdma_rx_refill(fdma);
+
+	return 0;
+}
+
 static int fdma_init_tx(struct ocelot_fdma *fdma)
 {
 	int i;
diff --git a/drivers/net/ethernet/mscc/ocelot_fdma.h b/drivers/net/ethernet/mscc/ocelot_fdma.h
index 6c5c5872abf5..74514a0b291a 100644
--- a/drivers/net/ethernet/mscc/ocelot_fdma.h
+++ b/drivers/net/ethernet/mscc/ocelot_fdma.h
@@ -55,5 +55,6 @@ int ocelot_fdma_start(struct ocelot_fdma *fdma);
 int ocelot_fdma_stop(struct ocelot_fdma *fdma);
 int ocelot_fdma_inject_frame(struct ocelot_fdma *fdma, int port, u32 rew_op,
 			     struct sk_buff *skb, struct net_device *dev);
+int ocelot_fdma_change_mtu(struct net_device *dev, int new_mtu);
 
 #endif
diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c
index 3971b810c5b4..d5e88d7b15c7 100644
--- a/drivers/net/ethernet/mscc/ocelot_net.c
+++ b/drivers/net/ethernet/mscc/ocelot_net.c
@@ -492,6 +492,13 @@ static int ocelot_change_mtu(struct net_device *dev, int new_mtu)
 	struct ocelot_port_private *priv = netdev_priv(dev);
 	struct ocelot_port *ocelot_port = &priv->port;
 	struct ocelot *ocelot = ocelot_port->ocelot;
+	int ret;
+
+	if (ocelot->fdma) {
+		ret = ocelot_fdma_change_mtu(dev, new_mtu);
+		if (ret)
+			return ret;
+	}
 
 	ocelot_port_set_maxlen(ocelot, priv->chip_port, new_mtu);
 	WRITE_ONCE(dev->mtu, new_mtu);
-- 
2.33.0


  parent reply	other threads:[~2021-11-03  9:20 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-03  9:19 [PATCH v2 0/6] Add FDMA support on ocelot switch driver Clément Léger
2021-11-03  9:19 ` [PATCH v2 1/6] net: ocelot: add support to get port mac from device-tree Clément Léger
2021-11-03 10:26   ` Vladimir Oltean
2021-11-15 11:19   ` Julian Wiedmann
2021-11-15 11:24     ` Clément Léger
2021-11-03  9:19 ` [PATCH v2 2/6] dt-bindings: net: convert mscc,vsc7514-switch bindings to yaml Clément Léger
2021-11-03 10:45   ` Vladimir Oltean
2021-11-08 11:13     ` Clément Léger
2021-11-12 20:06   ` Rob Herring
2021-11-03  9:19 ` [PATCH v2 3/6] net: ocelot: pre-compute injection frame header content Clément Léger
2021-11-03 12:38   ` Vladimir Oltean
2021-11-03 13:53     ` Clément Léger
2021-11-15 10:13       ` Clément Léger
2021-11-15 10:51         ` Vladimir Oltean
2021-11-15 10:58           ` Clément Léger
2021-11-15 14:08         ` Jakub Kicinski
2021-11-15 14:06           ` Clément Léger
2021-11-15 14:31             ` Vladimir Oltean
2021-11-15 16:03               ` Clément Léger
2021-11-03  9:19 ` [PATCH v2 4/6] net: ocelot: add support for ndo_change_mtu Clément Léger
2021-11-03 12:40   ` Vladimir Oltean
2021-11-03 13:07     ` Clément Léger
2021-11-03  9:19 ` [PATCH v2 5/6] net: ocelot: add FDMA support Clément Léger
2021-11-03 11:25   ` Denis Kirjanov
2021-11-03 12:31   ` Vladimir Oltean
2021-11-03 14:22     ` Clément Léger
2021-11-03  9:19 ` Clément Léger [this message]
2021-11-03 12:43   ` [PATCH v2 6/6] net: ocelot: add jumbo frame support for FDMA Vladimir Oltean
2021-11-03 14:30     ` Clément Léger
2021-11-03 10:46 ` [PATCH v2 0/6] Add FDMA support on ocelot switch driver Denis Kirjanov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211103091943.3878621-7-clement.leger@bootlin.com \
    --to=clement.leger@bootlin.com \
    --cc=UNGLinuxDriver@microchip.com \
    --cc=alexandre.belloni@bootlin.com \
    --cc=andrew@lunn.ch \
    --cc=claudiu.manoil@nxp.com \
    --cc=davem@davemloft.net \
    --cc=devicetree@vger.kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=robh+dt@kernel.org \
    --cc=thomas.petazzoni@bootlin.com \
    --cc=vladimir.oltean@nxp.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).