aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy/phy_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/phy/phy_device.c')
-rw-r--r--drivers/net/phy/phy_device.c57
1 files changed, 52 insertions, 5 deletions
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 2f6989b1e0dc..0ce606624296 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -139,6 +139,7 @@ static int phy_scan_fixups(struct phy_device *phydev)
139 mutex_unlock(&phy_fixup_lock); 139 mutex_unlock(&phy_fixup_lock);
140 return err; 140 return err;
141 } 141 }
142 phydev->has_fixups = true;
142 } 143 }
143 } 144 }
144 mutex_unlock(&phy_fixup_lock); 145 mutex_unlock(&phy_fixup_lock);
@@ -534,16 +535,16 @@ static int phy_poll_reset(struct phy_device *phydev)
534 535
535int phy_init_hw(struct phy_device *phydev) 536int phy_init_hw(struct phy_device *phydev)
536{ 537{
537 int ret; 538 int ret = 0;
538 539
539 if (!phydev->drv || !phydev->drv->config_init) 540 if (!phydev->drv || !phydev->drv->config_init)
540 return 0; 541 return 0;
541 542
542 ret = phy_write(phydev, MII_BMCR, BMCR_RESET); 543 if (phydev->drv->soft_reset)
543 if (ret < 0) 544 ret = phydev->drv->soft_reset(phydev);
544 return ret; 545 else
546 ret = genphy_soft_reset(phydev);
545 547
546 ret = phy_poll_reset(phydev);
547 if (ret < 0) 548 if (ret < 0)
548 return ret; 549 return ret;
549 550
@@ -864,6 +865,22 @@ int genphy_config_aneg(struct phy_device *phydev)
864} 865}
865EXPORT_SYMBOL(genphy_config_aneg); 866EXPORT_SYMBOL(genphy_config_aneg);
866 867
868/**
869 * genphy_aneg_done - return auto-negotiation status
870 * @phydev: target phy_device struct
871 *
872 * Description: Reads the status register and returns 0 either if
873 * auto-negotiation is incomplete, or if there was an error.
874 * Returns BMSR_ANEGCOMPLETE if auto-negotiation is done.
875 */
876int genphy_aneg_done(struct phy_device *phydev)
877{
878 int retval = phy_read(phydev, MII_BMSR);
879
880 return (retval < 0) ? retval : (retval & BMSR_ANEGCOMPLETE);
881}
882EXPORT_SYMBOL(genphy_aneg_done);
883
867static int gen10g_config_aneg(struct phy_device *phydev) 884static int gen10g_config_aneg(struct phy_device *phydev)
868{ 885{
869 return 0; 886 return 0;
@@ -1029,6 +1046,27 @@ static int gen10g_read_status(struct phy_device *phydev)
1029 return 0; 1046 return 0;
1030} 1047}
1031 1048
1049/**
1050 * genphy_soft_reset - software reset the PHY via BMCR_RESET bit
1051 * @phydev: target phy_device struct
1052 *
1053 * Description: Perform a software PHY reset using the standard
1054 * BMCR_RESET bit and poll for the reset bit to be cleared.
1055 *
1056 * Returns: 0 on success, < 0 on failure
1057 */
1058int genphy_soft_reset(struct phy_device *phydev)
1059{
1060 int ret;
1061
1062 ret = phy_write(phydev, MII_BMCR, BMCR_RESET);
1063 if (ret < 0)
1064 return ret;
1065
1066 return phy_poll_reset(phydev);
1067}
1068EXPORT_SYMBOL(genphy_soft_reset);
1069
1032static int genphy_config_init(struct phy_device *phydev) 1070static int genphy_config_init(struct phy_device *phydev)
1033{ 1071{
1034 int val; 1072 int val;
@@ -1075,6 +1113,12 @@ static int genphy_config_init(struct phy_device *phydev)
1075 return 0; 1113 return 0;
1076} 1114}
1077 1115
1116static int gen10g_soft_reset(struct phy_device *phydev)
1117{
1118 /* Do nothing for now */
1119 return 0;
1120}
1121
1078static int gen10g_config_init(struct phy_device *phydev) 1122static int gen10g_config_init(struct phy_device *phydev)
1079{ 1123{
1080 /* Temporarily just say we support everything */ 1124 /* Temporarily just say we support everything */
@@ -1249,9 +1293,11 @@ static struct phy_driver genphy_driver[] = {
1249 .phy_id = 0xffffffff, 1293 .phy_id = 0xffffffff,
1250 .phy_id_mask = 0xffffffff, 1294 .phy_id_mask = 0xffffffff,
1251 .name = "Generic PHY", 1295 .name = "Generic PHY",
1296 .soft_reset = genphy_soft_reset,
1252 .config_init = genphy_config_init, 1297 .config_init = genphy_config_init,
1253 .features = 0, 1298 .features = 0,
1254 .config_aneg = genphy_config_aneg, 1299 .config_aneg = genphy_config_aneg,
1300 .aneg_done = genphy_aneg_done,
1255 .read_status = genphy_read_status, 1301 .read_status = genphy_read_status,
1256 .suspend = genphy_suspend, 1302 .suspend = genphy_suspend,
1257 .resume = genphy_resume, 1303 .resume = genphy_resume,
@@ -1260,6 +1306,7 @@ static struct phy_driver genphy_driver[] = {
1260 .phy_id = 0xffffffff, 1306 .phy_id = 0xffffffff,
1261 .phy_id_mask = 0xffffffff, 1307 .phy_id_mask = 0xffffffff,
1262 .name = "Generic 10G PHY", 1308 .name = "Generic 10G PHY",
1309 .soft_reset = gen10g_soft_reset,
1263 .config_init = gen10g_config_init, 1310 .config_init = gen10g_config_init,
1264 .features = 0, 1311 .features = 0,
1265 .config_aneg = gen10g_config_aneg, 1312 .config_aneg = gen10g_config_aneg,