aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy/phy_device.c
diff options
context:
space:
mode:
authorFlorian Fainelli <f.fainelli@gmail.com>2014-02-17 16:34:03 -0500
committerDavid S. Miller <davem@davemloft.net>2014-02-17 16:40:09 -0500
commit9df81dd7583d14862d0cfb673a941b261f3b2112 (patch)
treea790b50329b80f6a6b29f745fd2baad8b4d1944f /drivers/net/phy/phy_device.c
parent797ac07137d9ae8572008e21e6123a9ae17dae50 (diff)
net: phy: allow PHY drivers to implement their own software reset
As pointed out by Shaohui, most 10G PHYs out there have a non-standard compliant software reset sequence, eventually something much more complex than just toggling the BMCR_RESET bit. Allow PHY driver to implement their own soft_reset() callback to deal with that. If no callback is provided, call into genphy_soft_reset() which makes sure the existing behavior is kept intact. Reported-by: Shaohui Xie <Shaohui.Xie@freescale.com> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/phy/phy_device.c')
-rw-r--r--drivers/net/phy/phy_device.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 7c21b8214bb9..a70b604ac644 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -535,12 +535,16 @@ static int phy_poll_reset(struct phy_device *phydev)
535 535
536int phy_init_hw(struct phy_device *phydev) 536int phy_init_hw(struct phy_device *phydev)
537{ 537{
538 int ret; 538 int ret = 0;
539 539
540 if (!phydev->drv || !phydev->drv->config_init) 540 if (!phydev->drv || !phydev->drv->config_init)
541 return 0; 541 return 0;
542 542
543 ret = genphy_soft_reset(phydev); 543 if (phydev->drv->soft_reset)
544 ret = phydev->drv->soft_reset(phydev);
545 else
546 ret = genphy_soft_reset(phydev);
547
544 if (ret < 0) 548 if (ret < 0)
545 return ret; 549 return ret;
546 550
@@ -1108,6 +1112,12 @@ static int genphy_config_init(struct phy_device *phydev)
1108 return 0; 1112 return 0;
1109} 1113}
1110 1114
1115static int gen10g_soft_reset(struct phy_device *phydev)
1116{
1117 /* Do nothing for now */
1118 return 0;
1119}
1120
1111static int gen10g_config_init(struct phy_device *phydev) 1121static int gen10g_config_init(struct phy_device *phydev)
1112{ 1122{
1113 /* Temporarily just say we support everything */ 1123 /* Temporarily just say we support everything */
@@ -1282,6 +1292,7 @@ static struct phy_driver genphy_driver[] = {
1282 .phy_id = 0xffffffff, 1292 .phy_id = 0xffffffff,
1283 .phy_id_mask = 0xffffffff, 1293 .phy_id_mask = 0xffffffff,
1284 .name = "Generic PHY", 1294 .name = "Generic PHY",
1295 .soft_reset = genphy_soft_reset,
1285 .config_init = genphy_config_init, 1296 .config_init = genphy_config_init,
1286 .features = 0, 1297 .features = 0,
1287 .config_aneg = genphy_config_aneg, 1298 .config_aneg = genphy_config_aneg,
@@ -1294,6 +1305,7 @@ static struct phy_driver genphy_driver[] = {
1294 .phy_id = 0xffffffff, 1305 .phy_id = 0xffffffff,
1295 .phy_id_mask = 0xffffffff, 1306 .phy_id_mask = 0xffffffff,
1296 .name = "Generic 10G PHY", 1307 .name = "Generic 10G PHY",
1308 .soft_reset = gen10g_soft_reset,
1297 .config_init = gen10g_config_init, 1309 .config_init = gen10g_config_init,
1298 .features = 0, 1310 .features = 0,
1299 .config_aneg = gen10g_config_aneg, 1311 .config_aneg = gen10g_config_aneg,