Skip to content

Commit

Permalink
net: phy: micrel: fix KSZ9477 PHY issues after suspend/resume
Browse files Browse the repository at this point in the history
When the PHY is powered up after powered down most of the registers are
reset, so the PHY setup code needs to be done again.  In addition the
interrupt register will need to be setup again so that link status
indication works again.

Fixes: 26dd297 ("net: phy: micrel: Move KSZ9477 errata fixes to PHY driver")
Signed-off-by: Tristram Ha <tristram.ha@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
triha2work authored and davem330 committed Jun 3, 2024
1 parent 33700a0 commit 6149db4
Showing 1 changed file with 56 additions and 6 deletions.
62 changes: 56 additions & 6 deletions drivers/net/phy/micrel.c
Original file line number Diff line number Diff line change
Expand Up @@ -1939,7 +1939,7 @@ static const struct ksz9477_errata_write ksz9477_errata_writes[] = {
{0x1c, 0x20, 0xeeee},
};

static int ksz9477_config_init(struct phy_device *phydev)
static int ksz9477_phy_errata(struct phy_device *phydev)
{
int err;
int i;
Expand Down Expand Up @@ -1967,16 +1967,30 @@ static int ksz9477_config_init(struct phy_device *phydev)
return err;
}

err = genphy_restart_aneg(phydev);
if (err)
return err;

return err;
}

static int ksz9477_config_init(struct phy_device *phydev)
{
int err;

/* Only KSZ9897 family of switches needs this fix. */
if ((phydev->phy_id & 0xf) == 1) {
err = ksz9477_phy_errata(phydev);
if (err)
return err;
}

/* According to KSZ9477 Errata DS80000754C (Module 4) all EEE modes
* in this switch shall be regarded as broken.
*/
if (phydev->dev_flags & MICREL_NO_EEE)
phydev->eee_broken_modes = -1;

err = genphy_restart_aneg(phydev);
if (err)
return err;

return kszphy_config_init(phydev);
}

Expand Down Expand Up @@ -2085,6 +2099,42 @@ static int kszphy_resume(struct phy_device *phydev)
return 0;
}

static int ksz9477_resume(struct phy_device *phydev)
{
int ret;

/* No need to initialize registers if not powered down. */
ret = phy_read(phydev, MII_BMCR);
if (ret < 0)
return ret;
if (!(ret & BMCR_PDOWN))
return 0;

genphy_resume(phydev);

/* After switching from power-down to normal mode, an internal global
* reset is automatically generated. Wait a minimum of 1 ms before
* read/write access to the PHY registers.
*/
usleep_range(1000, 2000);

/* Only KSZ9897 family of switches needs this fix. */
if ((phydev->phy_id & 0xf) == 1) {
ret = ksz9477_phy_errata(phydev);
if (ret)
return ret;
}

/* Enable PHY Interrupts */
if (phy_interrupt_is_valid(phydev)) {
phydev->interrupts = PHY_INTERRUPT_ENABLED;
if (phydev->drv->config_intr)
phydev->drv->config_intr(phydev);
}

return 0;
}

static int kszphy_probe(struct phy_device *phydev)
{
const struct kszphy_type *type = phydev->drv->driver_data;
Expand Down Expand Up @@ -5493,7 +5543,7 @@ static struct phy_driver ksphy_driver[] = {
.config_intr = kszphy_config_intr,
.handle_interrupt = kszphy_handle_interrupt,
.suspend = genphy_suspend,
.resume = genphy_resume,
.resume = ksz9477_resume,
.get_features = ksz9477_get_features,
} };

Expand Down

0 comments on commit 6149db4

Please sign in to comment.