1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * drivers/net/phy/realtek.c 4 * 5 * Driver for Realtek PHYs 6 * 7 * Author: Johnson Leung <r58129@freescale.com> 8 * 9 * Copyright (c) 2004 Freescale Semiconductor, Inc. 10 */ 11 #include <linux/bitops.h> 12 #include <linux/phy.h> 13 #include <linux/module.h> 14 15 #define RTL821x_PHYSR 0x11 16 #define RTL821x_PHYSR_DUPLEX BIT(13) 17 #define RTL821x_PHYSR_SPEED GENMASK(15, 14) 18 19 #define RTL821x_INER 0x12 20 #define RTL8211B_INER_INIT 0x6400 21 #define RTL8211E_INER_LINK_STATUS BIT(10) 22 #define RTL8211F_INER_LINK_STATUS BIT(4) 23 24 #define RTL821x_INSR 0x13 25 26 #define RTL821x_EXT_PAGE_SELECT 0x1e 27 #define RTL821x_PAGE_SELECT 0x1f 28 29 #define RTL8211F_INSR 0x1d 30 31 #define RTL8211F_TX_DELAY BIT(8) 32 #define RTL8211E_TX_DELAY BIT(1) 33 #define RTL8211E_RX_DELAY BIT(2) 34 #define RTL8211E_MODE_MII_GMII BIT(3) 35 36 #define RTL8201F_ISR 0x1e 37 #define RTL8201F_IER 0x13 38 39 #define RTL8366RB_POWER_SAVE 0x15 40 #define RTL8366RB_POWER_SAVE_ON BIT(12) 41 42 MODULE_DESCRIPTION("Realtek PHY driver"); 43 MODULE_AUTHOR("Johnson Leung"); 44 MODULE_LICENSE("GPL"); 45 46 static int rtl821x_read_page(struct phy_device *phydev) 47 { 48 return __phy_read(phydev, RTL821x_PAGE_SELECT); 49 } 50 51 static int rtl821x_write_page(struct phy_device *phydev, int page) 52 { 53 return __phy_write(phydev, RTL821x_PAGE_SELECT, page); 54 } 55 56 static int rtl8201_ack_interrupt(struct phy_device *phydev) 57 { 58 int err; 59 60 err = phy_read(phydev, RTL8201F_ISR); 61 62 return (err < 0) ? err : 0; 63 } 64 65 static int rtl821x_ack_interrupt(struct phy_device *phydev) 66 { 67 int err; 68 69 err = phy_read(phydev, RTL821x_INSR); 70 71 return (err < 0) ? err : 0; 72 } 73 74 static int rtl8211f_ack_interrupt(struct phy_device *phydev) 75 { 76 int err; 77 78 err = phy_read_paged(phydev, 0xa43, RTL8211F_INSR); 79 80 return (err < 0) ? err : 0; 81 } 82 83 static int rtl8201_config_intr(struct phy_device *phydev) 84 { 85 u16 val; 86 87 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) 88 val = BIT(13) | BIT(12) | BIT(11); 89 else 90 val = 0; 91 92 return phy_write_paged(phydev, 0x7, RTL8201F_IER, val); 93 } 94 95 static int rtl8211b_config_intr(struct phy_device *phydev) 96 { 97 int err; 98 99 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) 100 err = phy_write(phydev, RTL821x_INER, 101 RTL8211B_INER_INIT); 102 else 103 err = phy_write(phydev, RTL821x_INER, 0); 104 105 return err; 106 } 107 108 static int rtl8211e_config_intr(struct phy_device *phydev) 109 { 110 int err; 111 112 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) 113 err = phy_write(phydev, RTL821x_INER, 114 RTL8211E_INER_LINK_STATUS); 115 else 116 err = phy_write(phydev, RTL821x_INER, 0); 117 118 return err; 119 } 120 121 static int rtl8211f_config_intr(struct phy_device *phydev) 122 { 123 u16 val; 124 125 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) 126 val = RTL8211F_INER_LINK_STATUS; 127 else 128 val = 0; 129 130 return phy_write_paged(phydev, 0xa42, RTL821x_INER, val); 131 } 132 133 static int rtl8211_config_aneg(struct phy_device *phydev) 134 { 135 int ret; 136 137 ret = genphy_config_aneg(phydev); 138 if (ret < 0) 139 return ret; 140 141 /* Quirk was copied from vendor driver. Unfortunately it includes no 142 * description of the magic numbers. 143 */ 144 if (phydev->speed == SPEED_100 && phydev->autoneg == AUTONEG_DISABLE) { 145 phy_write(phydev, 0x17, 0x2138); 146 phy_write(phydev, 0x0e, 0x0260); 147 } else { 148 phy_write(phydev, 0x17, 0x2108); 149 phy_write(phydev, 0x0e, 0x0000); 150 } 151 152 return 0; 153 } 154 155 static int rtl8211c_config_init(struct phy_device *phydev) 156 { 157 /* RTL8211C has an issue when operating in Gigabit slave mode */ 158 return phy_set_bits(phydev, MII_CTRL1000, 159 CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER); 160 } 161 162 static int rtl8211f_config_init(struct phy_device *phydev) 163 { 164 u16 val; 165 166 /* enable TX-delay for rgmii-{id,txid}, and disable it for rgmii and 167 * rgmii-rxid. The RX-delay can be enabled by the external RXDLY pin. 168 */ 169 switch (phydev->interface) { 170 case PHY_INTERFACE_MODE_RGMII: 171 case PHY_INTERFACE_MODE_RGMII_RXID: 172 val = 0; 173 break; 174 case PHY_INTERFACE_MODE_RGMII_ID: 175 case PHY_INTERFACE_MODE_RGMII_TXID: 176 val = RTL8211F_TX_DELAY; 177 break; 178 default: /* the rest of the modes imply leaving delay as is. */ 179 return 0; 180 } 181 182 return phy_modify_paged(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY, val); 183 } 184 185 static int rtl8211e_config_init(struct phy_device *phydev) 186 { 187 int ret = 0, oldpage; 188 u16 val; 189 190 /* enable TX/RX delay for rgmii-* modes, and disable them for rgmii. */ 191 switch (phydev->interface) { 192 case PHY_INTERFACE_MODE_RGMII: 193 val = 0; 194 break; 195 case PHY_INTERFACE_MODE_RGMII_ID: 196 val = RTL8211E_TX_DELAY | RTL8211E_RX_DELAY; 197 break; 198 case PHY_INTERFACE_MODE_RGMII_RXID: 199 val = RTL8211E_RX_DELAY; 200 break; 201 case PHY_INTERFACE_MODE_RGMII_TXID: 202 val = RTL8211E_TX_DELAY; 203 break; 204 default: /* the rest of the modes imply leaving delays as is. */ 205 return 0; 206 } 207 208 /* According to a sample driver there is a 0x1c config register on the 209 * 0xa4 extension page (0x7) layout. It can be used to disable/enable 210 * the RX/TX delays otherwise controlled by RXDLY/TXDLY pins. It can 211 * also be used to customize the whole configuration register: 212 * 8:6 = PHY Address, 5:4 = Auto-Negotiation, 3 = Interface Mode Select, 213 * 2 = RX Delay, 1 = TX Delay, 0 = SELRGV (see original PHY datasheet 214 * for details). 215 */ 216 oldpage = phy_select_page(phydev, 0x7); 217 if (oldpage < 0) 218 goto err_restore_page; 219 220 ret = __phy_write(phydev, RTL821x_EXT_PAGE_SELECT, 0xa4); 221 if (ret) 222 goto err_restore_page; 223 224 ret = __phy_modify(phydev, 0x1c, RTL8211E_TX_DELAY | RTL8211E_RX_DELAY, 225 val); 226 227 err_restore_page: 228 return phy_restore_page(phydev, oldpage, ret); 229 } 230 231 static int rtl8211b_suspend(struct phy_device *phydev) 232 { 233 phy_write(phydev, MII_MMD_DATA, BIT(9)); 234 235 return genphy_suspend(phydev); 236 } 237 238 static int rtl8211b_resume(struct phy_device *phydev) 239 { 240 phy_write(phydev, MII_MMD_DATA, 0); 241 242 return genphy_resume(phydev); 243 } 244 245 static int rtl8366rb_config_init(struct phy_device *phydev) 246 { 247 int ret; 248 249 ret = phy_set_bits(phydev, RTL8366RB_POWER_SAVE, 250 RTL8366RB_POWER_SAVE_ON); 251 if (ret) { 252 dev_err(&phydev->mdio.dev, 253 "error enabling power management\n"); 254 } 255 256 return ret; 257 } 258 259 static struct phy_driver realtek_drvs[] = { 260 { 261 PHY_ID_MATCH_EXACT(0x00008201), 262 .name = "RTL8201CP Ethernet", 263 }, { 264 PHY_ID_MATCH_EXACT(0x001cc816), 265 .name = "RTL8201F Fast Ethernet", 266 .ack_interrupt = &rtl8201_ack_interrupt, 267 .config_intr = &rtl8201_config_intr, 268 .suspend = genphy_suspend, 269 .resume = genphy_resume, 270 .read_page = rtl821x_read_page, 271 .write_page = rtl821x_write_page, 272 }, { 273 PHY_ID_MATCH_EXACT(0x001cc910), 274 .name = "RTL8211 Gigabit Ethernet", 275 .config_aneg = rtl8211_config_aneg, 276 .read_mmd = &genphy_read_mmd_unsupported, 277 .write_mmd = &genphy_write_mmd_unsupported, 278 .read_page = rtl821x_read_page, 279 .write_page = rtl821x_write_page, 280 }, { 281 PHY_ID_MATCH_EXACT(0x001cc912), 282 .name = "RTL8211B Gigabit Ethernet", 283 .ack_interrupt = &rtl821x_ack_interrupt, 284 .config_intr = &rtl8211b_config_intr, 285 .read_mmd = &genphy_read_mmd_unsupported, 286 .write_mmd = &genphy_write_mmd_unsupported, 287 .suspend = rtl8211b_suspend, 288 .resume = rtl8211b_resume, 289 .read_page = rtl821x_read_page, 290 .write_page = rtl821x_write_page, 291 }, { 292 PHY_ID_MATCH_EXACT(0x001cc913), 293 .name = "RTL8211C Gigabit Ethernet", 294 .config_init = rtl8211c_config_init, 295 .read_mmd = &genphy_read_mmd_unsupported, 296 .write_mmd = &genphy_write_mmd_unsupported, 297 .read_page = rtl821x_read_page, 298 .write_page = rtl821x_write_page, 299 }, { 300 PHY_ID_MATCH_EXACT(0x001cc914), 301 .name = "RTL8211DN Gigabit Ethernet", 302 .ack_interrupt = rtl821x_ack_interrupt, 303 .config_intr = rtl8211e_config_intr, 304 .suspend = genphy_suspend, 305 .resume = genphy_resume, 306 .read_page = rtl821x_read_page, 307 .write_page = rtl821x_write_page, 308 }, { 309 PHY_ID_MATCH_EXACT(0x001cc915), 310 .name = "RTL8211E Gigabit Ethernet", 311 .config_init = &rtl8211e_config_init, 312 .ack_interrupt = &rtl821x_ack_interrupt, 313 .config_intr = &rtl8211e_config_intr, 314 .suspend = genphy_suspend, 315 .resume = genphy_resume, 316 .read_page = rtl821x_read_page, 317 .write_page = rtl821x_write_page, 318 }, { 319 PHY_ID_MATCH_EXACT(0x001cc916), 320 .name = "RTL8211F Gigabit Ethernet", 321 .config_init = &rtl8211f_config_init, 322 .ack_interrupt = &rtl8211f_ack_interrupt, 323 .config_intr = &rtl8211f_config_intr, 324 .suspend = genphy_suspend, 325 .resume = genphy_resume, 326 .read_page = rtl821x_read_page, 327 .write_page = rtl821x_write_page, 328 }, { 329 PHY_ID_MATCH_EXACT(0x001cc800), 330 .name = "Generic Realtek PHY", 331 .suspend = genphy_suspend, 332 .resume = genphy_resume, 333 .read_page = rtl821x_read_page, 334 .write_page = rtl821x_write_page, 335 }, { 336 PHY_ID_MATCH_EXACT(0x001cc961), 337 .name = "RTL8366RB Gigabit Ethernet", 338 .config_init = &rtl8366rb_config_init, 339 /* These interrupts are handled by the irq controller 340 * embedded inside the RTL8366RB, they get unmasked when the 341 * irq is requested and ACKed by reading the status register, 342 * which is done by the irqchip code. 343 */ 344 .ack_interrupt = genphy_no_ack_interrupt, 345 .config_intr = genphy_no_config_intr, 346 .suspend = genphy_suspend, 347 .resume = genphy_resume, 348 }, 349 }; 350 351 module_phy_driver(realtek_drvs); 352 353 static const struct mdio_device_id __maybe_unused realtek_tbl[] = { 354 { PHY_ID_MATCH_VENDOR(0x001cc800) }, 355 { } 356 }; 357 358 MODULE_DEVICE_TABLE(mdio, realtek_tbl); 359