162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * r8169_phy_config.c: RealTek 8169/8168/8101 ethernet driver. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw> 662306a36Sopenharmony_ci * Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com> 762306a36Sopenharmony_ci * Copyright (c) a lot of people too. Please respect their work. 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * See MAINTAINERS file for support contact information. 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <linux/delay.h> 1362306a36Sopenharmony_ci#include <linux/phy.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include "r8169.h" 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_citypedef void (*rtl_phy_cfg_fct)(struct rtl8169_private *tp, 1862306a36Sopenharmony_ci struct phy_device *phydev); 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_cistatic void r8168d_modify_extpage(struct phy_device *phydev, int extpage, 2162306a36Sopenharmony_ci int reg, u16 mask, u16 val) 2262306a36Sopenharmony_ci{ 2362306a36Sopenharmony_ci int oldpage = phy_select_page(phydev, 0x0007); 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci __phy_write(phydev, 0x1e, extpage); 2662306a36Sopenharmony_ci __phy_modify(phydev, reg, mask, val); 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci phy_restore_page(phydev, oldpage, 0); 2962306a36Sopenharmony_ci} 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistatic void r8168d_phy_param(struct phy_device *phydev, u16 parm, 3262306a36Sopenharmony_ci u16 mask, u16 val) 3362306a36Sopenharmony_ci{ 3462306a36Sopenharmony_ci int oldpage = phy_select_page(phydev, 0x0005); 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci __phy_write(phydev, 0x05, parm); 3762306a36Sopenharmony_ci __phy_modify(phydev, 0x06, mask, val); 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci phy_restore_page(phydev, oldpage, 0); 4062306a36Sopenharmony_ci} 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_cistatic void r8168g_phy_param(struct phy_device *phydev, u16 parm, 4362306a36Sopenharmony_ci u16 mask, u16 val) 4462306a36Sopenharmony_ci{ 4562306a36Sopenharmony_ci int oldpage = phy_select_page(phydev, 0x0a43); 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci __phy_write(phydev, 0x13, parm); 4862306a36Sopenharmony_ci __phy_modify(phydev, 0x14, mask, val); 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci phy_restore_page(phydev, oldpage, 0); 5162306a36Sopenharmony_ci} 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_cistruct phy_reg { 5462306a36Sopenharmony_ci u16 reg; 5562306a36Sopenharmony_ci u16 val; 5662306a36Sopenharmony_ci}; 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_cistatic void __rtl_writephy_batch(struct phy_device *phydev, 5962306a36Sopenharmony_ci const struct phy_reg *regs, int len) 6062306a36Sopenharmony_ci{ 6162306a36Sopenharmony_ci phy_lock_mdio_bus(phydev); 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci while (len-- > 0) { 6462306a36Sopenharmony_ci __phy_write(phydev, regs->reg, regs->val); 6562306a36Sopenharmony_ci regs++; 6662306a36Sopenharmony_ci } 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci phy_unlock_mdio_bus(phydev); 6962306a36Sopenharmony_ci} 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci#define rtl_writephy_batch(p, a) __rtl_writephy_batch(p, a, ARRAY_SIZE(a)) 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_cistatic void rtl8168f_config_eee_phy(struct phy_device *phydev) 7462306a36Sopenharmony_ci{ 7562306a36Sopenharmony_ci r8168d_modify_extpage(phydev, 0x0020, 0x15, 0, BIT(8)); 7662306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b85, 0, BIT(13)); 7762306a36Sopenharmony_ci} 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_cistatic void rtl8168g_config_eee_phy(struct phy_device *phydev) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci phy_modify_paged(phydev, 0x0a43, 0x11, 0, BIT(4)); 8262306a36Sopenharmony_ci} 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_cistatic void rtl8168h_config_eee_phy(struct phy_device *phydev) 8562306a36Sopenharmony_ci{ 8662306a36Sopenharmony_ci rtl8168g_config_eee_phy(phydev); 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci phy_modify_paged(phydev, 0xa4a, 0x11, 0x0000, 0x0200); 8962306a36Sopenharmony_ci phy_modify_paged(phydev, 0xa42, 0x14, 0x0000, 0x0080); 9062306a36Sopenharmony_ci} 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_cistatic void rtl8125a_config_eee_phy(struct phy_device *phydev) 9362306a36Sopenharmony_ci{ 9462306a36Sopenharmony_ci rtl8168h_config_eee_phy(phydev); 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci phy_modify_paged(phydev, 0xa6d, 0x12, 0x0001, 0x0000); 9762306a36Sopenharmony_ci phy_modify_paged(phydev, 0xa6d, 0x14, 0x0010, 0x0000); 9862306a36Sopenharmony_ci} 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_cistatic void rtl8125b_config_eee_phy(struct phy_device *phydev) 10162306a36Sopenharmony_ci{ 10262306a36Sopenharmony_ci phy_modify_paged(phydev, 0xa6d, 0x12, 0x0001, 0x0000); 10362306a36Sopenharmony_ci phy_modify_paged(phydev, 0xa6d, 0x14, 0x0010, 0x0000); 10462306a36Sopenharmony_ci phy_modify_paged(phydev, 0xa42, 0x14, 0x0080, 0x0000); 10562306a36Sopenharmony_ci phy_modify_paged(phydev, 0xa4a, 0x11, 0x0200, 0x0000); 10662306a36Sopenharmony_ci} 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_cistatic void rtl8169s_hw_phy_config(struct rtl8169_private *tp, 10962306a36Sopenharmony_ci struct phy_device *phydev) 11062306a36Sopenharmony_ci{ 11162306a36Sopenharmony_ci static const struct phy_reg phy_reg_init[] = { 11262306a36Sopenharmony_ci { 0x1f, 0x0001 }, 11362306a36Sopenharmony_ci { 0x06, 0x006e }, 11462306a36Sopenharmony_ci { 0x08, 0x0708 }, 11562306a36Sopenharmony_ci { 0x15, 0x4000 }, 11662306a36Sopenharmony_ci { 0x18, 0x65c7 }, 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci { 0x1f, 0x0001 }, 11962306a36Sopenharmony_ci { 0x03, 0x00a1 }, 12062306a36Sopenharmony_ci { 0x02, 0x0008 }, 12162306a36Sopenharmony_ci { 0x01, 0x0120 }, 12262306a36Sopenharmony_ci { 0x00, 0x1000 }, 12362306a36Sopenharmony_ci { 0x04, 0x0800 }, 12462306a36Sopenharmony_ci { 0x04, 0x0000 }, 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci { 0x03, 0xff41 }, 12762306a36Sopenharmony_ci { 0x02, 0xdf60 }, 12862306a36Sopenharmony_ci { 0x01, 0x0140 }, 12962306a36Sopenharmony_ci { 0x00, 0x0077 }, 13062306a36Sopenharmony_ci { 0x04, 0x7800 }, 13162306a36Sopenharmony_ci { 0x04, 0x7000 }, 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci { 0x03, 0x802f }, 13462306a36Sopenharmony_ci { 0x02, 0x4f02 }, 13562306a36Sopenharmony_ci { 0x01, 0x0409 }, 13662306a36Sopenharmony_ci { 0x00, 0xf0f9 }, 13762306a36Sopenharmony_ci { 0x04, 0x9800 }, 13862306a36Sopenharmony_ci { 0x04, 0x9000 }, 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci { 0x03, 0xdf01 }, 14162306a36Sopenharmony_ci { 0x02, 0xdf20 }, 14262306a36Sopenharmony_ci { 0x01, 0xff95 }, 14362306a36Sopenharmony_ci { 0x00, 0xba00 }, 14462306a36Sopenharmony_ci { 0x04, 0xa800 }, 14562306a36Sopenharmony_ci { 0x04, 0xa000 }, 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci { 0x03, 0xff41 }, 14862306a36Sopenharmony_ci { 0x02, 0xdf20 }, 14962306a36Sopenharmony_ci { 0x01, 0x0140 }, 15062306a36Sopenharmony_ci { 0x00, 0x00bb }, 15162306a36Sopenharmony_ci { 0x04, 0xb800 }, 15262306a36Sopenharmony_ci { 0x04, 0xb000 }, 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci { 0x03, 0xdf41 }, 15562306a36Sopenharmony_ci { 0x02, 0xdc60 }, 15662306a36Sopenharmony_ci { 0x01, 0x6340 }, 15762306a36Sopenharmony_ci { 0x00, 0x007d }, 15862306a36Sopenharmony_ci { 0x04, 0xd800 }, 15962306a36Sopenharmony_ci { 0x04, 0xd000 }, 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci { 0x03, 0xdf01 }, 16262306a36Sopenharmony_ci { 0x02, 0xdf20 }, 16362306a36Sopenharmony_ci { 0x01, 0x100a }, 16462306a36Sopenharmony_ci { 0x00, 0xa0ff }, 16562306a36Sopenharmony_ci { 0x04, 0xf800 }, 16662306a36Sopenharmony_ci { 0x04, 0xf000 }, 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci { 0x1f, 0x0000 }, 16962306a36Sopenharmony_ci { 0x0b, 0x0000 }, 17062306a36Sopenharmony_ci { 0x00, 0x9200 } 17162306a36Sopenharmony_ci }; 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci rtl_writephy_batch(phydev, phy_reg_init); 17462306a36Sopenharmony_ci} 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_cistatic void rtl8169sb_hw_phy_config(struct rtl8169_private *tp, 17762306a36Sopenharmony_ci struct phy_device *phydev) 17862306a36Sopenharmony_ci{ 17962306a36Sopenharmony_ci phy_write_paged(phydev, 0x0002, 0x01, 0x90d0); 18062306a36Sopenharmony_ci} 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_cistatic void rtl8169scd_hw_phy_config(struct rtl8169_private *tp, 18362306a36Sopenharmony_ci struct phy_device *phydev) 18462306a36Sopenharmony_ci{ 18562306a36Sopenharmony_ci static const struct phy_reg phy_reg_init[] = { 18662306a36Sopenharmony_ci { 0x1f, 0x0001 }, 18762306a36Sopenharmony_ci { 0x04, 0x0000 }, 18862306a36Sopenharmony_ci { 0x03, 0x00a1 }, 18962306a36Sopenharmony_ci { 0x02, 0x0008 }, 19062306a36Sopenharmony_ci { 0x01, 0x0120 }, 19162306a36Sopenharmony_ci { 0x00, 0x1000 }, 19262306a36Sopenharmony_ci { 0x04, 0x0800 }, 19362306a36Sopenharmony_ci { 0x04, 0x9000 }, 19462306a36Sopenharmony_ci { 0x03, 0x802f }, 19562306a36Sopenharmony_ci { 0x02, 0x4f02 }, 19662306a36Sopenharmony_ci { 0x01, 0x0409 }, 19762306a36Sopenharmony_ci { 0x00, 0xf099 }, 19862306a36Sopenharmony_ci { 0x04, 0x9800 }, 19962306a36Sopenharmony_ci { 0x04, 0xa000 }, 20062306a36Sopenharmony_ci { 0x03, 0xdf01 }, 20162306a36Sopenharmony_ci { 0x02, 0xdf20 }, 20262306a36Sopenharmony_ci { 0x01, 0xff95 }, 20362306a36Sopenharmony_ci { 0x00, 0xba00 }, 20462306a36Sopenharmony_ci { 0x04, 0xa800 }, 20562306a36Sopenharmony_ci { 0x04, 0xf000 }, 20662306a36Sopenharmony_ci { 0x03, 0xdf01 }, 20762306a36Sopenharmony_ci { 0x02, 0xdf20 }, 20862306a36Sopenharmony_ci { 0x01, 0x101a }, 20962306a36Sopenharmony_ci { 0x00, 0xa0ff }, 21062306a36Sopenharmony_ci { 0x04, 0xf800 }, 21162306a36Sopenharmony_ci { 0x04, 0x0000 }, 21262306a36Sopenharmony_ci { 0x1f, 0x0000 }, 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci { 0x1f, 0x0001 }, 21562306a36Sopenharmony_ci { 0x10, 0xf41b }, 21662306a36Sopenharmony_ci { 0x14, 0xfb54 }, 21762306a36Sopenharmony_ci { 0x18, 0xf5c7 }, 21862306a36Sopenharmony_ci { 0x1f, 0x0000 }, 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci { 0x1f, 0x0001 }, 22162306a36Sopenharmony_ci { 0x17, 0x0cc0 }, 22262306a36Sopenharmony_ci { 0x1f, 0x0000 } 22362306a36Sopenharmony_ci }; 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci rtl_writephy_batch(phydev, phy_reg_init); 22662306a36Sopenharmony_ci} 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_cistatic void rtl8169sce_hw_phy_config(struct rtl8169_private *tp, 22962306a36Sopenharmony_ci struct phy_device *phydev) 23062306a36Sopenharmony_ci{ 23162306a36Sopenharmony_ci static const struct phy_reg phy_reg_init[] = { 23262306a36Sopenharmony_ci { 0x1f, 0x0001 }, 23362306a36Sopenharmony_ci { 0x04, 0x0000 }, 23462306a36Sopenharmony_ci { 0x03, 0x00a1 }, 23562306a36Sopenharmony_ci { 0x02, 0x0008 }, 23662306a36Sopenharmony_ci { 0x01, 0x0120 }, 23762306a36Sopenharmony_ci { 0x00, 0x1000 }, 23862306a36Sopenharmony_ci { 0x04, 0x0800 }, 23962306a36Sopenharmony_ci { 0x04, 0x9000 }, 24062306a36Sopenharmony_ci { 0x03, 0x802f }, 24162306a36Sopenharmony_ci { 0x02, 0x4f02 }, 24262306a36Sopenharmony_ci { 0x01, 0x0409 }, 24362306a36Sopenharmony_ci { 0x00, 0xf099 }, 24462306a36Sopenharmony_ci { 0x04, 0x9800 }, 24562306a36Sopenharmony_ci { 0x04, 0xa000 }, 24662306a36Sopenharmony_ci { 0x03, 0xdf01 }, 24762306a36Sopenharmony_ci { 0x02, 0xdf20 }, 24862306a36Sopenharmony_ci { 0x01, 0xff95 }, 24962306a36Sopenharmony_ci { 0x00, 0xba00 }, 25062306a36Sopenharmony_ci { 0x04, 0xa800 }, 25162306a36Sopenharmony_ci { 0x04, 0xf000 }, 25262306a36Sopenharmony_ci { 0x03, 0xdf01 }, 25362306a36Sopenharmony_ci { 0x02, 0xdf20 }, 25462306a36Sopenharmony_ci { 0x01, 0x101a }, 25562306a36Sopenharmony_ci { 0x00, 0xa0ff }, 25662306a36Sopenharmony_ci { 0x04, 0xf800 }, 25762306a36Sopenharmony_ci { 0x04, 0x0000 }, 25862306a36Sopenharmony_ci { 0x1f, 0x0000 }, 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci { 0x1f, 0x0001 }, 26162306a36Sopenharmony_ci { 0x0b, 0x8480 }, 26262306a36Sopenharmony_ci { 0x1f, 0x0000 }, 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci { 0x1f, 0x0001 }, 26562306a36Sopenharmony_ci { 0x18, 0x67c7 }, 26662306a36Sopenharmony_ci { 0x04, 0x2000 }, 26762306a36Sopenharmony_ci { 0x03, 0x002f }, 26862306a36Sopenharmony_ci { 0x02, 0x4360 }, 26962306a36Sopenharmony_ci { 0x01, 0x0109 }, 27062306a36Sopenharmony_ci { 0x00, 0x3022 }, 27162306a36Sopenharmony_ci { 0x04, 0x2800 }, 27262306a36Sopenharmony_ci { 0x1f, 0x0000 }, 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci { 0x1f, 0x0001 }, 27562306a36Sopenharmony_ci { 0x17, 0x0cc0 }, 27662306a36Sopenharmony_ci { 0x1f, 0x0000 } 27762306a36Sopenharmony_ci }; 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci rtl_writephy_batch(phydev, phy_reg_init); 28062306a36Sopenharmony_ci} 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_cistatic void rtl8168bb_hw_phy_config(struct rtl8169_private *tp, 28362306a36Sopenharmony_ci struct phy_device *phydev) 28462306a36Sopenharmony_ci{ 28562306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0001); 28662306a36Sopenharmony_ci phy_set_bits(phydev, 0x16, BIT(0)); 28762306a36Sopenharmony_ci phy_write(phydev, 0x10, 0xf41b); 28862306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0000); 28962306a36Sopenharmony_ci} 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_cistatic void rtl8168bef_hw_phy_config(struct rtl8169_private *tp, 29262306a36Sopenharmony_ci struct phy_device *phydev) 29362306a36Sopenharmony_ci{ 29462306a36Sopenharmony_ci phy_write_paged(phydev, 0x0001, 0x10, 0xf41b); 29562306a36Sopenharmony_ci} 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_cistatic void rtl8168cp_1_hw_phy_config(struct rtl8169_private *tp, 29862306a36Sopenharmony_ci struct phy_device *phydev) 29962306a36Sopenharmony_ci{ 30062306a36Sopenharmony_ci phy_write(phydev, 0x1d, 0x0f00); 30162306a36Sopenharmony_ci phy_write_paged(phydev, 0x0002, 0x0c, 0x1ec8); 30262306a36Sopenharmony_ci} 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_cistatic void rtl8168cp_2_hw_phy_config(struct rtl8169_private *tp, 30562306a36Sopenharmony_ci struct phy_device *phydev) 30662306a36Sopenharmony_ci{ 30762306a36Sopenharmony_ci phy_set_bits(phydev, 0x14, BIT(5)); 30862306a36Sopenharmony_ci phy_set_bits(phydev, 0x0d, BIT(5)); 30962306a36Sopenharmony_ci phy_write_paged(phydev, 0x0001, 0x1d, 0x3d98); 31062306a36Sopenharmony_ci} 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_cistatic void rtl8168c_1_hw_phy_config(struct rtl8169_private *tp, 31362306a36Sopenharmony_ci struct phy_device *phydev) 31462306a36Sopenharmony_ci{ 31562306a36Sopenharmony_ci static const struct phy_reg phy_reg_init[] = { 31662306a36Sopenharmony_ci { 0x1f, 0x0001 }, 31762306a36Sopenharmony_ci { 0x12, 0x2300 }, 31862306a36Sopenharmony_ci { 0x1f, 0x0002 }, 31962306a36Sopenharmony_ci { 0x00, 0x88d4 }, 32062306a36Sopenharmony_ci { 0x01, 0x82b1 }, 32162306a36Sopenharmony_ci { 0x03, 0x7002 }, 32262306a36Sopenharmony_ci { 0x08, 0x9e30 }, 32362306a36Sopenharmony_ci { 0x09, 0x01f0 }, 32462306a36Sopenharmony_ci { 0x0a, 0x5500 }, 32562306a36Sopenharmony_ci { 0x0c, 0x00c8 }, 32662306a36Sopenharmony_ci { 0x1f, 0x0003 }, 32762306a36Sopenharmony_ci { 0x12, 0xc096 }, 32862306a36Sopenharmony_ci { 0x16, 0x000a }, 32962306a36Sopenharmony_ci { 0x1f, 0x0000 }, 33062306a36Sopenharmony_ci { 0x1f, 0x0000 }, 33162306a36Sopenharmony_ci { 0x09, 0x2000 }, 33262306a36Sopenharmony_ci { 0x09, 0x0000 } 33362306a36Sopenharmony_ci }; 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci rtl_writephy_batch(phydev, phy_reg_init); 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci phy_set_bits(phydev, 0x14, BIT(5)); 33862306a36Sopenharmony_ci phy_set_bits(phydev, 0x0d, BIT(5)); 33962306a36Sopenharmony_ci} 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_cistatic void rtl8168c_2_hw_phy_config(struct rtl8169_private *tp, 34262306a36Sopenharmony_ci struct phy_device *phydev) 34362306a36Sopenharmony_ci{ 34462306a36Sopenharmony_ci static const struct phy_reg phy_reg_init[] = { 34562306a36Sopenharmony_ci { 0x1f, 0x0001 }, 34662306a36Sopenharmony_ci { 0x12, 0x2300 }, 34762306a36Sopenharmony_ci { 0x03, 0x802f }, 34862306a36Sopenharmony_ci { 0x02, 0x4f02 }, 34962306a36Sopenharmony_ci { 0x01, 0x0409 }, 35062306a36Sopenharmony_ci { 0x00, 0xf099 }, 35162306a36Sopenharmony_ci { 0x04, 0x9800 }, 35262306a36Sopenharmony_ci { 0x04, 0x9000 }, 35362306a36Sopenharmony_ci { 0x1d, 0x3d98 }, 35462306a36Sopenharmony_ci { 0x1f, 0x0002 }, 35562306a36Sopenharmony_ci { 0x0c, 0x7eb8 }, 35662306a36Sopenharmony_ci { 0x06, 0x0761 }, 35762306a36Sopenharmony_ci { 0x1f, 0x0003 }, 35862306a36Sopenharmony_ci { 0x16, 0x0f0a }, 35962306a36Sopenharmony_ci { 0x1f, 0x0000 } 36062306a36Sopenharmony_ci }; 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci rtl_writephy_batch(phydev, phy_reg_init); 36362306a36Sopenharmony_ci 36462306a36Sopenharmony_ci phy_set_bits(phydev, 0x16, BIT(0)); 36562306a36Sopenharmony_ci phy_set_bits(phydev, 0x14, BIT(5)); 36662306a36Sopenharmony_ci phy_set_bits(phydev, 0x0d, BIT(5)); 36762306a36Sopenharmony_ci} 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_cistatic void rtl8168c_3_hw_phy_config(struct rtl8169_private *tp, 37062306a36Sopenharmony_ci struct phy_device *phydev) 37162306a36Sopenharmony_ci{ 37262306a36Sopenharmony_ci static const struct phy_reg phy_reg_init[] = { 37362306a36Sopenharmony_ci { 0x1f, 0x0001 }, 37462306a36Sopenharmony_ci { 0x12, 0x2300 }, 37562306a36Sopenharmony_ci { 0x1d, 0x3d98 }, 37662306a36Sopenharmony_ci { 0x1f, 0x0002 }, 37762306a36Sopenharmony_ci { 0x0c, 0x7eb8 }, 37862306a36Sopenharmony_ci { 0x06, 0x5461 }, 37962306a36Sopenharmony_ci { 0x1f, 0x0003 }, 38062306a36Sopenharmony_ci { 0x16, 0x0f0a }, 38162306a36Sopenharmony_ci { 0x1f, 0x0000 } 38262306a36Sopenharmony_ci }; 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_ci rtl_writephy_batch(phydev, phy_reg_init); 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ci phy_set_bits(phydev, 0x16, BIT(0)); 38762306a36Sopenharmony_ci phy_set_bits(phydev, 0x14, BIT(5)); 38862306a36Sopenharmony_ci phy_set_bits(phydev, 0x0d, BIT(5)); 38962306a36Sopenharmony_ci} 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_cistatic const struct phy_reg rtl8168d_1_phy_reg_init_0[] = { 39262306a36Sopenharmony_ci /* Channel Estimation */ 39362306a36Sopenharmony_ci { 0x1f, 0x0001 }, 39462306a36Sopenharmony_ci { 0x06, 0x4064 }, 39562306a36Sopenharmony_ci { 0x07, 0x2863 }, 39662306a36Sopenharmony_ci { 0x08, 0x059c }, 39762306a36Sopenharmony_ci { 0x09, 0x26b4 }, 39862306a36Sopenharmony_ci { 0x0a, 0x6a19 }, 39962306a36Sopenharmony_ci { 0x0b, 0xdcc8 }, 40062306a36Sopenharmony_ci { 0x10, 0xf06d }, 40162306a36Sopenharmony_ci { 0x14, 0x7f68 }, 40262306a36Sopenharmony_ci { 0x18, 0x7fd9 }, 40362306a36Sopenharmony_ci { 0x1c, 0xf0ff }, 40462306a36Sopenharmony_ci { 0x1d, 0x3d9c }, 40562306a36Sopenharmony_ci { 0x1f, 0x0003 }, 40662306a36Sopenharmony_ci { 0x12, 0xf49f }, 40762306a36Sopenharmony_ci { 0x13, 0x070b }, 40862306a36Sopenharmony_ci { 0x1a, 0x05ad }, 40962306a36Sopenharmony_ci { 0x14, 0x94c0 }, 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ci /* 41262306a36Sopenharmony_ci * Tx Error Issue 41362306a36Sopenharmony_ci * Enhance line driver power 41462306a36Sopenharmony_ci */ 41562306a36Sopenharmony_ci { 0x1f, 0x0002 }, 41662306a36Sopenharmony_ci { 0x06, 0x5561 }, 41762306a36Sopenharmony_ci { 0x1f, 0x0005 }, 41862306a36Sopenharmony_ci { 0x05, 0x8332 }, 41962306a36Sopenharmony_ci { 0x06, 0x5561 }, 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci /* 42262306a36Sopenharmony_ci * Can not link to 1Gbps with bad cable 42362306a36Sopenharmony_ci * Decrease SNR threshold form 21.07dB to 19.04dB 42462306a36Sopenharmony_ci */ 42562306a36Sopenharmony_ci { 0x1f, 0x0001 }, 42662306a36Sopenharmony_ci { 0x17, 0x0cc0 }, 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_ci { 0x1f, 0x0000 }, 42962306a36Sopenharmony_ci { 0x0d, 0xf880 } 43062306a36Sopenharmony_ci}; 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_cistatic void rtl8168d_apply_firmware_cond(struct rtl8169_private *tp, 43362306a36Sopenharmony_ci struct phy_device *phydev, 43462306a36Sopenharmony_ci u16 val) 43562306a36Sopenharmony_ci{ 43662306a36Sopenharmony_ci u16 reg_val; 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0005); 43962306a36Sopenharmony_ci phy_write(phydev, 0x05, 0x001b); 44062306a36Sopenharmony_ci reg_val = phy_read(phydev, 0x06); 44162306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0000); 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ci if (reg_val != val) 44462306a36Sopenharmony_ci phydev_warn(phydev, "chipset not ready for firmware\n"); 44562306a36Sopenharmony_ci else 44662306a36Sopenharmony_ci r8169_apply_firmware(tp); 44762306a36Sopenharmony_ci} 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_cistatic void rtl8168d_1_common(struct phy_device *phydev) 45062306a36Sopenharmony_ci{ 45162306a36Sopenharmony_ci u16 val; 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_ci phy_write_paged(phydev, 0x0002, 0x05, 0x669a); 45462306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8330, 0xffff, 0x669a); 45562306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0002); 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_ci val = phy_read(phydev, 0x0d); 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_ci if ((val & 0x00ff) != 0x006c) { 46062306a36Sopenharmony_ci static const u16 set[] = { 46162306a36Sopenharmony_ci 0x0065, 0x0066, 0x0067, 0x0068, 46262306a36Sopenharmony_ci 0x0069, 0x006a, 0x006b, 0x006c 46362306a36Sopenharmony_ci }; 46462306a36Sopenharmony_ci int i; 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_ci val &= 0xff00; 46762306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(set); i++) 46862306a36Sopenharmony_ci phy_write(phydev, 0x0d, val | set[i]); 46962306a36Sopenharmony_ci } 47062306a36Sopenharmony_ci} 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_cistatic void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp, 47362306a36Sopenharmony_ci struct phy_device *phydev) 47462306a36Sopenharmony_ci{ 47562306a36Sopenharmony_ci rtl_writephy_batch(phydev, rtl8168d_1_phy_reg_init_0); 47662306a36Sopenharmony_ci 47762306a36Sopenharmony_ci /* 47862306a36Sopenharmony_ci * Rx Error Issue 47962306a36Sopenharmony_ci * Fine Tune Switching regulator parameter 48062306a36Sopenharmony_ci */ 48162306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0002); 48262306a36Sopenharmony_ci phy_modify(phydev, 0x0b, 0x00ef, 0x0010); 48362306a36Sopenharmony_ci phy_modify(phydev, 0x0c, 0x5d00, 0xa200); 48462306a36Sopenharmony_ci 48562306a36Sopenharmony_ci if (rtl8168d_efuse_read(tp, 0x01) == 0xb1) { 48662306a36Sopenharmony_ci rtl8168d_1_common(phydev); 48762306a36Sopenharmony_ci } else { 48862306a36Sopenharmony_ci phy_write_paged(phydev, 0x0002, 0x05, 0x6662); 48962306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8330, 0xffff, 0x6662); 49062306a36Sopenharmony_ci } 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_ci /* RSET couple improve */ 49362306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0002); 49462306a36Sopenharmony_ci phy_set_bits(phydev, 0x0d, 0x0300); 49562306a36Sopenharmony_ci phy_set_bits(phydev, 0x0f, 0x0010); 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_ci /* Fine tune PLL performance */ 49862306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0002); 49962306a36Sopenharmony_ci phy_modify(phydev, 0x02, 0x0600, 0x0100); 50062306a36Sopenharmony_ci phy_clear_bits(phydev, 0x03, 0xe000); 50162306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0000); 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_ci rtl8168d_apply_firmware_cond(tp, phydev, 0xbf00); 50462306a36Sopenharmony_ci} 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_cistatic void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp, 50762306a36Sopenharmony_ci struct phy_device *phydev) 50862306a36Sopenharmony_ci{ 50962306a36Sopenharmony_ci rtl_writephy_batch(phydev, rtl8168d_1_phy_reg_init_0); 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_ci if (rtl8168d_efuse_read(tp, 0x01) == 0xb1) { 51262306a36Sopenharmony_ci rtl8168d_1_common(phydev); 51362306a36Sopenharmony_ci } else { 51462306a36Sopenharmony_ci phy_write_paged(phydev, 0x0002, 0x05, 0x2642); 51562306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8330, 0xffff, 0x2642); 51662306a36Sopenharmony_ci } 51762306a36Sopenharmony_ci 51862306a36Sopenharmony_ci /* Fine tune PLL performance */ 51962306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0002); 52062306a36Sopenharmony_ci phy_modify(phydev, 0x02, 0x0600, 0x0100); 52162306a36Sopenharmony_ci phy_clear_bits(phydev, 0x03, 0xe000); 52262306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0000); 52362306a36Sopenharmony_ci 52462306a36Sopenharmony_ci /* Switching regulator Slew rate */ 52562306a36Sopenharmony_ci phy_modify_paged(phydev, 0x0002, 0x0f, 0x0000, 0x0017); 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_ci rtl8168d_apply_firmware_cond(tp, phydev, 0xb300); 52862306a36Sopenharmony_ci} 52962306a36Sopenharmony_ci 53062306a36Sopenharmony_cistatic void rtl8168d_4_hw_phy_config(struct rtl8169_private *tp, 53162306a36Sopenharmony_ci struct phy_device *phydev) 53262306a36Sopenharmony_ci{ 53362306a36Sopenharmony_ci phy_write_paged(phydev, 0x0001, 0x17, 0x0cc0); 53462306a36Sopenharmony_ci r8168d_modify_extpage(phydev, 0x002d, 0x18, 0xffff, 0x0040); 53562306a36Sopenharmony_ci phy_set_bits(phydev, 0x0d, BIT(5)); 53662306a36Sopenharmony_ci} 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_cistatic void rtl8168e_1_hw_phy_config(struct rtl8169_private *tp, 53962306a36Sopenharmony_ci struct phy_device *phydev) 54062306a36Sopenharmony_ci{ 54162306a36Sopenharmony_ci static const struct phy_reg phy_reg_init[] = { 54262306a36Sopenharmony_ci /* Channel estimation fine tune */ 54362306a36Sopenharmony_ci { 0x1f, 0x0001 }, 54462306a36Sopenharmony_ci { 0x0b, 0x6c20 }, 54562306a36Sopenharmony_ci { 0x07, 0x2872 }, 54662306a36Sopenharmony_ci { 0x1c, 0xefff }, 54762306a36Sopenharmony_ci { 0x1f, 0x0003 }, 54862306a36Sopenharmony_ci { 0x14, 0x6420 }, 54962306a36Sopenharmony_ci { 0x1f, 0x0000 }, 55062306a36Sopenharmony_ci }; 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ci r8169_apply_firmware(tp); 55362306a36Sopenharmony_ci 55462306a36Sopenharmony_ci /* Enable Delay cap */ 55562306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b80, 0xffff, 0xc896); 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_ci rtl_writephy_batch(phydev, phy_reg_init); 55862306a36Sopenharmony_ci 55962306a36Sopenharmony_ci /* Update PFM & 10M TX idle timer */ 56062306a36Sopenharmony_ci r8168d_modify_extpage(phydev, 0x002f, 0x15, 0xffff, 0x1919); 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_ci r8168d_modify_extpage(phydev, 0x00ac, 0x18, 0xffff, 0x0006); 56362306a36Sopenharmony_ci 56462306a36Sopenharmony_ci /* DCO enable for 10M IDLE Power */ 56562306a36Sopenharmony_ci r8168d_modify_extpage(phydev, 0x0023, 0x17, 0x0000, 0x0006); 56662306a36Sopenharmony_ci 56762306a36Sopenharmony_ci /* For impedance matching */ 56862306a36Sopenharmony_ci phy_modify_paged(phydev, 0x0002, 0x08, 0x7f00, 0x8000); 56962306a36Sopenharmony_ci 57062306a36Sopenharmony_ci /* PHY auto speed down */ 57162306a36Sopenharmony_ci r8168d_modify_extpage(phydev, 0x002d, 0x18, 0x0000, 0x0050); 57262306a36Sopenharmony_ci phy_set_bits(phydev, 0x14, BIT(15)); 57362306a36Sopenharmony_ci 57462306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b86, 0x0000, 0x0001); 57562306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b85, 0x2000, 0x0000); 57662306a36Sopenharmony_ci 57762306a36Sopenharmony_ci r8168d_modify_extpage(phydev, 0x0020, 0x15, 0x1100, 0x0000); 57862306a36Sopenharmony_ci phy_write_paged(phydev, 0x0006, 0x00, 0x5a00); 57962306a36Sopenharmony_ci 58062306a36Sopenharmony_ci phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0x0000); 58162306a36Sopenharmony_ci} 58262306a36Sopenharmony_ci 58362306a36Sopenharmony_cistatic void rtl8168e_2_hw_phy_config(struct rtl8169_private *tp, 58462306a36Sopenharmony_ci struct phy_device *phydev) 58562306a36Sopenharmony_ci{ 58662306a36Sopenharmony_ci r8169_apply_firmware(tp); 58762306a36Sopenharmony_ci 58862306a36Sopenharmony_ci /* Enable Delay cap */ 58962306a36Sopenharmony_ci r8168d_modify_extpage(phydev, 0x00ac, 0x18, 0xffff, 0x0006); 59062306a36Sopenharmony_ci 59162306a36Sopenharmony_ci /* Channel estimation fine tune */ 59262306a36Sopenharmony_ci phy_write_paged(phydev, 0x0003, 0x09, 0xa20f); 59362306a36Sopenharmony_ci 59462306a36Sopenharmony_ci /* Green Setting */ 59562306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b5b, 0xffff, 0x9222); 59662306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b6d, 0xffff, 0x8000); 59762306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b76, 0xffff, 0x8000); 59862306a36Sopenharmony_ci 59962306a36Sopenharmony_ci /* For 4-corner performance improve */ 60062306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0005); 60162306a36Sopenharmony_ci phy_write(phydev, 0x05, 0x8b80); 60262306a36Sopenharmony_ci phy_set_bits(phydev, 0x17, 0x0006); 60362306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0000); 60462306a36Sopenharmony_ci 60562306a36Sopenharmony_ci /* PHY auto speed down */ 60662306a36Sopenharmony_ci r8168d_modify_extpage(phydev, 0x002d, 0x18, 0x0000, 0x0010); 60762306a36Sopenharmony_ci phy_set_bits(phydev, 0x14, BIT(15)); 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_ci /* improve 10M EEE waveform */ 61062306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b86, 0x0000, 0x0001); 61162306a36Sopenharmony_ci 61262306a36Sopenharmony_ci /* Improve 2-pair detection performance */ 61362306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b85, 0x0000, 0x4000); 61462306a36Sopenharmony_ci 61562306a36Sopenharmony_ci rtl8168f_config_eee_phy(phydev); 61662306a36Sopenharmony_ci 61762306a36Sopenharmony_ci /* Green feature */ 61862306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0003); 61962306a36Sopenharmony_ci phy_set_bits(phydev, 0x19, BIT(0)); 62062306a36Sopenharmony_ci phy_set_bits(phydev, 0x10, BIT(10)); 62162306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0000); 62262306a36Sopenharmony_ci phy_modify_paged(phydev, 0x0005, 0x01, 0, BIT(8)); 62362306a36Sopenharmony_ci} 62462306a36Sopenharmony_ci 62562306a36Sopenharmony_cistatic void rtl8168f_hw_phy_config(struct rtl8169_private *tp, 62662306a36Sopenharmony_ci struct phy_device *phydev) 62762306a36Sopenharmony_ci{ 62862306a36Sopenharmony_ci /* For 4-corner performance improve */ 62962306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b80, 0x0000, 0x0006); 63062306a36Sopenharmony_ci 63162306a36Sopenharmony_ci /* PHY auto speed down */ 63262306a36Sopenharmony_ci r8168d_modify_extpage(phydev, 0x002d, 0x18, 0x0000, 0x0010); 63362306a36Sopenharmony_ci phy_set_bits(phydev, 0x14, BIT(15)); 63462306a36Sopenharmony_ci 63562306a36Sopenharmony_ci /* Improve 10M EEE waveform */ 63662306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b86, 0x0000, 0x0001); 63762306a36Sopenharmony_ci 63862306a36Sopenharmony_ci rtl8168f_config_eee_phy(phydev); 63962306a36Sopenharmony_ci} 64062306a36Sopenharmony_ci 64162306a36Sopenharmony_cistatic void rtl8168f_1_hw_phy_config(struct rtl8169_private *tp, 64262306a36Sopenharmony_ci struct phy_device *phydev) 64362306a36Sopenharmony_ci{ 64462306a36Sopenharmony_ci r8169_apply_firmware(tp); 64562306a36Sopenharmony_ci 64662306a36Sopenharmony_ci /* Channel estimation fine tune */ 64762306a36Sopenharmony_ci phy_write_paged(phydev, 0x0003, 0x09, 0xa20f); 64862306a36Sopenharmony_ci 64962306a36Sopenharmony_ci /* Modify green table for giga & fnet */ 65062306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b55, 0xffff, 0x0000); 65162306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b5e, 0xffff, 0x0000); 65262306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b67, 0xffff, 0x0000); 65362306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b70, 0xffff, 0x0000); 65462306a36Sopenharmony_ci r8168d_modify_extpage(phydev, 0x0078, 0x17, 0xffff, 0x0000); 65562306a36Sopenharmony_ci r8168d_modify_extpage(phydev, 0x0078, 0x19, 0xffff, 0x00fb); 65662306a36Sopenharmony_ci 65762306a36Sopenharmony_ci /* Modify green table for 10M */ 65862306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b79, 0xffff, 0xaa00); 65962306a36Sopenharmony_ci 66062306a36Sopenharmony_ci /* Disable hiimpedance detection (RTCT) */ 66162306a36Sopenharmony_ci phy_write_paged(phydev, 0x0003, 0x01, 0x328a); 66262306a36Sopenharmony_ci 66362306a36Sopenharmony_ci rtl8168f_hw_phy_config(tp, phydev); 66462306a36Sopenharmony_ci 66562306a36Sopenharmony_ci /* Improve 2-pair detection performance */ 66662306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b85, 0x0000, 0x4000); 66762306a36Sopenharmony_ci} 66862306a36Sopenharmony_ci 66962306a36Sopenharmony_cistatic void rtl8168f_2_hw_phy_config(struct rtl8169_private *tp, 67062306a36Sopenharmony_ci struct phy_device *phydev) 67162306a36Sopenharmony_ci{ 67262306a36Sopenharmony_ci r8169_apply_firmware(tp); 67362306a36Sopenharmony_ci 67462306a36Sopenharmony_ci rtl8168f_hw_phy_config(tp, phydev); 67562306a36Sopenharmony_ci} 67662306a36Sopenharmony_ci 67762306a36Sopenharmony_cistatic void rtl8411_hw_phy_config(struct rtl8169_private *tp, 67862306a36Sopenharmony_ci struct phy_device *phydev) 67962306a36Sopenharmony_ci{ 68062306a36Sopenharmony_ci r8169_apply_firmware(tp); 68162306a36Sopenharmony_ci 68262306a36Sopenharmony_ci rtl8168f_hw_phy_config(tp, phydev); 68362306a36Sopenharmony_ci 68462306a36Sopenharmony_ci /* Improve 2-pair detection performance */ 68562306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b85, 0x0000, 0x4000); 68662306a36Sopenharmony_ci 68762306a36Sopenharmony_ci /* Channel estimation fine tune */ 68862306a36Sopenharmony_ci phy_write_paged(phydev, 0x0003, 0x09, 0xa20f); 68962306a36Sopenharmony_ci 69062306a36Sopenharmony_ci /* Modify green table for giga & fnet */ 69162306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b55, 0xffff, 0x0000); 69262306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b5e, 0xffff, 0x0000); 69362306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b67, 0xffff, 0x0000); 69462306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b70, 0xffff, 0x0000); 69562306a36Sopenharmony_ci r8168d_modify_extpage(phydev, 0x0078, 0x17, 0xffff, 0x0000); 69662306a36Sopenharmony_ci r8168d_modify_extpage(phydev, 0x0078, 0x19, 0xffff, 0x00aa); 69762306a36Sopenharmony_ci 69862306a36Sopenharmony_ci /* Modify green table for 10M */ 69962306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b79, 0xffff, 0xaa00); 70062306a36Sopenharmony_ci 70162306a36Sopenharmony_ci /* Disable hiimpedance detection (RTCT) */ 70262306a36Sopenharmony_ci phy_write_paged(phydev, 0x0003, 0x01, 0x328a); 70362306a36Sopenharmony_ci 70462306a36Sopenharmony_ci /* Modify green table for giga */ 70562306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b54, 0x0800, 0x0000); 70662306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b5d, 0x0800, 0x0000); 70762306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8a7c, 0x0100, 0x0000); 70862306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8a7f, 0x0000, 0x0100); 70962306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8a82, 0x0100, 0x0000); 71062306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8a85, 0x0100, 0x0000); 71162306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8a88, 0x0100, 0x0000); 71262306a36Sopenharmony_ci 71362306a36Sopenharmony_ci /* uc same-seed solution */ 71462306a36Sopenharmony_ci r8168d_phy_param(phydev, 0x8b85, 0x0000, 0x8000); 71562306a36Sopenharmony_ci 71662306a36Sopenharmony_ci /* Green feature */ 71762306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0003); 71862306a36Sopenharmony_ci phy_clear_bits(phydev, 0x19, BIT(0)); 71962306a36Sopenharmony_ci phy_clear_bits(phydev, 0x10, BIT(10)); 72062306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0000); 72162306a36Sopenharmony_ci} 72262306a36Sopenharmony_ci 72362306a36Sopenharmony_cistatic void rtl8168g_disable_aldps(struct phy_device *phydev) 72462306a36Sopenharmony_ci{ 72562306a36Sopenharmony_ci phy_modify_paged(phydev, 0x0a43, 0x10, BIT(2), 0); 72662306a36Sopenharmony_ci} 72762306a36Sopenharmony_ci 72862306a36Sopenharmony_cistatic void rtl8168g_enable_gphy_10m(struct phy_device *phydev) 72962306a36Sopenharmony_ci{ 73062306a36Sopenharmony_ci phy_modify_paged(phydev, 0x0a44, 0x11, 0, BIT(11)); 73162306a36Sopenharmony_ci} 73262306a36Sopenharmony_ci 73362306a36Sopenharmony_cistatic void rtl8168g_phy_adjust_10m_aldps(struct phy_device *phydev) 73462306a36Sopenharmony_ci{ 73562306a36Sopenharmony_ci phy_modify_paged(phydev, 0x0bcc, 0x14, BIT(8), 0); 73662306a36Sopenharmony_ci phy_modify_paged(phydev, 0x0a44, 0x11, 0, BIT(7) | BIT(6)); 73762306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x8084, 0x6000, 0x0000); 73862306a36Sopenharmony_ci phy_modify_paged(phydev, 0x0a43, 0x10, 0x0000, 0x1003); 73962306a36Sopenharmony_ci} 74062306a36Sopenharmony_ci 74162306a36Sopenharmony_cistatic void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp, 74262306a36Sopenharmony_ci struct phy_device *phydev) 74362306a36Sopenharmony_ci{ 74462306a36Sopenharmony_ci int ret; 74562306a36Sopenharmony_ci 74662306a36Sopenharmony_ci r8169_apply_firmware(tp); 74762306a36Sopenharmony_ci 74862306a36Sopenharmony_ci ret = phy_read_paged(phydev, 0x0a46, 0x10); 74962306a36Sopenharmony_ci if (ret & BIT(8)) 75062306a36Sopenharmony_ci phy_modify_paged(phydev, 0x0bcc, 0x12, BIT(15), 0); 75162306a36Sopenharmony_ci else 75262306a36Sopenharmony_ci phy_modify_paged(phydev, 0x0bcc, 0x12, 0, BIT(15)); 75362306a36Sopenharmony_ci 75462306a36Sopenharmony_ci ret = phy_read_paged(phydev, 0x0a46, 0x13); 75562306a36Sopenharmony_ci if (ret & BIT(8)) 75662306a36Sopenharmony_ci phy_modify_paged(phydev, 0x0c41, 0x15, 0, BIT(1)); 75762306a36Sopenharmony_ci else 75862306a36Sopenharmony_ci phy_modify_paged(phydev, 0x0c41, 0x15, BIT(1), 0); 75962306a36Sopenharmony_ci 76062306a36Sopenharmony_ci /* Enable PHY auto speed down */ 76162306a36Sopenharmony_ci phy_modify_paged(phydev, 0x0a44, 0x11, 0, BIT(3) | BIT(2)); 76262306a36Sopenharmony_ci 76362306a36Sopenharmony_ci rtl8168g_phy_adjust_10m_aldps(phydev); 76462306a36Sopenharmony_ci 76562306a36Sopenharmony_ci /* EEE auto-fallback function */ 76662306a36Sopenharmony_ci phy_modify_paged(phydev, 0x0a4b, 0x11, 0, BIT(2)); 76762306a36Sopenharmony_ci 76862306a36Sopenharmony_ci /* Enable UC LPF tune function */ 76962306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x8012, 0x0000, 0x8000); 77062306a36Sopenharmony_ci 77162306a36Sopenharmony_ci phy_modify_paged(phydev, 0x0c42, 0x11, BIT(13), BIT(14)); 77262306a36Sopenharmony_ci 77362306a36Sopenharmony_ci /* Improve SWR Efficiency */ 77462306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0bcd); 77562306a36Sopenharmony_ci phy_write(phydev, 0x14, 0x5065); 77662306a36Sopenharmony_ci phy_write(phydev, 0x14, 0xd065); 77762306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0bc8); 77862306a36Sopenharmony_ci phy_write(phydev, 0x11, 0x5655); 77962306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0bcd); 78062306a36Sopenharmony_ci phy_write(phydev, 0x14, 0x1065); 78162306a36Sopenharmony_ci phy_write(phydev, 0x14, 0x9065); 78262306a36Sopenharmony_ci phy_write(phydev, 0x14, 0x1065); 78362306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0000); 78462306a36Sopenharmony_ci 78562306a36Sopenharmony_ci rtl8168g_disable_aldps(phydev); 78662306a36Sopenharmony_ci rtl8168g_config_eee_phy(phydev); 78762306a36Sopenharmony_ci} 78862306a36Sopenharmony_ci 78962306a36Sopenharmony_cistatic void rtl8168g_2_hw_phy_config(struct rtl8169_private *tp, 79062306a36Sopenharmony_ci struct phy_device *phydev) 79162306a36Sopenharmony_ci{ 79262306a36Sopenharmony_ci r8169_apply_firmware(tp); 79362306a36Sopenharmony_ci rtl8168g_config_eee_phy(phydev); 79462306a36Sopenharmony_ci} 79562306a36Sopenharmony_ci 79662306a36Sopenharmony_cistatic void rtl8168h_2_hw_phy_config(struct rtl8169_private *tp, 79762306a36Sopenharmony_ci struct phy_device *phydev) 79862306a36Sopenharmony_ci{ 79962306a36Sopenharmony_ci u16 ioffset, rlen; 80062306a36Sopenharmony_ci u32 data; 80162306a36Sopenharmony_ci 80262306a36Sopenharmony_ci r8169_apply_firmware(tp); 80362306a36Sopenharmony_ci 80462306a36Sopenharmony_ci /* CHIN EST parameter update */ 80562306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x808a, 0x003f, 0x000a); 80662306a36Sopenharmony_ci 80762306a36Sopenharmony_ci /* enable R-tune & PGA-retune function */ 80862306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x0811, 0x0000, 0x0800); 80962306a36Sopenharmony_ci phy_modify_paged(phydev, 0x0a42, 0x16, 0x0000, 0x0002); 81062306a36Sopenharmony_ci 81162306a36Sopenharmony_ci rtl8168g_enable_gphy_10m(phydev); 81262306a36Sopenharmony_ci 81362306a36Sopenharmony_ci ioffset = rtl8168h_2_get_adc_bias_ioffset(tp); 81462306a36Sopenharmony_ci if (ioffset != 0xffff) 81562306a36Sopenharmony_ci phy_write_paged(phydev, 0x0bcf, 0x16, ioffset); 81662306a36Sopenharmony_ci 81762306a36Sopenharmony_ci /* Modify rlen (TX LPF corner frequency) level */ 81862306a36Sopenharmony_ci data = phy_read_paged(phydev, 0x0bcd, 0x16); 81962306a36Sopenharmony_ci data &= 0x000f; 82062306a36Sopenharmony_ci rlen = 0; 82162306a36Sopenharmony_ci if (data > 3) 82262306a36Sopenharmony_ci rlen = data - 3; 82362306a36Sopenharmony_ci data = rlen | (rlen << 4) | (rlen << 8) | (rlen << 12); 82462306a36Sopenharmony_ci phy_write_paged(phydev, 0x0bcd, 0x17, data); 82562306a36Sopenharmony_ci 82662306a36Sopenharmony_ci /* disable phy pfm mode */ 82762306a36Sopenharmony_ci phy_modify_paged(phydev, 0x0a44, 0x11, BIT(7), 0); 82862306a36Sopenharmony_ci 82962306a36Sopenharmony_ci /* disable 10m pll off */ 83062306a36Sopenharmony_ci phy_modify_paged(phydev, 0x0a43, 0x10, BIT(0), 0); 83162306a36Sopenharmony_ci 83262306a36Sopenharmony_ci rtl8168g_disable_aldps(phydev); 83362306a36Sopenharmony_ci rtl8168g_config_eee_phy(phydev); 83462306a36Sopenharmony_ci} 83562306a36Sopenharmony_ci 83662306a36Sopenharmony_cistatic void rtl8168ep_2_hw_phy_config(struct rtl8169_private *tp, 83762306a36Sopenharmony_ci struct phy_device *phydev) 83862306a36Sopenharmony_ci{ 83962306a36Sopenharmony_ci rtl8168g_phy_adjust_10m_aldps(phydev); 84062306a36Sopenharmony_ci 84162306a36Sopenharmony_ci /* Enable UC LPF tune function */ 84262306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x8012, 0x0000, 0x8000); 84362306a36Sopenharmony_ci 84462306a36Sopenharmony_ci /* Set rg_sel_sdm_rate */ 84562306a36Sopenharmony_ci phy_modify_paged(phydev, 0x0c42, 0x11, BIT(13), BIT(14)); 84662306a36Sopenharmony_ci 84762306a36Sopenharmony_ci /* Channel estimation parameters */ 84862306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x80f3, 0xff00, 0x8b00); 84962306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x80f0, 0xff00, 0x3a00); 85062306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x80ef, 0xff00, 0x0500); 85162306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x80f6, 0xff00, 0x6e00); 85262306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x80ec, 0xff00, 0x6800); 85362306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x80ed, 0xff00, 0x7c00); 85462306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x80f2, 0xff00, 0xf400); 85562306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x80f4, 0xff00, 0x8500); 85662306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x8110, 0xff00, 0xa800); 85762306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x810f, 0xff00, 0x1d00); 85862306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x8111, 0xff00, 0xf500); 85962306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x8113, 0xff00, 0x6100); 86062306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x8115, 0xff00, 0x9200); 86162306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x810e, 0xff00, 0x0400); 86262306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x810c, 0xff00, 0x7c00); 86362306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x810b, 0xff00, 0x5a00); 86462306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x80d1, 0xff00, 0xff00); 86562306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x80cd, 0xff00, 0x9e00); 86662306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x80d3, 0xff00, 0x0e00); 86762306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x80d5, 0xff00, 0xca00); 86862306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x80d7, 0xff00, 0x8400); 86962306a36Sopenharmony_ci 87062306a36Sopenharmony_ci /* Force PWM-mode */ 87162306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0bcd); 87262306a36Sopenharmony_ci phy_write(phydev, 0x14, 0x5065); 87362306a36Sopenharmony_ci phy_write(phydev, 0x14, 0xd065); 87462306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0bc8); 87562306a36Sopenharmony_ci phy_write(phydev, 0x12, 0x00ed); 87662306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0bcd); 87762306a36Sopenharmony_ci phy_write(phydev, 0x14, 0x1065); 87862306a36Sopenharmony_ci phy_write(phydev, 0x14, 0x9065); 87962306a36Sopenharmony_ci phy_write(phydev, 0x14, 0x1065); 88062306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0000); 88162306a36Sopenharmony_ci 88262306a36Sopenharmony_ci rtl8168g_disable_aldps(phydev); 88362306a36Sopenharmony_ci rtl8168g_config_eee_phy(phydev); 88462306a36Sopenharmony_ci} 88562306a36Sopenharmony_ci 88662306a36Sopenharmony_cistatic void rtl8117_hw_phy_config(struct rtl8169_private *tp, 88762306a36Sopenharmony_ci struct phy_device *phydev) 88862306a36Sopenharmony_ci{ 88962306a36Sopenharmony_ci /* CHN EST parameters adjust - fnet */ 89062306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x808e, 0xff00, 0x4800); 89162306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x8090, 0xff00, 0xcc00); 89262306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x8092, 0xff00, 0xb000); 89362306a36Sopenharmony_ci 89462306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x8088, 0xff00, 0x6000); 89562306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x808b, 0x3f00, 0x0b00); 89662306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x808d, 0x1f00, 0x0600); 89762306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x808c, 0xff00, 0xb000); 89862306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x80a0, 0xff00, 0x2800); 89962306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x80a2, 0xff00, 0x5000); 90062306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x809b, 0xf800, 0xb000); 90162306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x809a, 0xff00, 0x4b00); 90262306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x809d, 0x3f00, 0x0800); 90362306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x80a1, 0xff00, 0x7000); 90462306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x809f, 0x1f00, 0x0300); 90562306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x809e, 0xff00, 0x8800); 90662306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x80b2, 0xff00, 0x2200); 90762306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x80ad, 0xf800, 0x9800); 90862306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x80af, 0x3f00, 0x0800); 90962306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x80b3, 0xff00, 0x6f00); 91062306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x80b1, 0x1f00, 0x0300); 91162306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x80b0, 0xff00, 0x9300); 91262306a36Sopenharmony_ci 91362306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x8011, 0x0000, 0x0800); 91462306a36Sopenharmony_ci 91562306a36Sopenharmony_ci rtl8168g_enable_gphy_10m(phydev); 91662306a36Sopenharmony_ci 91762306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x8016, 0x0000, 0x0400); 91862306a36Sopenharmony_ci 91962306a36Sopenharmony_ci rtl8168g_disable_aldps(phydev); 92062306a36Sopenharmony_ci rtl8168h_config_eee_phy(phydev); 92162306a36Sopenharmony_ci} 92262306a36Sopenharmony_ci 92362306a36Sopenharmony_cistatic void rtl8102e_hw_phy_config(struct rtl8169_private *tp, 92462306a36Sopenharmony_ci struct phy_device *phydev) 92562306a36Sopenharmony_ci{ 92662306a36Sopenharmony_ci static const struct phy_reg phy_reg_init[] = { 92762306a36Sopenharmony_ci { 0x1f, 0x0003 }, 92862306a36Sopenharmony_ci { 0x08, 0x441d }, 92962306a36Sopenharmony_ci { 0x01, 0x9100 }, 93062306a36Sopenharmony_ci { 0x1f, 0x0000 } 93162306a36Sopenharmony_ci }; 93262306a36Sopenharmony_ci 93362306a36Sopenharmony_ci phy_set_bits(phydev, 0x11, BIT(12)); 93462306a36Sopenharmony_ci phy_set_bits(phydev, 0x19, BIT(13)); 93562306a36Sopenharmony_ci phy_set_bits(phydev, 0x10, BIT(15)); 93662306a36Sopenharmony_ci 93762306a36Sopenharmony_ci rtl_writephy_batch(phydev, phy_reg_init); 93862306a36Sopenharmony_ci} 93962306a36Sopenharmony_ci 94062306a36Sopenharmony_cistatic void rtl8401_hw_phy_config(struct rtl8169_private *tp, 94162306a36Sopenharmony_ci struct phy_device *phydev) 94262306a36Sopenharmony_ci{ 94362306a36Sopenharmony_ci phy_set_bits(phydev, 0x11, BIT(12)); 94462306a36Sopenharmony_ci phy_modify_paged(phydev, 0x0002, 0x0f, 0x0000, 0x0003); 94562306a36Sopenharmony_ci} 94662306a36Sopenharmony_ci 94762306a36Sopenharmony_cistatic void rtl8105e_hw_phy_config(struct rtl8169_private *tp, 94862306a36Sopenharmony_ci struct phy_device *phydev) 94962306a36Sopenharmony_ci{ 95062306a36Sopenharmony_ci /* Disable ALDPS before ram code */ 95162306a36Sopenharmony_ci phy_write(phydev, 0x18, 0x0310); 95262306a36Sopenharmony_ci msleep(100); 95362306a36Sopenharmony_ci 95462306a36Sopenharmony_ci r8169_apply_firmware(tp); 95562306a36Sopenharmony_ci 95662306a36Sopenharmony_ci phy_write_paged(phydev, 0x0005, 0x1a, 0x0000); 95762306a36Sopenharmony_ci phy_write_paged(phydev, 0x0004, 0x1c, 0x0000); 95862306a36Sopenharmony_ci phy_write_paged(phydev, 0x0001, 0x15, 0x7701); 95962306a36Sopenharmony_ci} 96062306a36Sopenharmony_ci 96162306a36Sopenharmony_cistatic void rtl8402_hw_phy_config(struct rtl8169_private *tp, 96262306a36Sopenharmony_ci struct phy_device *phydev) 96362306a36Sopenharmony_ci{ 96462306a36Sopenharmony_ci /* Disable ALDPS before setting firmware */ 96562306a36Sopenharmony_ci phy_write(phydev, 0x18, 0x0310); 96662306a36Sopenharmony_ci msleep(20); 96762306a36Sopenharmony_ci 96862306a36Sopenharmony_ci r8169_apply_firmware(tp); 96962306a36Sopenharmony_ci 97062306a36Sopenharmony_ci /* EEE setting */ 97162306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0004); 97262306a36Sopenharmony_ci phy_write(phydev, 0x10, 0x401f); 97362306a36Sopenharmony_ci phy_write(phydev, 0x19, 0x7030); 97462306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0000); 97562306a36Sopenharmony_ci} 97662306a36Sopenharmony_ci 97762306a36Sopenharmony_cistatic void rtl8106e_hw_phy_config(struct rtl8169_private *tp, 97862306a36Sopenharmony_ci struct phy_device *phydev) 97962306a36Sopenharmony_ci{ 98062306a36Sopenharmony_ci static const struct phy_reg phy_reg_init[] = { 98162306a36Sopenharmony_ci { 0x1f, 0x0004 }, 98262306a36Sopenharmony_ci { 0x10, 0xc07f }, 98362306a36Sopenharmony_ci { 0x19, 0x7030 }, 98462306a36Sopenharmony_ci { 0x1f, 0x0000 } 98562306a36Sopenharmony_ci }; 98662306a36Sopenharmony_ci 98762306a36Sopenharmony_ci /* Disable ALDPS before ram code */ 98862306a36Sopenharmony_ci phy_write(phydev, 0x18, 0x0310); 98962306a36Sopenharmony_ci msleep(100); 99062306a36Sopenharmony_ci 99162306a36Sopenharmony_ci r8169_apply_firmware(tp); 99262306a36Sopenharmony_ci 99362306a36Sopenharmony_ci rtl_writephy_batch(phydev, phy_reg_init); 99462306a36Sopenharmony_ci} 99562306a36Sopenharmony_ci 99662306a36Sopenharmony_cistatic void rtl8125_legacy_force_mode(struct phy_device *phydev) 99762306a36Sopenharmony_ci{ 99862306a36Sopenharmony_ci phy_modify_paged(phydev, 0xa5b, 0x12, BIT(15), 0); 99962306a36Sopenharmony_ci} 100062306a36Sopenharmony_ci 100162306a36Sopenharmony_cistatic void rtl8125a_2_hw_phy_config(struct rtl8169_private *tp, 100262306a36Sopenharmony_ci struct phy_device *phydev) 100362306a36Sopenharmony_ci{ 100462306a36Sopenharmony_ci int i; 100562306a36Sopenharmony_ci 100662306a36Sopenharmony_ci phy_modify_paged(phydev, 0xad4, 0x17, 0x0000, 0x0010); 100762306a36Sopenharmony_ci phy_modify_paged(phydev, 0xad1, 0x13, 0x03ff, 0x03ff); 100862306a36Sopenharmony_ci phy_modify_paged(phydev, 0xad3, 0x11, 0x003f, 0x0006); 100962306a36Sopenharmony_ci phy_modify_paged(phydev, 0xac0, 0x14, 0x1100, 0x0000); 101062306a36Sopenharmony_ci phy_modify_paged(phydev, 0xacc, 0x10, 0x0003, 0x0002); 101162306a36Sopenharmony_ci phy_modify_paged(phydev, 0xad4, 0x10, 0x00e7, 0x0044); 101262306a36Sopenharmony_ci phy_modify_paged(phydev, 0xac1, 0x12, 0x0080, 0x0000); 101362306a36Sopenharmony_ci phy_modify_paged(phydev, 0xac8, 0x10, 0x0300, 0x0000); 101462306a36Sopenharmony_ci phy_modify_paged(phydev, 0xac5, 0x17, 0x0007, 0x0002); 101562306a36Sopenharmony_ci phy_write_paged(phydev, 0xad4, 0x16, 0x00a8); 101662306a36Sopenharmony_ci phy_write_paged(phydev, 0xac5, 0x16, 0x01ff); 101762306a36Sopenharmony_ci phy_modify_paged(phydev, 0xac8, 0x15, 0x00f0, 0x0030); 101862306a36Sopenharmony_ci 101962306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0b87); 102062306a36Sopenharmony_ci phy_write(phydev, 0x16, 0x80a2); 102162306a36Sopenharmony_ci phy_write(phydev, 0x17, 0x0153); 102262306a36Sopenharmony_ci phy_write(phydev, 0x16, 0x809c); 102362306a36Sopenharmony_ci phy_write(phydev, 0x17, 0x0153); 102462306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0000); 102562306a36Sopenharmony_ci 102662306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0a43); 102762306a36Sopenharmony_ci phy_write(phydev, 0x13, 0x81B3); 102862306a36Sopenharmony_ci phy_write(phydev, 0x14, 0x0043); 102962306a36Sopenharmony_ci phy_write(phydev, 0x14, 0x00A7); 103062306a36Sopenharmony_ci phy_write(phydev, 0x14, 0x00D6); 103162306a36Sopenharmony_ci phy_write(phydev, 0x14, 0x00EC); 103262306a36Sopenharmony_ci phy_write(phydev, 0x14, 0x00F6); 103362306a36Sopenharmony_ci phy_write(phydev, 0x14, 0x00FB); 103462306a36Sopenharmony_ci phy_write(phydev, 0x14, 0x00FD); 103562306a36Sopenharmony_ci phy_write(phydev, 0x14, 0x00FF); 103662306a36Sopenharmony_ci phy_write(phydev, 0x14, 0x00BB); 103762306a36Sopenharmony_ci phy_write(phydev, 0x14, 0x0058); 103862306a36Sopenharmony_ci phy_write(phydev, 0x14, 0x0029); 103962306a36Sopenharmony_ci phy_write(phydev, 0x14, 0x0013); 104062306a36Sopenharmony_ci phy_write(phydev, 0x14, 0x0009); 104162306a36Sopenharmony_ci phy_write(phydev, 0x14, 0x0004); 104262306a36Sopenharmony_ci phy_write(phydev, 0x14, 0x0002); 104362306a36Sopenharmony_ci for (i = 0; i < 25; i++) 104462306a36Sopenharmony_ci phy_write(phydev, 0x14, 0x0000); 104562306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0000); 104662306a36Sopenharmony_ci 104762306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x8257, 0xffff, 0x020F); 104862306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x80ea, 0xffff, 0x7843); 104962306a36Sopenharmony_ci 105062306a36Sopenharmony_ci r8169_apply_firmware(tp); 105162306a36Sopenharmony_ci 105262306a36Sopenharmony_ci phy_modify_paged(phydev, 0xd06, 0x14, 0x0000, 0x2000); 105362306a36Sopenharmony_ci 105462306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x81a2, 0x0000, 0x0100); 105562306a36Sopenharmony_ci 105662306a36Sopenharmony_ci phy_modify_paged(phydev, 0xb54, 0x16, 0xff00, 0xdb00); 105762306a36Sopenharmony_ci phy_modify_paged(phydev, 0xa45, 0x12, 0x0001, 0x0000); 105862306a36Sopenharmony_ci phy_modify_paged(phydev, 0xa5d, 0x12, 0x0000, 0x0020); 105962306a36Sopenharmony_ci phy_modify_paged(phydev, 0xad4, 0x17, 0x0010, 0x0000); 106062306a36Sopenharmony_ci phy_modify_paged(phydev, 0xa86, 0x15, 0x0001, 0x0000); 106162306a36Sopenharmony_ci rtl8168g_enable_gphy_10m(phydev); 106262306a36Sopenharmony_ci 106362306a36Sopenharmony_ci rtl8125a_config_eee_phy(phydev); 106462306a36Sopenharmony_ci} 106562306a36Sopenharmony_ci 106662306a36Sopenharmony_cistatic void rtl8125b_hw_phy_config(struct rtl8169_private *tp, 106762306a36Sopenharmony_ci struct phy_device *phydev) 106862306a36Sopenharmony_ci{ 106962306a36Sopenharmony_ci r8169_apply_firmware(tp); 107062306a36Sopenharmony_ci 107162306a36Sopenharmony_ci phy_modify_paged(phydev, 0xa44, 0x11, 0x0000, 0x0800); 107262306a36Sopenharmony_ci phy_modify_paged(phydev, 0xac4, 0x13, 0x00f0, 0x0090); 107362306a36Sopenharmony_ci phy_modify_paged(phydev, 0xad3, 0x10, 0x0003, 0x0001); 107462306a36Sopenharmony_ci 107562306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0b87); 107662306a36Sopenharmony_ci phy_write(phydev, 0x16, 0x80f5); 107762306a36Sopenharmony_ci phy_write(phydev, 0x17, 0x760e); 107862306a36Sopenharmony_ci phy_write(phydev, 0x16, 0x8107); 107962306a36Sopenharmony_ci phy_write(phydev, 0x17, 0x360e); 108062306a36Sopenharmony_ci phy_write(phydev, 0x16, 0x8551); 108162306a36Sopenharmony_ci phy_modify(phydev, 0x17, 0xff00, 0x0800); 108262306a36Sopenharmony_ci phy_write(phydev, 0x1f, 0x0000); 108362306a36Sopenharmony_ci 108462306a36Sopenharmony_ci phy_modify_paged(phydev, 0xbf0, 0x10, 0xe000, 0xa000); 108562306a36Sopenharmony_ci phy_modify_paged(phydev, 0xbf4, 0x13, 0x0f00, 0x0300); 108662306a36Sopenharmony_ci 108762306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x8044, 0xffff, 0x2417); 108862306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x804a, 0xffff, 0x2417); 108962306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x8050, 0xffff, 0x2417); 109062306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x8056, 0xffff, 0x2417); 109162306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x805c, 0xffff, 0x2417); 109262306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x8062, 0xffff, 0x2417); 109362306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x8068, 0xffff, 0x2417); 109462306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x806e, 0xffff, 0x2417); 109562306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x8074, 0xffff, 0x2417); 109662306a36Sopenharmony_ci r8168g_phy_param(phydev, 0x807a, 0xffff, 0x2417); 109762306a36Sopenharmony_ci 109862306a36Sopenharmony_ci phy_modify_paged(phydev, 0xa4c, 0x15, 0x0000, 0x0040); 109962306a36Sopenharmony_ci phy_modify_paged(phydev, 0xbf8, 0x12, 0xe000, 0xa000); 110062306a36Sopenharmony_ci 110162306a36Sopenharmony_ci rtl8125_legacy_force_mode(phydev); 110262306a36Sopenharmony_ci rtl8125b_config_eee_phy(phydev); 110362306a36Sopenharmony_ci} 110462306a36Sopenharmony_ci 110562306a36Sopenharmony_civoid r8169_hw_phy_config(struct rtl8169_private *tp, struct phy_device *phydev, 110662306a36Sopenharmony_ci enum mac_version ver) 110762306a36Sopenharmony_ci{ 110862306a36Sopenharmony_ci static const rtl_phy_cfg_fct phy_configs[] = { 110962306a36Sopenharmony_ci /* PCI devices. */ 111062306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_02] = rtl8169s_hw_phy_config, 111162306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_03] = rtl8169s_hw_phy_config, 111262306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_04] = rtl8169sb_hw_phy_config, 111362306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_05] = rtl8169scd_hw_phy_config, 111462306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_06] = rtl8169sce_hw_phy_config, 111562306a36Sopenharmony_ci /* PCI-E devices. */ 111662306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_07] = rtl8102e_hw_phy_config, 111762306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_08] = rtl8102e_hw_phy_config, 111862306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_09] = rtl8102e_hw_phy_config, 111962306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_10] = NULL, 112062306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_11] = rtl8168bb_hw_phy_config, 112162306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_14] = rtl8401_hw_phy_config, 112262306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_17] = rtl8168bef_hw_phy_config, 112362306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_18] = rtl8168cp_1_hw_phy_config, 112462306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_19] = rtl8168c_1_hw_phy_config, 112562306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_20] = rtl8168c_2_hw_phy_config, 112662306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_21] = rtl8168c_3_hw_phy_config, 112762306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_22] = rtl8168c_3_hw_phy_config, 112862306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_23] = rtl8168cp_2_hw_phy_config, 112962306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_24] = rtl8168cp_2_hw_phy_config, 113062306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_25] = rtl8168d_1_hw_phy_config, 113162306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_26] = rtl8168d_2_hw_phy_config, 113262306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_28] = rtl8168d_4_hw_phy_config, 113362306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_29] = rtl8105e_hw_phy_config, 113462306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_30] = rtl8105e_hw_phy_config, 113562306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_31] = NULL, 113662306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_32] = rtl8168e_1_hw_phy_config, 113762306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_33] = rtl8168e_1_hw_phy_config, 113862306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_34] = rtl8168e_2_hw_phy_config, 113962306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_35] = rtl8168f_1_hw_phy_config, 114062306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_36] = rtl8168f_2_hw_phy_config, 114162306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_37] = rtl8402_hw_phy_config, 114262306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_38] = rtl8411_hw_phy_config, 114362306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_39] = rtl8106e_hw_phy_config, 114462306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_40] = rtl8168g_1_hw_phy_config, 114562306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_42] = rtl8168g_2_hw_phy_config, 114662306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_43] = rtl8168g_2_hw_phy_config, 114762306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_44] = rtl8168g_2_hw_phy_config, 114862306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_46] = rtl8168h_2_hw_phy_config, 114962306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_48] = rtl8168h_2_hw_phy_config, 115062306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_51] = rtl8168ep_2_hw_phy_config, 115162306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_52] = rtl8117_hw_phy_config, 115262306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_53] = rtl8117_hw_phy_config, 115362306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_61] = rtl8125a_2_hw_phy_config, 115462306a36Sopenharmony_ci [RTL_GIGA_MAC_VER_63] = rtl8125b_hw_phy_config, 115562306a36Sopenharmony_ci }; 115662306a36Sopenharmony_ci 115762306a36Sopenharmony_ci if (phy_configs[ver]) 115862306a36Sopenharmony_ci phy_configs[ver](tp, phydev); 115962306a36Sopenharmony_ci} 1160