[v6,08/17] net/r8169: add support for phy configuration

Message ID 20241108121123.248797-9-howard_wang@realsil.com.cn (mailing list archive)
State Changes Requested, archived
Delegated to: Ferruh Yigit
Headers
Series Modify code as suggested by the maintainer. |

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Howard Wang Nov. 8, 2024, 12:11 p.m. UTC
This patch contains phy config, ephy config and so on.

Signed-off-by: Howard Wang <howard_wang@realsil.com.cn>
---
 drivers/net/r8169/r8169_ethdev.c |  15 +-
 drivers/net/r8169/r8169_ethdev.h |   6 +
 drivers/net/r8169/r8169_phy.c    | 449 +++++++++++++++++++++++++++++++
 drivers/net/r8169/r8169_phy.h    | 100 +++++++
 4 files changed, 569 insertions(+), 1 deletion(-)
  

Comments

Ferruh Yigit Nov. 11, 2024, 12:16 a.m. UTC | #1
On 11/8/2024 12:11 PM, Howard Wang wrote:
> This patch contains phy config, ephy config and so on.
> 
> Signed-off-by: Howard Wang <howard_wang@realsil.com.cn>
> 

<...>

> @@ -62,6 +62,12 @@ rtl_dev_start(struct rte_eth_dev *dev)
>  	struct rtl_hw *hw = &adapter->hw;
>  	int err;
>  
> +	rtl_powerup_pll(hw);
> +
> +	rtl_hw_ephy_config(hw);
> +
> +	rtl_hw_phy_config(hw);
> +
>  	rtl_hw_config(hw);
>  
>  	/* Initialize transmission unit */
> @@ -74,6 +80,8 @@ rtl_dev_start(struct rte_eth_dev *dev)
>  		goto error;
>  	}
>  
> +	rtl_mdio_write(hw, 0x1F, 0x0000);
> +
>

It is very hard know what code like above does, which makes harder for
anyone to read and understand your code, can you please either create
macros for registers or comment as much as possible, so others can
improve/fix your code when required.
  
Howard Wang Nov. 11, 2024, 8:18 a.m. UTC | #2
Dear Ferruh,

Regarding the commit message, I will think about how to write it.

I’m sorry, but for the registers in the PMD that do not use macro definitions, most of them are company confidential and their meanings will not be disclosed to the public. This part will be maintained by us.

Best Regards,
Howard Wang

-----邮件原件-----
发件人: Ferruh Yigit <ferruh.yigit@amd.com> 
发送时间: 2024年11月11日 8:17
收件人: 王颢 <howard_wang@realsil.com.cn>; dev@dpdk.org
抄送: pro_nic_dpdk@realtek.com
主题: Re: [PATCH v6 08/17] net/r8169: add support for phy configuration


External mail.



On 11/8/2024 12:11 PM, Howard Wang wrote:
> This patch contains phy config, ephy config and so on.
>
> Signed-off-by: Howard Wang <howard_wang@realsil.com.cn>
>

<...>

> @@ -62,6 +62,12 @@ rtl_dev_start(struct rte_eth_dev *dev)
>       struct rtl_hw *hw = &adapter->hw;
>       int err;
>
> +     rtl_powerup_pll(hw);
> +
> +     rtl_hw_ephy_config(hw);
> +
> +     rtl_hw_phy_config(hw);
> +
>       rtl_hw_config(hw);
>
>       /* Initialize transmission unit */ @@ -74,6 +80,8 @@ 
> rtl_dev_start(struct rte_eth_dev *dev)
>               goto error;
>       }
>
> +     rtl_mdio_write(hw, 0x1F, 0x0000);
> +
>

It is very hard know what code like above does, which makes harder for anyone to read and understand your code, can you please either create macros for registers or comment as much as possible, so others can improve/fix your code when required.
  
Ferruh Yigit Nov. 11, 2024, 9:21 a.m. UTC | #3
On 11/11/2024 8:18 AM, 王颢 wrote:
> Dear Ferruh,
> 
> Regarding the commit message, I will think about how to write it.
> 
> I’m sorry, but for the registers in the PMD that do not use macro definitions, most of them are company confidential and their meanings will not be disclosed to the public. This part will be maintained by us.
> 

I understand, but this is conflicting with open sourcing the driver,
after patch is merged it becomes responsibility of the community, of
course primarily we will rely on you to maintain the driver, but for the
cases like refactoring, or users fixing defects etc, community members
may needs to update the driver code, and this requires for us to
understand the code.

Overall, I think there is a value to have the driver in DPDK, so please
continue upstreaming, but please try to explain and clarify the code as
much as possible.


> Best Regards,
> Howard Wang
> 
> -----邮件原件-----
> 发件人: Ferruh Yigit <ferruh.yigit@amd.com> 
> 发送时间: 2024年11月11日 8:17
> 收件人: 王颢 <howard_wang@realsil.com.cn>; dev@dpdk.org
> 抄送: pro_nic_dpdk@realtek.com
> 主题: Re: [PATCH v6 08/17] net/r8169: add support for phy configuration
> 
> 
> External mail.
> 
> 
> 
> On 11/8/2024 12:11 PM, Howard Wang wrote:
>> This patch contains phy config, ephy config and so on.
>>
>> Signed-off-by: Howard Wang <howard_wang@realsil.com.cn>
>>
> 
> <...>
> 
>> @@ -62,6 +62,12 @@ rtl_dev_start(struct rte_eth_dev *dev)
>>       struct rtl_hw *hw = &adapter->hw;
>>       int err;
>>
>> +     rtl_powerup_pll(hw);
>> +
>> +     rtl_hw_ephy_config(hw);
>> +
>> +     rtl_hw_phy_config(hw);
>> +
>>       rtl_hw_config(hw);
>>
>>       /* Initialize transmission unit */ @@ -74,6 +80,8 @@ 
>> rtl_dev_start(struct rte_eth_dev *dev)
>>               goto error;
>>       }
>>
>> +     rtl_mdio_write(hw, 0x1F, 0x0000);
>> +
>>
> 
> It is very hard know what code like above does, which makes harder for anyone to read and understand your code, can you please either create macros for registers or comment as much as possible, so others can improve/fix your code when required.
>
  

Patch

diff --git a/drivers/net/r8169/r8169_ethdev.c b/drivers/net/r8169/r8169_ethdev.c
index 7bc2d925a1..717a5ca599 100644
--- a/drivers/net/r8169/r8169_ethdev.c
+++ b/drivers/net/r8169/r8169_ethdev.c
@@ -62,6 +62,12 @@  rtl_dev_start(struct rte_eth_dev *dev)
 	struct rtl_hw *hw = &adapter->hw;
 	int err;
 
+	rtl_powerup_pll(hw);
+
+	rtl_hw_ephy_config(hw);
+
+	rtl_hw_phy_config(hw);
+
 	rtl_hw_config(hw);
 
 	/* Initialize transmission unit */
@@ -74,6 +80,8 @@  rtl_dev_start(struct rte_eth_dev *dev)
 		goto error;
 	}
 
+	rtl_mdio_write(hw, 0x1F, 0x0000);
+
 	return 0;
 error:
 	return -EIO;
@@ -83,8 +91,13 @@  rtl_dev_start(struct rte_eth_dev *dev)
  * Stop device: disable RX and TX functions to allow for reconfiguring.
  */
 static int
-rtl_dev_stop(struct rte_eth_dev *dev  __rte_unused)
+rtl_dev_stop(struct rte_eth_dev *dev)
 {
+	struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
+	struct rtl_hw *hw = &adapter->hw;
+
+	rtl_powerdown_pll(hw);
+
 	return 0;
 }
 
diff --git a/drivers/net/r8169/r8169_ethdev.h b/drivers/net/r8169/r8169_ethdev.h
index ef3f327c3a..ac7232c1ed 100644
--- a/drivers/net/r8169/r8169_ethdev.h
+++ b/drivers/net/r8169/r8169_ethdev.h
@@ -37,6 +37,12 @@  struct rtl_hw {
 
 	u8  NotWrRamCodeToMicroP;
 	u8  HwHasWrRamCodeToMicroP;
+	u8  HwSuppCheckPhyDisableModeVer;
+
+	u16 sw_ram_code_ver;
+	u16 hw_ram_code_ver;
+
+	u32 HwSuppMaxPhyLinkSpeed;
 
 	/* Enable Tx No Close */
 	u8 EnableTxNoClose;
diff --git a/drivers/net/r8169/r8169_phy.c b/drivers/net/r8169/r8169_phy.c
index bb900953b2..5f41e11ee5 100644
--- a/drivers/net/r8169/r8169_phy.c
+++ b/drivers/net/r8169/r8169_phy.c
@@ -14,6 +14,7 @@ 
 #include "r8169_phy.h"
 #include "r8169_logs.h"
 
+
 static void
 rtl_clear_set_mac_ocp_bit(struct rtl_hw *hw, u16 addr, u16 clearmask,
 			  u16 setmask)
@@ -328,3 +329,451 @@  rtl_set_phy_mcu_ram_code(struct rtl_hw *hw, const u16 *ramcode, u16 codesize)
 out:
 	return;
 }
