diff options
Diffstat (limited to 'drivers/net/phy')
-rw-r--r-- | drivers/net/phy/dp83640.c | 32 | ||||
-rw-r--r-- | drivers/net/phy/mdio-sun4i.c | 3 | ||||
-rw-r--r-- | drivers/net/phy/phy.c | 11 | ||||
-rw-r--r-- | drivers/net/phy/phy_device.c | 57 |
4 files changed, 64 insertions, 39 deletions
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index 547725fa8671..98e7cbf720a5 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c | |||
@@ -437,7 +437,10 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp, | |||
437 | if (on) { | 437 | if (on) { |
438 | gpio_num = gpio_tab[EXTTS0_GPIO + index]; | 438 | gpio_num = gpio_tab[EXTTS0_GPIO + index]; |
439 | evnt |= (gpio_num & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT; | 439 | evnt |= (gpio_num & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT; |
440 | evnt |= EVNT_RISE; | 440 | if (rq->extts.flags & PTP_FALLING_EDGE) |
441 | evnt |= EVNT_FALL; | ||
442 | else | ||
443 | evnt |= EVNT_RISE; | ||
441 | } | 444 | } |
442 | ext_write(0, phydev, PAGE5, PTP_EVNT, evnt); | 445 | ext_write(0, phydev, PAGE5, PTP_EVNT, evnt); |
443 | return 0; | 446 | return 0; |
@@ -1003,11 +1006,6 @@ static int dp83640_probe(struct phy_device *phydev) | |||
1003 | } else | 1006 | } else |
1004 | list_add_tail(&dp83640->list, &clock->phylist); | 1007 | list_add_tail(&dp83640->list, &clock->phylist); |
1005 | 1008 | ||
1006 | if (clock->chosen && !list_empty(&clock->phylist)) | ||
1007 | recalibrate(clock); | ||
1008 | else | ||
1009 | enable_broadcast(dp83640->phydev, clock->page, 1); | ||
1010 | |||
1011 | dp83640_clock_put(clock); | 1009 | dp83640_clock_put(clock); |
1012 | return 0; | 1010 | return 0; |
1013 | 1011 | ||
@@ -1058,6 +1056,21 @@ static void dp83640_remove(struct phy_device *phydev) | |||
1058 | kfree(dp83640); | 1056 | kfree(dp83640); |
1059 | } | 1057 | } |
1060 | 1058 | ||
1059 | static int dp83640_config_init(struct phy_device *phydev) | ||
1060 | { | ||
1061 | struct dp83640_private *dp83640 = phydev->priv; | ||
1062 | struct dp83640_clock *clock = dp83640->clock; | ||
1063 | |||
1064 | if (clock->chosen && !list_empty(&clock->phylist)) | ||
1065 | recalibrate(clock); | ||
1066 | else | ||
1067 | enable_broadcast(phydev, clock->page, 1); | ||
1068 | |||
1069 | enable_status_frames(phydev, true); | ||
1070 | ext_write(0, phydev, PAGE4, PTP_CTL, PTP_ENABLE); | ||
1071 | return 0; | ||
1072 | } | ||
1073 | |||
1061 | static int dp83640_ack_interrupt(struct phy_device *phydev) | 1074 | static int dp83640_ack_interrupt(struct phy_device *phydev) |
1062 | { | 1075 | { |
1063 | int err = phy_read(phydev, MII_DP83640_MISR); | 1076 | int err = phy_read(phydev, MII_DP83640_MISR); |
@@ -1195,11 +1208,6 @@ static int dp83640_hwtstamp(struct phy_device *phydev, struct ifreq *ifr) | |||
1195 | 1208 | ||
1196 | mutex_lock(&dp83640->clock->extreg_lock); | 1209 | mutex_lock(&dp83640->clock->extreg_lock); |
1197 | 1210 | ||
1198 | if (dp83640->hwts_tx_en || dp83640->hwts_rx_en) { | ||
1199 | enable_status_frames(phydev, true); | ||
1200 | ext_write(0, phydev, PAGE4, PTP_CTL, PTP_ENABLE); | ||
1201 | } | ||
1202 | |||
1203 | ext_write(0, phydev, PAGE5, PTP_TXCFG0, txcfg0); | 1211 | ext_write(0, phydev, PAGE5, PTP_TXCFG0, txcfg0); |
1204 | ext_write(0, phydev, PAGE5, PTP_RXCFG0, rxcfg0); | 1212 | ext_write(0, phydev, PAGE5, PTP_RXCFG0, rxcfg0); |
1205 | 1213 | ||
@@ -1281,6 +1289,7 @@ static void dp83640_txtstamp(struct phy_device *phydev, | |||
1281 | } | 1289 | } |
1282 | /* fall through */ | 1290 | /* fall through */ |
1283 | case HWTSTAMP_TX_ON: | 1291 | case HWTSTAMP_TX_ON: |
1292 | skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; | ||
1284 | skb_queue_tail(&dp83640->tx_queue, skb); | 1293 | skb_queue_tail(&dp83640->tx_queue, skb); |
1285 | schedule_work(&dp83640->ts_work); | 1294 | schedule_work(&dp83640->ts_work); |
1286 | break; | 1295 | break; |
@@ -1330,6 +1339,7 @@ static struct phy_driver dp83640_driver = { | |||
1330 | .flags = PHY_HAS_INTERRUPT, | 1339 | .flags = PHY_HAS_INTERRUPT, |
1331 | .probe = dp83640_probe, | 1340 | .probe = dp83640_probe, |
1332 | .remove = dp83640_remove, | 1341 | .remove = dp83640_remove, |
1342 | .config_init = dp83640_config_init, | ||
1333 | .config_aneg = genphy_config_aneg, | 1343 | .config_aneg = genphy_config_aneg, |
1334 | .read_status = genphy_read_status, | 1344 | .read_status = genphy_read_status, |
1335 | .ack_interrupt = dp83640_ack_interrupt, | 1345 | .ack_interrupt = dp83640_ack_interrupt, |
diff --git a/drivers/net/phy/mdio-sun4i.c b/drivers/net/phy/mdio-sun4i.c index bb88bc7d81fb..9367acc84fbb 100644 --- a/drivers/net/phy/mdio-sun4i.c +++ b/drivers/net/phy/mdio-sun4i.c | |||
@@ -170,6 +170,9 @@ static int sun4i_mdio_remove(struct platform_device *pdev) | |||
170 | } | 170 | } |
171 | 171 | ||
172 | static const struct of_device_id sun4i_mdio_dt_ids[] = { | 172 | static const struct of_device_id sun4i_mdio_dt_ids[] = { |
173 | { .compatible = "allwinner,sun4i-a10-mdio" }, | ||
174 | |||
175 | /* Deprecated */ | ||
173 | { .compatible = "allwinner,sun4i-mdio" }, | 176 | { .compatible = "allwinner,sun4i-mdio" }, |
174 | { } | 177 | { } |
175 | }; | 178 | }; |
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 19c9eca0ef26..76d96b9ebcdb 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c | |||
@@ -164,9 +164,9 @@ static const struct phy_setting settings[] = { | |||
164 | * of that setting. Returns the index of the last setting if | 164 | * of that setting. Returns the index of the last setting if |
165 | * none of the others match. | 165 | * none of the others match. |
166 | */ | 166 | */ |
167 | static inline int phy_find_setting(int speed, int duplex) | 167 | static inline unsigned int phy_find_setting(int speed, int duplex) |
168 | { | 168 | { |
169 | int idx = 0; | 169 | unsigned int idx = 0; |
170 | 170 | ||
171 | while (idx < ARRAY_SIZE(settings) && | 171 | while (idx < ARRAY_SIZE(settings) && |
172 | (settings[idx].speed != speed || settings[idx].duplex != duplex)) | 172 | (settings[idx].speed != speed || settings[idx].duplex != duplex)) |
@@ -185,7 +185,7 @@ static inline int phy_find_setting(int speed, int duplex) | |||
185 | * the mask in features. Returns the index of the last setting | 185 | * the mask in features. Returns the index of the last setting |
186 | * if nothing else matches. | 186 | * if nothing else matches. |
187 | */ | 187 | */ |
188 | static inline int phy_find_valid(int idx, u32 features) | 188 | static inline unsigned int phy_find_valid(unsigned int idx, u32 features) |
189 | { | 189 | { |
190 | while (idx < MAX_NUM_SETTINGS && !(settings[idx].setting & features)) | 190 | while (idx < MAX_NUM_SETTINGS && !(settings[idx].setting & features)) |
191 | idx++; | 191 | idx++; |
@@ -204,7 +204,7 @@ static inline int phy_find_valid(int idx, u32 features) | |||
204 | static void phy_sanitize_settings(struct phy_device *phydev) | 204 | static void phy_sanitize_settings(struct phy_device *phydev) |
205 | { | 205 | { |
206 | u32 features = phydev->supported; | 206 | u32 features = phydev->supported; |
207 | int idx; | 207 | unsigned int idx; |
208 | 208 | ||
209 | /* Sanitize settings based on PHY capabilities */ | 209 | /* Sanitize settings based on PHY capabilities */ |
210 | if ((features & SUPPORTED_Autoneg) == 0) | 210 | if ((features & SUPPORTED_Autoneg) == 0) |
@@ -954,7 +954,8 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable) | |||
954 | (phydev->interface == PHY_INTERFACE_MODE_RGMII))) { | 954 | (phydev->interface == PHY_INTERFACE_MODE_RGMII))) { |
955 | int eee_lp, eee_cap, eee_adv; | 955 | int eee_lp, eee_cap, eee_adv; |
956 | u32 lp, cap, adv; | 956 | u32 lp, cap, adv; |
957 | int idx, status; | 957 | int status; |
958 | unsigned int idx; | ||
958 | 959 | ||
959 | /* Read phy status to properly get the right settings */ | 960 | /* Read phy status to properly get the right settings */ |
960 | status = phy_read_status(phydev); | 961 | status = phy_read_status(phydev); |
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 4b03e63639b7..2f6989b1e0dc 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
@@ -683,10 +683,9 @@ EXPORT_SYMBOL(phy_detach); | |||
683 | int phy_suspend(struct phy_device *phydev) | 683 | int phy_suspend(struct phy_device *phydev) |
684 | { | 684 | { |
685 | struct phy_driver *phydrv = to_phy_driver(phydev->dev.driver); | 685 | struct phy_driver *phydrv = to_phy_driver(phydev->dev.driver); |
686 | struct ethtool_wolinfo wol; | 686 | struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL }; |
687 | 687 | ||
688 | /* If the device has WOL enabled, we cannot suspend the PHY */ | 688 | /* If the device has WOL enabled, we cannot suspend the PHY */ |
689 | wol.cmd = ETHTOOL_GWOL; | ||
690 | phy_ethtool_get_wol(phydev, &wol); | 689 | phy_ethtool_get_wol(phydev, &wol); |
691 | if (wol.wolopts) | 690 | if (wol.wolopts) |
692 | return -EBUSY; | 691 | return -EBUSY; |
@@ -719,7 +718,7 @@ int phy_resume(struct phy_device *phydev) | |||
719 | static int genphy_config_advert(struct phy_device *phydev) | 718 | static int genphy_config_advert(struct phy_device *phydev) |
720 | { | 719 | { |
721 | u32 advertise; | 720 | u32 advertise; |
722 | int oldadv, adv; | 721 | int oldadv, adv, bmsr; |
723 | int err, changed = 0; | 722 | int err, changed = 0; |
724 | 723 | ||
725 | /* Only allow advertising what this PHY supports */ | 724 | /* Only allow advertising what this PHY supports */ |
@@ -744,26 +743,36 @@ static int genphy_config_advert(struct phy_device *phydev) | |||
744 | changed = 1; | 743 | changed = 1; |
745 | } | 744 | } |
746 | 745 | ||
746 | bmsr = phy_read(phydev, MII_BMSR); | ||
747 | if (bmsr < 0) | ||
748 | return bmsr; | ||
749 | |||
750 | /* Per 802.3-2008, Section 22.2.4.2.16 Extended status all | ||
751 | * 1000Mbits/sec capable PHYs shall have the BMSR_ESTATEN bit set to a | ||
752 | * logical 1. | ||
753 | */ | ||
754 | if (!(bmsr & BMSR_ESTATEN)) | ||
755 | return changed; | ||
756 | |||
747 | /* Configure gigabit if it's supported */ | 757 | /* Configure gigabit if it's supported */ |
758 | adv = phy_read(phydev, MII_CTRL1000); | ||
759 | if (adv < 0) | ||
760 | return adv; | ||
761 | |||
762 | oldadv = adv; | ||
763 | adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); | ||
764 | |||
748 | if (phydev->supported & (SUPPORTED_1000baseT_Half | | 765 | if (phydev->supported & (SUPPORTED_1000baseT_Half | |
749 | SUPPORTED_1000baseT_Full)) { | 766 | 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); | 767 | adv |= ethtool_adv_to_mii_ctrl1000_t(advertise); |
757 | 768 | 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; | 769 | changed = 1; |
764 | } | ||
765 | } | 770 | } |
766 | 771 | ||
772 | err = phy_write(phydev, MII_CTRL1000, adv); | ||
773 | if (err < 0) | ||
774 | return err; | ||
775 | |||
767 | return changed; | 776 | return changed; |
768 | } | 777 | } |
769 | 778 | ||
@@ -906,6 +915,8 @@ int genphy_read_status(struct phy_device *phydev) | |||
906 | int err; | 915 | int err; |
907 | int lpa; | 916 | int lpa; |
908 | int lpagb = 0; | 917 | int lpagb = 0; |
918 | int common_adv; | ||
919 | int common_adv_gb = 0; | ||
909 | 920 | ||
910 | /* Update the link, but return if there was an error */ | 921 | /* Update the link, but return if there was an error */ |
911 | err = genphy_update_link(phydev); | 922 | err = genphy_update_link(phydev); |
@@ -927,7 +938,7 @@ int genphy_read_status(struct phy_device *phydev) | |||
927 | 938 | ||
928 | phydev->lp_advertising = | 939 | phydev->lp_advertising = |
929 | mii_stat1000_to_ethtool_lpa_t(lpagb); | 940 | mii_stat1000_to_ethtool_lpa_t(lpagb); |
930 | lpagb &= adv << 2; | 941 | common_adv_gb = lpagb & adv << 2; |
931 | } | 942 | } |
932 | 943 | ||
933 | lpa = phy_read(phydev, MII_LPA); | 944 | lpa = phy_read(phydev, MII_LPA); |
@@ -940,25 +951,25 @@ int genphy_read_status(struct phy_device *phydev) | |||
940 | if (adv < 0) | 951 | if (adv < 0) |
941 | return adv; | 952 | return adv; |
942 | 953 | ||
943 | lpa &= adv; | 954 | common_adv = lpa & adv; |
944 | 955 | ||
945 | phydev->speed = SPEED_10; | 956 | phydev->speed = SPEED_10; |
946 | phydev->duplex = DUPLEX_HALF; | 957 | phydev->duplex = DUPLEX_HALF; |
947 | phydev->pause = 0; | 958 | phydev->pause = 0; |
948 | phydev->asym_pause = 0; | 959 | phydev->asym_pause = 0; |
949 | 960 | ||
950 | if (lpagb & (LPA_1000FULL | LPA_1000HALF)) { | 961 | if (common_adv_gb & (LPA_1000FULL | LPA_1000HALF)) { |
951 | phydev->speed = SPEED_1000; | 962 | phydev->speed = SPEED_1000; |
952 | 963 | ||
953 | if (lpagb & LPA_1000FULL) | 964 | if (common_adv_gb & LPA_1000FULL) |
954 | phydev->duplex = DUPLEX_FULL; | 965 | phydev->duplex = DUPLEX_FULL; |
955 | } else if (lpa & (LPA_100FULL | LPA_100HALF)) { | 966 | } else if (common_adv & (LPA_100FULL | LPA_100HALF)) { |
956 | phydev->speed = SPEED_100; | 967 | phydev->speed = SPEED_100; |
957 | 968 | ||
958 | if (lpa & LPA_100FULL) | 969 | if (common_adv & LPA_100FULL) |
959 | phydev->duplex = DUPLEX_FULL; | 970 | phydev->duplex = DUPLEX_FULL; |
960 | } else | 971 | } else |
961 | if (lpa & LPA_10FULL) | 972 | if (common_adv & LPA_10FULL) |
962 | phydev->duplex = DUPLEX_FULL; | 973 | phydev->duplex = DUPLEX_FULL; |
963 | 974 | ||
964 | if (phydev->duplex == DUPLEX_FULL) { | 975 | if (phydev->duplex == DUPLEX_FULL) { |