* [PATCH net-next 0/5] net: cadence: macb: add IEEE 802.3az EEE support
@ 2026-02-23 9:04 Nicolai Buchwitz
2026-02-23 9:04 ` [PATCH net-next 1/5] net: cadence: macb: add EEE register definitions and capability flag Nicolai Buchwitz
` (5 more replies)
0 siblings, 6 replies; 9+ messages in thread
From: Nicolai Buchwitz @ 2026-02-23 9:04 UTC (permalink / raw)
To: netdev
Cc: andrew+netdev, claudiu.beznea, davem, edumazet, kuba,
nicolas.ferre, pabeni, linux, Nicolai Buchwitz
Add Energy Efficient Ethernet (IEEE 802.3az) support to the Cadence GEM
(macb) driver. The GEM MAC has hardware LPI registers but no built-in
idle timer, so the driver implements software-managed TX LPI using a
delayed_work timer, as recommended by Microchip's GMAC documentation.
The series is structured as follows:
1. Register definitions: LPI counter offsets (0x270-0x27c), TXLPIEN
bitfield (NCR bit 19), and a MACB_CAPS_EEE capability flag.
2. LPI statistics: Expose the four hardware EEE counters (RX/TX LPI
transitions and time) through ethtool -S, accumulated in software
since they are clear-on-read.
3. TX LPI engine: A delayed_work-based idle timer that enters LPI
after 250ms of TX inactivity and wakes before transmit with a
conservative 50us PHY wake delay. LPI entry is deferred 1 second
after link-up per IEEE 802.3az.
4. ethtool EEE ops: get_eee/set_eee delegating to phylink for PHY
negotiation; the MAC-level TXLPIEN is controlled only from the
phylink mac_link_up/mac_link_down callbacks.
5. RP1 enablement: Set MACB_CAPS_EEE for the Raspberry Pi 5's RP1
southbridge (Cadence GEM_GXL rev 0x00070109 + BCM54213PE PHY).
Tested on Raspberry Pi 5 with iperf3 throughput/latency benchmarks,
ethtool --show-eee / --set-eee, ethtool -S LPI counter verification,
and cable unplug/replug cycling.
Nicolai Buchwitz (5):
net: cadence: macb: add EEE register definitions and capability flag
net: cadence: macb: add EEE LPI statistics counters
net: cadence: macb: implement EEE TX LPI support
net: cadence: macb: add ethtool EEE support
net: cadence: macb: enable EEE for Raspberry Pi RP1
drivers/net/ethernet/cadence/macb.h | 23 ++++
drivers/net/ethernet/cadence/macb_main.c | 160 ++++++++++++++++++++++-
2 files changed, 180 insertions(+), 3 deletions(-)
--
2.39.5
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH net-next 1/5] net: cadence: macb: add EEE register definitions and capability flag
2026-02-23 9:04 [PATCH net-next 0/5] net: cadence: macb: add IEEE 802.3az EEE support Nicolai Buchwitz
@ 2026-02-23 9:04 ` Nicolai Buchwitz
2026-02-23 9:04 ` [PATCH net-next 2/5] net: cadence: macb: add EEE LPI statistics counters Nicolai Buchwitz
` (4 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Nicolai Buchwitz @ 2026-02-23 9:04 UTC (permalink / raw)
To: netdev
Cc: andrew+netdev, claudiu.beznea, davem, edumazet, kuba,
nicolas.ferre, pabeni, linux, Nicolai Buchwitz
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>
---
drivers/net/ethernet/cadence/macb.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index 87414a2ddf6e..f8fdb83bb5f3 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -170,6 +170,10 @@
#define GEM_PCSANNPTX 0x021c /* PCS AN Next Page TX */
#define GEM_PCSANNPLP 0x0220 /* PCS AN Next Page LP */
#define GEM_PCSANEXTSTS 0x023c /* PCS AN Extended Status */
+#define GEM_RXLPI 0x0270 /* EEE RX LPI Transitions */
+#define GEM_RXLPITIME 0x0274 /* EEE RX LPI Time */
+#define GEM_TXLPI 0x0278 /* EEE TX LPI Transitions */
+#define GEM_TXLPITIME 0x027c /* EEE TX LPI Time */
#define GEM_DCFG1 0x0280 /* Design Config 1 */
#define GEM_DCFG2 0x0284 /* Design Config 2 */
#define GEM_DCFG3 0x0288 /* Design Config 3 */
@@ -264,6 +268,10 @@
#define MACB_MIIONRGMII_OFFSET 28 /* MII Usage on RGMII Interface */
#define MACB_MIIONRGMII_SIZE 1
+/* GEM specific NCR bitfields. */
+#define GEM_TXLPIEN_OFFSET 19 /* TX LPI Enable */
+#define GEM_TXLPIEN_SIZE 1
+
/* Bitfields in NCFGR */
#define MACB_SPD_OFFSET 0 /* Speed */
#define MACB_SPD_SIZE 1
@@ -779,6 +787,7 @@
#define MACB_CAPS_DMA_PTP BIT(22)
#define MACB_CAPS_RSC BIT(23)
#define MACB_CAPS_NO_LSO BIT(24)
+#define MACB_CAPS_EEE BIT(25)
/* LSO settings */
#define MACB_LSO_UFO_ENABLE 0x01
--
2.39.5
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH net-next 2/5] net: cadence: macb: add EEE LPI statistics counters
2026-02-23 9:04 [PATCH net-next 0/5] net: cadence: macb: add IEEE 802.3az EEE support Nicolai Buchwitz
2026-02-23 9:04 ` [PATCH net-next 1/5] net: cadence: macb: add EEE register definitions and capability flag Nicolai Buchwitz
@ 2026-02-23 9:04 ` Nicolai Buchwitz
2026-02-23 9:04 ` [PATCH net-next 3/5] net: cadence: macb: implement EEE TX LPI support Nicolai Buchwitz
` (3 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Nicolai Buchwitz @ 2026-02-23 9:04 UTC (permalink / raw)
To: netdev
Cc: andrew+netdev, claudiu.beznea, davem, edumazet, kuba,
nicolas.ferre, pabeni, linux, Nicolai Buchwitz
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>
---
drivers/net/ethernet/cadence/macb.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index f8fdb83bb5f3..95317965080c 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -1052,6 +1052,10 @@ struct gem_stats {
u64 rx_ip_header_checksum_errors;
u64 rx_tcp_checksum_errors;
u64 rx_udp_checksum_errors;
+ u64 rx_lpi_transitions;
+ u64 rx_lpi_time;
+ u64 tx_lpi_transitions;
+ u64 tx_lpi_time;
};
/* Describes the name and offset of an individual statistic register, as
@@ -1151,6 +1155,10 @@ static const struct gem_statistic gem_statistics[] = {
GEM_BIT(NDS_RXERR)),
GEM_STAT_TITLE_BITS(RXUDPCCNT, "rx_udp_checksum_errors",
GEM_BIT(NDS_RXERR)),
+ GEM_STAT_TITLE(RXLPI, "rx_lpi_transitions"),
+ GEM_STAT_TITLE(RXLPITIME, "rx_lpi_time"),
+ GEM_STAT_TITLE(TXLPI, "tx_lpi_transitions"),
+ GEM_STAT_TITLE(TXLPITIME, "tx_lpi_time"),
};
#define GEM_STATS_LEN ARRAY_SIZE(gem_statistics)
--
2.39.5
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH net-next 3/5] net: cadence: macb: implement EEE TX LPI support
2026-02-23 9:04 [PATCH net-next 0/5] net: cadence: macb: add IEEE 802.3az EEE support Nicolai Buchwitz
2026-02-23 9:04 ` [PATCH net-next 1/5] net: cadence: macb: add EEE register definitions and capability flag Nicolai Buchwitz
2026-02-23 9:04 ` [PATCH net-next 2/5] net: cadence: macb: add EEE LPI statistics counters Nicolai Buchwitz
@ 2026-02-23 9:04 ` Nicolai Buchwitz
2026-02-23 10:07 ` Russell King (Oracle)
2026-02-23 9:04 ` [PATCH net-next 4/5] net: cadence: macb: add ethtool EEE support Nicolai Buchwitz
` (2 subsequent siblings)
5 siblings, 1 reply; 9+ messages in thread
From: Nicolai Buchwitz @ 2026-02-23 9:04 UTC (permalink / raw)
To: netdev
Cc: andrew+netdev, claudiu.beznea, davem, edumazet, kuba,
nicolas.ferre, pabeni, linux, Nicolai Buchwitz
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 250ms). The work function
verifies all TX queues are truly idle before entering LPI to
prevent entering LPI while traffic is still active.
- 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>
---
drivers/net/ethernet/cadence/macb.h | 6 ++
drivers/net/ethernet/cadence/macb_main.c | 120 ++++++++++++++++++++++-
2 files changed, 124 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index 95317965080c..d132ad95ee61 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -1358,6 +1358,12 @@ struct macb {
struct macb_ptp_info *ptp_info; /* macb-ptp interface */
+ /* EEE / LPI state */
+ bool eee_active;
+ bool tx_lpi_enabled;
+ struct delayed_work tx_lpi_work;
+ unsigned int tx_lpi_timer_ms; /* idle timeout before LPI */
+
struct phy *phy;
spinlock_t tsu_clk_lock; /* gem tsu clock locking */
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 43cd013bb70e..d4a81f3a7b9a 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -589,6 +589,86 @@ static const struct phylink_pcs_ops macb_phylink_pcs_ops = {
.pcs_config = macb_pcs_config,
};
+/* Default TX LPI idle timeout in milliseconds.
+ * The MAC will enter LPI after this period of TX inactivity.
+ */
+#define MACB_TX_LPI_TIMER_DEFAULT_MS 250
+
+/* PHY wake time from LPI in microseconds.
+ * IEEE 802.3az: Tw_sys is ~17us for 1000BASE-T, ~30us for 100BASE-TX.
+ * Use a conservative value to ensure the PHY has fully exited LPI.
+ */
+#define MACB_TX_LPI_WAKE_TIME_US 50
+
+static void macb_tx_lpi_set(struct macb *bp, bool enable)
+{
+ unsigned long flags;
+ u32 ncr;
+
+ spin_lock_irqsave(&bp->lock, flags);
+
+ ncr = macb_readl(bp, NCR);
+ if (enable)
+ ncr |= GEM_BIT(TXLPIEN);
+ else
+ ncr &= ~GEM_BIT(TXLPIEN);
+ macb_writel(bp, NCR, ncr);
+
+ bp->tx_lpi_enabled = enable;
+
+ spin_unlock_irqrestore(&bp->lock, flags);
+
+ netdev_dbg(bp->dev, "EEE TX LPI %s\n",
+ enable ? "enabled" : "disabled");
+}
+
+/* Schedule LPI re-entry after TX idle timeout */
+static inline void macb_tx_lpi_schedule(struct macb *bp)
+{
+ if (!bp->eee_active)
+ return;
+
+ mod_delayed_work(system_wq, &bp->tx_lpi_work,
+ msecs_to_jiffies(bp->tx_lpi_timer_ms));
+}
+
+static void macb_tx_lpi_work_fn(struct work_struct *work)
+{
+ struct macb *bp = container_of(work, struct macb, tx_lpi_work.work);
+ unsigned int q;
+
+ if (!bp->eee_active)
+ return;
+
+ /* Only enter LPI if all TX queues are truly idle. The timer may
+ * have been scheduled when one queue drained but traffic resumed
+ * before the timer fired.
+ */
+ for (q = 0; q < bp->num_queues; q++) {
+ if (bp->queues[q].tx_head != bp->queues[q].tx_tail) {
+ /* TX still active, reschedule and check again later */
+ macb_tx_lpi_schedule(bp);
+ return;
+ }
+ }
+
+ macb_tx_lpi_set(bp, true);
+}
+
+/* Called from TX path to wake from LPI before transmitting */
+static inline void macb_tx_lpi_wake(struct macb *bp)
+{
+ if (!bp->tx_lpi_enabled)
+ return;
+
+ macb_tx_lpi_set(bp, false);
+ /* Cancel any pending re-entry */
+ cancel_delayed_work(&bp->tx_lpi_work);
+
+ /* Wait for PHY to exit LPI before transmitting */
+ udelay(MACB_TX_LPI_WAKE_TIME_US);
+}
+
static void macb_mac_config(struct phylink_config *config, unsigned int mode,
const struct phylink_link_state *state)
{
@@ -661,10 +741,16 @@ static void macb_mac_link_down(struct phylink_config *config, unsigned int mode,
queue_writel(queue, IDR,
bp->rx_intr_mask | MACB_TX_INT_FLAGS | MACB_BIT(HRESP));
- /* Disable Rx and Tx */
- ctrl = macb_readl(bp, NCR) & ~(MACB_BIT(RE) | MACB_BIT(TE));
+ /* Cancel any pending LPI entry */
+ cancel_delayed_work(&bp->tx_lpi_work);
+
+ /* Disable TX LPI, Rx, and Tx */
+ ctrl = macb_readl(bp, NCR) & ~(GEM_BIT(TXLPIEN) | MACB_BIT(RE) | MACB_BIT(TE));
macb_writel(bp, NCR, ctrl);
+ bp->eee_active = false;
+ bp->tx_lpi_enabled = false;
+
netif_tx_stop_all_queues(ndev);
}
@@ -732,6 +818,19 @@ static void macb_mac_link_up(struct phylink_config *config,
macb_writel(bp, NCR, ctrl | MACB_BIT(RE) | MACB_BIT(TE));
netif_tx_wake_all_queues(ndev);
+
+ /* EEE: check if link partner negotiated EEE.
+ * Per IEEE 802.3az / Microchip GMAC docs: LPI must not be
+ * requested until the link has been up for at least 1 second.
+ */
+ if (phy && (bp->caps & MACB_CAPS_EEE)) {
+ bp->eee_active = phy_init_eee(phy, false) >= 0 &&
+ phy->enable_tx_lpi;
+ netdev_dbg(ndev, "EEE: active=%d\n", bp->eee_active);
+ if (bp->eee_active)
+ schedule_delayed_work(&bp->tx_lpi_work,
+ msecs_to_jiffies(1000));
+ }
}
static struct phylink_pcs *macb_mac_select_pcs(struct phylink_config *config,
@@ -1242,6 +1341,11 @@ static int macb_tx_complete(struct macb_queue *queue, int budget)
CIRC_CNT(queue->tx_head, queue->tx_tail,
bp->tx_ring_size) <= MACB_TX_WAKEUP_THRESH(bp))
netif_wake_subqueue(bp->dev, queue_index);
+
+ /* Schedule LPI re-entry when TX ring is drained */
+ if (queue->tx_head == queue->tx_tail)
+ macb_tx_lpi_schedule(bp);
+
spin_unlock_irqrestore(&queue->tx_ptr_lock, flags);
return packets;
@@ -2270,6 +2374,10 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
bool is_lso;
netdev_tx_t ret = NETDEV_TX_OK;
+ /* Wake from LPI before transmitting */
+ if (unlikely(bp->tx_lpi_enabled))
+ macb_tx_lpi_wake(bp);
+
if (macb_clear_csum(skb)) {
dev_kfree_skb_any(skb);
return ret;
@@ -2973,6 +3081,9 @@ static int macb_open(struct net_device *dev)
if (err)
goto phy_off;
+ if ((bp->caps & MACB_CAPS_EEE) && dev->phydev)
+ phy_support_eee(dev->phydev);
+
netif_tx_start_all_queues(dev);
if (bp->ptp_info)
@@ -3004,6 +3115,8 @@ static int macb_close(struct net_device *dev)
netif_tx_stop_all_queues(dev);
+ cancel_delayed_work_sync(&bp->tx_lpi_work);
+
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
napi_disable(&queue->napi_rx);
napi_disable(&queue->napi_tx);
@@ -5616,6 +5729,8 @@ static int macb_probe(struct platform_device *pdev)
}
INIT_WORK(&bp->hresp_err_bh_work, macb_hresp_error_task);
+ INIT_DELAYED_WORK(&bp->tx_lpi_work, macb_tx_lpi_work_fn);
+ bp->tx_lpi_timer_ms = MACB_TX_LPI_TIMER_DEFAULT_MS;
netdev_info(dev, "Cadence %s rev 0x%08x at 0x%08lx irq %d (%pM)\n",
macb_is_gem(bp) ? "GEM" : "MACB", macb_readl(bp, MID),
@@ -5659,6 +5774,7 @@ static void macb_remove(struct platform_device *pdev)
mdiobus_free(bp->mii_bus);
device_set_wakeup_enable(&bp->pdev->dev, 0);
+ cancel_delayed_work_sync(&bp->tx_lpi_work);
cancel_work_sync(&bp->hresp_err_bh_work);
pm_runtime_disable(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
--
2.39.5
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH net-next 4/5] net: cadence: macb: add ethtool EEE support
2026-02-23 9:04 [PATCH net-next 0/5] net: cadence: macb: add IEEE 802.3az EEE support Nicolai Buchwitz
` (2 preceding siblings ...)
2026-02-23 9:04 ` [PATCH net-next 3/5] net: cadence: macb: implement EEE TX LPI support Nicolai Buchwitz
@ 2026-02-23 9:04 ` Nicolai Buchwitz
2026-02-23 9:04 ` [PATCH net-next 5/5] net: cadence: macb: enable EEE for Raspberry Pi RP1 Nicolai Buchwitz
2026-02-23 9:14 ` [PATCH net-next 0/5] net: cadence: macb: add IEEE 802.3az EEE support Russell King (Oracle)
5 siblings, 0 replies; 9+ messages in thread
From: Nicolai Buchwitz @ 2026-02-23 9:04 UTC (permalink / raw)
To: netdev
Cc: andrew+netdev, claudiu.beznea, davem, edumazet, kuba,
nicolas.ferre, pabeni, linux, Nicolai Buchwitz
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>
---
drivers/net/ethernet/cadence/macb_main.c | 37 ++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index d4a81f3a7b9a..178c0ddc78cd 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -3634,6 +3634,41 @@ static int macb_set_ringparam(struct net_device *netdev,
return 0;
}
+static int macb_get_eee(struct net_device *ndev, struct ethtool_keee *edata)
+{
+ struct macb *bp = netdev_priv(ndev);
+ int ret;
+
+ if (!(bp->caps & MACB_CAPS_EEE))
+ return -EOPNOTSUPP;
+
+ ret = phylink_ethtool_get_eee(bp->phylink, edata);
+ if (ret)
+ return ret;
+
+ edata->tx_lpi_timer = bp->tx_lpi_timer_ms * 1000;
+
+ return 0;
+}
+
+static int macb_set_eee(struct net_device *ndev, struct ethtool_keee *edata)
+{
+ struct macb *bp = netdev_priv(ndev);
+
+ if (!(bp->caps & MACB_CAPS_EEE))
+ return -EOPNOTSUPP;
+
+ if (edata->tx_lpi_timer)
+ bp->tx_lpi_timer_ms = edata->tx_lpi_timer / 1000;
+
+ /* Don't directly control TXLPIEN here. phylink_ethtool_set_eee()
+ * updates the PHY, which will bounce the link if tx_lpi_enabled
+ * changes. That triggers mac_link_down/mac_link_up where we
+ * enable/disable TXLPIEN based on the negotiated state.
+ */
+ return phylink_ethtool_set_eee(bp->phylink, edata);
+}
+
#ifdef CONFIG_MACB_USE_HWSTAMP
static unsigned int gem_get_tsu_rate(struct macb *bp)
{
@@ -4058,6 +4093,8 @@ static const struct ethtool_ops gem_ethtool_ops = {
.get_rxnfc = gem_get_rxnfc,
.set_rxnfc = gem_set_rxnfc,
.get_rx_ring_count = gem_get_rx_ring_count,
+ .get_eee = macb_get_eee,
+ .set_eee = macb_set_eee,
};
static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
--
2.39.5
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH net-next 5/5] net: cadence: macb: enable EEE for Raspberry Pi RP1
2026-02-23 9:04 [PATCH net-next 0/5] net: cadence: macb: add IEEE 802.3az EEE support Nicolai Buchwitz
` (3 preceding siblings ...)
2026-02-23 9:04 ` [PATCH net-next 4/5] net: cadence: macb: add ethtool EEE support Nicolai Buchwitz
@ 2026-02-23 9:04 ` Nicolai Buchwitz
2026-02-23 9:14 ` [PATCH net-next 0/5] net: cadence: macb: add IEEE 802.3az EEE support Russell King (Oracle)
5 siblings, 0 replies; 9+ messages in thread
From: Nicolai Buchwitz @ 2026-02-23 9:04 UTC (permalink / raw)
To: netdev
Cc: andrew+netdev, claudiu.beznea, davem, edumazet, kuba,
nicolas.ferre, pabeni, linux, Nicolai Buchwitz
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>
---
drivers/net/ethernet/cadence/macb_main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 178c0ddc78cd..7377c0f0c040 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -5536,7 +5536,8 @@ static const struct macb_config eyeq5_config = {
static const struct macb_config raspberrypi_rp1_config = {
.caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_CLK_HW_CHG |
MACB_CAPS_JUMBO |
- MACB_CAPS_GEM_HAS_PTP,
+ MACB_CAPS_GEM_HAS_PTP |
+ MACB_CAPS_EEE,
.dma_burst_length = 16,
.clk_init = macb_clk_init,
.init = macb_init,
--
2.39.5
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH net-next 0/5] net: cadence: macb: add IEEE 802.3az EEE support
2026-02-23 9:04 [PATCH net-next 0/5] net: cadence: macb: add IEEE 802.3az EEE support Nicolai Buchwitz
` (4 preceding siblings ...)
2026-02-23 9:04 ` [PATCH net-next 5/5] net: cadence: macb: enable EEE for Raspberry Pi RP1 Nicolai Buchwitz
@ 2026-02-23 9:14 ` Russell King (Oracle)
5 siblings, 0 replies; 9+ messages in thread
From: Russell King (Oracle) @ 2026-02-23 9:14 UTC (permalink / raw)
To: Nicolai Buchwitz
Cc: netdev, andrew+netdev, claudiu.beznea, davem, edumazet, kuba,
nicolas.ferre, pabeni
On Mon, Feb 23, 2026 at 10:04:07AM +0100, Nicolai Buchwitz wrote:
> Add Energy Efficient Ethernet (IEEE 802.3az) support to the Cadence GEM
> (macb) driver. The GEM MAC has hardware LPI registers but no built-in
> idle timer, so the driver implements software-managed TX LPI using a
> delayed_work timer, as recommended by Microchip's GMAC documentation.
>
> The series is structured as follows:
>
> 1. Register definitions: LPI counter offsets (0x270-0x27c), TXLPIEN
> bitfield (NCR bit 19), and a MACB_CAPS_EEE capability flag.
>
> 2. LPI statistics: Expose the four hardware EEE counters (RX/TX LPI
> transitions and time) through ethtool -S, accumulated in software
> since they are clear-on-read.
>
> 3. TX LPI engine: A delayed_work-based idle timer that enters LPI
> after 250ms of TX inactivity and wakes before transmit with a
> conservative 50us PHY wake delay. LPI entry is deferred 1 second
> after link-up per IEEE 802.3az.
>
> 4. ethtool EEE ops: get_eee/set_eee delegating to phylink for PHY
> negotiation; the MAC-level TXLPIEN is controlled only from the
> phylink mac_link_up/mac_link_down callbacks.
This needs a rewrite - phylink has EEE support now, with new callbacks
and configuration. There is no need to use the obsolete (and incorrect)
phy_init_eee() anymore.
Please see:
e9f03a6a879b net: phylink: add support for notifying PCS about EEE
and
03abf2a7c654 net: phylink: add EEE management
Thanks.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH net-next 3/5] net: cadence: macb: implement EEE TX LPI support
2026-02-23 9:04 ` [PATCH net-next 3/5] net: cadence: macb: implement EEE TX LPI support Nicolai Buchwitz
@ 2026-02-23 10:07 ` Russell King (Oracle)
2026-02-23 14:54 ` nb
0 siblings, 1 reply; 9+ messages in thread
From: Russell King (Oracle) @ 2026-02-23 10:07 UTC (permalink / raw)
To: Nicolai Buchwitz
Cc: netdev, andrew+netdev, claudiu.beznea, davem, edumazet, kuba,
nicolas.ferre, pabeni
On Mon, Feb 23, 2026 at 10:04:10AM +0100, Nicolai Buchwitz wrote:
> 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 250ms). The work function
> verifies all TX queues are truly idle before entering LPI to
> prevent entering LPI while traffic is still active.
> - 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.
In addition to my comments, please check the nipabot status for this
patch which can be found at:
https://patchwork.kernel.org/project/netdevbpf/patch/20260223090412.44070-4-nb@tipi-net.de/
Thanks.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH net-next 3/5] net: cadence: macb: implement EEE TX LPI support
2026-02-23 10:07 ` Russell King (Oracle)
@ 2026-02-23 14:54 ` nb
0 siblings, 0 replies; 9+ messages in thread
From: nb @ 2026-02-23 14:54 UTC (permalink / raw)
To: Russell King (Oracle)
Cc: netdev, andrew+netdev, claudiu.beznea, davem, edumazet, kuba,
nicolas.ferre, pabeni
On 23.2.2026 11:07, Russell King (Oracle) wrote:
> On Mon, Feb 23, 2026 at 10:04:10AM +0100, Nicolai Buchwitz wrote:
>> 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 250ms). The work function
>> verifies all TX queues are truly idle before entering LPI to
>> prevent entering LPI while traffic is still active.
>> - 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.
>
> In addition to my comments, please check the nipabot status for this
> patch which can be found at:
>
> https://patchwork.kernel.org/project/netdevbpf/patch/20260223090412.44070-4-nb@tipi-net.de/
>
Thanks. I will have a look at the mentioned patches + feedback from the
pipeline and prepare a v2 of this series.
> Thanks.
Nicolai
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-02-23 14:54 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-23 9:04 [PATCH net-next 0/5] net: cadence: macb: add IEEE 802.3az EEE support Nicolai Buchwitz
2026-02-23 9:04 ` [PATCH net-next 1/5] net: cadence: macb: add EEE register definitions and capability flag Nicolai Buchwitz
2026-02-23 9:04 ` [PATCH net-next 2/5] net: cadence: macb: add EEE LPI statistics counters Nicolai Buchwitz
2026-02-23 9:04 ` [PATCH net-next 3/5] net: cadence: macb: implement EEE TX LPI support Nicolai Buchwitz
2026-02-23 10:07 ` Russell King (Oracle)
2026-02-23 14:54 ` nb
2026-02-23 9:04 ` [PATCH net-next 4/5] net: cadence: macb: add ethtool EEE support Nicolai Buchwitz
2026-02-23 9:04 ` [PATCH net-next 5/5] net: cadence: macb: enable EEE for Raspberry Pi RP1 Nicolai Buchwitz
2026-02-23 9:14 ` [PATCH net-next 0/5] net: cadence: macb: add IEEE 802.3az EEE support Russell King (Oracle)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox