[PATCH] kernel: backport Mediatek SoC EEE support

Qingfang Deng dqfext at gmail.com
Wed Mar 5 07:23:09 PST 2025


Backport Mediatek SoC EEE support from net-next upstream.

Signed-off-by: Qingfang Deng <dqfext at gmail.com>
---
 ...et-ethernet-mediatek-add-EEE-support.patch | 139 ++++++++++++++++++
 1 file changed, 139 insertions(+)
 create mode 100644 target/linux/generic/backport-6.6/753-v6.15-net-ethernet-mediatek-add-EEE-support.patch

diff --git a/target/linux/generic/backport-6.6/753-v6.15-net-ethernet-mediatek-add-EEE-support.patch b/target/linux/generic/backport-6.6/753-v6.15-net-ethernet-mediatek-add-EEE-support.patch
new file mode 100644
index 0000000000..862bc18ab5
--- /dev/null
+++ b/target/linux/generic/backport-6.6/753-v6.15-net-ethernet-mediatek-add-EEE-support.patch
@@ -0,0 +1,136 @@
+From 952d7325362ffbefa6ce5619fb4e53c2159ec7a7 Mon Sep 17 00:00:00 2001
+From: Qingfang Deng <dqfext at gmail.com>
+Date: Mon, 17 Feb 2025 17:40:21 +0800
+Subject: [PATCH] net: ethernet: mediatek: add EEE support
+
+Add EEE support to MediaTek SoC Ethernet. The register fields are
+similar to the ones in MT7531, except that the LPI threshold is in
+milliseconds.
+
+Signed-off-by: Qingfang Deng <dqfext at gmail.com>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 64 +++++++++++++++++++++
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 11 ++++
+ 2 files changed, 75 insertions(+)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -786,6 +786,7 @@ static void mtk_mac_link_up(struct phyli
+ 
+ 	mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
+ 	mcr &= ~(MAC_MCR_SPEED_100 | MAC_MCR_SPEED_1000 |
++		 MAC_MCR_EEE100M | MAC_MCR_EEE1G |
+ 		 MAC_MCR_FORCE_DPX | MAC_MCR_FORCE_TX_FC |
+ 		 MAC_MCR_FORCE_RX_FC);
+ 
+@@ -811,6 +812,18 @@ static void mtk_mac_link_up(struct phyli
+ 	if (rx_pause)
+ 		mcr |= MAC_MCR_FORCE_RX_FC;
+ 
++	if (mode == MLO_AN_PHY && phy && phy_init_eee(phy, false) >= 0) {
++		switch (speed) {
++		case SPEED_2500:
++		case SPEED_1000:
++			mcr |= MAC_MCR_EEE1G;
++			break;
++		case SPEED_100:
++			mcr |= MAC_MCR_EEE100M;
++			break;
++		}
++	}
++
+ 	mcr |= MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK;
+ 	mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
+ }
+@@ -4476,6 +4489,55 @@ static int mtk_set_pauseparam(struct net
+ 	return phylink_ethtool_set_pauseparam(mac->phylink, pause);
+ }
+ 
++static int mtk_get_eee(struct net_device *dev, struct ethtool_eee *eee)
++{
++	struct mtk_mac *mac = netdev_priv(dev);
++	u32 reg;
++	int ret;
++
++	ret = phylink_ethtool_get_eee(mac->phylink, eee);
++	if (ret)
++		return ret;
++
++	reg = mtk_r32(mac->hw, MTK_MAC_EEECR(mac->id));
++	eee->tx_lpi_enabled = !(reg & MAC_EEE_LPI_MODE);
++	eee->tx_lpi_timer = FIELD_GET(MAC_EEE_LPI_TXIDLE_THD, reg) * 1000;
++
++	return 0;
++}
++
++static int mtk_set_eee(struct net_device *dev, struct ethtool_eee *eee)
++{
++	struct mtk_mac *mac = netdev_priv(dev);
++	u32 txidle_thd_ms, reg;
++	int ret;
++
++	/* Tx idle timer in ms */
++	txidle_thd_ms = DIV_ROUND_UP(eee->tx_lpi_timer, 1000);
++	if (!FIELD_FIT(MAC_EEE_LPI_TXIDLE_THD, txidle_thd_ms))
++		return -EINVAL;
++
++	reg = FIELD_PREP(MAC_EEE_LPI_TXIDLE_THD, txidle_thd_ms);
++
++	/* PHY Wake-up time, this field does not have a reset value, so use the
++	 * reset value from MT7531 (36us for 100BaseT and 17us for 1000BaseT).
++	 */
++	reg |= FIELD_PREP(MAC_EEE_WAKEUP_TIME_1000, 17) |
++	       FIELD_PREP(MAC_EEE_WAKEUP_TIME_100, 36);
++
++	if (!eee->tx_lpi_enabled)
++		/* Force LPI Mode without a delay */
++		reg |= MAC_EEE_LPI_MODE;
++
++	ret = phylink_ethtool_set_eee(mac->phylink, eee);
++	if (ret)
++		return ret;
++
++	mtk_w32(mac->hw, reg, MTK_MAC_EEECR(mac->id));
++
++	return 0;
++}
++
+ static u16 mtk_select_queue(struct net_device *dev, struct sk_buff *skb,
+ 			    struct net_device *sb_dev)
+ {
+@@ -4508,6 +4570,8 @@ static const struct ethtool_ops mtk_etht
+ 	.set_pauseparam		= mtk_set_pauseparam,
+ 	.get_rxnfc		= mtk_get_rxnfc,
+ 	.set_rxnfc		= mtk_set_rxnfc,
++	.get_eee		= mtk_get_eee,
++	.set_eee		= mtk_set_eee,
+ };
+ 
+ static const struct net_device_ops mtk_netdev_ops = {
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -453,6 +453,8 @@
+ #define MAC_MCR_RX_FIFO_CLR_DIS	BIT(12)
+ #define MAC_MCR_BACKOFF_EN	BIT(9)
+ #define MAC_MCR_BACKPR_EN	BIT(8)
++#define MAC_MCR_EEE1G		BIT(7)
++#define MAC_MCR_EEE100M		BIT(6)
+ #define MAC_MCR_FORCE_RX_FC	BIT(5)
+ #define MAC_MCR_FORCE_TX_FC	BIT(4)
+ #define MAC_MCR_SPEED_1000	BIT(3)
+@@ -461,6 +463,15 @@
+ #define MAC_MCR_FORCE_LINK	BIT(0)
+ #define MAC_MCR_FORCE_LINK_DOWN	(MAC_MCR_FORCE_MODE)
+ 
++/* Mac EEE control registers */
++#define MTK_MAC_EEECR(x)		(0x10104 + (x * 0x100))
++#define MAC_EEE_WAKEUP_TIME_1000	GENMASK(31, 24)
++#define MAC_EEE_WAKEUP_TIME_100		GENMASK(23, 16)
++#define MAC_EEE_LPI_TXIDLE_THD		GENMASK(15, 8)
++#define MAC_EEE_CKG_TXIDLE		BIT(3)
++#define MAC_EEE_CKG_RXLPI		BIT(2)
++#define MAC_EEE_LPI_MODE		BIT(0)
++
+ /* Mac status registers */
+ #define MTK_MAC_MSR(x)		(0x10108 + (x * 0x100))
+ #define MAC_MSR_EEE1G		BIT(7)
-- 
2.34.1




More information about the openwrt-devel mailing list