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.c54
1 files changed, 33 insertions, 21 deletions
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 4b03e63639b7..4b970f7624c0 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -719,7 +719,7 @@ int phy_resume(struct phy_device *phydev)
719static int genphy_config_advert(struct phy_device *phydev) 719static int genphy_config_advert(struct phy_device *phydev)
720{ 720{
721 u32 advertise; 721 u32 advertise;
722 int oldadv, adv; 722 int oldadv, adv, bmsr;
723 int err, changed = 0; 723 int err, changed = 0;
724 724
725 /* Only allow advertising what this PHY supports */ 725 /* Only allow advertising what this PHY supports */
@@ -744,26 +744,36 @@ static int genphy_config_advert(struct phy_device *phydev)
744 changed = 1; 744 changed = 1;
745 } 745 }
746 746
747 bmsr = phy_read(phydev, MII_BMSR);
748 if (bmsr < 0)
749 return bmsr;
750
751 /* Per 802.3-2008, Section 22.2.4.2.16 Extended status all
752 * 1000Mbits/sec capable PHYs shall have the BMSR_ESTATEN bit set to a
753 * logical 1.
754 */
755 if (!(bmsr & BMSR_ESTATEN))
756 return changed;
757
747 /* Configure gigabit if it's supported */ 758 /* Configure gigabit if it's supported */
759 adv = phy_read(phydev, MII_CTRL1000);
760 if (adv < 0)
761 return adv;
762
763 oldadv = adv;
764 adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
765
748 if (phydev->supported & (SUPPORTED_1000baseT_Half | 766 if (phydev->supported & (SUPPORTED_1000baseT_Half |
749 SUPPORTED_1000baseT_Full)) { 767 SUPPORTED_1000baseT_Full)) {
750 adv = phy_read(phydev, MII_CTRL1000);
751 if (adv < 0)
752 return adv;
753
754 oldadv = adv;
755 adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
756 adv |= ethtool_adv_to_mii_ctrl1000_t(advertise); 768 adv |= ethtool_adv_to_mii_ctrl1000_t(advertise);
757 769 if (adv != oldadv)
758 if (adv != oldadv) {
759 err = phy_write(phydev, MII_CTRL1000, adv);
760
761 if (err < 0)
762 return err;
763 changed = 1; 770 changed = 1;
764 }
765 } 771 }
766 772
773 err = phy_write(phydev, MII_CTRL1000, adv);
774 if (err < 0)
775 return err;
776
767 return changed; 777 return changed;
768} 778}
769 779
@@ -906,6 +916,8 @@ int genphy_read_status(struct phy_device *phydev)
906 int err; 916 int err;
907 int lpa; 917 int lpa;
908 int lpagb = 0; 918 int lpagb = 0;
919 int common_adv;
920 int common_adv_gb = 0;
909 921
910 /* Update the link, but return if there was an error */ 922 /* Update the link, but return if there was an error */
911 err = genphy_update_link(phydev); 923 err = genphy_update_link(phydev);
@@ -927,7 +939,7 @@ int genphy_read_status(struct phy_device *phydev)
927 939
928 phydev->lp_advertising = 940 phydev->lp_advertising =
929 mii_stat1000_to_ethtool_lpa_t(lpagb); 941 mii_stat1000_to_ethtool_lpa_t(lpagb);
930 lpagb &= adv << 2; 942 common_adv_gb = lpagb & adv << 2;
931 } 943 }
932 944
933 lpa = phy_read(phydev, MII_LPA); 945 lpa = phy_read(phydev, MII_LPA);
@@ -940,25 +952,25 @@ int genphy_read_status(struct phy_device *phydev)
940 if (adv < 0) 952 if (adv < 0)
941 return adv; 953 return adv;
942 954
943 lpa &= adv; 955 common_adv = lpa & adv;
944 956
945 phydev->speed = SPEED_10; 957 phydev->speed = SPEED_10;
946 phydev->duplex = DUPLEX_HALF; 958 phydev->duplex = DUPLEX_HALF;
947 phydev->pause = 0; 959 phydev->pause = 0;
948 phydev->asym_pause = 0; 960 phydev->asym_pause = 0;
949 961
950 if (lpagb & (LPA_1000FULL | LPA_1000HALF)) { 962 if (common_adv_gb & (LPA_1000FULL | LPA_1000HALF)) {
951 phydev->speed = SPEED_1000; 963 phydev->speed = SPEED_1000;
952 964
953 if (lpagb & LPA_1000FULL) 965 if (common_adv_gb & LPA_1000FULL)
954 phydev->duplex = DUPLEX_FULL; 966 phydev->duplex = DUPLEX_FULL;
955 } else if (lpa & (LPA_100FULL | LPA_100HALF)) { 967 } else if (common_adv & (LPA_100FULL | LPA_100HALF)) {
956 phydev->speed = SPEED_100; 968 phydev->speed = SPEED_100;
957 969
958 if (lpa & LPA_100FULL) 970 if (common_adv & LPA_100FULL)
959 phydev->duplex = DUPLEX_FULL; 971 phydev->duplex = DUPLEX_FULL;
960 } else 972 } else
961 if (lpa & LPA_10FULL) 973 if (common_adv & LPA_10FULL)
962 phydev->duplex = DUPLEX_FULL; 974 phydev->duplex = DUPLEX_FULL;
963 975
964 if (phydev->duplex == DUPLEX_FULL) { 976 if (phydev->duplex == DUPLEX_FULL) {