+
+static u8
+rtl_is_phy_disable_mode_enabled(struct rtl_hw *hw)
+{
+	u8 phy_disable_mode_enabled = FALSE;
+
+	switch (hw->HwSuppCheckPhyDisableModeVer) {
+	case 3:
+		if (RTL_R8(hw, 0xF2) & BIT_5)
+			phy_disable_mode_enabled = TRUE;
+		break;
+	}
+
+	return phy_disable_mode_enabled;
+}
+
+static u8
+rtl_is_gpio_low(struct rtl_hw *hw)
+{
+	u8 gpio_low = FALSE;
+
+	switch (hw->HwSuppCheckPhyDisableModeVer) {
+	case 3:
+		if (!(rtl_mac_ocp_read(hw, 0xDC04) & BIT_13))
+			gpio_low = TRUE;
+		break;
+	}
+
+	return gpio_low;
+}
+
+static u8
+rtl_is_in_phy_disable_mode(struct rtl_hw *hw)
+{
+	u8 in_phy_disable_mode = FALSE;
+
+	if (rtl_is_phy_disable_mode_enabled(hw) && rtl_is_gpio_low(hw))
+		in_phy_disable_mode = TRUE;
+
+	return in_phy_disable_mode;
+}
+
+static void
+rtl_wait_phy_ups_resume(struct rtl_hw *hw, u16 PhyState)
+{
+	u16 tmp_phy_state;
+	int i = 0;
+
+	switch (hw->mcfg) {
+	case CFG_METHOD_48 ... CFG_METHOD_57:
+	case CFG_METHOD_69 ... CFG_METHOD_71:
+		do {
+			tmp_phy_state = rtl_mdio_direct_read_phy_ocp(hw, 0xA420);
+			tmp_phy_state &= 0x7;
+			rte_delay_ms(1);
+			i++;
+		} while ((i < 100) && (tmp_phy_state != PhyState));
+	}
+}
+
+static void
+rtl_phy_power_up(struct rtl_hw *hw)
+{
+	if (rtl_is_in_phy_disable_mode(hw))
+		return;
+
+	rtl_mdio_write(hw, 0x1F, 0x0000);
+	rtl_mdio_write(hw, MII_BMCR, BMCR_ANENABLE);
+
+	/* Wait ups resume (phy state 3) */
+	switch (hw->mcfg) {
+	case CFG_METHOD_48 ... CFG_METHOD_57:
+	case CFG_METHOD_69 ... CFG_METHOD_71:
+		rtl_wait_phy_ups_resume(hw, 3);
+	}
+}
+
+void
+rtl_powerup_pll(struct rtl_hw *hw)
+{
+	switch (hw->mcfg) {
+	case CFG_METHOD_48 ... CFG_METHOD_57:
+	case CFG_METHOD_69 ... CFG_METHOD_71:
+		RTL_W8(hw, PMCH, RTL_R8(hw, PMCH) | BIT_7 | BIT_6);
+	}
+
+	rtl_phy_power_up(hw);
+}
+
+static void
+rtl_phy_power_down(struct rtl_hw *hw)
+{
+	rtl_mdio_write(hw, 0x1F, 0x0000);
+	rtl_mdio_write(hw, MII_BMCR, BMCR_ANENABLE | BMCR_PDOWN);
+}
+
+void
+rtl_powerdown_pll(struct rtl_hw *hw)
+{
+	if (hw->DASH)
+		return;
+
+	rtl_phy_power_down(hw);
+
+	switch (hw->mcfg) {
+	case CFG_METHOD_48 ... CFG_METHOD_57:
+	case CFG_METHOD_69 ... CFG_METHOD_71:
+		RTL_W8(hw, PMCH, RTL_R8(hw, PMCH) & ~BIT_7);
+		break;
+	}
+}
+
+void
+rtl_hw_ephy_config(struct rtl_hw *hw)
+{
+	hw->hw_ops.hw_ephy_config(hw);
+}
+
+static int
+rtl_wait_phy_reset_complete(struct rtl_hw *hw)
+{
+	int i, val;
+
+	for (i = 0; i < 2500; i++) {
+		val = rtl_mdio_read(hw, MII_BMCR) & BMCR_RESET;
+		if (!val)
+			return 0;
+
+		rte_delay_ms(1);
+	}
+
+	return -1;
+}
+
+static void
+rtl_xmii_reset_enable(struct rtl_hw *hw)
+{
+	if (rtl_is_in_phy_disable_mode(hw))
+		return;
+
+	rtl_mdio_write(hw, 0x1F, 0x0000);
+	rtl_mdio_write(hw, MII_ADVERTISE, rtl_mdio_read(hw, MII_ADVERTISE) &
+		       ~(ADVERTISE_10HALF | ADVERTISE_10FULL | ADVERTISE_100HALF |
+		       ADVERTISE_100FULL));
+	rtl_mdio_write(hw, MII_CTRL1000, rtl_mdio_read(hw, MII_CTRL1000) &
+		       ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL));
+	rtl_mdio_direct_write_phy_ocp(hw, 0xA5D4, rtl_mdio_direct_read_phy_ocp(hw, 0xA5D4) &
+				      ~(RTK_ADVERTISE_2500FULL | RTK_ADVERTISE_5000FULL));
+	rtl_mdio_write(hw, MII_BMCR, BMCR_RESET | BMCR_ANENABLE);
+
+	if (rtl_wait_phy_reset_complete(hw) == 0)
+		return;
+}
+
+static void
+rtl8125_set_hw_phy_before_init_phy_mcu(struct rtl_hw *hw)
+{
+	u16 phy_reg_value;
+
+	switch (hw->mcfg) {
+	case CFG_METHOD_4:
+		rtl_mdio_direct_write_phy_ocp(hw, 0xBF86, 0x9000);
+
+		rtl_set_eth_phy_ocp_bit(hw, 0xC402, BIT_10);
+		rtl_clear_eth_phy_ocp_bit(hw, 0xC402, BIT_10);
+
+		phy_reg_value = rtl_mdio_direct_read_phy_ocp(hw, 0xBF86);
+		phy_reg_value &= (BIT_1 | BIT_0);
+		if (phy_reg_value != 0)
+			PMD_INIT_LOG(NOTICE, "PHY watch dog not clear, value = 0x%x",
+				     phy_reg_value);
+
+		rtl_mdio_direct_write_phy_ocp(hw, 0xBD86, 0x1010);
+		rtl_mdio_direct_write_phy_ocp(hw, 0xBD88, 0x1010);
+
+		rtl_clear_and_set_eth_phy_ocp_bit(hw, 0xBD4E, (BIT_11 | BIT_10), BIT_11);
+		rtl_clear_and_set_eth_phy_ocp_bit(hw, 0xBF46, (BIT_11 | BIT_10 | BIT_9 | BIT_8),
+						  (BIT_10 | BIT_9 | BIT_8));
+		break;
+	}
+}
+
+static u16
+rtl_get_hw_phy_mcu_code_ver(struct rtl_hw *hw)
+{
+	u16 hw_ram_code_ver = ~0;
+
+	switch (hw->mcfg) {
+	case CFG_METHOD_48 ... CFG_METHOD_57:
+	case CFG_METHOD_69 ... CFG_METHOD_71:
+		rtl_mdio_direct_write_phy_ocp(hw, 0xA436, 0x801E);
+		hw_ram_code_ver = rtl_mdio_direct_read_phy_ocp(hw, 0xA438);
+		break;
+	}
+
+	return hw_ram_code_ver;
+}
+
+static int
+rtl_check_hw_phy_mcu_code_ver(struct rtl_hw *hw)
+{
+	int ram_code_ver_match = 0;
+
+	hw->hw_ram_code_ver = rtl_get_hw_phy_mcu_code_ver(hw);
+
+	if (hw->hw_ram_code_ver == hw->sw_ram_code_ver) {
+		ram_code_ver_match = 1;
+		hw->HwHasWrRamCodeToMicroP = TRUE;
+	} else {
+		hw->HwHasWrRamCodeToMicroP = FALSE;
+	}
+
+	return ram_code_ver_match;
+}
+
+static void
+rtl_write_hw_phy_mcu_code_ver(struct rtl_hw *hw)
+{
+	switch (hw->mcfg) {
+	case CFG_METHOD_48 ... CFG_METHOD_57:
+	case CFG_METHOD_69 ... CFG_METHOD_71:
+		rtl_mdio_direct_write_phy_ocp(hw, 0xA436, 0x801E);
+		rtl_mdio_direct_write_phy_ocp(hw, 0xA438, hw->sw_ram_code_ver);
+		hw->hw_ram_code_ver = hw->sw_ram_code_ver;
+		break;
+	}
+}
+
+static void
+rtl_enable_phy_disable_mode(struct rtl_hw *hw)
+{
+	switch (hw->HwSuppCheckPhyDisableModeVer) {
+	case 3:
+		RTL_W8(hw, 0xF2, RTL_R8(hw, 0xF2) | BIT_5);
+		break;
+	}
+}
+
+static void
+rtl_disable_phy_disable_mode(struct rtl_hw *hw)
+{
+	switch (hw->HwSuppCheckPhyDisableModeVer) {
+	case 3:
+		RTL_W8(hw, 0xF2, RTL_R8(hw, 0xF2) & ~BIT_5);
+		break;
+	}
+
+	rte_delay_ms(1);
+}
+
+static void
+rtl_init_hw_phy_mcu(struct rtl_hw *hw)
+{
+	u8 require_disable_phy_disable_mode = FALSE;
+
+	if (hw->NotWrRamCodeToMicroP == TRUE)
+		return;
+
+	if (rtl_check_hw_phy_mcu_code_ver(hw))
+		return;
+
+	if (HW_SUPPORT_CHECK_PHY_DISABLE_MODE(hw) && rtl_is_in_phy_disable_mode(hw))
+		require_disable_phy_disable_mode = TRUE;
+
+	if (require_disable_phy_disable_mode)
+		rtl_disable_phy_disable_mode(hw);
+
+	hw->hw_ops.hw_phy_mcu_config(hw);
+
+	if (require_disable_phy_disable_mode)
+		rtl_enable_phy_disable_mode(hw);
+
+	rtl_write_hw_phy_mcu_code_ver(hw);
+
+	rtl_mdio_write(hw, 0x1F, 0x0000);
+
+	hw->HwHasWrRamCodeToMicroP = TRUE;
+}
+
+static void
+rtl_disable_aldps(struct rtl_hw *hw)
+{
+	u16 tmp_ushort;
+	u32 timeout, wait_cnt;
+
+	tmp_ushort = rtl_mdio_real_read_phy_ocp(hw, 0xA430);
+	if (tmp_ushort & BIT_2) {
+		timeout = 0;
+		wait_cnt = 200;
+		rtl_clear_eth_phy_ocp_bit(hw, 0xA430, BIT_2);
+
+		do {
+			rte_delay_us(100);
+
+			tmp_ushort = rtl_mac_ocp_read(hw, 0xE908);
+
+			timeout++;
+		} while (!(tmp_ushort & BIT_7) && timeout < wait_cnt);
+	}
+}
+
+static bool
+rtl_is_adv_eee_enabled(struct rtl_hw *hw)
+{
+	switch (hw->mcfg) {
+	case CFG_METHOD_48 ... CFG_METHOD_55:
+	case CFG_METHOD_69 ... CFG_METHOD_71:
+		if (rtl_mdio_direct_read_phy_ocp(hw, 0xA430) & BIT_15)
+			return true;
+		break;
+	default:
+		break;
+	}
+
+	return false;
+}
+
+static void
+_rtl_disable_adv_eee(struct rtl_hw *hw)
+{
+	bool lock;
+
+	if (rtl_is_adv_eee_enabled(hw))
+		lock = true;
+	else
+		lock = false;
+
+	if (lock)
+		rtl_set_phy_mcu_patch_request(hw);
+
+	rtl_clear_mac_ocp_bit(hw, 0xE052, BIT_0);
+	rtl_clear_eth_phy_ocp_bit(hw, 0xA442, (BIT_12 | BIT_13));
+	rtl_clear_eth_phy_ocp_bit(hw, 0xA430, BIT_15);
+
+	if (lock)
+		rtl_clear_phy_mcu_patch_request(hw);
+}
+
+static void
+rtl_disable_adv_eee(struct rtl_hw *hw)
+{
+	switch (hw->mcfg) {
+	case CFG_METHOD_48:
+	case CFG_METHOD_49:
+	case CFG_METHOD_52:
+	case CFG_METHOD_54:
+	case CFG_METHOD_55:
+		rtl8125_oob_mutex_lock(hw);
+		break;
+	}
+
+	_rtl_disable_adv_eee(hw);
+
+	switch (hw->mcfg) {
+	case CFG_METHOD_48:
+	case CFG_METHOD_49:
+	case CFG_METHOD_52:
+	case CFG_METHOD_54:
+	case CFG_METHOD_55:
+		rtl8125_oob_mutex_unlock(hw);
+		break;
+	}
+}
+
+static void
+rtl_disable_eee(struct rtl_hw *hw)
+{
+	switch (hw->mcfg) {
+	case CFG_METHOD_48:
+	case CFG_METHOD_49:
+	case CFG_METHOD_52:
+		rtl_clear_mac_ocp_bit(hw, 0xE040, (BIT_1 | BIT_0));
+		rtl_clear_mac_ocp_bit(hw, 0xEB62, (BIT_2 | BIT_1));
+
+		rtl_clear_eth_phy_ocp_bit(hw, 0xA432, BIT_4);
+		rtl_clear_eth_phy_ocp_bit(hw, 0xA5D0, (BIT_2 | BIT_1));
+		rtl_clear_eth_phy_ocp_bit(hw, 0xA6D4, BIT_0);
+
+		rtl_clear_eth_phy_ocp_bit(hw, 0xA6D8, BIT_4);
+		rtl_clear_eth_phy_ocp_bit(hw, 0xA428, BIT_7);
+		rtl_clear_eth_phy_ocp_bit(hw, 0xA4A2, BIT_9);
+		break;
+	case CFG_METHOD_50:
+	case CFG_METHOD_51:
+	case CFG_METHOD_53 ... CFG_METHOD_57:
+		rtl_clear_mac_ocp_bit(hw, 0xE040, (BIT_1 | BIT_0));
+
+		rtl_set_eth_phy_ocp_bit(hw, 0xA432, BIT_4);
+		rtl_clear_eth_phy_ocp_bit(hw, 0xA5D0, (BIT_2 | BIT_1));
+		rtl_clear_eth_phy_ocp_bit(hw, 0xA6D4, BIT_0);
+
+		rtl_clear_eth_phy_ocp_bit(hw, 0xA6D8, BIT_4);
+		rtl_clear_eth_phy_ocp_bit(hw, 0xA428, BIT_7);
+		rtl_clear_eth_phy_ocp_bit(hw, 0xA4A2, BIT_9);
+		break;
+	case CFG_METHOD_69 ... CFG_METHOD_71:
+		rtl_clear_mac_ocp_bit(hw, 0xE040, (BIT_1 | BIT_0));
+
+		rtl_clear_eth_phy_ocp_bit(hw, 0xA5D0, (MDIO_EEE_100TX | MDIO_EEE_1000T));
+		rtl_clear_eth_phy_ocp_bit(hw, 0xA6D4, MDIO_EEE_2_5GT);
+		if (HW_SUPP_PHY_LINK_SPEED_5000M(hw))
+			rtl_clear_eth_phy_ocp_bit(hw, 0xA6D4, MDIO_EEE_5GT);
+
+		rtl_clear_eth_phy_ocp_bit(hw, 0xA6D8, BIT_4);
+		rtl_clear_eth_phy_ocp_bit(hw, 0xA428, BIT_7);
+		rtl_clear_eth_phy_ocp_bit(hw, 0xA4A2, BIT_9);
+		break;
+	default:
+		/* Not support EEE */
+		break;
+	}
+
+	/* Advanced EEE */
+	rtl_disable_adv_eee(hw);
+}
+
+void
+rtl_hw_phy_config(struct rtl_hw *hw)
+{
+	rtl_xmii_reset_enable(hw);
+
+	rtl8125_set_hw_phy_before_init_phy_mcu(hw);
+
+	rtl_init_hw_phy_mcu(hw);
+
+	hw->hw_ops.hw_phy_config(hw);
+
+	switch (hw->mcfg) {
+	case CFG_METHOD_48 ... CFG_METHOD_57:
+	case CFG_METHOD_69 ... CFG_METHOD_71:
+		rtl_disable_aldps(hw);
+		break;
+	}
+
+	/* Legacy force mode (chap 22) */
+	switch (hw->mcfg) {
+	case CFG_METHOD_48 ... CFG_METHOD_57:
+	case CFG_METHOD_69 ... CFG_METHOD_71:
+	default:
+		rtl_clear_eth_phy_ocp_bit(hw, 0xA5B4, BIT_15);
+		break;
+	}
+
+	rtl_mdio_write(hw, 0x1F, 0x0000);
+
+	if (HW_HAS_WRITE_PHY_MCU_RAM_CODE(hw))
+		rtl_disable_eee(hw);
+}
diff --git a/drivers/net/r8169/r8169_phy.h b/drivers/net/r8169/r8169_phy.h
index 6700fb9257..4cd715f023 100644
--- a/drivers/net/r8169/r8169_phy.h
+++ b/drivers/net/r8169/r8169_phy.h
@@ -14,6 +14,101 @@ 
 #include "r8169_compat.h"
 #include "r8169_ethdev.h"
 
+/* Generic MII registers. */
+#define MII_BMCR		0x00	/* Basic mode control register */
+#define MII_BMSR		0x01	/* Basic mode status register  */
+#define MII_PHYSID1		0x02	/* PHYS ID 1                   */
+#define MII_PHYSID2		0x03	/* PHYS ID 2                   */
+#define MII_ADVERTISE		0x04	/* Advertisement control reg   */
+#define MII_LPA                 0x05	/* Link partner ability reg    */
+#define MII_EXPANSION		0x06	/* Expansion register          */
+#define MII_CTRL1000		0x09	/* 1000BASE-T control          */
+#define MII_STAT1000		0x0a	/* 1000BASE-T status           */
+#define MII_MMD_CTRL		0x0d	/* MMD Access Control Register */
+#define MII_MMD_DATA		0x0e	/* MMD Access Data Register    */
+#define MII_ESTATUS		0x0f	/* Extended Status             */
+#define MII_DCOUNTER		0x12	/* Disconnect counter          */
+#define MII_FCSCOUNTER		0x13	/* False carrier counter       */
+#define MII_NWAYTEST		0x14	/* N-way auto-neg test reg     */
+#define MII_RERRCOUNTER         0x15	/* Receive error counter       */
+#define MII_SREVISION		0x16	/* Silicon revision            */
+#define MII_RESV1		0x17	/* Reserved...                 */
+#define MII_LBRERROR		0x18	/* Lpback, rx, bypass error    */
+#define MII_PHYADDR		0x19	/* PHY address                 */
+#define MII_RESV2		0x1a	/* Reserved...                 */
+#define MII_TPISTATUS		0x1b	/* TPI status for 10mbps       */
+#define MII_NCONFIG		0x1c	/* Network interface config    */
+
+/* Basic mode control register. */
+#define BMCR_RESV		0x003f	/* Unused...                   */
+#define BMCR_SPEED1000		0x0040	/* MSB of Speed (1000)         */
+#define BMCR_CTST		0x0080	/* Collision test              */
+#define BMCR_FULLDPLX		0x0100	/* Full duplex                 */
+#define BMCR_ANRESTART		0x0200	/* Auto negotiation restart    */
+#define BMCR_ISOLATE		0x0400	/* Isolate data paths from MII */
+#define BMCR_PDOWN		0x0800	/* Enable low power state      */
+#define BMCR_ANENABLE		0x1000	/* Enable auto negotiation     */
+#define BMCR_SPEED100		0x2000	/* Select 100Mbps              */
+#define BMCR_LOOPBACK		0x4000	/* TXD loopback bits           */
+#define BMCR_RESET		0x8000	/* Reset to default state      */
+#define BMCR_SPEED10		0x0000	/* Select 10Mbps               */
+
+/* Basic mode status register. */
+#define BMSR_ERCAP		0x0001	/* Ext-reg capability          */
+#define BMSR_JCD		0x0002	/* Jabber detected             */
+#define BMSR_LSTATUS		0x0004	/* Link status                 */
+#define BMSR_ANEGCAPABLE	0x0008	/* Able to do auto-negotiation */
+#define BMSR_RFAULT		0x0010	/* Remote fault detected       */
+#define BMSR_ANEGCOMPLETE	0x0020	/* Auto-negotiation complete   */
+#define BMSR_RESV		0x00c0	/* Unused...                   */
+#define BMSR_ESTATEN		0x0100	/* Extended Status in R15      */
+#define BMSR_100HALF2		0x0200	/* Can do 100BASE-T2 HDX       */
+#define BMSR_100FULL2		0x0400	/* Can do 100BASE-T2 FDX       */
+#define BMSR_10HALF		0x0800	/* Can do 10mbps, half-duplex  */
+#define BMSR_10FULL		0x1000	/* Can do 10mbps, full-duplex  */
+#define BMSR_100HALF		0x2000	/* Can do 100mbps, half-duplex */
+#define BMSR_100FULL		0x4000	/* Can do 100mbps, full-duplex */
+#define BMSR_100BASE4		0x8000	/* Can do 100mbps, 4k packets  */
+
+/* Advertisement control register. */
+#define ADVERTISE_SLCT		0x001f	/* Selector bits               */
+#define ADVERTISE_CSMA		0x0001	/* Only selector supported     */
+#define ADVERTISE_10HALF	0x0020	/* Try for 10mbps half-duplex  */
+#define ADVERTISE_1000XFULL	0x0020	/* Try for 1000BASE-X full-duplex */
+#define ADVERTISE_10FULL	0x0040	/* Try for 10mbps full-duplex  */
+#define ADVERTISE_1000XHALF	0x0040	/* Try for 1000BASE-X half-duplex */
+#define ADVERTISE_100HALF	0x0080	/* Try for 100mbps half-duplex */
+#define ADVERTISE_1000XPAUSE	0x0080	/* Try for 1000BASE-X pause    */
+#define ADVERTISE_100FULL	0x0100	/* Try for 100mbps full-duplex */
+#define ADVERTISE_1000XPSE_ASYM 0x0100	/* Try for 1000BASE-X asym pause */
+#define ADVERTISE_100BASE4	0x0200	/* Try for 100mbps 4k packets  */
+#define ADVERTISE_PAUSE_CAP	0x0400	/* Try for pause               */
+#define ADVERTISE_PAUSE_ASYM	0x0800	/* Try for asymetric pause     */
+#define ADVERTISE_RESV		0x1000	/* Unused...                   */
+#define ADVERTISE_RFAULT	0x2000	/* Say we can detect faults    */
+#define ADVERTISE_LPACK         0x4000	/* Ack link partners response  */
+#define ADVERTISE_NPAGE         0x8000	/* Next page bit               */
+
+/* 1000BASE-T Control register */
+#define ADVERTISE_1000FULL	0x0200  /* Advertise 1000BASE-T full duplex */
+#define ADVERTISE_1000HALF	0x0100  /* Advertise 1000BASE-T half duplex */
+
+#define RTK_ADVERTISE_2500FULL		0x80
+#define RTK_ADVERTISE_5000FULL		0x100
+#define RTK_ADVERTISE_10000FULL         0x1000
+#define RTK_LPA_ADVERTISE_2500FULL	0x20
+#define RTK_LPA_ADVERTISE_5000FULL	0x40
+#define RTK_LPA_ADVERTISE_10000FULL	0x800
+
+#define HW_SUPPORT_CHECK_PHY_DISABLE_MODE(_M) ((_M)->HwSuppCheckPhyDisableModeVer > 0)
+
+#define HW_SUPP_PHY_LINK_SPEED_5000M(_M)      ((_M)->HwSuppMaxPhyLinkSpeed >= 5000)
+
+#define  MDIO_EEE_100TX  0x0002
+#define  MDIO_EEE_1000T  0x0004
+#define  MDIO_EEE_2_5GT  0x0001
+#define  MDIO_EEE_5GT    0x0002
+
 void rtl_clear_mac_ocp_bit(struct rtl_hw *hw, u16 addr, u16 mask);
 void rtl_set_mac_ocp_bit(struct rtl_hw *hw, u16 addr, u16 mask);
 
@@ -41,4 +136,9 @@  bool rtl_clear_phy_mcu_patch_request(struct rtl_hw *hw);
 void rtl_set_phy_mcu_ram_code(struct rtl_hw *hw, const u16 *ramcode,
 			      u16 codesize);
 
+void rtl_powerup_pll(struct rtl_hw *hw);
+void rtl_powerdown_pll(struct rtl_hw *hw);
+
+void rtl_hw_ephy_config(struct rtl_hw *hw);
+void rtl_hw_phy_config(struct rtl_hw *hw);
 #endif