From: "A. Sverdlin" <alexander.sverdlin@siemens.com>
To: netdev@vger.kernel.org
Cc: Alexander Sverdlin <alexander.sverdlin@siemens.com>,
Wei Fang <wei.fang@nxp.com>, Frank Li <frank.li@nxp.com>,
Shenwei Wang <shenwei.wang@nxp.com>,
Andrew Lunn <andrew+netdev@lunn.ch>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Shawn Guo <shawnguo@kernel.org>, Linux Team <linux-imx@nxp.com>,
imx@lists.linux.dev, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH net-next 2/2] net: fec: support receive flushing via fsl,rx-flush-queues
Date: Fri, 14 Aug 2026 11:09:01 +0200 [thread overview]
Message-ID: <20260814090906.2225075-3-alexander.sverdlin@siemens.com> (raw)
In-Reply-To: <20260814090906.2225075-1-alexander.sverdlin@siemens.com>
From: Alexander Sverdlin <alexander.sverdlin@siemens.com>
The FEC/ENET controller can flush frames stuck at the head of the RX FIFO
when their destination ring has no empty buffer descriptor, instead of
letting them block the FIFO. This is controlled per RX queue through the
RX_FLUSHn bits of the QOS Scheme register (FEC_QOS_SCHEME).
Parse the new fsl,rx-flush-queues property, build the RX flush mask and
program it in fec_enet_enable_ring().
Erratum ERR050395 (e.g. i.MX8QXP) can cause an RX path lock-up when
flushing is enabled on more than one queue at a time. Rather than encoding
that limitation in the binding, enforce it in the driver: reject a
configuration that enables flushing on multiple queues unless the
controller advertises FEC_QUIRK_HAS_MULTI_RX_FLUSH, which future parts with
the erratum fixed can set.
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@siemens.com>
---
drivers/net/ethernet/freescale/fec.h | 14 ++++++++++
drivers/net/ethernet/freescale/fec_main.c | 34 +++++++++++++++++++++++
2 files changed, 48 insertions(+)
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index 7176803146f3d..4af3ae286895f 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -186,6 +186,7 @@
#define FEC_RCMR_2 0xfff
#define FEC_DMA_CFG_1 0xfff
#define FEC_DMA_CFG_2 0xfff
+#define FEC_QOS_SCHEME 0xfff
#define FEC_TXIC0 0xfff
#define FEC_TXIC1 0xfff
#define FEC_TXIC2 0xfff
@@ -322,6 +323,10 @@ struct bufdesc_ex {
#define RCMR_CMP(X) (((X) == 1) ? RCMR_CMP_1 : RCMR_CMP_2)
#define FEC_TX_BD_FTYPE(X) (((X) & 0xf) << 20)
+/* FEC_QOS_SCHEME bits */
+#define QOS_RX_FLUSH(X) (1 << (3 + (X))) /* RX_FLUSHn, n = 0, 1, 2 */
+#define QOS_RX_FLUSH_MASK (QOS_RX_FLUSH(0) | QOS_RX_FLUSH(1) | QOS_RX_FLUSH(2))
+
/* The number of Tx and Rx buffers. These are allocated from the page
* pool. The code may assume these are power of two, so it is best
* to keep them that size.
@@ -499,6 +504,12 @@ struct bufdesc_ex {
/* Jumbo Frame support */
#define FEC_QUIRK_JUMBO_FRAME BIT(25)
+/* Receive flushing (QOS Scheme register RX_FLUSHn) may be enabled on more than
+ * one RX queue at a time. Parts without this quirk are subject to erratum
+ * ERR050395 and must limit RX flushing to a single queue.
+ */
+#define FEC_QUIRK_HAS_MULTI_RX_FLUSH BIT(24)
+
struct bufdesc_prop {
int qid;
/* Address of Rx and Tx buffers */
@@ -604,6 +615,9 @@ struct fec_enet_private {
unsigned int num_tx_queues;
unsigned int num_rx_queues;
+ /* Bitmask of RX queues with receive flushing enabled */
+ u32 rx_flush_mask;
+
struct fec_enet_priv_tx_q *tx_queue[FEC_ENET_MAX_TX_QS];
struct fec_enet_priv_rx_q *rx_queue[FEC_ENET_MAX_RX_QS];
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index ced4dbf8cd90f..a4fe8423630b5 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1090,6 +1090,15 @@ static void fec_enet_enable_ring(struct net_device *ndev)
fep->hwp + FEC_RCMR(i));
}
+ /* Enable receive flushing for the selected queues */
+ if (fep->rx_flush_mask) {
+ u32 val = readl(fep->hwp + FEC_QOS_SCHEME);
+
+ val &= ~QOS_RX_FLUSH_MASK;
+ val |= fep->rx_flush_mask;
+ writel(val, fep->hwp + FEC_QOS_SCHEME);
+ }
+
for (i = 0; i < fep->num_tx_queues; i++) {
txq = fep->tx_queue[i];
writel(txq->bd.dma, fep->hwp + FEC_X_DES_START(i));
@@ -5239,6 +5248,31 @@ fec_probe(struct platform_device *pdev)
fep->num_rx_queues = num_rx_qs;
fep->num_tx_queues = num_tx_qs;
+ /* Enable receive flushing on the requested queues. Erratum ERR050395
+ * restricts flushing to a single queue; only accept more than one queue
+ * on controllers known to have the erratum fixed.
+ */
+ for (i = 0; i < of_property_count_u32_elems(np, "fsl,rx-flush-queues"); i++) {
+ u32 q;
+
+ if (of_property_read_u32_index(np, "fsl,rx-flush-queues", i, &q))
+ break;
+ if (q >= num_rx_qs) {
+ dev_warn(&pdev->dev,
+ "fsl,rx-flush-queues: queue %u exceeds num-rx-queues, ignoring\n",
+ q);
+ continue;
+ }
+ fep->rx_flush_mask |= QOS_RX_FLUSH(q);
+ }
+ if (hweight32(fep->rx_flush_mask) > 1 &&
+ !(fep->quirks & FEC_QUIRK_HAS_MULTI_RX_FLUSH)) {
+ dev_err(&pdev->dev,
+ "fsl,rx-flush-queues: RX flush on multiple queues not supported\n");
+ ret = -EINVAL;
+ goto failed_ioremap;
+ }
+
/* default enable pause frame auto negotiation */
if (fep->quirks & FEC_QUIRK_HAS_GBIT)
fep->pause_flag |= FEC_PAUSE_FLAG_AUTONEG;
--
2.55.0
next prev parent reply other threads:[~2026-08-14 9:19 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-14 9:08 [PATCH net-next 0/2] net: fec: support RX flushing via fsl,rx-flush-queues A. Sverdlin
2026-08-14 9:09 ` [PATCH net-next 1/2] dt-bindings: net: fsl,fec: add fsl,rx-flush-queues A. Sverdlin
2026-08-14 9:09 ` A. Sverdlin [this message]
2026-08-14 10:31 ` [PATCH net-next 2/2] net: fec: support receive flushing via fsl,rx-flush-queues Sverdlin, Alexander
2026-08-14 13:56 ` [PATCH net-next 0/2] net: fec: support RX " Andrew Lunn
2026-08-14 14:21 ` Sverdlin, Alexander
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=20260814090906.2225075-3-alexander.sverdlin@siemens.com \
--to=alexander.sverdlin@siemens.com \
--cc=andrew+netdev@lunn.ch \
--cc=conor+dt@kernel.org \
--cc=davem@davemloft.net \
--cc=devicetree@vger.kernel.org \
--cc=edumazet@google.com \
--cc=frank.li@nxp.com \
--cc=imx@lists.linux.dev \
--cc=krzk+dt@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-imx@nxp.com \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=robh@kernel.org \
--cc=shawnguo@kernel.org \
--cc=shenwei.wang@nxp.com \
--cc=wei.fang@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