Commit cd998ecd authored by Pavel Fedin's avatar Pavel Fedin Committed by David S. Miller

net: smsc911x: Reset PHY during initialization

On certain hardware after software reboot the chip may get stuck and fail
to reinitialize during reset. This can be fixed by ensuring that PHY is
reset too.

Old PHY resetting method required operational MDIO interface, therefore
the chip should have been already set up. In order to be able to function
during probe, it is changed to use PMT_CTRL register.

The problem could be observed on SMDK5410 board.
Signed-off-by: default avatarPavel Fedin <p.fedin@samsung.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c3d4c682
...@@ -809,22 +809,17 @@ static int smsc911x_phy_check_loopbackpkt(struct smsc911x_data *pdata) ...@@ -809,22 +809,17 @@ static int smsc911x_phy_check_loopbackpkt(struct smsc911x_data *pdata)
static int smsc911x_phy_reset(struct smsc911x_data *pdata) static int smsc911x_phy_reset(struct smsc911x_data *pdata)
{ {
struct phy_device *phy_dev = pdata->phy_dev;
unsigned int temp; unsigned int temp;
unsigned int i = 100000; unsigned int i = 100000;
BUG_ON(!phy_dev); temp = smsc911x_reg_read(pdata, PMT_CTRL);
BUG_ON(!phy_dev->bus); smsc911x_reg_write(pdata, PMT_CTRL, temp | PMT_CTRL_PHY_RST_);
SMSC_TRACE(pdata, hw, "Performing PHY BCR Reset");
smsc911x_mii_write(phy_dev->bus, phy_dev->addr, MII_BMCR, BMCR_RESET);
do { do {
msleep(1); msleep(1);
temp = smsc911x_mii_read(phy_dev->bus, phy_dev->addr, temp = smsc911x_reg_read(pdata, PMT_CTRL);
MII_BMCR); } while ((i--) && (temp & PMT_CTRL_PHY_RST_));
} while ((i--) && (temp & BMCR_RESET));
if (temp & BMCR_RESET) { if (unlikely(temp & PMT_CTRL_PHY_RST_)) {
SMSC_WARN(pdata, hw, "PHY reset failed to complete"); SMSC_WARN(pdata, hw, "PHY reset failed to complete");
return -EIO; return -EIO;
} }
...@@ -2296,7 +2291,7 @@ static int smsc911x_init(struct net_device *dev) ...@@ -2296,7 +2291,7 @@ static int smsc911x_init(struct net_device *dev)
} }
/* Reset the LAN911x */ /* Reset the LAN911x */
if (smsc911x_soft_reset(pdata)) if (smsc911x_phy_reset(pdata) || smsc911x_soft_reset(pdata))
return -ENODEV; return -ENODEV;
dev->flags |= IFF_MULTICAST; dev->flags |= IFF_MULTICAST;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment