Commit def7279fa51043802cb94e8eb9ccf91a87ef25a9

Authored by Eric Lee
1 parent 6c1a649f77

Fix LAN8720 Link Problem When Ethernet Cable is not Plugged at Boot Up

Showing 1 changed file with 45 additions and 1 deletions Side-by-side Diff

drivers/net/phy/smsc.c
... ... @@ -80,6 +80,49 @@
80 80 return smsc_phy_ack_interrupt(phydev);
81 81 }
82 82  
  83 +/*
  84 + * The LAN8710/LAN8720 requires a minimum of 2 link pulses within 64ms of each
  85 + * other in order to set the ENERGYON bit and exit EDPD mode. If a link partner
  86 + * does send the pulses within this interval, the PHY will remained powered
  87 + * down.
  88 + *
  89 + * This workaround will manually toggle the PHY on/off upon calls to read_status
  90 + * in order to generate link test pulses if the link is down. If a link partner
  91 + * is present, it will respond to the pulses, which will cause the ENERGYON bit
  92 + * to be set and will cause the EDPD mode to be exited.
  93 + */
  94 +static int lan87xx_read_status(struct phy_device *phydev)
  95 +{
  96 + int err = genphy_read_status(phydev);
  97 +
  98 + if (!phydev->link) {
  99 + /* Disable EDPD to wake up PHY */
  100 + int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS);
  101 + if (rc < 0)
  102 + return rc;
  103 +
  104 + rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS,
  105 + rc & ~MII_LAN83C185_EDPWRDOWN);
  106 + if (rc < 0)
  107 + return rc;
  108 +
  109 + /* Sleep 64 ms to allow ~5 link test pulses to be sent */
  110 + msleep(64);
  111 +
  112 + /* Re-enable EDPD */
  113 + rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS);
  114 + if (rc < 0)
  115 + return rc;
  116 +
  117 + rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS,
  118 + rc | MII_LAN83C185_EDPWRDOWN);
  119 + if (rc < 0)
  120 + return rc;
  121 + }
  122 +
  123 + return err;
  124 +}
  125 +
83 126 static struct phy_driver lan83c185_driver = {
84 127 .phy_id = 0x0007c0a0, /* OUI=0x00800f, Model#=0x0a */
85 128 .phy_id_mask = 0xfffffff0,
... ... @@ -187,7 +230,8 @@
187 230  
188 231 /* basic functions */
189 232 .config_aneg = genphy_config_aneg,
190   - .read_status = genphy_read_status,
  233 + /*.read_status = genphy_read_status,*/
  234 + .read_status = lan87xx_read_status,
191 235 .config_init = smsc_phy_config_init,
192 236  
193 237 /* IRQ related */