19082eeacSAndy Fleming /* 29082eeacSAndy Fleming * Marvell PHY drivers 39082eeacSAndy Fleming * 41a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 59082eeacSAndy Fleming * 69082eeacSAndy Fleming * Copyright 2010-2011 Freescale Semiconductor, Inc. 79082eeacSAndy Fleming * author Andy Fleming 89082eeacSAndy Fleming */ 99082eeacSAndy Fleming #include <config.h> 109082eeacSAndy Fleming #include <common.h> 11fbfa1abaSSimon Glass #include <errno.h> 129082eeacSAndy Fleming #include <phy.h> 139082eeacSAndy Fleming 149082eeacSAndy Fleming #define PHY_AUTONEGOTIATE_TIMEOUT 5000 159082eeacSAndy Fleming 169082eeacSAndy Fleming /* 88E1011 PHY Status Register */ 179082eeacSAndy Fleming #define MIIM_88E1xxx_PHY_STATUS 0x11 189082eeacSAndy Fleming #define MIIM_88E1xxx_PHYSTAT_SPEED 0xc000 199082eeacSAndy Fleming #define MIIM_88E1xxx_PHYSTAT_GBIT 0x8000 209082eeacSAndy Fleming #define MIIM_88E1xxx_PHYSTAT_100 0x4000 219082eeacSAndy Fleming #define MIIM_88E1xxx_PHYSTAT_DUPLEX 0x2000 229082eeacSAndy Fleming #define MIIM_88E1xxx_PHYSTAT_SPDDONE 0x0800 239082eeacSAndy Fleming #define MIIM_88E1xxx_PHYSTAT_LINK 0x0400 249082eeacSAndy Fleming 259082eeacSAndy Fleming #define MIIM_88E1xxx_PHY_SCR 0x10 269082eeacSAndy Fleming #define MIIM_88E1xxx_PHY_MDI_X_AUTO 0x0060 279082eeacSAndy Fleming 289082eeacSAndy Fleming /* 88E1111 PHY LED Control Register */ 299082eeacSAndy Fleming #define MIIM_88E1111_PHY_LED_CONTROL 24 309082eeacSAndy Fleming #define MIIM_88E1111_PHY_LED_DIRECT 0x4100 319082eeacSAndy Fleming #define MIIM_88E1111_PHY_LED_COMBINE 0x411C 329082eeacSAndy Fleming 33fa12a08eSZang Roy-R61911 /* 88E1111 Extended PHY Specific Control Register */ 34fa12a08eSZang Roy-R61911 #define MIIM_88E1111_PHY_EXT_CR 0x14 35fa12a08eSZang Roy-R61911 #define MIIM_88E1111_RX_DELAY 0x80 36fa12a08eSZang Roy-R61911 #define MIIM_88E1111_TX_DELAY 0x2 37fa12a08eSZang Roy-R61911 38fa12a08eSZang Roy-R61911 /* 88E1111 Extended PHY Specific Status Register */ 39fa12a08eSZang Roy-R61911 #define MIIM_88E1111_PHY_EXT_SR 0x1b 40fa12a08eSZang Roy-R61911 #define MIIM_88E1111_HWCFG_MODE_MASK 0xf 41fa12a08eSZang Roy-R61911 #define MIIM_88E1111_HWCFG_MODE_COPPER_RGMII 0xb 42fa12a08eSZang Roy-R61911 #define MIIM_88E1111_HWCFG_MODE_FIBER_RGMII 0x3 43fa12a08eSZang Roy-R61911 #define MIIM_88E1111_HWCFG_MODE_SGMII_NO_CLK 0x4 44fa12a08eSZang Roy-R61911 #define MIIM_88E1111_HWCFG_MODE_COPPER_RTBI 0x9 45fa12a08eSZang Roy-R61911 #define MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO 0x8000 46fa12a08eSZang Roy-R61911 #define MIIM_88E1111_HWCFG_FIBER_COPPER_RES 0x2000 47fa12a08eSZang Roy-R61911 48fa12a08eSZang Roy-R61911 #define MIIM_88E1111_COPPER 0 49fa12a08eSZang Roy-R61911 #define MIIM_88E1111_FIBER 1 50fa12a08eSZang Roy-R61911 519082eeacSAndy Fleming /* 88E1118 PHY defines */ 529082eeacSAndy Fleming #define MIIM_88E1118_PHY_PAGE 22 539082eeacSAndy Fleming #define MIIM_88E1118_PHY_LED_PAGE 3 549082eeacSAndy Fleming 559082eeacSAndy Fleming /* 88E1121 PHY LED Control Register */ 569082eeacSAndy Fleming #define MIIM_88E1121_PHY_LED_CTRL 16 579082eeacSAndy Fleming #define MIIM_88E1121_PHY_LED_PAGE 3 589082eeacSAndy Fleming #define MIIM_88E1121_PHY_LED_DEF 0x0030 599082eeacSAndy Fleming 609082eeacSAndy Fleming /* 88E1121 PHY IRQ Enable/Status Register */ 619082eeacSAndy Fleming #define MIIM_88E1121_PHY_IRQ_EN 18 629082eeacSAndy Fleming #define MIIM_88E1121_PHY_IRQ_STATUS 19 639082eeacSAndy Fleming 649082eeacSAndy Fleming #define MIIM_88E1121_PHY_PAGE 22 659082eeacSAndy Fleming 669082eeacSAndy Fleming /* 88E1145 Extended PHY Specific Control Register */ 679082eeacSAndy Fleming #define MIIM_88E1145_PHY_EXT_CR 20 689082eeacSAndy Fleming #define MIIM_M88E1145_RGMII_RX_DELAY 0x0080 699082eeacSAndy Fleming #define MIIM_M88E1145_RGMII_TX_DELAY 0x0002 709082eeacSAndy Fleming 719082eeacSAndy Fleming #define MIIM_88E1145_PHY_LED_CONTROL 24 729082eeacSAndy Fleming #define MIIM_88E1145_PHY_LED_DIRECT 0x4100 739082eeacSAndy Fleming 749082eeacSAndy Fleming #define MIIM_88E1145_PHY_PAGE 29 759082eeacSAndy Fleming #define MIIM_88E1145_PHY_CAL_OV 30 769082eeacSAndy Fleming 779082eeacSAndy Fleming #define MIIM_88E1149_PHY_PAGE 29 789082eeacSAndy Fleming 79aeceec0dSSebastian Hesselbarth /* 88E1310 PHY defines */ 80aeceec0dSSebastian Hesselbarth #define MIIM_88E1310_PHY_LED_CTRL 16 81aeceec0dSSebastian Hesselbarth #define MIIM_88E1310_PHY_IRQ_EN 18 82aeceec0dSSebastian Hesselbarth #define MIIM_88E1310_PHY_RGMII_CTRL 21 83aeceec0dSSebastian Hesselbarth #define MIIM_88E1310_PHY_PAGE 22 84aeceec0dSSebastian Hesselbarth 859082eeacSAndy Fleming /* Marvell 88E1011S */ 869082eeacSAndy Fleming static int m88e1011s_config(struct phy_device *phydev) 879082eeacSAndy Fleming { 889082eeacSAndy Fleming /* Reset and configure the PHY */ 899082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET); 909082eeacSAndy Fleming 919082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f); 929082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x200c); 939082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5); 949082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0); 959082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); 969082eeacSAndy Fleming 979082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET); 989082eeacSAndy Fleming 999082eeacSAndy Fleming genphy_config_aneg(phydev); 1009082eeacSAndy Fleming 1019082eeacSAndy Fleming return 0; 1029082eeacSAndy Fleming } 1039082eeacSAndy Fleming 1049082eeacSAndy Fleming /* Parse the 88E1011's status register for speed and duplex 1059082eeacSAndy Fleming * information 1069082eeacSAndy Fleming */ 107ef5e821bSMichal Simek static int m88e1xxx_parse_status(struct phy_device *phydev) 1089082eeacSAndy Fleming { 1099082eeacSAndy Fleming unsigned int speed; 1109082eeacSAndy Fleming unsigned int mii_reg; 1119082eeacSAndy Fleming 1129082eeacSAndy Fleming mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1xxx_PHY_STATUS); 1139082eeacSAndy Fleming 1149082eeacSAndy Fleming if ((mii_reg & MIIM_88E1xxx_PHYSTAT_LINK) && 1159082eeacSAndy Fleming !(mii_reg & MIIM_88E1xxx_PHYSTAT_SPDDONE)) { 1169082eeacSAndy Fleming int i = 0; 1179082eeacSAndy Fleming 1189082eeacSAndy Fleming puts("Waiting for PHY realtime link"); 1199082eeacSAndy Fleming while (!(mii_reg & MIIM_88E1xxx_PHYSTAT_SPDDONE)) { 1209082eeacSAndy Fleming /* Timeout reached ? */ 1219082eeacSAndy Fleming if (i > PHY_AUTONEGOTIATE_TIMEOUT) { 1229082eeacSAndy Fleming puts(" TIMEOUT !\n"); 1239082eeacSAndy Fleming phydev->link = 0; 124ef5e821bSMichal Simek return -ETIMEDOUT; 1259082eeacSAndy Fleming } 1269082eeacSAndy Fleming 1279082eeacSAndy Fleming if ((i++ % 1000) == 0) 1289082eeacSAndy Fleming putc('.'); 1299082eeacSAndy Fleming udelay(1000); 1309082eeacSAndy Fleming mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, 1319082eeacSAndy Fleming MIIM_88E1xxx_PHY_STATUS); 1329082eeacSAndy Fleming } 1339082eeacSAndy Fleming puts(" done\n"); 1349082eeacSAndy Fleming udelay(500000); /* another 500 ms (results in faster booting) */ 1359082eeacSAndy Fleming } else { 1369082eeacSAndy Fleming if (mii_reg & MIIM_88E1xxx_PHYSTAT_LINK) 1379082eeacSAndy Fleming phydev->link = 1; 1389082eeacSAndy Fleming else 1399082eeacSAndy Fleming phydev->link = 0; 1409082eeacSAndy Fleming } 1419082eeacSAndy Fleming 1429082eeacSAndy Fleming if (mii_reg & MIIM_88E1xxx_PHYSTAT_DUPLEX) 1439082eeacSAndy Fleming phydev->duplex = DUPLEX_FULL; 1449082eeacSAndy Fleming else 1459082eeacSAndy Fleming phydev->duplex = DUPLEX_HALF; 1469082eeacSAndy Fleming 1479082eeacSAndy Fleming speed = mii_reg & MIIM_88E1xxx_PHYSTAT_SPEED; 1489082eeacSAndy Fleming 1499082eeacSAndy Fleming switch (speed) { 1509082eeacSAndy Fleming case MIIM_88E1xxx_PHYSTAT_GBIT: 1519082eeacSAndy Fleming phydev->speed = SPEED_1000; 1529082eeacSAndy Fleming break; 1539082eeacSAndy Fleming case MIIM_88E1xxx_PHYSTAT_100: 1549082eeacSAndy Fleming phydev->speed = SPEED_100; 1559082eeacSAndy Fleming break; 1569082eeacSAndy Fleming default: 1579082eeacSAndy Fleming phydev->speed = SPEED_10; 1589082eeacSAndy Fleming break; 1599082eeacSAndy Fleming } 1609082eeacSAndy Fleming 1619082eeacSAndy Fleming return 0; 1629082eeacSAndy Fleming } 1639082eeacSAndy Fleming 1649082eeacSAndy Fleming static int m88e1011s_startup(struct phy_device *phydev) 1659082eeacSAndy Fleming { 166b733c278SMichal Simek int ret; 1679082eeacSAndy Fleming 168b733c278SMichal Simek ret = genphy_update_link(phydev); 169b733c278SMichal Simek if (ret) 170b733c278SMichal Simek return ret; 171b733c278SMichal Simek 172b733c278SMichal Simek return m88e1xxx_parse_status(phydev); 1739082eeacSAndy Fleming } 1749082eeacSAndy Fleming 1759082eeacSAndy Fleming /* Marvell 88E1111S */ 1769082eeacSAndy Fleming static int m88e1111s_config(struct phy_device *phydev) 1779082eeacSAndy Fleming { 1789082eeacSAndy Fleming int reg; 1799082eeacSAndy Fleming 1809082eeacSAndy Fleming if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) || 1819082eeacSAndy Fleming (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) || 1829082eeacSAndy Fleming (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) || 1839082eeacSAndy Fleming (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) { 184fa12a08eSZang Roy-R61911 reg = phy_read(phydev, 185fa12a08eSZang Roy-R61911 MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR); 186fa12a08eSZang Roy-R61911 if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) || 187fa12a08eSZang Roy-R61911 (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)) { 188fa12a08eSZang Roy-R61911 reg |= (MIIM_88E1111_RX_DELAY | MIIM_88E1111_TX_DELAY); 189fa12a08eSZang Roy-R61911 } else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) { 190fa12a08eSZang Roy-R61911 reg &= ~MIIM_88E1111_TX_DELAY; 191fa12a08eSZang Roy-R61911 reg |= MIIM_88E1111_RX_DELAY; 192fa12a08eSZang Roy-R61911 } else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) { 193fa12a08eSZang Roy-R61911 reg &= ~MIIM_88E1111_RX_DELAY; 194fa12a08eSZang Roy-R61911 reg |= MIIM_88E1111_TX_DELAY; 1959082eeacSAndy Fleming } 1969082eeacSAndy Fleming 197fa12a08eSZang Roy-R61911 phy_write(phydev, 198fa12a08eSZang Roy-R61911 MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR, reg); 199fa12a08eSZang Roy-R61911 200fa12a08eSZang Roy-R61911 reg = phy_read(phydev, 201fa12a08eSZang Roy-R61911 MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_SR); 202fa12a08eSZang Roy-R61911 203fa12a08eSZang Roy-R61911 reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK); 204fa12a08eSZang Roy-R61911 205fa12a08eSZang Roy-R61911 if (reg & MIIM_88E1111_HWCFG_FIBER_COPPER_RES) 206fa12a08eSZang Roy-R61911 reg |= MIIM_88E1111_HWCFG_MODE_FIBER_RGMII; 207fa12a08eSZang Roy-R61911 else 208fa12a08eSZang Roy-R61911 reg |= MIIM_88E1111_HWCFG_MODE_COPPER_RGMII; 209fa12a08eSZang Roy-R61911 210fa12a08eSZang Roy-R61911 phy_write(phydev, 211fa12a08eSZang Roy-R61911 MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_SR, reg); 212fa12a08eSZang Roy-R61911 } 213fa12a08eSZang Roy-R61911 214fa12a08eSZang Roy-R61911 if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { 215fa12a08eSZang Roy-R61911 reg = phy_read(phydev, 216fa12a08eSZang Roy-R61911 MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_SR); 217fa12a08eSZang Roy-R61911 218fa12a08eSZang Roy-R61911 reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK); 219fa12a08eSZang Roy-R61911 reg |= MIIM_88E1111_HWCFG_MODE_SGMII_NO_CLK; 220fa12a08eSZang Roy-R61911 reg |= MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO; 221fa12a08eSZang Roy-R61911 222fa12a08eSZang Roy-R61911 phy_write(phydev, MDIO_DEVAD_NONE, 223fa12a08eSZang Roy-R61911 MIIM_88E1111_PHY_EXT_SR, reg); 224fa12a08eSZang Roy-R61911 } 225fa12a08eSZang Roy-R61911 226fa12a08eSZang Roy-R61911 if (phydev->interface == PHY_INTERFACE_MODE_RTBI) { 227fa12a08eSZang Roy-R61911 reg = phy_read(phydev, 228fa12a08eSZang Roy-R61911 MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR); 229fa12a08eSZang Roy-R61911 reg |= (MIIM_88E1111_RX_DELAY | MIIM_88E1111_TX_DELAY); 230fa12a08eSZang Roy-R61911 phy_write(phydev, 231fa12a08eSZang Roy-R61911 MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR, reg); 232fa12a08eSZang Roy-R61911 233fa12a08eSZang Roy-R61911 reg = phy_read(phydev, MDIO_DEVAD_NONE, 234fa12a08eSZang Roy-R61911 MIIM_88E1111_PHY_EXT_SR); 235fa12a08eSZang Roy-R61911 reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK | 236fa12a08eSZang Roy-R61911 MIIM_88E1111_HWCFG_FIBER_COPPER_RES); 237fa12a08eSZang Roy-R61911 reg |= 0x7 | MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO; 238fa12a08eSZang Roy-R61911 phy_write(phydev, MDIO_DEVAD_NONE, 239fa12a08eSZang Roy-R61911 MIIM_88E1111_PHY_EXT_SR, reg); 240fa12a08eSZang Roy-R61911 241fa12a08eSZang Roy-R61911 /* soft reset */ 2423089c47dSStefan Roese phy_reset(phydev); 243fa12a08eSZang Roy-R61911 244fa12a08eSZang Roy-R61911 reg = phy_read(phydev, MDIO_DEVAD_NONE, 245fa12a08eSZang Roy-R61911 MIIM_88E1111_PHY_EXT_SR); 246fa12a08eSZang Roy-R61911 reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK | 247fa12a08eSZang Roy-R61911 MIIM_88E1111_HWCFG_FIBER_COPPER_RES); 248fa12a08eSZang Roy-R61911 reg |= MIIM_88E1111_HWCFG_MODE_COPPER_RTBI | 249fa12a08eSZang Roy-R61911 MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO; 250fa12a08eSZang Roy-R61911 phy_write(phydev, MDIO_DEVAD_NONE, 251fa12a08eSZang Roy-R61911 MIIM_88E1111_PHY_EXT_SR, reg); 252fa12a08eSZang Roy-R61911 } 253fa12a08eSZang Roy-R61911 254fa12a08eSZang Roy-R61911 /* soft reset */ 2553089c47dSStefan Roese phy_reset(phydev); 2569082eeacSAndy Fleming 2579082eeacSAndy Fleming genphy_config_aneg(phydev); 258a8c3eca4SStefan Roese genphy_restart_aneg(phydev); 2599082eeacSAndy Fleming 2609082eeacSAndy Fleming return 0; 2619082eeacSAndy Fleming } 2629082eeacSAndy Fleming 26335fa0ddaSHao Zhang /** 26435fa0ddaSHao Zhang * m88e1518_phy_writebits - write bits to a register 26535fa0ddaSHao Zhang */ 26635fa0ddaSHao Zhang void m88e1518_phy_writebits(struct phy_device *phydev, 26735fa0ddaSHao Zhang u8 reg_num, u16 offset, u16 len, u16 data) 26835fa0ddaSHao Zhang { 26935fa0ddaSHao Zhang u16 reg, mask; 27035fa0ddaSHao Zhang 27135fa0ddaSHao Zhang if ((len + offset) >= 16) 27235fa0ddaSHao Zhang mask = 0 - (1 << offset); 27335fa0ddaSHao Zhang else 27435fa0ddaSHao Zhang mask = (1 << (len + offset)) - (1 << offset); 27535fa0ddaSHao Zhang 27635fa0ddaSHao Zhang reg = phy_read(phydev, MDIO_DEVAD_NONE, reg_num); 27735fa0ddaSHao Zhang 27835fa0ddaSHao Zhang reg &= ~mask; 27935fa0ddaSHao Zhang reg |= data << offset; 28035fa0ddaSHao Zhang 28135fa0ddaSHao Zhang phy_write(phydev, MDIO_DEVAD_NONE, reg_num, reg); 28235fa0ddaSHao Zhang } 28335fa0ddaSHao Zhang 28435fa0ddaSHao Zhang static int m88e1518_config(struct phy_device *phydev) 28535fa0ddaSHao Zhang { 28635fa0ddaSHao Zhang /* 28735fa0ddaSHao Zhang * As per Marvell Release Notes - Alaska 88E1510/88E1518/88E1512 28835fa0ddaSHao Zhang * /88E1514 Rev A0, Errata Section 3.1 28935fa0ddaSHao Zhang */ 29090a94ef6SClemens Gruber 29190a94ef6SClemens Gruber /* EEE initialization */ 29290a94ef6SClemens Gruber phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x00ff); 29335fa0ddaSHao Zhang phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x214B); 29435fa0ddaSHao Zhang phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2144); 29535fa0ddaSHao Zhang phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x0C28); 29635fa0ddaSHao Zhang phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2146); 29735fa0ddaSHao Zhang phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xB233); 29835fa0ddaSHao Zhang phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x214D); 29935fa0ddaSHao Zhang phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xCC0C); 30035fa0ddaSHao Zhang phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2159); 30190a94ef6SClemens Gruber phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x0000); 30290a94ef6SClemens Gruber 30390a94ef6SClemens Gruber /* SGMII-to-Copper mode initialization */ 30490a94ef6SClemens Gruber if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { 30590a94ef6SClemens Gruber /* Select page 18 */ 30690a94ef6SClemens Gruber phy_write(phydev, MDIO_DEVAD_NONE, 22, 18); 30790a94ef6SClemens Gruber 30890a94ef6SClemens Gruber /* In reg 20, write MODE[2:0] = 0x1 (SGMII to Copper) */ 30935fa0ddaSHao Zhang m88e1518_phy_writebits(phydev, 20, 0, 3, 1); 31035fa0ddaSHao Zhang 31190a94ef6SClemens Gruber /* PHY reset is necessary after changing MODE[2:0] */ 31235fa0ddaSHao Zhang m88e1518_phy_writebits(phydev, 20, 15, 1, 1); 31390a94ef6SClemens Gruber 31490a94ef6SClemens Gruber /* Reset page selection */ 31590a94ef6SClemens Gruber phy_write(phydev, MDIO_DEVAD_NONE, 22, 0); 31690a94ef6SClemens Gruber 31735fa0ddaSHao Zhang udelay(100); 31835fa0ddaSHao Zhang } 31935fa0ddaSHao Zhang 32035fa0ddaSHao Zhang return m88e1111s_config(phydev); 32135fa0ddaSHao Zhang } 32235fa0ddaSHao Zhang 3238396d0abSClemens Gruber /* Marvell 88E1510 */ 3248396d0abSClemens Gruber static int m88e1510_config(struct phy_device *phydev) 3258396d0abSClemens Gruber { 3268396d0abSClemens Gruber /* Select page 3 */ 3278396d0abSClemens Gruber phy_write(phydev, MDIO_DEVAD_NONE, 22, 3); 3288396d0abSClemens Gruber 3298396d0abSClemens Gruber /* Enable INTn output on LED[2] */ 3308396d0abSClemens Gruber m88e1518_phy_writebits(phydev, 18, 7, 1, 1); 3318396d0abSClemens Gruber 3328396d0abSClemens Gruber /* Configure LEDs */ 3338396d0abSClemens Gruber m88e1518_phy_writebits(phydev, 16, 0, 4, 3); /* LED[0]:0011 (ACT) */ 3348396d0abSClemens Gruber m88e1518_phy_writebits(phydev, 16, 4, 4, 6); /* LED[1]:0110 (LINK) */ 3358396d0abSClemens Gruber 3368396d0abSClemens Gruber /* Reset page selection */ 3378396d0abSClemens Gruber phy_write(phydev, MDIO_DEVAD_NONE, 22, 0); 3388396d0abSClemens Gruber 3398396d0abSClemens Gruber return m88e1518_config(phydev); 3408396d0abSClemens Gruber } 3418396d0abSClemens Gruber 3429082eeacSAndy Fleming /* Marvell 88E1118 */ 3439082eeacSAndy Fleming static int m88e1118_config(struct phy_device *phydev) 3449082eeacSAndy Fleming { 3459082eeacSAndy Fleming /* Change Page Number */ 3469082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0002); 3479082eeacSAndy Fleming /* Delay RGMII TX and RX */ 3489082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, 0x15, 0x1070); 3499082eeacSAndy Fleming /* Change Page Number */ 3509082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0003); 3519082eeacSAndy Fleming /* Adjust LED control */ 3529082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, 0x10, 0x021e); 3539082eeacSAndy Fleming /* Change Page Number */ 3549082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0000); 3559082eeacSAndy Fleming 3561b008fdbSMichal Simek return genphy_config_aneg(phydev); 3579082eeacSAndy Fleming } 3589082eeacSAndy Fleming 3599082eeacSAndy Fleming static int m88e1118_startup(struct phy_device *phydev) 3609082eeacSAndy Fleming { 361b733c278SMichal Simek int ret; 362b733c278SMichal Simek 3639082eeacSAndy Fleming /* Change Page Number */ 3649082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0000); 3659082eeacSAndy Fleming 366b733c278SMichal Simek ret = genphy_update_link(phydev); 367b733c278SMichal Simek if (ret) 368b733c278SMichal Simek return ret; 3699082eeacSAndy Fleming 370b733c278SMichal Simek return m88e1xxx_parse_status(phydev); 3719082eeacSAndy Fleming } 3729082eeacSAndy Fleming 3739082eeacSAndy Fleming /* Marvell 88E1121R */ 3749082eeacSAndy Fleming static int m88e1121_config(struct phy_device *phydev) 3759082eeacSAndy Fleming { 3769082eeacSAndy Fleming int pg; 3779082eeacSAndy Fleming 3789082eeacSAndy Fleming /* Configure the PHY */ 3799082eeacSAndy Fleming genphy_config_aneg(phydev); 3809082eeacSAndy Fleming 3819082eeacSAndy Fleming /* Switch the page to access the led register */ 3829082eeacSAndy Fleming pg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_PAGE); 3839082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_PAGE, 3849082eeacSAndy Fleming MIIM_88E1121_PHY_LED_PAGE); 3859082eeacSAndy Fleming /* Configure leds */ 3869082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_LED_CTRL, 3879082eeacSAndy Fleming MIIM_88E1121_PHY_LED_DEF); 3889082eeacSAndy Fleming /* Restore the page pointer */ 3899082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_PAGE, pg); 3909082eeacSAndy Fleming 3919082eeacSAndy Fleming /* Disable IRQs and de-assert interrupt */ 3929082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_IRQ_EN, 0); 3939082eeacSAndy Fleming phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_IRQ_STATUS); 3949082eeacSAndy Fleming 3959082eeacSAndy Fleming return 0; 3969082eeacSAndy Fleming } 3979082eeacSAndy Fleming 3989082eeacSAndy Fleming /* Marvell 88E1145 */ 3999082eeacSAndy Fleming static int m88e1145_config(struct phy_device *phydev) 4009082eeacSAndy Fleming { 4019082eeacSAndy Fleming int reg; 4029082eeacSAndy Fleming 4039082eeacSAndy Fleming /* Errata E0, E1 */ 4049082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_PAGE, 0x001b); 4059082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_CAL_OV, 0x418f); 4069082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_PAGE, 0x0016); 4079082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_CAL_OV, 0xa2da); 4089082eeacSAndy Fleming 4099082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1xxx_PHY_SCR, 4109082eeacSAndy Fleming MIIM_88E1xxx_PHY_MDI_X_AUTO); 4119082eeacSAndy Fleming 4129082eeacSAndy Fleming reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_EXT_CR); 4139082eeacSAndy Fleming if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) 4149082eeacSAndy Fleming reg |= MIIM_M88E1145_RGMII_RX_DELAY | 4159082eeacSAndy Fleming MIIM_M88E1145_RGMII_TX_DELAY; 4169082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_EXT_CR, reg); 4179082eeacSAndy Fleming 4189082eeacSAndy Fleming genphy_config_aneg(phydev); 4199082eeacSAndy Fleming 4209082eeacSAndy Fleming phy_reset(phydev); 4219082eeacSAndy Fleming 4229082eeacSAndy Fleming return 0; 4239082eeacSAndy Fleming } 4249082eeacSAndy Fleming 4259082eeacSAndy Fleming static int m88e1145_startup(struct phy_device *phydev) 4269082eeacSAndy Fleming { 427b733c278SMichal Simek int ret; 428b733c278SMichal Simek 429b733c278SMichal Simek ret = genphy_update_link(phydev); 430b733c278SMichal Simek if (ret) 431b733c278SMichal Simek return ret; 432b733c278SMichal Simek 4339082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_LED_CONTROL, 4349082eeacSAndy Fleming MIIM_88E1145_PHY_LED_DIRECT); 435b733c278SMichal Simek return m88e1xxx_parse_status(phydev); 4369082eeacSAndy Fleming } 4379082eeacSAndy Fleming 4389082eeacSAndy Fleming /* Marvell 88E1149S */ 4399082eeacSAndy Fleming static int m88e1149_config(struct phy_device *phydev) 4409082eeacSAndy Fleming { 4419082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1149_PHY_PAGE, 0x1f); 4429082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x200c); 4439082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1149_PHY_PAGE, 0x5); 4449082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x0); 4459082eeacSAndy Fleming phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); 4469082eeacSAndy Fleming 4479082eeacSAndy Fleming genphy_config_aneg(phydev); 4489082eeacSAndy Fleming 4499082eeacSAndy Fleming phy_reset(phydev); 4509082eeacSAndy Fleming 4519082eeacSAndy Fleming return 0; 4529082eeacSAndy Fleming } 4539082eeacSAndy Fleming 454aeceec0dSSebastian Hesselbarth /* Marvell 88E1310 */ 455aeceec0dSSebastian Hesselbarth static int m88e1310_config(struct phy_device *phydev) 456aeceec0dSSebastian Hesselbarth { 457aeceec0dSSebastian Hesselbarth u16 reg; 458aeceec0dSSebastian Hesselbarth 459aeceec0dSSebastian Hesselbarth /* LED link and activity */ 460aeceec0dSSebastian Hesselbarth phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_PAGE, 0x0003); 461aeceec0dSSebastian Hesselbarth reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_LED_CTRL); 462aeceec0dSSebastian Hesselbarth reg = (reg & ~0xf) | 0x1; 463aeceec0dSSebastian Hesselbarth phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_LED_CTRL, reg); 464aeceec0dSSebastian Hesselbarth 465aeceec0dSSebastian Hesselbarth /* Set LED2/INT to INT mode, low active */ 466aeceec0dSSebastian Hesselbarth phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_PAGE, 0x0003); 467aeceec0dSSebastian Hesselbarth reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_IRQ_EN); 468aeceec0dSSebastian Hesselbarth reg = (reg & 0x77ff) | 0x0880; 469aeceec0dSSebastian Hesselbarth phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_IRQ_EN, reg); 470aeceec0dSSebastian Hesselbarth 471aeceec0dSSebastian Hesselbarth /* Set RGMII delay */ 472aeceec0dSSebastian Hesselbarth phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_PAGE, 0x0002); 473aeceec0dSSebastian Hesselbarth reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_RGMII_CTRL); 474aeceec0dSSebastian Hesselbarth reg |= 0x0030; 475aeceec0dSSebastian Hesselbarth phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_RGMII_CTRL, reg); 476aeceec0dSSebastian Hesselbarth 477aeceec0dSSebastian Hesselbarth /* Ensure to return to page 0 */ 478aeceec0dSSebastian Hesselbarth phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1310_PHY_PAGE, 0x0000); 479aeceec0dSSebastian Hesselbarth 48008e64cecSNathan Rossi return genphy_config_aneg(phydev); 481aeceec0dSSebastian Hesselbarth } 4829082eeacSAndy Fleming 483*c52d428dSDirk Eibach static int m88e1680_config(struct phy_device *phydev) 484*c52d428dSDirk Eibach { 485*c52d428dSDirk Eibach /* 486*c52d428dSDirk Eibach * As per Marvell Release Notes - Alaska V 88E1680 Rev A2 487*c52d428dSDirk Eibach * Errata Section 4.1 488*c52d428dSDirk Eibach */ 489*c52d428dSDirk Eibach u16 reg; 490*c52d428dSDirk Eibach int res; 491*c52d428dSDirk Eibach 492*c52d428dSDirk Eibach /* Matrix LED mode (not neede if single LED mode is used */ 493*c52d428dSDirk Eibach phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0004); 494*c52d428dSDirk Eibach reg = phy_read(phydev, MDIO_DEVAD_NONE, 27); 495*c52d428dSDirk Eibach reg |= (1 << 5); 496*c52d428dSDirk Eibach phy_write(phydev, MDIO_DEVAD_NONE, 27, reg); 497*c52d428dSDirk Eibach 498*c52d428dSDirk Eibach /* QSGMII TX amplitude change */ 499*c52d428dSDirk Eibach phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x00fd); 500*c52d428dSDirk Eibach phy_write(phydev, MDIO_DEVAD_NONE, 8, 0x0b53); 501*c52d428dSDirk Eibach phy_write(phydev, MDIO_DEVAD_NONE, 7, 0x200d); 502*c52d428dSDirk Eibach phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0000); 503*c52d428dSDirk Eibach 504*c52d428dSDirk Eibach /* EEE initialization */ 505*c52d428dSDirk Eibach phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x00ff); 506*c52d428dSDirk Eibach phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xb030); 507*c52d428dSDirk Eibach phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x215c); 508*c52d428dSDirk Eibach phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x00fc); 509*c52d428dSDirk Eibach phy_write(phydev, MDIO_DEVAD_NONE, 24, 0x888c); 510*c52d428dSDirk Eibach phy_write(phydev, MDIO_DEVAD_NONE, 25, 0x888c); 511*c52d428dSDirk Eibach phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0000); 512*c52d428dSDirk Eibach phy_write(phydev, MDIO_DEVAD_NONE, 0, 0x9140); 513*c52d428dSDirk Eibach 514*c52d428dSDirk Eibach res = genphy_config_aneg(phydev); 515*c52d428dSDirk Eibach if (res < 0) 516*c52d428dSDirk Eibach return res; 517*c52d428dSDirk Eibach 518*c52d428dSDirk Eibach /* soft reset */ 519*c52d428dSDirk Eibach reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); 520*c52d428dSDirk Eibach reg |= BMCR_RESET; 521*c52d428dSDirk Eibach phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, reg); 522*c52d428dSDirk Eibach 523*c52d428dSDirk Eibach return 0; 524*c52d428dSDirk Eibach } 525*c52d428dSDirk Eibach 5269082eeacSAndy Fleming static struct phy_driver M88E1011S_driver = { 5279082eeacSAndy Fleming .name = "Marvell 88E1011S", 5289082eeacSAndy Fleming .uid = 0x1410c60, 5299082eeacSAndy Fleming .mask = 0xffffff0, 5309082eeacSAndy Fleming .features = PHY_GBIT_FEATURES, 5319082eeacSAndy Fleming .config = &m88e1011s_config, 5329082eeacSAndy Fleming .startup = &m88e1011s_startup, 5339082eeacSAndy Fleming .shutdown = &genphy_shutdown, 5349082eeacSAndy Fleming }; 5359082eeacSAndy Fleming 5369082eeacSAndy Fleming static struct phy_driver M88E1111S_driver = { 5379082eeacSAndy Fleming .name = "Marvell 88E1111S", 5389082eeacSAndy Fleming .uid = 0x1410cc0, 5399082eeacSAndy Fleming .mask = 0xffffff0, 5409082eeacSAndy Fleming .features = PHY_GBIT_FEATURES, 5419082eeacSAndy Fleming .config = &m88e1111s_config, 5429082eeacSAndy Fleming .startup = &m88e1011s_startup, 5439082eeacSAndy Fleming .shutdown = &genphy_shutdown, 5449082eeacSAndy Fleming }; 5459082eeacSAndy Fleming 5469082eeacSAndy Fleming static struct phy_driver M88E1118_driver = { 5479082eeacSAndy Fleming .name = "Marvell 88E1118", 5489082eeacSAndy Fleming .uid = 0x1410e10, 5499082eeacSAndy Fleming .mask = 0xffffff0, 5509082eeacSAndy Fleming .features = PHY_GBIT_FEATURES, 5519082eeacSAndy Fleming .config = &m88e1118_config, 5529082eeacSAndy Fleming .startup = &m88e1118_startup, 5539082eeacSAndy Fleming .shutdown = &genphy_shutdown, 5549082eeacSAndy Fleming }; 5559082eeacSAndy Fleming 556b4b81e83SMichal Simek static struct phy_driver M88E1118R_driver = { 557b4b81e83SMichal Simek .name = "Marvell 88E1118R", 558b4b81e83SMichal Simek .uid = 0x1410e40, 559b4b81e83SMichal Simek .mask = 0xffffff0, 560b4b81e83SMichal Simek .features = PHY_GBIT_FEATURES, 561b4b81e83SMichal Simek .config = &m88e1118_config, 562b4b81e83SMichal Simek .startup = &m88e1118_startup, 563b4b81e83SMichal Simek .shutdown = &genphy_shutdown, 564b4b81e83SMichal Simek }; 565b4b81e83SMichal Simek 5669082eeacSAndy Fleming static struct phy_driver M88E1121R_driver = { 5679082eeacSAndy Fleming .name = "Marvell 88E1121R", 5689082eeacSAndy Fleming .uid = 0x1410cb0, 5699082eeacSAndy Fleming .mask = 0xffffff0, 5709082eeacSAndy Fleming .features = PHY_GBIT_FEATURES, 5719082eeacSAndy Fleming .config = &m88e1121_config, 5729082eeacSAndy Fleming .startup = &genphy_startup, 5739082eeacSAndy Fleming .shutdown = &genphy_shutdown, 5749082eeacSAndy Fleming }; 5759082eeacSAndy Fleming 5769082eeacSAndy Fleming static struct phy_driver M88E1145_driver = { 5779082eeacSAndy Fleming .name = "Marvell 88E1145", 5789082eeacSAndy Fleming .uid = 0x1410cd0, 5799082eeacSAndy Fleming .mask = 0xffffff0, 5809082eeacSAndy Fleming .features = PHY_GBIT_FEATURES, 5819082eeacSAndy Fleming .config = &m88e1145_config, 5829082eeacSAndy Fleming .startup = &m88e1145_startup, 5839082eeacSAndy Fleming .shutdown = &genphy_shutdown, 5849082eeacSAndy Fleming }; 5859082eeacSAndy Fleming 5869082eeacSAndy Fleming static struct phy_driver M88E1149S_driver = { 5879082eeacSAndy Fleming .name = "Marvell 88E1149S", 5889082eeacSAndy Fleming .uid = 0x1410ca0, 5899082eeacSAndy Fleming .mask = 0xffffff0, 5909082eeacSAndy Fleming .features = PHY_GBIT_FEATURES, 5919082eeacSAndy Fleming .config = &m88e1149_config, 5929082eeacSAndy Fleming .startup = &m88e1011s_startup, 5939082eeacSAndy Fleming .shutdown = &genphy_shutdown, 5949082eeacSAndy Fleming }; 5959082eeacSAndy Fleming 5968396d0abSClemens Gruber static struct phy_driver M88E1510_driver = { 5978396d0abSClemens Gruber .name = "Marvell 88E1510", 5988396d0abSClemens Gruber .uid = 0x1410dd0, 5998396d0abSClemens Gruber .mask = 0xffffff0, 6008396d0abSClemens Gruber .features = PHY_GBIT_FEATURES, 6018396d0abSClemens Gruber .config = &m88e1510_config, 6028396d0abSClemens Gruber .startup = &m88e1011s_startup, 6038396d0abSClemens Gruber .shutdown = &genphy_shutdown, 6048396d0abSClemens Gruber }; 6058396d0abSClemens Gruber 6061415107eSMichal Simek static struct phy_driver M88E1518_driver = { 6071415107eSMichal Simek .name = "Marvell 88E1518", 6081415107eSMichal Simek .uid = 0x1410dd1, 6091415107eSMichal Simek .mask = 0xffffff0, 6101415107eSMichal Simek .features = PHY_GBIT_FEATURES, 61135fa0ddaSHao Zhang .config = &m88e1518_config, 6121415107eSMichal Simek .startup = &m88e1011s_startup, 6131415107eSMichal Simek .shutdown = &genphy_shutdown, 6141415107eSMichal Simek }; 6151415107eSMichal Simek 616aeceec0dSSebastian Hesselbarth static struct phy_driver M88E1310_driver = { 617aeceec0dSSebastian Hesselbarth .name = "Marvell 88E1310", 618aeceec0dSSebastian Hesselbarth .uid = 0x01410e90, 619aeceec0dSSebastian Hesselbarth .mask = 0xffffff0, 620aeceec0dSSebastian Hesselbarth .features = PHY_GBIT_FEATURES, 621aeceec0dSSebastian Hesselbarth .config = &m88e1310_config, 622aeceec0dSSebastian Hesselbarth .startup = &m88e1011s_startup, 623aeceec0dSSebastian Hesselbarth .shutdown = &genphy_shutdown, 624aeceec0dSSebastian Hesselbarth }; 625aeceec0dSSebastian Hesselbarth 626*c52d428dSDirk Eibach static struct phy_driver M88E1680_driver = { 627*c52d428dSDirk Eibach .name = "Marvell 88E1680", 628*c52d428dSDirk Eibach .uid = 0x1410ed0, 629*c52d428dSDirk Eibach .mask = 0xffffff0, 630*c52d428dSDirk Eibach .features = PHY_GBIT_FEATURES, 631*c52d428dSDirk Eibach .config = &m88e1680_config, 632*c52d428dSDirk Eibach .startup = &genphy_startup, 633*c52d428dSDirk Eibach .shutdown = &genphy_shutdown, 634*c52d428dSDirk Eibach }; 635*c52d428dSDirk Eibach 6369082eeacSAndy Fleming int phy_marvell_init(void) 6379082eeacSAndy Fleming { 638aeceec0dSSebastian Hesselbarth phy_register(&M88E1310_driver); 6399082eeacSAndy Fleming phy_register(&M88E1149S_driver); 6409082eeacSAndy Fleming phy_register(&M88E1145_driver); 6419082eeacSAndy Fleming phy_register(&M88E1121R_driver); 6429082eeacSAndy Fleming phy_register(&M88E1118_driver); 643b4b81e83SMichal Simek phy_register(&M88E1118R_driver); 6449082eeacSAndy Fleming phy_register(&M88E1111S_driver); 6459082eeacSAndy Fleming phy_register(&M88E1011S_driver); 6468396d0abSClemens Gruber phy_register(&M88E1510_driver); 6471415107eSMichal Simek phy_register(&M88E1518_driver); 648*c52d428dSDirk Eibach phy_register(&M88E1680_driver); 6499082eeacSAndy Fleming 6509082eeacSAndy Fleming return 0; 6519082eeacSAndy Fleming } 652