From: Nicolai Buchwitz <nb@tipi-net.de>
To: "Russell King (Oracle)" <linux@armlinux.org.uk>
Cc: netdev@vger.kernel.org, andrew+netdev@lunn.ch,
claudiu.beznea@tuxon.dev, davem@davemloft.net,
edumazet@google.com, kuba@kernel.org,
nicolas.ferre@microchip.com, pabeni@redhat.com,
phil@raspberrypi.com
Subject: Re: [PATCH net-next v2 3/5] net: cadence: macb: implement EEE TX LPI support
Date: Tue, 24 Feb 2026 11:40:10 +0100 [thread overview]
Message-ID: <d8463e10e0c07ddf404a2515e2a8640c@tipi-net.de> (raw)
In-Reply-To: <aZ16qgIsRxkUuoW1@shell.armlinux.org.uk>
On 24.2.2026 11:17, Russell King (Oracle) wrote:
> On Tue, Feb 24, 2026 at 10:18:19AM +0100, Nicolai Buchwitz wrote:
>> Implement Energy Efficient Ethernet TX Low Power Idle using phylink's
>> managed EEE framework. The Cadence GEM MAC has no built-in idle timer
>> - TXLPIEN (NCR bit 19) immediately blocks all TX when set and the MAC
>> does NOT auto-wake - so the driver uses a software delayed_work timer
>> for idle detection.
>>
>> The TX LPI lifecycle:
>> - phylink calls mac_enable_tx_lpi() after link-up with the
>> negotiated
>> timer value. The driver defers the first LPI entry by 1 second per
>> IEEE 802.3az section 22.7a.
>> - macb_tx_complete() reschedules the idle timer after each TX drain.
>> - macb_start_xmit() wakes from LPI by clearing TXLPIEN, cancelling
>> the pending work, and waiting 50us (conservative Tw_sys) before
>> initiating the transmit.
>> - phylink calls mac_disable_tx_lpi() before link-down, which cancels
>> the work and clears TXLPIEN.
>>
>> The phylink_config is populated with LPI capabilities (MII, GMII,
>> RGMII
>> modes; 100FD and 1000FD speeds) and a 250ms default idle timer, gated
>> on MACB_CAPS_EEE.
>
> Much better, thanks. One suggestion:
Thanks for the quick feedback! I will address this in a v3 of this
series.
>
>> +static void macb_tx_lpi_set(struct macb *bp, bool enable)
>
> bool return type.
>
>> +{
>> + unsigned long flags;
>> + u32 ncr;
>
> u32 old, ncr;
>
>> +
>> + spin_lock_irqsave(&bp->lock, flags);
>> + ncr = macb_readl(bp, NCR);
>
> old = ncr;
>
>> + if (enable)
>> + ncr |= GEM_BIT(TXLPIEN);
>> + else
>> + ncr &= ~GEM_BIT(TXLPIEN);
>
> if (old != ncr)
>> + macb_writel(bp, NCR, ncr);
>> + bp->tx_lpi_enabled = enable;
>
> No need for tx_lpi_enabled
>
>> + spin_unlock_irqrestore(&bp->lock, flags);
>
> return old != ncr;
>
>> +}
>
> ...
>
>> +/* Wake from LPI before transmitting. The MAC must deassert TXLPIEN
>> + * and wait for the PHY to exit LPI before any frame can be sent.
>> + * IEEE 802.3az Tw_sys is ~17us for 1000BASE-T, ~30us for 100BASE-TX;
>> + * we use a conservative 50us.
>> + */
>> +static void macb_tx_lpi_wake(struct macb *bp)
>> +{
>> + if (!bp->tx_lpi_enabled)
>> + return;
>
> No need for this if().
>
>> +
>> + macb_tx_lpi_set(bp, false);
>
> instead:
> if (!macb_tx_lpi_set(bp, false))
> return;
>
> The presence of the spinlock in macb_tx_lpi_set() suggests that there
> could be races, so keeping the state completely inside the spinlock
> region would be sensible.
>
>> + cancel_delayed_work(&bp->tx_lpi_work);
>
> I wonder whether this is reliable on its own. cancel_delayed_work()
> documentation says:
>
> * Note:
> * The work callback function may still be running on return, unless
> * it returns %true and the work doesn't re-arm itself. Explicitly
> flush or
> * use cancel_delayed_work_sync() to wait on it.
>
> That means macb_tx_lpi_work_fn() could have just been entered at the
> point that cancel_delayed_work() has been called. Would that cause a
> problem, e.g. setting LPI mode again, or would we be guaranteed that
> macb_tx_all_queues_idle() returns false preventing LPI mode being set
> again?
AFAIK, the race shouldn't be an issue here because macb_tx_lpi_wake()
is called from macb_start_xmit() after the TX descriptors have been
written and tx_head has been advanced (there's a wmb() before the
call to ensure visibility). So if macb_tx_lpi_work_fn() happens to
be running concurrently, macb_tx_all_queues_idle() will see
tx_head != tx_tail and return false, preventing LPI from being
re-enabled.
>
> Thanks.
Nicolai
next prev parent reply other threads:[~2026-02-24 10:40 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-24 9:18 [PATCH net-next v2 0/5] net: cadence: macb: add IEEE 802.3az EEE support Nicolai Buchwitz
2026-02-24 9:18 ` [PATCH net-next v2 1/5] net: cadence: macb: add EEE register definitions and capability flag Nicolai Buchwitz
2026-02-24 9:18 ` [PATCH net-next v2 2/5] net: cadence: macb: add EEE LPI statistics counters Nicolai Buchwitz
2026-02-24 9:18 ` [PATCH net-next v2 3/5] net: cadence: macb: implement EEE TX LPI support Nicolai Buchwitz
2026-02-24 10:17 ` Russell King (Oracle)
2026-02-24 10:40 ` Nicolai Buchwitz [this message]
2026-02-24 9:18 ` [PATCH net-next v2 4/5] net: cadence: macb: add ethtool EEE support Nicolai Buchwitz
2026-02-24 9:18 ` [PATCH net-next v2 5/5] net: cadence: macb: enable EEE for Raspberry Pi RP1 Nicolai Buchwitz
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=d8463e10e0c07ddf404a2515e2a8640c@tipi-net.de \
--to=nb@tipi-net.de \
--cc=andrew+netdev@lunn.ch \
--cc=claudiu.beznea@tuxon.dev \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=kuba@kernel.org \
--cc=linux@armlinux.org.uk \
--cc=netdev@vger.kernel.org \
--cc=nicolas.ferre@microchip.com \
--cc=pabeni@redhat.com \
--cc=phil@raspberrypi.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