Skip to content

EEE support for rp1 mac#7251

Open
nbuchwitz wants to merge 8 commits intoraspberrypi:rpi-6.12.yfrom
nbuchwitz:devel/gmac-eee
Open

EEE support for rp1 mac#7251
nbuchwitz wants to merge 8 commits intoraspberrypi:rpi-6.12.yfrom
nbuchwitz:devel/gmac-eee

Conversation

@nbuchwitz
Copy link
Contributor

This adds EEE support to the macb driver for the Pi 5 / CM5. Right now EEE is broken on the Pi because the PHY advertises EEE but the MAC has no LPI support, so it was marked as broken in #6900. This series fixes that by implementing proper software-managed TX LPI in the driver and reverting the DT workaround.

See #6855

This should go through mainline as the EEE registers are the same across all Cadence GEM variants (SAMA5D2, SAME70, PIC32CZ, RP1, ...) and the code is generic, just gated on a capability flag. I'm looking for early feedback from Pi users before sending it upstream though. If you've got a Pi 5 or CM5, give it a spin and let me know how it goes — link stability, ethtool --show-eee, ethtool -S | grep lpi, that kind of thing.

nbuchwitz and others added 2 commits February 18, 2026 11:50
Wire phy_ethtool_nway_reset() as the .nway_reset ethtool operation,
allowing userspace to restart PHY autonegotiation via 'ethtool -r'.

Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
@nbuchwitz
Copy link
Contributor Author

f0d41dc is not directly EEE related, but I noticed it was missing while debugging

@pelwell
Copy link
Contributor

pelwell commented Feb 18, 2026

Thanks, Nicolai - this looks great.

For anyone wishing to try the new EEE capability, you can install a trial build using sudo rpi-update pulls/7251, after reading the caveats.

@pelwell
Copy link
Contributor

pelwell commented Feb 18, 2026

For comparison, these are the values I get after being up for a few minutes:

pi@philpi5:~$ ethtool --show-eee eth0
EEE settings for eth0:
        EEE status: enabled - active
        Tx LPI: 0 (us)
        Supported EEE link modes:  100baseT/Full
                                   1000baseT/Full
        Advertised EEE link modes:  100baseT/Full
                                    1000baseT/Full
        Link partner advertised EEE link modes:  100baseT/Full
                                                 1000baseT/Full
pi@philpi5:~$ ethtool -S eth0 | grep lpi
     rx_lpi_transitions: 0
     rx_lpi_time: 0
     tx_lpi_transitions: 88
     tx_lpi_time: 85760892

@nbuchwitz
Copy link
Contributor Author

For better comparison: is the ethernet link actively used or not? If yes, how do the tx lpi rate change when the ethernet is mostly idle (eg wifi used)?

Add register and bitfield definitions for the Cadence GEM MAC's
IEEE 802.3az Energy Efficient Ethernet (EEE) support:

- LPI statistics counter registers (GEM_RXLPI, GEM_RXLPITIME,
  GEM_TXLPI, GEM_TXLPITIME) at offsets 0x270-0x27c
- TX LPI enable bitfield (GEM_TXLPIEN) in the NCR register (bit 19),
  which directly asserts/deasserts LPI on the transmit path
- MACB_CAPS_EEE capability flag to gate EEE support per platform

These registers are present in all Cadence GEM revisions that support
EEE (verified on SAMA5D2, SAME70, PIC32CZ, and RP1 variants).

No functional change.

Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
Expose the GEM MAC's EEE Low Power Idle hardware counters through
ethtool -S:

- rx_lpi_transitions: number of RX LPI entry events
- rx_lpi_time: cumulative time spent in RX LPI
- tx_lpi_transitions: number of TX LPI entry events (TXLPIEN 0->1)
- tx_lpi_time: cumulative time in TX LPI

