From: Simon Horman <horms@kernel.org>
To: Wei Fang <wei.fang@nxp.com>
Cc: claudiu.manoil@nxp.com, vladimir.oltean@nxp.com,
xiaoning.wang@nxp.com, andrew+netdev@lunn.ch,
davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, linux@armlinux.org.uk, Frank.Li@nxp.com,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
imx@lists.linux.dev
Subject: Re: [PATCH v2 net] net: enetc: safely reinitialize TX BD ring when it has unsent frames
Date: Tue, 10 Mar 2026 17:07:52 +0000 [thread overview]
Message-ID: <20260310170752.GL461701@kernel.org> (raw)
In-Reply-To: <20260309030412.2716984-1-wei.fang@nxp.com>
On Mon, Mar 09, 2026 at 11:04:12AM +0800, Wei Fang wrote:
> Currently the driver does not reset the producer index register (PIR) and
> consumer index register (CIR) when initializing a TX BD ring. The driver
> only reads the PIR and CIR and initializes the software indexes. If the
> TX BD ring is reinitialized when it still contains unsent frames, its PIR
> and CIR will not be equal after the reinitialization. However, the BDs
> between CIR and PIR have been freed and become invalid and this can lead
> to a hardware malfunction, causing the TX BD ring will not work perperly.
>
> Since the PIR and CIR are sofeware-configurable on ENETC v4. Therefore,
> the driver must reset them if they are not equal when reinitializing
> the TX BD ring.
>
> However, resetting the PIR and CIR alone is insufficient, it cannot
> completely solve the problem. When a link-down event occurs while the
> the TX BD ring is transmitting frames, subsequent reinitialization of
> the TX BD ring may cause it to malfunction. For example, the following
> steps may reproduce the problem (not 100% reproducible).
>
> 1. Unplug the cable when the TX BD ring is busy transmitting frames.
> 2. Disable the network interface (ifconfig eth0 down).
> 3. Re-enable the network interface (ifconfig eth0 up).
> 4. Plug in the cable, the TX BD ring may fail to transmit packets.
>
> When the link-down event occurs, enetc4_pl_mac_link_down() only clears
> PMa_COMMAND_CONFIG[TX_EN] to disable MAC transmit data path. It doesn't
> set PORT[TXDIS] to 1 to flush the TX BD ring. Therefore, reinitializing
> the TX BD ring at this point is unsafe. To safely reinitialize the TX BD
> ring after a link-down event, we checked with the NETC IP team, a proper
> Ethernet MAC graceful stop is necessary. Therefore, add the Ethernet MAC
> graceful stop to the link-down event handler enetc4_pl_mac_link_down().
>
> Fixes: 99100d0d9922 ("net: enetc: add preliminary support for i.MX95 ENETC PF")
> Signed-off-by: Wei Fang <wei.fang@nxp.com>
> ---
> v2:
> 1. Remove unused register macros (ENETC_SISR and SISR_TX_BUSY)
> 2. Remove spurious semicolon from enetc4_mac_wait_rx_empty()
> ---
> drivers/net/ethernet/freescale/enetc/enetc.c | 9 ++
> .../net/ethernet/freescale/enetc/enetc4_hw.h | 11 ++
> .../net/ethernet/freescale/enetc/enetc4_pf.c | 126 ++++++++++++++++--
> 3 files changed, 132 insertions(+), 14 deletions(-)
Hi,
This is a not a small patch for a fix.
Could you consider splitting it up a bit?
Say one patch for the ENETC_TBPIR/ENETC_TBCIR
portion and another for the graceful stop?
>
> diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
> index 70768392912c..825a5d1f2965 100644
> --- a/drivers/net/ethernet/freescale/enetc/enetc.c
> +++ b/drivers/net/ethernet/freescale/enetc/enetc.c
> @@ -2578,6 +2578,7 @@ EXPORT_SYMBOL_GPL(enetc_free_si_resources);
>
> static void enetc_setup_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring)
> {
> + struct enetc_si *si = container_of(hw, struct enetc_si, hw);
> int idx = tx_ring->index;
> u32 tbmr;
>
> @@ -2595,6 +2596,14 @@ static void enetc_setup_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring)
The line above this hunk is:
/* clearing PI/CI registers for Tx not supported, adjust sw indexes */
And the AI generated review reports:
This isn't a bug, but the comment now contradicts the code. The comment
says "clearing PI/CI registers for Tx not supported" but the code
immediately below clears TBPIR and TBCIR for ENETC v4 hardware.
Should the comment be updated to clarify that clearing is only
unsupported on ENETC rev1?
> tx_ring->next_to_use = enetc_txbdr_rd(hw, idx, ENETC_TBPIR);
> tx_ring->next_to_clean = enetc_txbdr_rd(hw, idx, ENETC_TBCIR);
>
> + if (tx_ring->next_to_use != tx_ring->next_to_clean &&
> + !is_enetc_rev1(si)) {
> + tx_ring->next_to_use = 0;
> + tx_ring->next_to_clean = 0;
> + enetc_txbdr_wr(hw, idx, ENETC_TBPIR, 0);
> + enetc_txbdr_wr(hw, idx, ENETC_TBCIR, 0);
> + }
> +
> /* enable Tx ints by setting pkt thr to 1 */
> enetc_txbdr_wr(hw, idx, ENETC_TBICR0, ENETC_TBICR0_ICEN | 0x1);
>
...
> diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
...
> @@ -801,15 +792,120 @@ static void enetc4_set_tx_pause(struct enetc_pf *pf, int num_rxbdr, bool tx_paus
> enetc_port_wr(hw, ENETC4_PPAUOFFTR, pause_off_thresh);
> }
>
> -static void enetc4_enable_mac(struct enetc_pf *pf, bool en)
> +static void enetc4_mac_wait_tx_empty(struct enetc_si *si, int mac)
> +{
> + u32 timeout = 0;
> +
> + while (!(enetc_port_rd(&si->hw, ENETC4_PM_IEVENT(mac)) &
> + PM_IEVENT_TX_EMPTY)) {
> + if (timeout >= 100) {
> + dev_warn(&si->pdev->dev,
> + "MAC %d TX is not empty\n", mac);
> + break;
> + }
> +
> + usleep_range(100, 110);
> + timeout++;
> + }
> +}
Can this be implemented using poll_timeout_us() ?
...
> +static void enetc4_mac_wait_rx_empty(struct enetc_si *si, int mac)
> +{
> + u32 timeout = 0;
> +
> + while (!(enetc_port_rd(&si->hw, ENETC4_PM_IEVENT(mac)) &
> + PM_IEVENT_RX_EMPTY)) {
> + if (timeout >= 100) {
> + dev_warn(&si->pdev->dev,
> + "MAC %d RX is not empty\n", mac);
> + break;
> + }
> +
> + usleep_range(100, 110);
> + timeout++;
> + }
> +}
Likewise, here.
...
next prev parent reply other threads:[~2026-03-10 17:07 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-09 3:04 [PATCH v2 net] net: enetc: safely reinitialize TX BD ring when it has unsent frames Wei Fang
2026-03-10 17:07 ` Simon Horman [this message]
2026-03-11 3:21 ` Wei Fang
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=20260310170752.GL461701@kernel.org \
--to=horms@kernel.org \
--cc=Frank.Li@nxp.com \
--cc=andrew+netdev@lunn.ch \
--cc=claudiu.manoil@nxp.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=imx@lists.linux.dev \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=vladimir.oltean@nxp.com \
--cc=wei.fang@nxp.com \
--cc=xiaoning.wang@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