aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/phy')
-rw-r--r--drivers/net/phy/phy.c81
-rw-r--r--drivers/net/phy/phy_device.c1
2 files changed, 40 insertions, 42 deletions
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 95f0419ba21e..88237bdb5255 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -713,60 +713,57 @@ static void phy_timer(unsigned long data)
713 713
714 break; 714 break;
715 case PHY_AN: 715 case PHY_AN:
716 err = phy_read_status(phydev);
717
718 if (err < 0)
719 break;
720
721 /* If the link is down, give up on
722 * negotiation for now */
723 if (!phydev->link) {
724 phydev->state = PHY_NOLINK;
725 netif_carrier_off(phydev->attached_dev);
726 phydev->adjust_link(phydev->attached_dev);
727 break;
728 }
729
716 /* Check if negotiation is done. Break 730 /* Check if negotiation is done. Break
717 * if there's an error */ 731 * if there's an error */
718 err = phy_aneg_done(phydev); 732 err = phy_aneg_done(phydev);
719 if (err < 0) 733 if (err < 0)
720 break; 734 break;
721 735
722 /* If auto-negotiation is done, we change to 736 /* If AN is done, we're running */
723 * either RUNNING, or NOLINK */
724 if (err > 0) { 737 if (err > 0) {
725 err = phy_read_status(phydev); 738 phydev->state = PHY_RUNNING;
739 netif_carrier_on(phydev->attached_dev);
740 phydev->adjust_link(phydev->attached_dev);
741
742 } else if (0 == phydev->link_timeout--) {
743 int idx;
726 744
727 if (err) 745 needs_aneg = 1;
746 /* If we have the magic_aneg bit,
747 * we try again */
748 if (phydev->drv->flags & PHY_HAS_MAGICANEG)
728 break; 749 break;
729 750
730 if (phydev->link) { 751 /* The timer expired, and we still
731 phydev->state = PHY_RUNNING; 752 * don't have a setting, so we try
732 netif_carrier_on(phydev->attached_dev); 753 * forcing it until we find one that
733 } else { 754 * works, starting from the fastest speed,
734 phydev->state = PHY_NOLINK; 755 * and working our way down */
735 netif_carrier_off(phydev->attached_dev); 756 idx = phy_find_valid(0, phydev->supported);
736 }
737 757
738 phydev->adjust_link(phydev->attached_dev); 758 phydev->speed = settings[idx].speed;
759 phydev->duplex = settings[idx].duplex;
739 760
740 } else if (0 == phydev->link_timeout--) { 761 phydev->autoneg = AUTONEG_DISABLE;
741 /* The counter expired, so either we
742 * switch to forced mode, or the
743 * magic_aneg bit exists, and we try aneg
744 * again */
745 if (!(phydev->drv->flags & PHY_HAS_MAGICANEG)) {
746 int idx;
747
748 /* We'll start from the
749 * fastest speed, and work
750 * our way down */
751 idx = phy_find_valid(0,
752 phydev->supported);
753
754 phydev->speed = settings[idx].speed;
755 phydev->duplex = settings[idx].duplex;
756
757 phydev->autoneg = AUTONEG_DISABLE;
758 phydev->state = PHY_FORCING;
759 phydev->link_timeout =
760 PHY_FORCE_TIMEOUT;
761
762 pr_info("Trying %d/%s\n",
763 phydev->speed,
764 DUPLEX_FULL ==
765 phydev->duplex ?
766 "FULL" : "HALF");
767 }
768 762
769 needs_aneg = 1; 763 pr_info("Trying %d/%s\n", phydev->speed,
764 DUPLEX_FULL ==
765 phydev->duplex ?
766 "FULL" : "HALF");
770 } 767 }
771 break; 768 break;
772 case PHY_NOLINK: 769 case PHY_NOLINK:
@@ -782,7 +779,7 @@ static void phy_timer(unsigned long data)
782 } 779 }
783 break; 780 break;
784 case PHY_FORCING: 781 case PHY_FORCING:
785 err = phy_read_status(phydev); 782 err = genphy_update_link(phydev);
786 783
787 if (err) 784 if (err)
788 break; 785 break;
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 3bbd5e70c209..2a08b2b62c4c 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -427,6 +427,7 @@ int genphy_update_link(struct phy_device *phydev)
427 427
428 return 0; 428 return 0;
429} 429}
430EXPORT_SYMBOL(genphy_update_link);
430 431
431/* genphy_read_status 432/* genphy_read_status
432 * 433 *