These are clear-on-read hardware registers at offsets 0x270-0x27c,
automatically collected by the existing gem_statistics read loop.

Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
Implement software-managed TX Low Power Idle (LPI) for the Cadence GEM
MAC as part of IEEE 802.3az Energy Efficient Ethernet support.

The GEM MAC has no built-in idle timer - the TXLPIEN bit (NCR bit 19)
immediately asserts LPI and blocks all TX while set. The MAC does not
auto-wake for transmit. Per Microchip GMAC documentation (section
40.6.19): "It is best to use firmware to control LPI."

This patch implements a software idle timer using delayed_work:
- On TX completion with an empty ring, schedule LPI entry after a
  configurable idle timeout (default 500ms, chosen as a good
  compromise between energy savings and minimizing throughput impact
  during bursty workloads - lower values cause more frequent LPI
  wake transitions with associated retransmission overhead)
- On TX start, wake from LPI by clearing TXLPIEN, cancelling any
  pending re-entry, and waiting 50us for the PHY to exit LPI
  (conservative vs IEEE 802.3az Tw_sys of ~17us/~30us)
- On link up, check EEE negotiation via phy_init_eee() and defer
  first LPI entry by 1 second per IEEE 802.3az requirements
- On link down, immediately cancel pending work and clear TXLPIEN

The timer value is configurable at runtime via ethtool --set-eee
tx-timer.

The implementation is gated on MACB_CAPS_EEE so platforms must
explicitly opt in via their macb_config.

Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
Implement ethtool get_eee and set_eee operations for the Cadence GEM
MAC, delegating to phylink for PHY-level EEE negotiation state.

The MAC-level LPI control (TXLPIEN) is not manipulated directly in the
ethtool ops. Instead, phylink_ethtool_set_eee() updates the PHY's EEE
advertisement, which triggers link renegotiation. The mac_link_up
callback then checks the negotiated EEE state and enables LPI
accordingly.

Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
Enable IEEE 802.3az Energy Efficient Ethernet on the Raspberry Pi 5's
RP1 southbridge by adding MACB_CAPS_EEE to its platform config.

The RP1 contains a Cadence GEM_GXL MAC (revision 0x00070109) paired
with a Broadcom BCM54213PE PHY, both of which support EEE at
1000BASE-T and 100BASE-TX.

Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
@nbuchwitz
Copy link
Contributor Author

nbuchwitz commented Feb 19, 2026

After some more testing, I've improved the patch set further and fixed a bug.

Changes since v1:

  • Use mod_delayed_work() instead of schedule_delayed_work() for LPI idle timer re-entry. schedule_delayed_work() is a no-op when work is already pending, so the timer was never reset by TX completions - causing LPI to be asserted periodically even under full load.
  • Set MACB_TX_LPI_TIMER_DEFAULT_MS to 500ms (was 250ms). Chosen as a good compromise between energy savings and throughput stability - lower values cause more frequent LPI wake transitions with associated retransmission overhead on bursty workloads.
  • Remove unused RX LPI status bit change interrupt definitions (RXLPISBC). The interrupt is not wired up in this series and can be added later if needed for diagnostics.
  • Include fix for a probable upstream bug in phy_ethtool_set_eee() where EEE advertised modes were not correctly restored after an off/on toggle, because eee_cfg.eee_enabled was updated after genphy_c45_ethtool_set_eee() instead of before. -> already fixed in a615309 (not part of rpi-6.12.y yet)

…of phydev->eee_cfg.eee_enabled

This is a follow-up to 41ffcd9 ("net: phy: fix phylib's dual
eee_enabled") and resolves an issue with genphy_c45_an_config_eee_aneg()
(called from genphy_c45_ethtool_set_eee) not seeing the new value of
phydev->eee_cfg.eee_enabled.

Fixes: 49168d1 ("net: phy: Add phy_support_eee() indicating MAC support EEE")
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Reported-by: Choong Yong Liang <yong.liang.choong@linux.intel.com>
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit f26a29a)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Comments