diff options
Diffstat (limited to 'drivers/net/phy/phy_device.c')
| -rw-r--r-- | drivers/net/phy/phy_device.c | 442 |
1 files changed, 363 insertions, 79 deletions
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 9e4ba8e80a18..26c41ede54a4 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
| 30 | #include <linux/mii.h> | 30 | #include <linux/mii.h> |
| 31 | #include <linux/ethtool.h> | 31 | #include <linux/ethtool.h> |
| 32 | #include <linux/bitmap.h> | ||
| 32 | #include <linux/phy.h> | 33 | #include <linux/phy.h> |
| 33 | #include <linux/phy_led_triggers.h> | 34 | #include <linux/phy_led_triggers.h> |
| 34 | #include <linux/mdio.h> | 35 | #include <linux/mdio.h> |
| @@ -42,6 +43,149 @@ MODULE_DESCRIPTION("PHY library"); | |||
| 42 | MODULE_AUTHOR("Andy Fleming"); | 43 | MODULE_AUTHOR("Andy Fleming"); |
| 43 | MODULE_LICENSE("GPL"); | 44 | MODULE_LICENSE("GPL"); |
| 44 | 45 | ||
| 46 | __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_basic_features) __ro_after_init; | ||
| 47 | EXPORT_SYMBOL_GPL(phy_basic_features); | ||
| 48 | |||
| 49 | __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_basic_t1_features) __ro_after_init; | ||
| 50 | EXPORT_SYMBOL_GPL(phy_basic_t1_features); | ||
| 51 | |||
| 52 | __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_features) __ro_after_init; | ||
| 53 | EXPORT_SYMBOL_GPL(phy_gbit_features); | ||
| 54 | |||
| 55 | __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_fibre_features) __ro_after_init; | ||
| 56 | EXPORT_SYMBOL_GPL(phy_gbit_fibre_features); | ||
| 57 | |||
| 58 | __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_all_ports_features) __ro_after_init; | ||
| 59 | EXPORT_SYMBOL_GPL(phy_gbit_all_ports_features); | ||
| 60 | |||
| 61 | __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_features) __ro_after_init; | ||
| 62 | EXPORT_SYMBOL_GPL(phy_10gbit_features); | ||
| 63 | |||
| 64 | static const int phy_basic_ports_array[] = { | ||
| 65 | ETHTOOL_LINK_MODE_Autoneg_BIT, | ||
| 66 | ETHTOOL_LINK_MODE_TP_BIT, | ||
| 67 | ETHTOOL_LINK_MODE_MII_BIT, | ||
| 68 | }; | ||
| 69 | |||
| 70 | static const int phy_fibre_port_array[] = { | ||
| 71 | ETHTOOL_LINK_MODE_FIBRE_BIT, | ||
| 72 | }; | ||
| 73 | |||
| 74 | static const int phy_all_ports_features_array[] = { | ||
| 75 | ETHTOOL_LINK_MODE_Autoneg_BIT, | ||
| 76 | ETHTOOL_LINK_MODE_TP_BIT, | ||
| 77 | ETHTOOL_LINK_MODE_MII_BIT, | ||
| 78 | ETHTOOL_LINK_MODE_FIBRE_BIT, | ||
| 79 | ETHTOOL_LINK_MODE_AUI_BIT, | ||
| 80 | ETHTOOL_LINK_MODE_BNC_BIT, | ||
| 81 | ETHTOOL_LINK_MODE_Backplane_BIT, | ||
| 82 | }; | ||
| 83 | |||
| 84 | static const int phy_10_100_features_array[] = { | ||
| 85 | ETHTOOL_LINK_MODE_10baseT_Half_BIT, | ||
| 86 | ETHTOOL_LINK_MODE_10baseT_Full_BIT, | ||
| 87 | ETHTOOL_LINK_MODE_100baseT_Half_BIT, | ||
| 88 | ETHTOOL_LINK_MODE_100baseT_Full_BIT, | ||
| 89 | }; | ||
| 90 | |||
| 91 | static const int phy_basic_t1_features_array[] = { | ||
| 92 | ETHTOOL_LINK_MODE_TP_BIT, | ||
| 93 | ETHTOOL_LINK_MODE_100baseT_Full_BIT, | ||
| 94 | }; | ||
| 95 | |||
| 96 | static const int phy_gbit_features_array[] = { | ||
| 97 | ETHTOOL_LINK_MODE_1000baseT_Half_BIT, | ||
| 98 | ETHTOOL_LINK_MODE_1000baseT_Full_BIT, | ||
| 99 | }; | ||
| 100 | |||
| 101 | static const int phy_10gbit_features_array[] = { | ||
| 102 | ETHTOOL_LINK_MODE_10000baseT_Full_BIT, | ||
| 103 | }; | ||
| 104 | |||
| 105 | __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_full_features) __ro_after_init; | ||
| 106 | EXPORT_SYMBOL_GPL(phy_10gbit_full_features); | ||
| 107 | |||
| 108 | static const int phy_10gbit_full_features_array[] = { | ||
| 109 | ETHTOOL_LINK_MODE_10baseT_Full_BIT, | ||
| 110 | ETHTOOL_LINK_MODE_100baseT_Full_BIT, | ||
| 111 | ETHTOOL_LINK_MODE_1000baseT_Full_BIT, | ||
| 112 | ETHTOOL_LINK_MODE_10000baseT_Full_BIT, | ||
| 113 | }; | ||
| 114 | |||
| 115 | static void features_init(void) | ||
| 116 | { | ||
| 117 | /* 10/100 half/full*/ | ||
| 118 | linkmode_set_bit_array(phy_basic_ports_array, | ||
| 119 | ARRAY_SIZE(phy_basic_ports_array), | ||
| 120 | phy_basic_features); | ||
| 121 | linkmode_set_bit_array(phy_10_100_features_array, | ||
| 122 | ARRAY_SIZE(phy_10_100_features_array), | ||
| 123 | phy_basic_features); | ||
| 124 | |||
| 125 | /* 100 full, TP */ | ||
| 126 | linkmode_set_bit_array(phy_basic_t1_features_array, | ||
| 127 | ARRAY_SIZE(phy_basic_t1_features_array), | ||
| 128 | phy_basic_t1_features); | ||
| 129 | |||
| 130 | /* 10/100 half/full + 1000 half/full */ | ||
| 131 | linkmode_set_bit_array(phy_basic_ports_array, | ||
| 132 | ARRAY_SIZE(phy_basic_ports_array), | ||
| 133 | phy_gbit_features); | ||
| 134 | linkmode_set_bit_array(phy_10_100_features_array, | ||
| 135 | ARRAY_SIZE(phy_10_100_features_array), | ||
| 136 | phy_gbit_features); | ||
| 137 | linkmode_set_bit_array(phy_gbit_features_array, | ||
| 138 | ARRAY_SIZE(phy_gbit_features_array), | ||
| 139 | phy_gbit_features); | ||
| 140 | |||
| 141 | /* 10/100 half/full + 1000 half/full + fibre*/ | ||
| 142 | linkmode_set_bit_array(phy_basic_ports_array, | ||
| 143 | ARRAY_SIZE(phy_basic_ports_array), | ||
| 144 | phy_gbit_fibre_features); | ||
| 145 | linkmode_set_bit_array(phy_10_100_features_array, | ||
| 146 | ARRAY_SIZE(phy_10_100_features_array), | ||
| 147 | phy_gbit_fibre_features); | ||
| 148 | linkmode_set_bit_array(phy_gbit_features_array, | ||
| 149 | ARRAY_SIZE(phy_gbit_features_array), | ||
| 150 | phy_gbit_fibre_features); | ||
| 151 | linkmode_set_bit_array(phy_fibre_port_array, | ||
| 152 | ARRAY_SIZE(phy_fibre_port_array), | ||
| 153 | phy_gbit_fibre_features); | ||
| 154 | |||
| 155 | /* 10/100 half/full + 1000 half/full + TP/MII/FIBRE/AUI/BNC/Backplane*/ | ||
| 156 | linkmode_set_bit_array(phy_all_ports_features_array, | ||
| 157 | ARRAY_SIZE(phy_all_ports_features_array), | ||
| 158 | phy_gbit_all_ports_features); | ||
| 159 | linkmode_set_bit_array(phy_10_100_features_array, | ||
| 160 | ARRAY_SIZE(phy_10_100_features_array), | ||
| 161 | phy_gbit_all_ports_features); | ||
| 162 | linkmode_set_bit_array(phy_gbit_features_array, | ||
| 163 | ARRAY_SIZE(phy_gbit_features_array), | ||
| 164 | phy_gbit_all_ports_features); | ||
| 165 | |||
| 166 | /* 10/100 half/full + 1000 half/full + 10G full*/ | ||
| 167 | linkmode_set_bit_array(phy_all_ports_features_array, | ||
| 168 | ARRAY_SIZE(phy_all_ports_features_array), | ||
| 169 | phy_10gbit_features); | ||
| 170 | linkmode_set_bit_array(phy_10_100_features_array, | ||
| 171 | ARRAY_SIZE(phy_10_100_features_array), | ||
| 172 | phy_10gbit_features); | ||
| 173 | linkmode_set_bit_array(phy_gbit_features_array, | ||
| 174 | ARRAY_SIZE(phy_gbit_features_array), | ||
| 175 | phy_10gbit_features); | ||
| 176 | linkmode_set_bit_array(phy_10gbit_features_array, | ||
| 177 | ARRAY_SIZE(phy_10gbit_features_array), | ||
| 178 | phy_10gbit_features); | ||
| 179 | |||
| 180 | /* 10/100/1000/10G full */ | ||
| 181 | linkmode_set_bit_array(phy_all_ports_features_array, | ||
| 182 | ARRAY_SIZE(phy_all_ports_features_array), | ||
| 183 | phy_10gbit_full_features); | ||
| 184 | linkmode_set_bit_array(phy_10gbit_full_features_array, | ||
| 185 | ARRAY_SIZE(phy_10gbit_full_features_array), | ||
| 186 | phy_10gbit_full_features); | ||
| 187 | } | ||
| 188 | |||
| 45 | void phy_device_free(struct phy_device *phydev) | 189 | void phy_device_free(struct phy_device *phydev) |
| 46 | { | 190 | { |
| 47 | put_device(&phydev->mdio.dev); | 191 | put_device(&phydev->mdio.dev); |
| @@ -93,7 +237,12 @@ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev) | |||
| 93 | if (!netdev) | 237 | if (!netdev) |
| 94 | return !phydev->suspended; | 238 | return !phydev->suspended; |
| 95 | 239 | ||
| 96 | /* Don't suspend PHY if the attached netdev parent may wakeup. | 240 | if (netdev->wol_enabled) |
| 241 | return false; | ||
| 242 | |||
| 243 | /* As long as not all affected network drivers support the | ||
| 244 | * wol_enabled flag, let's check for hints that WoL is enabled. | ||
| 245 | * Don't suspend PHY if the attached netdev parent may wake up. | ||
| 97 | * The parent may point to a PCI device, as in tg3 driver. | 246 | * The parent may point to a PCI device, as in tg3 driver. |
| 98 | */ | 247 | */ |
| 99 | if (netdev->dev.parent && device_may_wakeup(netdev->dev.parent)) | 248 | if (netdev->dev.parent && device_may_wakeup(netdev->dev.parent)) |
| @@ -159,11 +308,8 @@ static int mdio_bus_phy_restore(struct device *dev) | |||
| 159 | if (ret < 0) | 308 | if (ret < 0) |
| 160 | return ret; | 309 | return ret; |
| 161 | 310 | ||
| 162 | /* The PHY needs to renegotiate. */ | 311 | if (phydev->attached_dev && phydev->adjust_link) |
| 163 | phydev->link = 0; | 312 | phy_start_machine(phydev); |
| 164 | phydev->state = PHY_UP; | ||
| 165 | |||
| 166 | phy_start_machine(phydev); | ||
| 167 | 313 | ||
| 168 | return 0; | 314 | return 0; |
| 169 | } | 315 | } |
| @@ -346,6 +492,55 @@ static int phy_bus_match(struct device *dev, struct device_driver *drv) | |||
| 346 | } | 492 | } |
| 347 | } | 493 | } |
| 348 | 494 | ||
| 495 | static ssize_t | ||
| 496 | phy_id_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 497 | { | ||
| 498 | struct phy_device *phydev = to_phy_device(dev); | ||
| 499 | |||
| 500 | return sprintf(buf, "0x%.8lx\n", (unsigned long)phydev->phy_id); | ||
| 501 | } | ||
| 502 | static DEVICE_ATTR_RO(phy_id); | ||
| 503 | |||
| 504 | static ssize_t | ||
| 505 | phy_interface_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 506 | { | ||
| 507 | struct phy_device *phydev = to_phy_device(dev); | ||
| 508 | const char *mode = NULL; | ||
| 509 | |||
| 510 | if (phy_is_internal(phydev)) | ||
| 511 | mode = "internal"; | ||
| 512 | else | ||
| 513 | mode = phy_modes(phydev->interface); | ||
| 514 | |||
| 515 | return sprintf(buf, "%s\n", mode); | ||
| 516 | } | ||
| 517 | static DEVICE_ATTR_RO(phy_interface); | ||
| 518 | |||
| 519 | static ssize_t | ||
| 520 | phy_has_fixups_show(struct device *dev, struct device_attribute *attr, | ||
| 521 | char *buf) | ||
| 522 | { | ||
| 523 | struct phy_device *phydev = to_phy_device(dev); | ||
| 524 | |||
| 525 | return sprintf(buf, "%d\n", phydev->has_fixups); | ||
| 526 | } | ||
| 527 | static DEVICE_ATTR_RO(phy_has_fixups); | ||
| 528 | |||
| 529 | static struct attribute *phy_dev_attrs[] = { | ||
| 530 | &dev_attr_phy_id.attr, | ||
| 531 | &dev_attr_phy_interface.attr, | ||
| 532 | &dev_attr_phy_has_fixups.attr, | ||
| 533 | NULL, | ||
| 534 | }; | ||
| 535 | ATTRIBUTE_GROUPS(phy_dev); | ||
| 536 | |||
| 537 | static const struct device_type mdio_bus_phy_type = { | ||
| 538 | .name = "PHY", | ||
| 539 | .groups = phy_dev_groups, | ||
| 540 | .release = phy_device_release, | ||
| 541 | .pm = MDIO_BUS_PHY_PM_OPS, | ||
| 542 | }; | ||
| 543 | |||
| 349 | struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id, | 544 | struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id, |
| 350 | bool is_c45, | 545 | bool is_c45, |
| 351 | struct phy_c45_device_ids *c45_ids) | 546 | struct phy_c45_device_ids *c45_ids) |
| @@ -359,11 +554,10 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id, | |||
| 359 | return ERR_PTR(-ENOMEM); | 554 | return ERR_PTR(-ENOMEM); |
| 360 | 555 | ||
| 361 | mdiodev = &dev->mdio; | 556 | mdiodev = &dev->mdio; |
| 362 | mdiodev->dev.release = phy_device_release; | ||
| 363 | mdiodev->dev.parent = &bus->dev; | 557 | mdiodev->dev.parent = &bus->dev; |
| 364 | mdiodev->dev.bus = &mdio_bus_type; | 558 | mdiodev->dev.bus = &mdio_bus_type; |
| 559 | mdiodev->dev.type = &mdio_bus_phy_type; | ||
| 365 | mdiodev->bus = bus; | 560 | mdiodev->bus = bus; |
| 366 | mdiodev->pm_ops = MDIO_BUS_PHY_PM_OPS; | ||
| 367 | mdiodev->bus_match = phy_bus_match; | 561 | mdiodev->bus_match = phy_bus_match; |
| 368 | mdiodev->addr = addr; | 562 | mdiodev->addr = addr; |
| 369 | mdiodev->flags = MDIO_DEVICE_FLAG_PHY; | 563 | mdiodev->flags = MDIO_DEVICE_FLAG_PHY; |
| @@ -587,48 +781,6 @@ struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45) | |||
| 587 | } | 781 | } |
| 588 | EXPORT_SYMBOL(get_phy_device); | 782 | EXPORT_SYMBOL(get_phy_device); |
| 589 | 783 | ||
| 590 | static ssize_t | ||
| 591 | phy_id_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 592 | { | ||
| 593 | struct phy_device *phydev = to_phy_device(dev); | ||
| 594 | |||
| 595 | return sprintf(buf, "0x%.8lx\n", (unsigned long)phydev->phy_id); | ||
| 596 | } | ||
| 597 | static DEVICE_ATTR_RO(phy_id); | ||
| 598 | |||
| 599 | static ssize_t | ||
| 600 | phy_interface_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 601 | { | ||
| 602 | struct phy_device *phydev = to_phy_device(dev); | ||
| 603 | const char *mode = NULL; | ||
| 604 | |||
| 605 | if (phy_is_internal(phydev)) | ||
| 606 | mode = "internal"; | ||
| 607 | else | ||
| 608 | mode = phy_modes(phydev->interface); | ||
| 609 | |||
| 610 | return sprintf(buf, "%s\n", mode); | ||
| 611 | } | ||
| 612 | static DEVICE_ATTR_RO(phy_interface); | ||
| 613 | |||
| 614 | static ssize_t | ||
| 615 | phy_has_fixups_show(struct device *dev, struct device_attribute *attr, | ||
| 616 | char *buf) | ||
| 617 | { | ||
| 618 | struct phy_device *phydev = to_phy_device(dev); | ||
| 619 | |||
| 620 | return sprintf(buf, "%d\n", phydev->has_fixups); | ||
| 621 | } | ||
| 622 | static DEVICE_ATTR_RO(phy_has_fixups); | ||
| 623 | |||
| 624 | static struct attribute *phy_dev_attrs[] = { | ||
| 625 | &dev_attr_phy_id.attr, | ||
| 626 | &dev_attr_phy_interface.attr, | ||
| 627 | &dev_attr_phy_has_fixups.attr, | ||
| 628 | NULL, | ||
| 629 | }; | ||
| 630 | ATTRIBUTE_GROUPS(phy_dev); | ||
| 631 | |||
| 632 | /** | 784 | /** |
| 633 | * phy_device_register - Register the phy device on the MDIO bus | 785 | * phy_device_register - Register the phy device on the MDIO bus |
| 634 | * @phydev: phy_device structure to be added to the MDIO bus | 786 | * @phydev: phy_device structure to be added to the MDIO bus |
| @@ -651,8 +803,6 @@ int phy_device_register(struct phy_device *phydev) | |||
| 651 | goto out; | 803 | goto out; |
| 652 | } | 804 | } |
| 653 | 805 | ||
| 654 | phydev->mdio.dev.groups = phy_dev_groups; | ||
| 655 | |||
| 656 | err = device_add(&phydev->mdio.dev); | 806 | err = device_add(&phydev->mdio.dev); |
| 657 | if (err) { | 807 | if (err) { |
| 658 | pr_err("PHY %d failed to add\n", phydev->mdio.addr); | 808 | pr_err("PHY %d failed to add\n", phydev->mdio.addr); |
| @@ -876,8 +1026,6 @@ int phy_init_hw(struct phy_device *phydev) | |||
| 876 | 1026 | ||
| 877 | if (phydev->drv->soft_reset) | 1027 | if (phydev->drv->soft_reset) |
| 878 | ret = phydev->drv->soft_reset(phydev); | 1028 | ret = phydev->drv->soft_reset(phydev); |
| 879 | else | ||
| 880 | ret = genphy_soft_reset(phydev); | ||
| 881 | 1029 | ||
| 882 | if (ret < 0) | 1030 | if (ret < 0) |
| 883 | return ret; | 1031 | return ret; |
| @@ -918,13 +1066,13 @@ void phy_attached_print(struct phy_device *phydev, const char *fmt, ...) | |||
| 918 | 1066 | ||
| 919 | 1067 | ||
| 920 | if (!fmt) { | 1068 | if (!fmt) { |
| 921 | dev_info(&phydev->mdio.dev, ATTACHED_FMT "\n", | 1069 | phydev_info(phydev, ATTACHED_FMT "\n", |
| 922 | drv_name, phydev_name(phydev), | 1070 | drv_name, phydev_name(phydev), |
| 923 | irq_str); | 1071 | irq_str); |
| 924 | } else { | 1072 | } else { |
| 925 | va_list ap; | 1073 | va_list ap; |
| 926 | 1074 | ||
| 927 | dev_info(&phydev->mdio.dev, ATTACHED_FMT, | 1075 | phydev_info(phydev, ATTACHED_FMT, |
| 928 | drv_name, phydev_name(phydev), | 1076 | drv_name, phydev_name(phydev), |
| 929 | irq_str); | 1077 | irq_str); |
| 930 | 1078 | ||
| @@ -1128,9 +1276,9 @@ void phy_detach(struct phy_device *phydev) | |||
| 1128 | sysfs_remove_link(&dev->dev.kobj, "phydev"); | 1276 | sysfs_remove_link(&dev->dev.kobj, "phydev"); |
| 1129 | sysfs_remove_link(&phydev->mdio.dev.kobj, "attached_dev"); | 1277 | sysfs_remove_link(&phydev->mdio.dev.kobj, "attached_dev"); |
| 1130 | } | 1278 | } |
| 1279 | phy_suspend(phydev); | ||
| 1131 | phydev->attached_dev->phydev = NULL; | 1280 | phydev->attached_dev->phydev = NULL; |
| 1132 | phydev->attached_dev = NULL; | 1281 | phydev->attached_dev = NULL; |
| 1133 | phy_suspend(phydev); | ||
| 1134 | phydev->phylink = NULL; | 1282 | phydev->phylink = NULL; |
| 1135 | 1283 | ||
| 1136 | phy_led_triggers_unregister(phydev); | 1284 | phy_led_triggers_unregister(phydev); |
| @@ -1164,12 +1312,13 @@ EXPORT_SYMBOL(phy_detach); | |||
| 1164 | int phy_suspend(struct phy_device *phydev) | 1312 | int phy_suspend(struct phy_device *phydev) |
| 1165 | { | 1313 | { |
| 1166 | struct phy_driver *phydrv = to_phy_driver(phydev->mdio.dev.driver); | 1314 | struct phy_driver *phydrv = to_phy_driver(phydev->mdio.dev.driver); |
| 1315 | struct net_device *netdev = phydev->attached_dev; | ||
| 1167 | struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL }; | 1316 | struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL }; |
| 1168 | int ret = 0; | 1317 | int ret = 0; |
| 1169 | 1318 | ||
| 1170 | /* If the device has WOL enabled, we cannot suspend the PHY */ | 1319 | /* If the device has WOL enabled, we cannot suspend the PHY */ |
| 1171 | phy_ethtool_get_wol(phydev, &wol); | 1320 | phy_ethtool_get_wol(phydev, &wol); |
| 1172 | if (wol.wolopts) | 1321 | if (wol.wolopts || (netdev && netdev->wol_enabled)) |
| 1173 | return -EBUSY; | 1322 | return -EBUSY; |
| 1174 | 1323 | ||
| 1175 | if (phydev->drv && phydrv->suspend) | 1324 | if (phydev->drv && phydrv->suspend) |
| @@ -1551,6 +1700,14 @@ int genphy_read_status(struct phy_device *phydev) | |||
| 1551 | if (adv < 0) | 1700 | if (adv < 0) |
| 1552 | return adv; | 1701 | return adv; |
| 1553 | 1702 | ||
| 1703 | if (lpagb & LPA_1000MSFAIL) { | ||
| 1704 | if (adv & CTL1000_ENABLE_MASTER) | ||
| 1705 | phydev_err(phydev, "Master/Slave resolution failed, maybe conflicting manual settings?\n"); | ||
| 1706 | else | ||
| 1707 | phydev_err(phydev, "Master/Slave resolution failed\n"); | ||
| 1708 | return -ENOLINK; | ||
| 1709 | } | ||
| 1710 | |||
| 1554 | phydev->lp_advertising = | 1711 | phydev->lp_advertising = |
| 1555 | mii_stat1000_to_ethtool_lpa_t(lpagb); | 1712 | mii_stat1000_to_ethtool_lpa_t(lpagb); |
| 1556 | common_adv_gb = lpagb & adv << 2; | 1713 | common_adv_gb = lpagb & adv << 2; |
| @@ -1720,23 +1877,17 @@ EXPORT_SYMBOL(genphy_loopback); | |||
| 1720 | 1877 | ||
| 1721 | static int __set_phy_supported(struct phy_device *phydev, u32 max_speed) | 1878 | static int __set_phy_supported(struct phy_device *phydev, u32 max_speed) |
| 1722 | { | 1879 | { |
| 1723 | /* The default values for phydev->supported are provided by the PHY | ||
| 1724 | * driver "features" member, we want to reset to sane defaults first | ||
| 1725 | * before supporting higher speeds. | ||
| 1726 | */ | ||
| 1727 | phydev->supported &= PHY_DEFAULT_FEATURES; | ||
| 1728 | |||
| 1729 | switch (max_speed) { | 1880 | switch (max_speed) { |
| 1730 | default: | 1881 | case SPEED_10: |
| 1731 | return -ENOTSUPP; | 1882 | phydev->supported &= ~PHY_100BT_FEATURES; |
| 1732 | case SPEED_1000: | ||
| 1733 | phydev->supported |= PHY_1000BT_FEATURES; | ||
| 1734 | /* fall through */ | 1883 | /* fall through */ |
| 1735 | case SPEED_100: | 1884 | case SPEED_100: |
| 1736 | phydev->supported |= PHY_100BT_FEATURES; | 1885 | phydev->supported &= ~PHY_1000BT_FEATURES; |
| 1737 | /* fall through */ | 1886 | break; |
| 1738 | case SPEED_10: | 1887 | case SPEED_1000: |
| 1739 | phydev->supported |= PHY_10BT_FEATURES; | 1888 | break; |
| 1889 | default: | ||
| 1890 | return -ENOTSUPP; | ||
| 1740 | } | 1891 | } |
| 1741 | 1892 | ||
| 1742 | return 0; | 1893 | return 0; |
| @@ -1756,6 +1907,125 @@ int phy_set_max_speed(struct phy_device *phydev, u32 max_speed) | |||
| 1756 | } | 1907 | } |
| 1757 | EXPORT_SYMBOL(phy_set_max_speed); | 1908 | EXPORT_SYMBOL(phy_set_max_speed); |
| 1758 | 1909 | ||
| 1910 | /** | ||
| 1911 | * phy_remove_link_mode - Remove a supported link mode | ||
| 1912 | * @phydev: phy_device structure to remove link mode from | ||
| 1913 | * @link_mode: Link mode to be removed | ||
| 1914 | * | ||
| 1915 | * Description: Some MACs don't support all link modes which the PHY | ||
| 1916 | * does. e.g. a 1G MAC often does not support 1000Half. Add a helper | ||
| 1917 | * to remove a link mode. | ||
| 1918 | */ | ||
| 1919 | void phy_remove_link_mode(struct phy_device *phydev, u32 link_mode) | ||
| 1920 | { | ||
| 1921 | WARN_ON(link_mode > 31); | ||
| 1922 | |||
| 1923 | phydev->supported &= ~BIT(link_mode); | ||
| 1924 | phydev->advertising = phydev->supported; | ||
| 1925 | } | ||
| 1926 | EXPORT_SYMBOL(phy_remove_link_mode); | ||
| 1927 | |||
| 1928 | /** | ||
| 1929 | * phy_support_sym_pause - Enable support of symmetrical pause | ||
| 1930 | * @phydev: target phy_device struct | ||
| 1931 | * | ||
| 1932 | * Description: Called by the MAC to indicate is supports symmetrical | ||
| 1933 | * Pause, but not asym pause. | ||
| 1934 | */ | ||
| 1935 | void phy_support_sym_pause(struct phy_device *phydev) | ||
| 1936 | { | ||
| 1937 | phydev->supported &= ~SUPPORTED_Asym_Pause; | ||
| 1938 | phydev->supported |= SUPPORTED_Pause; | ||
| 1939 | phydev->advertising = phydev->supported; | ||
| 1940 | } | ||
| 1941 | EXPORT_SYMBOL(phy_support_sym_pause); | ||
| 1942 | |||
| 1943 | /** | ||
| 1944 | * phy_support_asym_pause - Enable support of asym pause | ||
| 1945 | * @phydev: target phy_device struct | ||
| 1946 | * | ||
| 1947 | * Description: Called by the MAC to indicate is supports Asym Pause. | ||
| 1948 | */ | ||
| 1949 | void phy_support_asym_pause(struct phy_device *phydev) | ||
| 1950 | { | ||
| 1951 | phydev->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; | ||
| 1952 | phydev->advertising = phydev->supported; | ||
| 1953 | } | ||
| 1954 | EXPORT_SYMBOL(phy_support_asym_pause); | ||
| 1955 | |||
| 1956 | /** | ||
| 1957 | * phy_set_sym_pause - Configure symmetric Pause | ||
| 1958 | * @phydev: target phy_device struct | ||
| 1959 | * @rx: Receiver Pause is supported | ||
| 1960 | * @tx: Transmit Pause is supported | ||
| 1961 | * @autoneg: Auto neg should be used | ||
| 1962 | * | ||
| 1963 | * Description: Configure advertised Pause support depending on if | ||
| 1964 | * receiver pause and pause auto neg is supported. Generally called | ||
| 1965 | * from the set_pauseparam .ndo. | ||
| 1966 | */ | ||
| 1967 | void phy_set_sym_pause(struct phy_device *phydev, bool rx, bool tx, | ||
| 1968 | bool autoneg) | ||
| 1969 | { | ||
| 1970 | phydev->supported &= ~SUPPORTED_Pause; | ||
| 1971 | |||
| 1972 | if (rx && tx && autoneg) | ||
| 1973 | phydev->supported |= SUPPORTED_Pause; | ||
| 1974 | |||
| 1975 | phydev->advertising = phydev->supported; | ||
| 1976 | } | ||
| 1977 | EXPORT_SYMBOL(phy_set_sym_pause); | ||
| 1978 | |||
| 1979 | /** | ||
| 1980 | * phy_set_asym_pause - Configure Pause and Asym Pause | ||
| 1981 | * @phydev: target phy_device struct | ||
| 1982 | * @rx: Receiver Pause is supported | ||
| 1983 | * @tx: Transmit Pause is supported | ||
| 1984 | * | ||
| 1985 | * Description: Configure advertised Pause support depending on if | ||
| 1986 | * transmit and receiver pause is supported. If there has been a | ||
| 1987 | * change in adverting, trigger a new autoneg. Generally called from | ||
| 1988 | * the set_pauseparam .ndo. | ||
| 1989 | */ | ||
| 1990 | void phy_set_asym_pause(struct phy_device *phydev, bool rx, bool tx) | ||
| 1991 | { | ||
| 1992 | u16 oldadv = phydev->advertising; | ||
| 1993 | u16 newadv = oldadv &= ~(SUPPORTED_Pause | SUPPORTED_Asym_Pause); | ||
| 1994 | |||
| 1995 | if (rx) | ||
| 1996 | newadv |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; | ||
| 1997 | if (tx) | ||
| 1998 | newadv ^= SUPPORTED_Asym_Pause; | ||
| 1999 | |||
| 2000 | if (oldadv != newadv) { | ||
| 2001 | phydev->advertising = newadv; | ||
| 2002 | |||
| 2003 | if (phydev->autoneg) | ||
| 2004 | phy_start_aneg(phydev); | ||
| 2005 | } | ||
| 2006 | } | ||
| 2007 | EXPORT_SYMBOL(phy_set_asym_pause); | ||
| 2008 | |||
| 2009 | /** | ||
| 2010 | * phy_validate_pause - Test if the PHY/MAC support the pause configuration | ||
| 2011 | * @phydev: phy_device struct | ||
| 2012 | * @pp: requested pause configuration | ||
| 2013 | * | ||
| 2014 | * Description: Test if the PHY/MAC combination supports the Pause | ||
| 2015 | * configuration the user is requesting. Returns True if it is | ||
| 2016 | * supported, false otherwise. | ||
| 2017 | */ | ||
| 2018 | bool phy_validate_pause(struct phy_device *phydev, | ||
| 2019 | struct ethtool_pauseparam *pp) | ||
| 2020 | { | ||
| 2021 | if (!(phydev->supported & SUPPORTED_Pause) || | ||
| 2022 | (!(phydev->supported & SUPPORTED_Asym_Pause) && | ||
| 2023 | pp->rx_pause != pp->tx_pause)) | ||
| 2024 | return false; | ||
| 2025 | return true; | ||
| 2026 | } | ||
| 2027 | EXPORT_SYMBOL(phy_validate_pause); | ||
| 2028 | |||
| 1759 | static void of_set_phy_supported(struct phy_device *phydev) | 2029 | static void of_set_phy_supported(struct phy_device *phydev) |
| 1760 | { | 2030 | { |
| 1761 | struct device_node *node = phydev->mdio.dev.of_node; | 2031 | struct device_node *node = phydev->mdio.dev.of_node; |
| @@ -1811,6 +2081,7 @@ static int phy_probe(struct device *dev) | |||
| 1811 | struct phy_device *phydev = to_phy_device(dev); | 2081 | struct phy_device *phydev = to_phy_device(dev); |
| 1812 | struct device_driver *drv = phydev->mdio.dev.driver; | 2082 | struct device_driver *drv = phydev->mdio.dev.driver; |
| 1813 | struct phy_driver *phydrv = to_phy_driver(drv); | 2083 | struct phy_driver *phydrv = to_phy_driver(drv); |
| 2084 | u32 features; | ||
| 1814 | int err = 0; | 2085 | int err = 0; |
| 1815 | 2086 | ||
| 1816 | phydev->drv = phydrv; | 2087 | phydev->drv = phydrv; |
| @@ -1831,7 +2102,8 @@ static int phy_probe(struct device *dev) | |||
| 1831 | * a controller will attach, and may modify one | 2102 | * a controller will attach, and may modify one |
| 1832 | * or both of these values | 2103 | * or both of these values |
| 1833 | */ | 2104 | */ |
| 1834 | phydev->supported = phydrv->features; | 2105 | ethtool_convert_link_mode_to_legacy_u32(&features, phydrv->features); |
| 2106 | phydev->supported = features; | ||
| 1835 | of_set_phy_supported(phydev); | 2107 | of_set_phy_supported(phydev); |
| 1836 | phydev->advertising = phydev->supported; | 2108 | phydev->advertising = phydev->supported; |
| 1837 | 2109 | ||
| @@ -1851,10 +2123,14 @@ static int phy_probe(struct device *dev) | |||
| 1851 | * (e.g. hardware erratum) where the driver wants to set only one | 2123 | * (e.g. hardware erratum) where the driver wants to set only one |
| 1852 | * of these bits. | 2124 | * of these bits. |
| 1853 | */ | 2125 | */ |
| 1854 | if (phydrv->features & (SUPPORTED_Pause | SUPPORTED_Asym_Pause)) { | 2126 | if (test_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydrv->features) || |
| 2127 | test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydrv->features)) { | ||
| 1855 | phydev->supported &= ~(SUPPORTED_Pause | SUPPORTED_Asym_Pause); | 2128 | phydev->supported &= ~(SUPPORTED_Pause | SUPPORTED_Asym_Pause); |
| 1856 | phydev->supported |= phydrv->features & | 2129 | if (test_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydrv->features)) |
| 1857 | (SUPPORTED_Pause | SUPPORTED_Asym_Pause); | 2130 | phydev->supported |= SUPPORTED_Pause; |
| 2131 | if (test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, | ||
| 2132 | phydrv->features)) | ||
| 2133 | phydev->supported |= SUPPORTED_Asym_Pause; | ||
| 1858 | } else { | 2134 | } else { |
| 1859 | phydev->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; | 2135 | phydev->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; |
| 1860 | } | 2136 | } |
| @@ -1915,6 +2191,14 @@ int phy_driver_register(struct phy_driver *new_driver, struct module *owner) | |||
| 1915 | new_driver->mdiodrv.driver.remove = phy_remove; | 2191 | new_driver->mdiodrv.driver.remove = phy_remove; |
| 1916 | new_driver->mdiodrv.driver.owner = owner; | 2192 | new_driver->mdiodrv.driver.owner = owner; |
| 1917 | 2193 | ||
| 2194 | /* The following works around an issue where the PHY driver doesn't bind | ||
| 2195 | * to the device, resulting in the genphy driver being used instead of | ||
| 2196 | * the dedicated driver. The root cause of the issue isn't known yet | ||
| 2197 | * and seems to be in the base driver core. Once this is fixed we may | ||
| 2198 | * remove this workaround. | ||
| 2199 | */ | ||
| 2200 | new_driver->mdiodrv.driver.probe_type = PROBE_FORCE_SYNCHRONOUS; | ||
| 2201 | |||
| 1918 | retval = driver_register(&new_driver->mdiodrv.driver); | 2202 | retval = driver_register(&new_driver->mdiodrv.driver); |
| 1919 | if (retval) { | 2203 | if (retval) { |
| 1920 | pr_err("%s: Error %d in registering driver\n", | 2204 | pr_err("%s: Error %d in registering driver\n", |
| @@ -1967,9 +2251,7 @@ static struct phy_driver genphy_driver = { | |||
| 1967 | .name = "Generic PHY", | 2251 | .name = "Generic PHY", |
| 1968 | .soft_reset = genphy_no_soft_reset, | 2252 | .soft_reset = genphy_no_soft_reset, |
| 1969 | .config_init = genphy_config_init, | 2253 | .config_init = genphy_config_init, |
| 1970 | .features = PHY_GBIT_FEATURES | SUPPORTED_MII | | 2254 | .features = PHY_GBIT_ALL_PORTS_FEATURES, |
| 1971 | SUPPORTED_AUI | SUPPORTED_FIBRE | | ||
| 1972 | SUPPORTED_BNC, | ||
| 1973 | .aneg_done = genphy_aneg_done, | 2255 | .aneg_done = genphy_aneg_done, |
| 1974 | .suspend = genphy_suspend, | 2256 | .suspend = genphy_suspend, |
| 1975 | .resume = genphy_resume, | 2257 | .resume = genphy_resume, |
| @@ -1984,6 +2266,8 @@ static int __init phy_init(void) | |||
| 1984 | if (rc) | 2266 | if (rc) |
| 1985 | return rc; | 2267 | return rc; |
| 1986 | 2268 | ||
| 2269 | features_init(); | ||
| 2270 | |||
| 1987 | rc = phy_driver_register(&genphy_10g_driver, THIS_MODULE); | 2271 | rc = phy_driver_register(&genphy_10g_driver, THIS_MODULE); |
| 1988 | if (rc) | 2272 | if (rc) |
| 1989 | goto err_10g; | 2273 | goto err_10g; |
