diff options
Diffstat (limited to 'drivers/net/phy/phy.c')
-rw-r--r-- | drivers/net/phy/phy.c | 34 |
1 files changed, 19 insertions, 15 deletions
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 52cd8db2c57d..47cd578052fc 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c | |||
@@ -742,6 +742,9 @@ EXPORT_SYMBOL(phy_stop); | |||
742 | */ | 742 | */ |
743 | void phy_start(struct phy_device *phydev) | 743 | void phy_start(struct phy_device *phydev) |
744 | { | 744 | { |
745 | bool do_resume = false; | ||
746 | int err = 0; | ||
747 | |||
745 | mutex_lock(&phydev->lock); | 748 | mutex_lock(&phydev->lock); |
746 | 749 | ||
747 | switch (phydev->state) { | 750 | switch (phydev->state) { |
@@ -752,11 +755,22 @@ void phy_start(struct phy_device *phydev) | |||
752 | phydev->state = PHY_UP; | 755 | phydev->state = PHY_UP; |
753 | break; | 756 | break; |
754 | case PHY_HALTED: | 757 | case PHY_HALTED: |
758 | /* make sure interrupts are re-enabled for the PHY */ | ||
759 | err = phy_enable_interrupts(phydev); | ||
760 | if (err < 0) | ||
761 | break; | ||
762 | |||
755 | phydev->state = PHY_RESUMING; | 763 | phydev->state = PHY_RESUMING; |
764 | do_resume = true; | ||
765 | break; | ||
756 | default: | 766 | default: |
757 | break; | 767 | break; |
758 | } | 768 | } |
759 | mutex_unlock(&phydev->lock); | 769 | mutex_unlock(&phydev->lock); |
770 | |||
771 | /* if phy was suspended, bring the physical link up again */ | ||
772 | if (do_resume) | ||
773 | phy_resume(phydev); | ||
760 | } | 774 | } |
761 | EXPORT_SYMBOL(phy_start); | 775 | EXPORT_SYMBOL(phy_start); |
762 | 776 | ||
@@ -769,7 +783,7 @@ void phy_state_machine(struct work_struct *work) | |||
769 | struct delayed_work *dwork = to_delayed_work(work); | 783 | struct delayed_work *dwork = to_delayed_work(work); |
770 | struct phy_device *phydev = | 784 | struct phy_device *phydev = |
771 | container_of(dwork, struct phy_device, state_queue); | 785 | container_of(dwork, struct phy_device, state_queue); |
772 | bool needs_aneg = false, do_suspend = false, do_resume = false; | 786 | bool needs_aneg = false, do_suspend = false; |
773 | int err = 0; | 787 | int err = 0; |
774 | 788 | ||
775 | mutex_lock(&phydev->lock); | 789 | mutex_lock(&phydev->lock); |
@@ -888,14 +902,6 @@ void phy_state_machine(struct work_struct *work) | |||
888 | } | 902 | } |
889 | break; | 903 | break; |
890 | case PHY_RESUMING: | 904 | case PHY_RESUMING: |
891 | err = phy_clear_interrupt(phydev); | ||
892 | if (err) | ||
893 | break; | ||
894 | |||
895 | err = phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED); | ||
896 | if (err) | ||
897 | break; | ||
898 | |||
899 | if (AUTONEG_ENABLE == phydev->autoneg) { | 905 | if (AUTONEG_ENABLE == phydev->autoneg) { |
900 | err = phy_aneg_done(phydev); | 906 | err = phy_aneg_done(phydev); |
901 | if (err < 0) | 907 | if (err < 0) |
@@ -933,7 +939,6 @@ void phy_state_machine(struct work_struct *work) | |||
933 | } | 939 | } |
934 | phydev->adjust_link(phydev->attached_dev); | 940 | phydev->adjust_link(phydev->attached_dev); |
935 | } | 941 | } |
936 | do_resume = true; | ||
937 | break; | 942 | break; |
938 | } | 943 | } |
939 | 944 | ||
@@ -943,8 +948,6 @@ void phy_state_machine(struct work_struct *work) | |||
943 | err = phy_start_aneg(phydev); | 948 | err = phy_start_aneg(phydev); |
944 | else if (do_suspend) | 949 | else if (do_suspend) |
945 | phy_suspend(phydev); | 950 | phy_suspend(phydev); |
946 | else if (do_resume) | ||
947 | phy_resume(phydev); | ||
948 | 951 | ||
949 | if (err < 0) | 952 | if (err < 0) |
950 | phy_error(phydev); | 953 | phy_error(phydev); |
@@ -1053,13 +1056,14 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable) | |||
1053 | { | 1056 | { |
1054 | /* According to 802.3az,the EEE is supported only in full duplex-mode. | 1057 | /* According to 802.3az,the EEE is supported only in full duplex-mode. |
1055 | * Also EEE feature is active when core is operating with MII, GMII | 1058 | * Also EEE feature is active when core is operating with MII, GMII |
1056 | * or RGMII. Internal PHYs are also allowed to proceed and should | 1059 | * or RGMII (all kinds). Internal PHYs are also allowed to proceed and |
1057 | * return an error if they do not support EEE. | 1060 | * should return an error if they do not support EEE. |
1058 | */ | 1061 | */ |
1059 | if ((phydev->duplex == DUPLEX_FULL) && | 1062 | if ((phydev->duplex == DUPLEX_FULL) && |
1060 | ((phydev->interface == PHY_INTERFACE_MODE_MII) || | 1063 | ((phydev->interface == PHY_INTERFACE_MODE_MII) || |
1061 | (phydev->interface == PHY_INTERFACE_MODE_GMII) || | 1064 | (phydev->interface == PHY_INTERFACE_MODE_GMII) || |
1062 | (phydev->interface == PHY_INTERFACE_MODE_RGMII) || | 1065 | (phydev->interface >= PHY_INTERFACE_MODE_RGMII && |
1066 | phydev->interface <= PHY_INTERFACE_MODE_RGMII_TXID) || | ||
1063 | phy_is_internal(phydev))) { | 1067 | phy_is_internal(phydev))) { |
1064 | int eee_lp, eee_cap, eee_adv; | 1068 | int eee_lp, eee_cap, eee_adv; |
1065 | u32 lp, cap, adv; | 1069 | u32 lp, cap, adv; |