[PATCH net-next v3] net: ethernet: mediatek: add EEE support

Qingfang Deng posted 1 patch 10 months ago
There is a newer version of this series
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 65 +++++++++++++++++++++
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 11 ++++
2 files changed, 76 insertions(+)
[PATCH net-next v3] net: ethernet: mediatek: add EEE support
Posted by Qingfang Deng 10 months ago
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@gmail.com>
---
v3: use phylink managed EEE

 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 65 +++++++++++++++++++++
 drivers/net/ethernet/mediatek/mtk_eth_soc.h | 11 ++++
 2 files changed, 76 insertions(+)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 0ad965ced5ef..985010a7b277 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -815,12 +815,58 @@ static void mtk_mac_link_up(struct phylink_config *config,
 	mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
 }
 
+static void mtk_mac_disable_tx_lpi(struct phylink_config *config)
+{
+	struct mtk_mac *mac = container_of(config, struct mtk_mac,
+					   phylink_config);
+	struct mtk_eth *eth = mac->hw;
+
+	mtk_m32(eth, MAC_MCR_EEE100M | MAC_MCR_EEE1G, 0, MTK_MAC_MCR(mac->id));
+}
+
+static int mtk_mac_enable_tx_lpi(struct phylink_config *config, u32 timer,
+				 bool tx_clk_stop)
+{
+	struct mtk_mac *mac = container_of(config, struct mtk_mac,
+					   phylink_config);
+	struct mtk_eth *eth = mac->hw;
+	u32 val;
+
+	/* Tx idle timer in ms */
+	timer = DIV_ROUND_UP(timer, 1000);
+
+	/* If the timer is zero, then set LPI_MODE, which allows the
+	 * system to enter LPI mode immediately rather than waiting for
+	 * the LPI threshold.
+	 */
+	if (!timer)
+		val = MAC_EEE_LPI_MODE;
+	else if (FIELD_FIT(MAC_EEE_LPI_TXIDLE_THD, timer))
+		val = FIELD_PREP(MAC_EEE_LPI_TXIDLE_THD, timer);
+	else
+		val = MAC_EEE_LPI_TXIDLE_THD;
+
+	if (tx_clk_stop)
+		val |= MAC_EEE_CKG_TXIDLE;
+
+	/* PHY Wake-up time, this field does not have a reset value, so use the
+	 * reset value from MT7531 (36us for 100M and 17us for 1000M).
+	 */
+	val |= FIELD_PREP(MAC_EEE_WAKEUP_TIME_1000, 17) |
+	       FIELD_PREP(MAC_EEE_WAKEUP_TIME_100, 36);
+
+	mtk_w32(eth, val, MTK_MAC_EEECR(mac->id));
+	mtk_m32(eth, 0, MAC_MCR_EEE100M | MAC_MCR_EEE1G, MTK_MAC_MCR(mac->id));
+}
+
 static const struct phylink_mac_ops mtk_phylink_ops = {
 	.mac_select_pcs = mtk_mac_select_pcs,
 	.mac_config = mtk_mac_config,
 	.mac_finish = mtk_mac_finish,
 	.mac_link_down = mtk_mac_link_down,
 	.mac_link_up = mtk_mac_link_up,
+	.mac_disable_tx_lpi = mtk_mac_disable_tx_lpi,
+	.mac_enable_tx_lpi = mtk_mac_enable_tx_lpi,
 };
 
 static int mtk_mdio_init(struct mtk_eth *eth)
@@ -4469,6 +4515,20 @@ static int mtk_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
 	return phylink_ethtool_set_pauseparam(mac->phylink, pause);
 }
 
