@@ -43,6 +43,22 @@ static int smsc_phy_ack_interrupt(struct phy_device *phydev)
static int smsc_phy_config_init(struct phy_device *phydev)
{
+ int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS);
+
+ if (rc < 0)
+ return rc;
+
+ /* Enable energy detect mode for this SMSC Transceivers */
+ rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS,
+ rc | MII_LAN83C185_EDPWRDOWN);
+ if (rc < 0)
+ return rc;
+
+ return smsc_phy_ack_interrupt(phydev);
+}
+
+static int smsc_phy_reset(struct phy_device *phydev)
+{
int rc = phy_read(phydev, MII_LAN83C185_SPECIAL_MODES);
if (rc < 0)
return rc;
@@ -66,18 +82,7 @@ static int smsc_phy_config_init(struct phy_device *phydev)
rc = phy_read(phydev, MII_BMCR);
} while (rc & BMCR_RESET);
}
-
- rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS);
- if (rc < 0)
- return rc;
-
- /* Enable energy detect mode for this SMSC Transceivers */
- rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS,
- rc | MII_LAN83C185_EDPWRDOWN);
- if (rc < 0)
- return rc;
-
- return smsc_phy_ack_interrupt (phydev);
+ return 0;
}
static int lan911x_config_init(struct phy_device *phydev)
@@ -142,6 +147,7 @@ static struct phy_driver smsc_phy_driver[] = {
.config_aneg = genphy_config_aneg,
.read_status = genphy_read_status,
.config_init = smsc_phy_config_init,
+ .soft_reset = smsc_phy_reset,
/* IRQ related */
.ack_interrupt = smsc_phy_ack_interrupt,
@@ -164,6 +170,7 @@ static struct phy_driver smsc_phy_driver[] = {
.config_aneg = genphy_config_aneg,
.read_status = genphy_read_status,
.config_init = smsc_phy_config_init,
+ .soft_reset = smsc_phy_reset,
/* IRQ related */
.ack_interrupt = smsc_phy_ack_interrupt,
@@ -186,6 +193,7 @@ static struct phy_driver smsc_phy_driver[] = {
.config_aneg = genphy_config_aneg,
.read_status = genphy_read_status,
.config_init = smsc_phy_config_init,
+ .soft_reset = smsc_phy_reset,
/* IRQ related */
.ack_interrupt = smsc_phy_ack_interrupt,
@@ -230,6 +238,7 @@ static struct phy_driver smsc_phy_driver[] = {
.config_aneg = genphy_config_aneg,
.read_status = lan87xx_read_status,
.config_init = smsc_phy_config_init,
+ .soft_reset = smsc_phy_reset,
/* IRQ related */
.ack_interrupt = smsc_phy_ack_interrupt,
On the one hand, phy_device.c provides a generic reset function if the phy driver does not provide a soft_reset pointer. This generic reset does not take into account the state of the phy, with a potential failure if the phy is in powerdown mode. On the other hand, smsc driver provides a function with both correct reset behaviour and configuration. This patch moves the reset part into a new smsc_phy_reset function and provides the soft_reset pointer to have a correct reset behaviour by default. Signed-off-by: Gwenhael Goavec-Merou <gwenhael.goavec-merou@armadeus.com> --- drivers/net/phy/smsc.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-)