aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/phy/phy_device.c49
1 files changed, 30 insertions, 19 deletions
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 16a0e7de5888..171627480058 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -419,13 +419,14 @@ EXPORT_SYMBOL(phy_detach);
419 * 419 *
420 * Description: Writes MII_ADVERTISE with the appropriate values, 420 * Description: Writes MII_ADVERTISE with the appropriate values,
421 * after sanitizing the values to make sure we only advertise 421 * after sanitizing the values to make sure we only advertise
422 * what is supported. 422 * what is supported. Returns < 0 on error, 0 if the PHY's advertisement
423 * hasn't changed, and > 0 if it has changed.
423 */ 424 */
424int genphy_config_advert(struct phy_device *phydev) 425int genphy_config_advert(struct phy_device *phydev)
425{ 426{
426 u32 advertise; 427 u32 advertise;
427 int adv; 428 int oldadv, adv;
428 int err; 429 int err, changed = 0;
429 430
430 /* Only allow advertising what 431 /* Only allow advertising what
431 * this PHY supports */ 432 * this PHY supports */
@@ -433,7 +434,7 @@ int genphy_config_advert(struct phy_device *phydev)
433 advertise = phydev->advertising; 434 advertise = phydev->advertising;
434 435
435 /* Setup standard advertisement */ 436 /* Setup standard advertisement */
436 adv = phy_read(phydev, MII_ADVERTISE); 437 oldadv = adv = phy_read(phydev, MII_ADVERTISE);
437 438
438 if (adv < 0) 439 if (adv < 0)
439 return adv; 440 return adv;
@@ -453,15 +454,18 @@ int genphy_config_advert(struct phy_device *phydev)
453 if (advertise & ADVERTISED_Asym_Pause) 454 if (advertise & ADVERTISED_Asym_Pause)
454 adv |= ADVERTISE_PAUSE_ASYM; 455 adv |= ADVERTISE_PAUSE_ASYM;
455 456
456 err = phy_write(phydev, MII_ADVERTISE, adv); 457 if (adv != oldadv) {
458 err = phy_write(phydev, MII_ADVERTISE, adv);
457 459
458 if (err < 0) 460 if (err < 0)
459 return err; 461 return err;
462 changed = 1;
463 }
460 464
461 /* Configure gigabit if it's supported */ 465 /* Configure gigabit if it's supported */
462 if (phydev->supported & (SUPPORTED_1000baseT_Half | 466 if (phydev->supported & (SUPPORTED_1000baseT_Half |
463 SUPPORTED_1000baseT_Full)) { 467 SUPPORTED_1000baseT_Full)) {
464 adv = phy_read(phydev, MII_CTRL1000); 468 oldadv = adv = phy_read(phydev, MII_CTRL1000);
465 469
466 if (adv < 0) 470 if (adv < 0)
467 return adv; 471 return adv;
@@ -471,13 +475,17 @@ int genphy_config_advert(struct phy_device *phydev)
471 adv |= ADVERTISE_1000HALF; 475 adv |= ADVERTISE_1000HALF;
472 if (advertise & SUPPORTED_1000baseT_Full) 476 if (advertise & SUPPORTED_1000baseT_Full)
473 adv |= ADVERTISE_1000FULL; 477 adv |= ADVERTISE_1000FULL;
474 err = phy_write(phydev, MII_CTRL1000, adv);
475 478
476 if (err < 0) 479 if (adv != oldadv) {
477 return err; 480 err = phy_write(phydev, MII_CTRL1000, adv);
481
482 if (err < 0)
483 return err;
484 changed = 1;
485 }
478 } 486 }
479 487
480 return adv; 488 return changed;
481} 489}
482EXPORT_SYMBOL(genphy_config_advert); 490EXPORT_SYMBOL(genphy_config_advert);
483 491
@@ -561,19 +569,22 @@ int genphy_restart_aneg(struct phy_device *phydev)
561 */ 569 */
562int genphy_config_aneg(struct phy_device *phydev) 570int genphy_config_aneg(struct phy_device *phydev)
563{ 571{
564 int err = 0; 572 int result = 0;
565 573
566 if (AUTONEG_ENABLE == phydev->autoneg) { 574 if (AUTONEG_ENABLE == phydev->autoneg) {
567 err = genphy_config_advert(phydev); 575 int result = genphy_config_advert(phydev);
568 576
569 if (err < 0) 577 if (result < 0) /* error */
570 return err; 578 return result;
571 579
572 err = genphy_restart_aneg(phydev); 580 /* Only restart aneg if we are advertising something different
581 * than we were before. */
582 if (result > 0)
583 result = genphy_restart_aneg(phydev);
573 } else 584 } else
574 err = genphy_setup_forced(phydev); 585 result = genphy_setup_forced(phydev);
575 586
576 return err; 587 return result;
577} 588}
578EXPORT_SYMBOL(genphy_config_aneg); 589EXPORT_SYMBOL(genphy_config_aneg);
579 590