+static int mtk_get_eee(struct net_device *dev, struct ethtool_keee *eee)
+{
+	struct mtk_mac *mac = netdev_priv(dev);
+
+	return phylink_ethtool_get_eee(mac->phylink, eee);
+}
+
+static int mtk_set_eee(struct net_device *dev, struct ethtool_keee *eee)
+{
+	struct mtk_mac *mac = netdev_priv(dev);
+
+	return phylink_ethtool_set_eee(mac->phylink, eee);
+}
+
 static u16 mtk_select_queue(struct net_device *dev, struct sk_buff *skb,
 			    struct net_device *sb_dev)
 {
@@ -4501,6 +4561,8 @@ static const struct ethtool_ops mtk_ethtool_ops = {
 	.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 = {
@@ -4610,6 +4672,9 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
 	mac->phylink_config.type = PHYLINK_NETDEV;
 	mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
 		MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;
+	mac->phylink_config.lpi_capabilities = MAC_100FD | MAC_1000FD |
+		MAC_2500FD;
+	mac->phylink_config.lpi_timer_default = 1000;
 
 	/* MT7623 gmac0 is now missing its speed-specific PLL configuration
 	 * in its .mac_config method (since state->speed is not valid there.
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 0d5225f1d3ee..90a377ab4359 100644
--- 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.43.0
Re: [PATCH net-next v3] net: ethernet: mediatek: add EEE support
Posted by Jakub Kicinski 10 months ago
On Mon, 17 Feb 2025 11:39:53 +0800 Qingfang Deng wrote:
> 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.

Please wait 24h before reposting next time.
-- 
pv-bot: 24h
Re: [PATCH net-next v3] net: ethernet: mediatek: add EEE support
Posted by kernel test robot 10 months ago
Hi Qingfang,

kernel test robot noticed the following build warnings:

[auto build test WARNING on net-next/main]

url:    https://github.com/intel-lab-lkp/linux/commits/Qingfang-Deng/net-ethernet-mediatek-add-EEE-support/20250217-114148
base:   net-next/main
patch link:    https://lore.kernel.org/r/20250217033954.3698772-1-dqfext%40gmail.com
patch subject: [PATCH net-next v3] net: ethernet: mediatek: add EEE support
config: arm64-randconfig-001-20250217 (https://download.01.org/0day-ci/archive/20250217/202502171610.TU1Cuzq5-lkp@intel.com/config)
compiler: aarch64-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250217/202502171610.TU1Cuzq5-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202502171610.TU1Cuzq5-lkp@intel.com/

All warnings (new ones prefixed by >>):

   drivers/net/ethernet/mediatek/mtk_eth_soc.c: In function 'mtk_mac_enable_tx_lpi':
>> drivers/net/ethernet/mediatek/mtk_eth_soc.c:860:1: warning: control reaches end of non-void function [-Wreturn-type]
     860 | }
         | ^


vim +860 drivers/net/ethernet/mediatek/mtk_eth_soc.c

   826	
   827	static int mtk_mac_enable_tx_lpi(struct phylink_config *config, u32 timer,
   828					 bool tx_clk_stop)
   829	{
   830		struct mtk_mac *mac = container_of(config, struct mtk_mac,
   831						   phylink_config);
   832		struct mtk_eth *eth = mac->hw;
   833		u32 val;
   834	
   835		/* Tx idle timer in ms */
   836		timer = DIV_ROUND_UP(timer, 1000);
   837	
   838		/* If the timer is zero, then set LPI_MODE, which allows the
   839		 * system to enter LPI mode immediately rather than waiting for
   840		 * the LPI threshold.
   841		 */
   842		if (!timer)
   843			val = MAC_EEE_LPI_MODE;
   844		else if (FIELD_FIT(MAC_EEE_LPI_TXIDLE_THD, timer))
   845			val = FIELD_PREP(MAC_EEE_LPI_TXIDLE_THD, timer);
   846		else
   847			val = MAC_EEE_LPI_TXIDLE_THD;
   848	
   849		if (tx_clk_stop)
   850			val |= MAC_EEE_CKG_TXIDLE;
   851	
   852		/* PHY Wake-up time, this field does not have a reset value, so use the
   853		 * reset value from MT7531 (36us for 100M and 17us for 1000M).
   854		 */
   855		val |= FIELD_PREP(MAC_EEE_WAKEUP_TIME_1000, 17) |
   856		       FIELD_PREP(MAC_EEE_WAKEUP_TIME_100, 36);
   857	
   858		mtk_w32(eth, val, MTK_MAC_EEECR(mac->id));
   859		mtk_m32(eth, 0, MAC_MCR_EEE100M | MAC_MCR_EEE1G, MTK_MAC_MCR(mac->id));
 > 860	}
   861	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH net-next v3] net: ethernet: mediatek: add EEE support
Posted by kernel test robot 10 months ago
Hi Qingfang,

kernel test robot noticed the following build warnings:

[auto build test WARNING on net-next/main]

url:    https://github.com/intel-lab-lkp/linux/commits/Qingfang-Deng/net-ethernet-mediatek-add-EEE-support/20250217-114148
base:   net-next/main
patch link:    https://lore.kernel.org/r/20250217033954.3698772-1-dqfext%40gmail.com
patch subject: [PATCH net-next v3] net: ethernet: mediatek: add EEE support
config: arm64-randconfig-002-20250217 (https://download.01.org/0day-ci/archive/20250217/202502171639.wrPFfdvn-lkp@intel.com/config)
compiler: clang version 21.0.0git (https://github.com/llvm/llvm-project 910be4ff90d7d07bd4518ea03b85c0974672bf9c)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250217/202502171639.wrPFfdvn-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202502171639.wrPFfdvn-lkp@intel.com/

All warnings (new ones prefixed by >>):

   In file included from drivers/net/ethernet/mediatek/mtk_eth_soc.c:10:
   In file included from include/linux/of_mdio.h:12:
   In file included from include/linux/phy.h:16:
   In file included from include/linux/ethtool.h:18:
   In file included from include/linux/if_ether.h:19:
   In file included from include/linux/skbuff.h:17:
   In file included from include/linux/bvec.h:10:
   In file included from include/linux/highmem.h:8:
   In file included from include/linux/cacheflush.h:5:
   In file included from arch/arm64/include/asm/cacheflush.h:11:
   In file included from include/linux/kgdb.h:19:
   In file included from include/linux/kprobes.h:28:
   In file included from include/linux/ftrace.h:13:
   In file included from include/linux/kallsyms.h:13:
   In file included from include/linux/mm.h:2224:
   include/linux/vmstat.h:504:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     504 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     505 |                            item];
         |                            ~~~~
   include/linux/vmstat.h:511:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     511 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     512 |                            NR_VM_NUMA_EVENT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~~
   include/linux/vmstat.h:524:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
     524 |         return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~ ^
     525 |                            NR_VM_NUMA_EVENT_ITEMS +
         |                            ~~~~~~~~~~~~~~~~~~~~~~
>> drivers/net/ethernet/mediatek/mtk_eth_soc.c:860:1: warning: non-void function does not return a value in all control paths [-Wreturn-type]
     860 | }
         | ^
   4 warnings generated.


vim +860 drivers/net/ethernet/mediatek/mtk_eth_soc.c

   826	
   827	static int mtk_mac_enable_tx_lpi(struct phylink_config *config, u32 timer,
   828					 bool tx_clk_stop)
   829	{
   830		struct mtk_mac *mac = container_of(config, struct mtk_mac,
   831						   phylink_config);
   832		struct mtk_eth *eth = mac->hw;
   833		u32 val;
   834	
   835		/* Tx idle timer in ms */
   836		timer = DIV_ROUND_UP(timer, 1000);
   837	
   838		/* If the timer is zero, then set LPI_MODE, which allows the
   839		 * system to enter LPI mode immediately rather than waiting for
   840		 * the LPI threshold.
   841		 */
   842		if (!timer)
   843			val = MAC_EEE_LPI_MODE;
   844		else if (FIELD_FIT(MAC_EEE_LPI_TXIDLE_THD, timer))
   845			val = FIELD_PREP(MAC_EEE_LPI_TXIDLE_THD, timer);
   846		else
   847			val = MAC_EEE_LPI_TXIDLE_THD;
   848	
   849		if (tx_clk_stop)
   850			val |= MAC_EEE_CKG_TXIDLE;
   851	
   852		/* PHY Wake-up time, this field does not have a reset value, so use the
   853		 * reset value from MT7531 (36us for 100M and 17us for 1000M).
   854		 */
   855		val |= FIELD_PREP(MAC_EEE_WAKEUP_TIME_1000, 17) |
   856		       FIELD_PREP(MAC_EEE_WAKEUP_TIME_100, 36);
   857	
   858		mtk_w32(eth, val, MTK_MAC_EEECR(mac->id));
   859		mtk_m32(eth, 0, MAC_MCR_EEE100M | MAC_MCR_EEE1G, MTK_MAC_MCR(mac->id));
 > 860	}
   861	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki