Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'r8169-improve-rtl8168g-phy-suspend-quirk'

Heiner Kallweit says:

====================
r8169: improve RTL8168g PHY suspend quirk

According to Realtek the ERI register 0x1a8 quirk is needed to work
around a hw issue with the PHY on RTL8168g. The register needs to be
changed before powering down the PHY. Currently we don't meet this
requirement, however I'm not aware of any problems caused by this.
Therefore I see the change as an improvement.

The PHY driver has no means to access the chip ERI registers,
therefore we have to intercept MDIO writes to the BMCR register.
If the BMCR_PDOWN bit is going to be set, then let's apply the
quirk before actually powering down the PHY.
====================

Link: https://lore.kernel.org/r/9303c2cf-c521-beea-c09f-63b5dfa91b9c@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+90 -90
+90 -90
drivers/net/ethernet/realtek/r8169_main.c
··· 746 746 \ 747 747 static bool name ## _check(struct rtl8169_private *tp) 748 748 749 + static void r8168fp_adjust_ocp_cmd(struct rtl8169_private *tp, u32 *cmd, int type) 750 + { 751 + /* based on RTL8168FP_OOBMAC_BASE in vendor driver */ 752 + if (tp->mac_version == RTL_GIGA_MAC_VER_52 && type == ERIAR_OOB) 753 + *cmd |= 0x7f0 << 18; 754 + } 755 + 756 + DECLARE_RTL_COND(rtl_eriar_cond) 757 + { 758 + return RTL_R32(tp, ERIAR) & ERIAR_FLAG; 759 + } 760 + 761 + static void _rtl_eri_write(struct rtl8169_private *tp, int addr, u32 mask, 762 + u32 val, int type) 763 + { 764 + u32 cmd = ERIAR_WRITE_CMD | type | mask | addr; 765 + 766 + BUG_ON((addr & 3) || (mask == 0)); 767 + RTL_W32(tp, ERIDR, val); 768 + r8168fp_adjust_ocp_cmd(tp, &cmd, type); 769 + RTL_W32(tp, ERIAR, cmd); 770 + 771 + rtl_loop_wait_low(tp, &rtl_eriar_cond, 100, 100); 772 + } 773 + 774 + static void rtl_eri_write(struct rtl8169_private *tp, int addr, u32 mask, 775 + u32 val) 776 + { 777 + _rtl_eri_write(tp, addr, mask, val, ERIAR_EXGMAC); 778 + } 779 + 780 + static u32 _rtl_eri_read(struct rtl8169_private *tp, int addr, int type) 781 + { 782 + u32 cmd = ERIAR_READ_CMD | type | ERIAR_MASK_1111 | addr; 783 + 784 + r8168fp_adjust_ocp_cmd(tp, &cmd, type); 785 + RTL_W32(tp, ERIAR, cmd); 786 + 787 + return rtl_loop_wait_high(tp, &rtl_eriar_cond, 100, 100) ? 788 + RTL_R32(tp, ERIDR) : ~0; 789 + } 790 + 791 + static u32 rtl_eri_read(struct rtl8169_private *tp, int addr) 792 + { 793 + return _rtl_eri_read(tp, addr, ERIAR_EXGMAC); 794 + } 795 + 796 + static void rtl_w0w1_eri(struct rtl8169_private *tp, int addr, u32 p, u32 m) 797 + { 798 + u32 val = rtl_eri_read(tp, addr); 799 + 800 + rtl_eri_write(tp, addr, ERIAR_MASK_1111, (val & ~m) | p); 801 + } 802 + 803 + static void rtl_eri_set_bits(struct rtl8169_private *tp, int addr, u32 p) 804 + { 805 + rtl_w0w1_eri(tp, addr, p, 0); 806 + } 807 + 808 + static void rtl_eri_clear_bits(struct rtl8169_private *tp, int addr, u32 m) 809 + { 810 + rtl_w0w1_eri(tp, addr, 0, m); 811 + } 812 + 749 813 static bool rtl_ocp_reg_failure(struct rtl8169_private *tp, u32 reg) 750 814 { 751 815 if (reg & 0xffff0001) { ··· 872 808 r8168_mac_ocp_write(tp, reg, (data & ~mask) | set); 873 809 } 874 810 811 + /* Work around a hw issue with RTL8168g PHY, the quirk disables 812 + * PHY MCU interrupts before PHY power-down. 813 + */ 814 + static void rtl8168g_phy_suspend_quirk(struct rtl8169_private *tp, int value) 815 + { 816 + switch (tp->mac_version) { 817 + case RTL_GIGA_MAC_VER_40: 818 + case RTL_GIGA_MAC_VER_41: 819 + case RTL_GIGA_MAC_VER_49: 820 + if (value & BMCR_RESET || !(value & BMCR_PDOWN)) 821 + rtl_eri_set_bits(tp, 0x1a8, 0xfc000000); 822 + else 823 + rtl_eri_clear_bits(tp, 0x1a8, 0xfc000000); 824 + break; 825 + default: 826 + break; 827 + } 828 + }; 829 + 875 830 static void r8168g_mdio_write(struct rtl8169_private *tp, int reg, int value) 876 831 { 877 832 if (reg == 0x1f) { ··· 900 817 901 818 if (tp->ocp_base != OCP_STD_PHY_BASE) 902 819 reg -= 0x10; 820 + 821 + if (tp->ocp_base == OCP_STD_PHY_BASE && reg == MII_BMCR) 822 + rtl8168g_phy_suspend_quirk(tp, value); 903 823 904 824 r8168_phy_ocp_write(tp, tp->ocp_base + reg * 2, value); 905 825 } ··· 1093 1007 1094 1008 return rtl_loop_wait_high(tp, &rtl_ephyar_cond, 10, 100) ? 1095 1009 RTL_R32(tp, EPHYAR) & EPHYAR_DATA_MASK : ~0; 1096 - } 1097 - 1098 - static void r8168fp_adjust_ocp_cmd(struct rtl8169_private *tp, u32 *cmd, int type) 1099 - { 1100 - /* based on RTL8168FP_OOBMAC_BASE in vendor driver */ 1101 - if (tp->mac_version == RTL_GIGA_MAC_VER_52 && type == ERIAR_OOB) 1102 - *cmd |= 0x7f0 << 18; 1103 - } 1104 - 1105 - DECLARE_RTL_COND(rtl_eriar_cond) 1106 - { 1107 - return RTL_R32(tp, ERIAR) & ERIAR_FLAG; 1108 - } 1109 - 1110 - static void _rtl_eri_write(struct rtl8169_private *tp, int addr, u32 mask, 1111 - u32 val, int type) 1112 - { 1113 - u32 cmd = ERIAR_WRITE_CMD | type | mask | addr; 1114 - 1115 - BUG_ON((addr & 3) || (mask == 0)); 1116 - RTL_W32(tp, ERIDR, val); 1117 - r8168fp_adjust_ocp_cmd(tp, &cmd, type); 1118 - RTL_W32(tp, ERIAR, cmd); 1119 - 1120 - rtl_loop_wait_low(tp, &rtl_eriar_cond, 100, 100); 1121 - } 1122 - 1123 - static void rtl_eri_write(struct rtl8169_private *tp, int addr, u32 mask, 1124 - u32 val) 1125 - { 1126 - _rtl_eri_write(tp, addr, mask, val, ERIAR_EXGMAC); 1127 - } 1128 - 1129 - static u32 _rtl_eri_read(struct rtl8169_private *tp, int addr, int type) 1130 - { 1131 - u32 cmd = ERIAR_READ_CMD | type | ERIAR_MASK_1111 | addr; 1132 - 1133 - r8168fp_adjust_ocp_cmd(tp, &cmd, type); 1134 - RTL_W32(tp, ERIAR, cmd); 1135 - 1136 - return rtl_loop_wait_high(tp, &rtl_eriar_cond, 100, 100) ? 1137 - RTL_R32(tp, ERIDR) : ~0; 1138 - } 1139 - 1140 - static u32 rtl_eri_read(struct rtl8169_private *tp, int addr) 1141 - { 1142 - return _rtl_eri_read(tp, addr, ERIAR_EXGMAC); 1143 - } 1144 - 1145 - static void rtl_w0w1_eri(struct rtl8169_private *tp, int addr, u32 p, u32 m) 1146 - { 1147 - u32 val = rtl_eri_read(tp, addr); 1148 - 1149 - rtl_eri_write(tp, addr, ERIAR_MASK_1111, (val & ~m) | p); 1150 - } 1151 - 1152 - static void rtl_eri_set_bits(struct rtl8169_private *tp, int addr, u32 p) 1153 - { 1154 - rtl_w0w1_eri(tp, addr, p, 0); 1155 - } 1156 - 1157 - static void rtl_eri_clear_bits(struct rtl8169_private *tp, int addr, u32 m) 1158 - { 1159 - rtl_w0w1_eri(tp, addr, 0, m); 1160 1010 } 1161 1011 1162 1012 static u32 r8168dp_ocp_read(struct rtl8169_private *tp, u16 reg) ··· 2232 2210 case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_26: 2233 2211 case RTL_GIGA_MAC_VER_32 ... RTL_GIGA_MAC_VER_33: 2234 2212 case RTL_GIGA_MAC_VER_37: 2235 - case RTL_GIGA_MAC_VER_39: 2236 - case RTL_GIGA_MAC_VER_43: 2237 - case RTL_GIGA_MAC_VER_44: 2238 - case RTL_GIGA_MAC_VER_45: 2239 - case RTL_GIGA_MAC_VER_46: 2240 - case RTL_GIGA_MAC_VER_47: 2241 - case RTL_GIGA_MAC_VER_48: 2242 - case RTL_GIGA_MAC_VER_50 ... RTL_GIGA_MAC_VER_63: 2243 - RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~0x80); 2244 - break; 2245 - case RTL_GIGA_MAC_VER_40: 2246 - case RTL_GIGA_MAC_VER_41: 2247 - case RTL_GIGA_MAC_VER_49: 2248 - rtl_eri_clear_bits(tp, 0x1a8, 0xfc000000); 2213 + case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_41: 2214 + case RTL_GIGA_MAC_VER_43 ... RTL_GIGA_MAC_VER_63: 2249 2215 RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~0x80); 2250 2216 break; 2251 2217 default: ··· 2251 2241 case RTL_GIGA_MAC_VER_43: 2252 2242 RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | 0x80); 2253 2243 break; 2254 - case RTL_GIGA_MAC_VER_44: 2255 - case RTL_GIGA_MAC_VER_45: 2256 - case RTL_GIGA_MAC_VER_46: 2257 - case RTL_GIGA_MAC_VER_47: 2258 - case RTL_GIGA_MAC_VER_48: 2259 - case RTL_GIGA_MAC_VER_50 ... RTL_GIGA_MAC_VER_63: 2244 + case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_41: 2245 + case RTL_GIGA_MAC_VER_44 ... RTL_GIGA_MAC_VER_63: 2260 2246 RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | 0xc0); 2261 - break; 2262 - case RTL_GIGA_MAC_VER_40: 2263 - case RTL_GIGA_MAC_VER_41: 2264 - case RTL_GIGA_MAC_VER_49: 2265 - RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | 0xc0); 2266 - rtl_eri_set_bits(tp, 0x1a8, 0xfc000000); 2267 2247 break; 2268 2248 default: 2269 2249 break;