.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0+ |
---|
1 | 2 | /* Framework for finding and configuring PHYs. |
---|
2 | 3 | * Also contains generic PHY driver |
---|
3 | 4 | * |
---|
4 | 5 | * Author: Andy Fleming |
---|
5 | 6 | * |
---|
6 | 7 | * Copyright (c) 2004 Freescale Semiconductor, Inc. |
---|
7 | | - * |
---|
8 | | - * This program is free software; you can redistribute it and/or modify it |
---|
9 | | - * under the terms of the GNU General Public License as published by the |
---|
10 | | - * Free Software Foundation; either version 2 of the License, or (at your |
---|
11 | | - * option) any later version. |
---|
12 | | - * |
---|
13 | 8 | */ |
---|
14 | 9 | |
---|
15 | 10 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
---|
16 | 11 | |
---|
17 | | -#include <linux/kernel.h> |
---|
18 | | -#include <linux/string.h> |
---|
19 | | -#include <linux/errno.h> |
---|
20 | | -#include <linux/unistd.h> |
---|
21 | | -#include <linux/slab.h> |
---|
22 | | -#include <linux/interrupt.h> |
---|
23 | | -#include <linux/init.h> |
---|
| 12 | +#include <linux/bitmap.h> |
---|
24 | 13 | #include <linux/delay.h> |
---|
25 | | -#include <linux/netdevice.h> |
---|
| 14 | +#include <linux/errno.h> |
---|
26 | 15 | #include <linux/etherdevice.h> |
---|
27 | | -#include <linux/skbuff.h> |
---|
| 16 | +#include <linux/ethtool.h> |
---|
| 17 | +#include <linux/init.h> |
---|
| 18 | +#include <linux/interrupt.h> |
---|
| 19 | +#include <linux/io.h> |
---|
| 20 | +#include <linux/kernel.h> |
---|
| 21 | +#include <linux/mdio.h> |
---|
| 22 | +#include <linux/mii.h> |
---|
28 | 23 | #include <linux/mm.h> |
---|
29 | 24 | #include <linux/module.h> |
---|
30 | | -#include <linux/mii.h> |
---|
31 | | -#include <linux/ethtool.h> |
---|
| 25 | +#include <linux/netdevice.h> |
---|
32 | 26 | #include <linux/phy.h> |
---|
33 | 27 | #include <linux/phy_led_triggers.h> |
---|
34 | | -#include <linux/mdio.h> |
---|
35 | | -#include <linux/io.h> |
---|
| 28 | +#include <linux/property.h> |
---|
| 29 | +#include <linux/sfp.h> |
---|
| 30 | +#include <linux/skbuff.h> |
---|
| 31 | +#include <linux/slab.h> |
---|
| 32 | +#include <linux/string.h> |
---|
36 | 33 | #include <linux/uaccess.h> |
---|
37 | | -#include <linux/of.h> |
---|
38 | | - |
---|
39 | | -#include <asm/irq.h> |
---|
| 34 | +#include <linux/unistd.h> |
---|
40 | 35 | |
---|
41 | 36 | MODULE_DESCRIPTION("PHY library"); |
---|
42 | 37 | MODULE_AUTHOR("Andy Fleming"); |
---|
43 | 38 | MODULE_LICENSE("GPL"); |
---|
| 39 | + |
---|
| 40 | +__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_basic_features) __ro_after_init; |
---|
| 41 | +EXPORT_SYMBOL_GPL(phy_basic_features); |
---|
| 42 | + |
---|
| 43 | +__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_basic_t1_features) __ro_after_init; |
---|
| 44 | +EXPORT_SYMBOL_GPL(phy_basic_t1_features); |
---|
| 45 | + |
---|
| 46 | +__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_features) __ro_after_init; |
---|
| 47 | +EXPORT_SYMBOL_GPL(phy_gbit_features); |
---|
| 48 | + |
---|
| 49 | +__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_fibre_features) __ro_after_init; |
---|
| 50 | +EXPORT_SYMBOL_GPL(phy_gbit_fibre_features); |
---|
| 51 | + |
---|
| 52 | +__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_all_ports_features) __ro_after_init; |
---|
| 53 | +EXPORT_SYMBOL_GPL(phy_gbit_all_ports_features); |
---|
| 54 | + |
---|
| 55 | +__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_features) __ro_after_init; |
---|
| 56 | +EXPORT_SYMBOL_GPL(phy_10gbit_features); |
---|
| 57 | + |
---|
| 58 | +__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_fec_features) __ro_after_init; |
---|
| 59 | +EXPORT_SYMBOL_GPL(phy_10gbit_fec_features); |
---|
| 60 | + |
---|
| 61 | +const int phy_basic_ports_array[3] = { |
---|
| 62 | + ETHTOOL_LINK_MODE_Autoneg_BIT, |
---|
| 63 | + ETHTOOL_LINK_MODE_TP_BIT, |
---|
| 64 | + ETHTOOL_LINK_MODE_MII_BIT, |
---|
| 65 | +}; |
---|
| 66 | +EXPORT_SYMBOL_GPL(phy_basic_ports_array); |
---|
| 67 | + |
---|
| 68 | +const int phy_fibre_port_array[1] = { |
---|
| 69 | + ETHTOOL_LINK_MODE_FIBRE_BIT, |
---|
| 70 | +}; |
---|
| 71 | +EXPORT_SYMBOL_GPL(phy_fibre_port_array); |
---|
| 72 | + |
---|
| 73 | +const int phy_all_ports_features_array[7] = { |
---|
| 74 | + ETHTOOL_LINK_MODE_Autoneg_BIT, |
---|
| 75 | + ETHTOOL_LINK_MODE_TP_BIT, |
---|
| 76 | + ETHTOOL_LINK_MODE_MII_BIT, |
---|
| 77 | + ETHTOOL_LINK_MODE_FIBRE_BIT, |
---|
| 78 | + ETHTOOL_LINK_MODE_AUI_BIT, |
---|
| 79 | + ETHTOOL_LINK_MODE_BNC_BIT, |
---|
| 80 | + ETHTOOL_LINK_MODE_Backplane_BIT, |
---|
| 81 | +}; |
---|
| 82 | +EXPORT_SYMBOL_GPL(phy_all_ports_features_array); |
---|
| 83 | + |
---|
| 84 | +const int phy_10_100_features_array[4] = { |
---|
| 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 | +EXPORT_SYMBOL_GPL(phy_10_100_features_array); |
---|
| 91 | + |
---|
| 92 | +const int phy_basic_t1_features_array[2] = { |
---|
| 93 | + ETHTOOL_LINK_MODE_TP_BIT, |
---|
| 94 | + ETHTOOL_LINK_MODE_100baseT1_Full_BIT, |
---|
| 95 | +}; |
---|
| 96 | +EXPORT_SYMBOL_GPL(phy_basic_t1_features_array); |
---|
| 97 | + |
---|
| 98 | +const int phy_gbit_features_array[2] = { |
---|
| 99 | + ETHTOOL_LINK_MODE_1000baseT_Half_BIT, |
---|
| 100 | + ETHTOOL_LINK_MODE_1000baseT_Full_BIT, |
---|
| 101 | +}; |
---|
| 102 | +EXPORT_SYMBOL_GPL(phy_gbit_features_array); |
---|
| 103 | + |
---|
| 104 | +const int phy_10gbit_features_array[1] = { |
---|
| 105 | + ETHTOOL_LINK_MODE_10000baseT_Full_BIT, |
---|
| 106 | +}; |
---|
| 107 | +EXPORT_SYMBOL_GPL(phy_10gbit_features_array); |
---|
| 108 | + |
---|
| 109 | +static const int phy_10gbit_fec_features_array[1] = { |
---|
| 110 | + ETHTOOL_LINK_MODE_10000baseR_FEC_BIT, |
---|
| 111 | +}; |
---|
| 112 | + |
---|
| 113 | +__ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_full_features) __ro_after_init; |
---|
| 114 | +EXPORT_SYMBOL_GPL(phy_10gbit_full_features); |
---|
| 115 | + |
---|
| 116 | +static const int phy_10gbit_full_features_array[] = { |
---|
| 117 | + ETHTOOL_LINK_MODE_10baseT_Full_BIT, |
---|
| 118 | + ETHTOOL_LINK_MODE_100baseT_Full_BIT, |
---|
| 119 | + ETHTOOL_LINK_MODE_1000baseT_Full_BIT, |
---|
| 120 | + ETHTOOL_LINK_MODE_10000baseT_Full_BIT, |
---|
| 121 | +}; |
---|
| 122 | + |
---|
| 123 | +static void features_init(void) |
---|
| 124 | +{ |
---|
| 125 | + /* 10/100 half/full*/ |
---|
| 126 | + linkmode_set_bit_array(phy_basic_ports_array, |
---|
| 127 | + ARRAY_SIZE(phy_basic_ports_array), |
---|
| 128 | + phy_basic_features); |
---|
| 129 | + linkmode_set_bit_array(phy_10_100_features_array, |
---|
| 130 | + ARRAY_SIZE(phy_10_100_features_array), |
---|
| 131 | + phy_basic_features); |
---|
| 132 | + |
---|
| 133 | + /* 100 full, TP */ |
---|
| 134 | + linkmode_set_bit_array(phy_basic_t1_features_array, |
---|
| 135 | + ARRAY_SIZE(phy_basic_t1_features_array), |
---|
| 136 | + phy_basic_t1_features); |
---|
| 137 | + |
---|
| 138 | + /* 10/100 half/full + 1000 half/full */ |
---|
| 139 | + linkmode_set_bit_array(phy_basic_ports_array, |
---|
| 140 | + ARRAY_SIZE(phy_basic_ports_array), |
---|
| 141 | + phy_gbit_features); |
---|
| 142 | + linkmode_set_bit_array(phy_10_100_features_array, |
---|
| 143 | + ARRAY_SIZE(phy_10_100_features_array), |
---|
| 144 | + phy_gbit_features); |
---|
| 145 | + linkmode_set_bit_array(phy_gbit_features_array, |
---|
| 146 | + ARRAY_SIZE(phy_gbit_features_array), |
---|
| 147 | + phy_gbit_features); |
---|
| 148 | + |
---|
| 149 | + /* 10/100 half/full + 1000 half/full + fibre*/ |
---|
| 150 | + linkmode_set_bit_array(phy_basic_ports_array, |
---|
| 151 | + ARRAY_SIZE(phy_basic_ports_array), |
---|
| 152 | + phy_gbit_fibre_features); |
---|
| 153 | + linkmode_set_bit_array(phy_10_100_features_array, |
---|
| 154 | + ARRAY_SIZE(phy_10_100_features_array), |
---|
| 155 | + phy_gbit_fibre_features); |
---|
| 156 | + linkmode_set_bit_array(phy_gbit_features_array, |
---|
| 157 | + ARRAY_SIZE(phy_gbit_features_array), |
---|
| 158 | + phy_gbit_fibre_features); |
---|
| 159 | + linkmode_set_bit_array(phy_fibre_port_array, |
---|
| 160 | + ARRAY_SIZE(phy_fibre_port_array), |
---|
| 161 | + phy_gbit_fibre_features); |
---|
| 162 | + |
---|
| 163 | + /* 10/100 half/full + 1000 half/full + TP/MII/FIBRE/AUI/BNC/Backplane*/ |
---|
| 164 | + linkmode_set_bit_array(phy_all_ports_features_array, |
---|
| 165 | + ARRAY_SIZE(phy_all_ports_features_array), |
---|
| 166 | + phy_gbit_all_ports_features); |
---|
| 167 | + linkmode_set_bit_array(phy_10_100_features_array, |
---|
| 168 | + ARRAY_SIZE(phy_10_100_features_array), |
---|
| 169 | + phy_gbit_all_ports_features); |
---|
| 170 | + linkmode_set_bit_array(phy_gbit_features_array, |
---|
| 171 | + ARRAY_SIZE(phy_gbit_features_array), |
---|
| 172 | + phy_gbit_all_ports_features); |
---|
| 173 | + |
---|
| 174 | + /* 10/100 half/full + 1000 half/full + 10G full*/ |
---|
| 175 | + linkmode_set_bit_array(phy_all_ports_features_array, |
---|
| 176 | + ARRAY_SIZE(phy_all_ports_features_array), |
---|
| 177 | + phy_10gbit_features); |
---|
| 178 | + linkmode_set_bit_array(phy_10_100_features_array, |
---|
| 179 | + ARRAY_SIZE(phy_10_100_features_array), |
---|
| 180 | + phy_10gbit_features); |
---|
| 181 | + linkmode_set_bit_array(phy_gbit_features_array, |
---|
| 182 | + ARRAY_SIZE(phy_gbit_features_array), |
---|
| 183 | + phy_10gbit_features); |
---|
| 184 | + linkmode_set_bit_array(phy_10gbit_features_array, |
---|
| 185 | + ARRAY_SIZE(phy_10gbit_features_array), |
---|
| 186 | + phy_10gbit_features); |
---|
| 187 | + |
---|
| 188 | + /* 10/100/1000/10G full */ |
---|
| 189 | + linkmode_set_bit_array(phy_all_ports_features_array, |
---|
| 190 | + ARRAY_SIZE(phy_all_ports_features_array), |
---|
| 191 | + phy_10gbit_full_features); |
---|
| 192 | + linkmode_set_bit_array(phy_10gbit_full_features_array, |
---|
| 193 | + ARRAY_SIZE(phy_10gbit_full_features_array), |
---|
| 194 | + phy_10gbit_full_features); |
---|
| 195 | + /* 10G FEC only */ |
---|
| 196 | + linkmode_set_bit_array(phy_10gbit_fec_features_array, |
---|
| 197 | + ARRAY_SIZE(phy_10gbit_fec_features_array), |
---|
| 198 | + phy_10gbit_fec_features); |
---|
| 199 | +} |
---|
44 | 200 | |
---|
45 | 201 | void phy_device_free(struct phy_device *phydev) |
---|
46 | 202 | { |
---|
.. | .. |
---|
70 | 226 | } |
---|
71 | 227 | |
---|
72 | 228 | static struct phy_driver genphy_driver; |
---|
73 | | -extern struct phy_driver genphy_10g_driver; |
---|
74 | 229 | |
---|
75 | 230 | static LIST_HEAD(phy_fixup_list); |
---|
76 | 231 | static DEFINE_MUTEX(phy_fixup_lock); |
---|
77 | 232 | |
---|
78 | | -#ifdef CONFIG_PM |
---|
79 | 233 | static bool mdio_bus_phy_may_suspend(struct phy_device *phydev) |
---|
80 | 234 | { |
---|
81 | 235 | struct device_driver *drv = phydev->mdio.dev.driver; |
---|
.. | .. |
---|
115 | 269 | return !phydev->suspended; |
---|
116 | 270 | } |
---|
117 | 271 | |
---|
118 | | -static int mdio_bus_phy_suspend(struct device *dev) |
---|
| 272 | +static __maybe_unused int mdio_bus_phy_suspend(struct device *dev) |
---|
119 | 273 | { |
---|
120 | 274 | struct phy_device *phydev = to_phy_device(dev); |
---|
121 | 275 | |
---|
.. | .. |
---|
135 | 289 | return phy_suspend(phydev); |
---|
136 | 290 | } |
---|
137 | 291 | |
---|
138 | | -static int mdio_bus_phy_resume(struct device *dev) |
---|
| 292 | +static __maybe_unused int mdio_bus_phy_resume(struct device *dev) |
---|
139 | 293 | { |
---|
140 | 294 | struct phy_device *phydev = to_phy_device(dev); |
---|
141 | 295 | int ret; |
---|
.. | .. |
---|
145 | 299 | |
---|
146 | 300 | phydev->suspended_by_mdio_bus = 0; |
---|
147 | 301 | |
---|
148 | | - ret = phy_resume(phydev); |
---|
| 302 | + ret = phy_init_hw(phydev); |
---|
149 | 303 | if (ret < 0) |
---|
150 | 304 | return ret; |
---|
151 | 305 | |
---|
| 306 | + ret = phy_resume(phydev); |
---|
| 307 | + if (ret < 0) |
---|
| 308 | + return ret; |
---|
152 | 309 | no_resume: |
---|
153 | 310 | if (phydev->attached_dev && phydev->adjust_link) |
---|
154 | 311 | phy_start_machine(phydev); |
---|
.. | .. |
---|
156 | 313 | return 0; |
---|
157 | 314 | } |
---|
158 | 315 | |
---|
159 | | -static int mdio_bus_phy_restore(struct device *dev) |
---|
160 | | -{ |
---|
161 | | - struct phy_device *phydev = to_phy_device(dev); |
---|
162 | | - struct net_device *netdev = phydev->attached_dev; |
---|
163 | | - int ret; |
---|
164 | | - |
---|
165 | | - if (!netdev) |
---|
166 | | - return 0; |
---|
167 | | - |
---|
168 | | - ret = phy_init_hw(phydev); |
---|
169 | | - if (ret < 0) |
---|
170 | | - return ret; |
---|
171 | | - |
---|
172 | | - if (phydev->attached_dev && phydev->adjust_link) |
---|
173 | | - phy_start_machine(phydev); |
---|
174 | | - |
---|
175 | | - return 0; |
---|
176 | | -} |
---|
177 | | - |
---|
178 | | -static const struct dev_pm_ops mdio_bus_phy_pm_ops = { |
---|
179 | | - .suspend = mdio_bus_phy_suspend, |
---|
180 | | - .resume = mdio_bus_phy_resume, |
---|
181 | | - .freeze = mdio_bus_phy_suspend, |
---|
182 | | - .thaw = mdio_bus_phy_resume, |
---|
183 | | - .restore = mdio_bus_phy_restore, |
---|
184 | | -}; |
---|
185 | | - |
---|
186 | | -#define MDIO_BUS_PHY_PM_OPS (&mdio_bus_phy_pm_ops) |
---|
187 | | - |
---|
188 | | -#else |
---|
189 | | - |
---|
190 | | -#define MDIO_BUS_PHY_PM_OPS NULL |
---|
191 | | - |
---|
192 | | -#endif /* CONFIG_PM */ |
---|
| 316 | +static SIMPLE_DEV_PM_OPS(mdio_bus_phy_pm_ops, mdio_bus_phy_suspend, |
---|
| 317 | + mdio_bus_phy_resume); |
---|
193 | 318 | |
---|
194 | 319 | /** |
---|
195 | 320 | * phy_register_fixup - creates a new phy_fixup and adds it to the list |
---|
.. | .. |
---|
338 | 463 | |
---|
339 | 464 | if (phydev->is_c45) { |
---|
340 | 465 | for (i = 1; i < num_ids; i++) { |
---|
341 | | - if (!(phydev->c45_ids.devices_in_package & (1 << i))) |
---|
| 466 | + if (phydev->c45_ids.device_ids[i] == 0xffffffff) |
---|
342 | 467 | continue; |
---|
343 | 468 | |
---|
344 | 469 | if ((phydrv->phy_id & phydrv->phy_id_mask) == |
---|
.. | .. |
---|
457 | 582 | .name = "PHY", |
---|
458 | 583 | .groups = phy_dev_groups, |
---|
459 | 584 | .release = phy_device_release, |
---|
460 | | - .pm = MDIO_BUS_PHY_PM_OPS, |
---|
| 585 | + .pm = pm_ptr(&mdio_bus_phy_pm_ops), |
---|
461 | 586 | }; |
---|
462 | 587 | |
---|
463 | | -struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id, |
---|
| 588 | +static int phy_request_driver_module(struct phy_device *dev, u32 phy_id) |
---|
| 589 | +{ |
---|
| 590 | + int ret; |
---|
| 591 | + |
---|
| 592 | + ret = request_module(MDIO_MODULE_PREFIX MDIO_ID_FMT, |
---|
| 593 | + MDIO_ID_ARGS(phy_id)); |
---|
| 594 | + /* We only check for failures in executing the usermode binary, |
---|
| 595 | + * not whether a PHY driver module exists for the PHY ID. |
---|
| 596 | + * Accept -ENOENT because this may occur in case no initramfs exists, |
---|
| 597 | + * then modprobe isn't available. |
---|
| 598 | + */ |
---|
| 599 | + if (IS_ENABLED(CONFIG_MODULES) && ret < 0 && ret != -ENOENT) { |
---|
| 600 | + phydev_err(dev, "error %d loading PHY driver module for ID 0x%08lx\n", |
---|
| 601 | + ret, (unsigned long)phy_id); |
---|
| 602 | + return ret; |
---|
| 603 | + } |
---|
| 604 | + |
---|
| 605 | + return 0; |
---|
| 606 | +} |
---|
| 607 | + |
---|
| 608 | +struct phy_device *phy_device_create(struct mii_bus *bus, int addr, u32 phy_id, |
---|
464 | 609 | bool is_c45, |
---|
465 | 610 | struct phy_c45_device_ids *c45_ids) |
---|
466 | 611 | { |
---|
467 | 612 | struct phy_device *dev; |
---|
468 | 613 | struct mdio_device *mdiodev; |
---|
| 614 | + int ret = 0; |
---|
469 | 615 | |
---|
470 | 616 | /* We allocate the device, and initialize the default values */ |
---|
471 | 617 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
---|
.. | .. |
---|
488 | 634 | dev->pause = 0; |
---|
489 | 635 | dev->asym_pause = 0; |
---|
490 | 636 | dev->link = 0; |
---|
| 637 | + dev->port = PORT_TP; |
---|
491 | 638 | dev->interface = PHY_INTERFACE_MODE_GMII; |
---|
492 | 639 | |
---|
493 | 640 | dev->autoneg = AUTONEG_ENABLE; |
---|
.. | .. |
---|
497 | 644 | if (c45_ids) |
---|
498 | 645 | dev->c45_ids = *c45_ids; |
---|
499 | 646 | dev->irq = bus->irq[addr]; |
---|
| 647 | + |
---|
500 | 648 | dev_set_name(&mdiodev->dev, PHY_ID_FMT, bus->id, addr); |
---|
| 649 | + device_initialize(&mdiodev->dev); |
---|
501 | 650 | |
---|
502 | 651 | dev->state = PHY_DOWN; |
---|
503 | 652 | |
---|
504 | 653 | mutex_init(&dev->lock); |
---|
505 | 654 | INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine); |
---|
506 | | - INIT_WORK(&dev->phy_queue, phy_change_work); |
---|
507 | | - |
---|
508 | | - /* Try to avoid __request_module warning */ |
---|
509 | | -#define RK630_PHY_ID 0x00441400 |
---|
510 | | -#define PHY_ID_YT8511 0x0000010a |
---|
511 | | -#define PHY_ID_YT8531S 0x4f51e91a |
---|
512 | | -#define PHY_ID_YT8531 0x4f51e91b |
---|
513 | | - if ((IS_BUILTIN(CONFIG_RK630_PHY) && phy_id == RK630_PHY_ID) || |
---|
514 | | - (IS_BUILTIN(CONFIG_MOTORCOMM_PHY) && (phy_id == PHY_ID_YT8511 || phy_id == PHY_ID_YT8531S || phy_id == PHY_ID_YT8531))) |
---|
515 | | - goto skip_request_module; |
---|
516 | 655 | |
---|
517 | 656 | /* Request the appropriate module unconditionally; don't |
---|
518 | 657 | * bother trying to do so only if it isn't already loaded, |
---|
.. | .. |
---|
524 | 663 | * driver will get bored and give up as soon as it finds that |
---|
525 | 664 | * there's no driver _already_ loaded. |
---|
526 | 665 | */ |
---|
527 | | - request_module(MDIO_MODULE_PREFIX MDIO_ID_FMT, MDIO_ID_ARGS(phy_id)); |
---|
| 666 | + if (is_c45 && c45_ids) { |
---|
| 667 | + const int num_ids = ARRAY_SIZE(c45_ids->device_ids); |
---|
| 668 | + int i; |
---|
528 | 669 | |
---|
529 | | -skip_request_module: |
---|
530 | | - device_initialize(&mdiodev->dev); |
---|
| 670 | + for (i = 1; i < num_ids; i++) { |
---|
| 671 | + if (c45_ids->device_ids[i] == 0xffffffff) |
---|
| 672 | + continue; |
---|
| 673 | + |
---|
| 674 | + ret = phy_request_driver_module(dev, |
---|
| 675 | + c45_ids->device_ids[i]); |
---|
| 676 | + if (ret) |
---|
| 677 | + break; |
---|
| 678 | + } |
---|
| 679 | + } else { |
---|
| 680 | + ret = phy_request_driver_module(dev, phy_id); |
---|
| 681 | + } |
---|
| 682 | + |
---|
| 683 | + if (ret) { |
---|
| 684 | + put_device(&mdiodev->dev); |
---|
| 685 | + dev = ERR_PTR(ret); |
---|
| 686 | + } |
---|
531 | 687 | |
---|
532 | 688 | return dev; |
---|
533 | 689 | } |
---|
534 | 690 | EXPORT_SYMBOL(phy_device_create); |
---|
| 691 | + |
---|
| 692 | +/* phy_c45_probe_present - checks to see if a MMD is present in the package |
---|
| 693 | + * @bus: the target MII bus |
---|
| 694 | + * @prtad: PHY package address on the MII bus |
---|
| 695 | + * @devad: PHY device (MMD) address |
---|
| 696 | + * |
---|
| 697 | + * Read the MDIO_STAT2 register, and check whether a device is responding |
---|
| 698 | + * at this address. |
---|
| 699 | + * |
---|
| 700 | + * Returns: negative error number on bus access error, zero if no device |
---|
| 701 | + * is responding, or positive if a device is present. |
---|
| 702 | + */ |
---|
| 703 | +static int phy_c45_probe_present(struct mii_bus *bus, int prtad, int devad) |
---|
| 704 | +{ |
---|
| 705 | + int stat2; |
---|
| 706 | + |
---|
| 707 | + stat2 = mdiobus_c45_read(bus, prtad, devad, MDIO_STAT2); |
---|
| 708 | + if (stat2 < 0) |
---|
| 709 | + return stat2; |
---|
| 710 | + |
---|
| 711 | + return (stat2 & MDIO_STAT2_DEVPRST) == MDIO_STAT2_DEVPRST_VAL; |
---|
| 712 | +} |
---|
535 | 713 | |
---|
536 | 714 | /* get_phy_c45_devs_in_pkg - reads a MMD's devices in package registers. |
---|
537 | 715 | * @bus: the target MII bus |
---|
.. | .. |
---|
547 | 725 | static int get_phy_c45_devs_in_pkg(struct mii_bus *bus, int addr, int dev_addr, |
---|
548 | 726 | u32 *devices_in_package) |
---|
549 | 727 | { |
---|
550 | | - int phy_reg, reg_addr; |
---|
| 728 | + int phy_reg; |
---|
551 | 729 | |
---|
552 | | - reg_addr = MII_ADDR_C45 | dev_addr << 16 | MDIO_DEVS2; |
---|
553 | | - phy_reg = mdiobus_read(bus, addr, reg_addr); |
---|
| 730 | + phy_reg = mdiobus_c45_read(bus, addr, dev_addr, MDIO_DEVS2); |
---|
554 | 731 | if (phy_reg < 0) |
---|
555 | 732 | return -EIO; |
---|
556 | | - *devices_in_package = (phy_reg & 0xffff) << 16; |
---|
| 733 | + *devices_in_package = phy_reg << 16; |
---|
557 | 734 | |
---|
558 | | - reg_addr = MII_ADDR_C45 | dev_addr << 16 | MDIO_DEVS1; |
---|
559 | | - phy_reg = mdiobus_read(bus, addr, reg_addr); |
---|
| 735 | + phy_reg = mdiobus_c45_read(bus, addr, dev_addr, MDIO_DEVS1); |
---|
560 | 736 | if (phy_reg < 0) |
---|
561 | 737 | return -EIO; |
---|
562 | | - *devices_in_package |= (phy_reg & 0xffff); |
---|
| 738 | + *devices_in_package |= phy_reg; |
---|
563 | 739 | |
---|
564 | 740 | return 0; |
---|
565 | 741 | } |
---|
.. | .. |
---|
568 | 744 | * get_phy_c45_ids - reads the specified addr for its 802.3-c45 IDs. |
---|
569 | 745 | * @bus: the target MII bus |
---|
570 | 746 | * @addr: PHY address on the MII bus |
---|
571 | | - * @phy_id: where to store the ID retrieved. |
---|
572 | 747 | * @c45_ids: where to store the c45 ID information. |
---|
573 | 748 | * |
---|
574 | | - * If the PHY devices-in-package appears to be valid, it and the |
---|
575 | | - * corresponding identifiers are stored in @c45_ids, zero is stored |
---|
576 | | - * in @phy_id. Otherwise 0xffffffff is stored in @phy_id. Returns |
---|
577 | | - * zero on success. |
---|
| 749 | + * Read the PHY "devices in package". If this appears to be valid, read |
---|
| 750 | + * the PHY identifiers for each device. Return the "devices in package" |
---|
| 751 | + * and identifiers in @c45_ids. |
---|
578 | 752 | * |
---|
| 753 | + * Returns zero on success, %-EIO on bus access error, or %-ENODEV if |
---|
| 754 | + * the "devices in package" is invalid. |
---|
579 | 755 | */ |
---|
580 | | -static int get_phy_c45_ids(struct mii_bus *bus, int addr, u32 *phy_id, |
---|
581 | | - struct phy_c45_device_ids *c45_ids) { |
---|
582 | | - int phy_reg; |
---|
583 | | - int i, reg_addr; |
---|
| 756 | +static int get_phy_c45_ids(struct mii_bus *bus, int addr, |
---|
| 757 | + struct phy_c45_device_ids *c45_ids) |
---|
| 758 | +{ |
---|
584 | 759 | const int num_ids = ARRAY_SIZE(c45_ids->device_ids); |
---|
585 | | - u32 *devs = &c45_ids->devices_in_package; |
---|
| 760 | + u32 devs_in_pkg = 0; |
---|
| 761 | + int i, ret, phy_reg; |
---|
586 | 762 | |
---|
587 | 763 | /* Find first non-zero Devices In package. Device zero is reserved |
---|
588 | 764 | * for 802.3 c45 complied PHYs, so don't probe it at first. |
---|
589 | 765 | */ |
---|
590 | | - for (i = 1; i < num_ids && *devs == 0; i++) { |
---|
591 | | - phy_reg = get_phy_c45_devs_in_pkg(bus, addr, i, devs); |
---|
| 766 | + for (i = 1; i < MDIO_MMD_NUM && (devs_in_pkg == 0 || |
---|
| 767 | + (devs_in_pkg & 0x1fffffff) == 0x1fffffff); i++) { |
---|
| 768 | + if (i == MDIO_MMD_VEND1 || i == MDIO_MMD_VEND2) { |
---|
| 769 | + /* Check that there is a device present at this |
---|
| 770 | + * address before reading the devices-in-package |
---|
| 771 | + * register to avoid reading garbage from the PHY. |
---|
| 772 | + * Some PHYs (88x3310) vendor space is not IEEE802.3 |
---|
| 773 | + * compliant. |
---|
| 774 | + */ |
---|
| 775 | + ret = phy_c45_probe_present(bus, addr, i); |
---|
| 776 | + if (ret < 0) |
---|
| 777 | + return -EIO; |
---|
| 778 | + |
---|
| 779 | + if (!ret) |
---|
| 780 | + continue; |
---|
| 781 | + } |
---|
| 782 | + phy_reg = get_phy_c45_devs_in_pkg(bus, addr, i, &devs_in_pkg); |
---|
| 783 | + if (phy_reg < 0) |
---|
| 784 | + return -EIO; |
---|
| 785 | + } |
---|
| 786 | + |
---|
| 787 | + if ((devs_in_pkg & 0x1fffffff) == 0x1fffffff) { |
---|
| 788 | + /* If mostly Fs, there is no device there, then let's probe |
---|
| 789 | + * MMD 0, as some 10G PHYs have zero Devices In package, |
---|
| 790 | + * e.g. Cortina CS4315/CS4340 PHY. |
---|
| 791 | + */ |
---|
| 792 | + phy_reg = get_phy_c45_devs_in_pkg(bus, addr, 0, &devs_in_pkg); |
---|
592 | 793 | if (phy_reg < 0) |
---|
593 | 794 | return -EIO; |
---|
594 | 795 | |
---|
595 | | - if ((*devs & 0x1fffffff) == 0x1fffffff) { |
---|
596 | | - /* If mostly Fs, there is no device there, |
---|
597 | | - * then let's continue to probe more, as some |
---|
598 | | - * 10G PHYs have zero Devices In package, |
---|
599 | | - * e.g. Cortina CS4315/CS4340 PHY. |
---|
600 | | - */ |
---|
601 | | - phy_reg = get_phy_c45_devs_in_pkg(bus, addr, 0, devs); |
---|
602 | | - if (phy_reg < 0) |
---|
603 | | - return -EIO; |
---|
604 | | - /* no device there, let's get out of here */ |
---|
605 | | - if ((*devs & 0x1fffffff) == 0x1fffffff) { |
---|
606 | | - *phy_id = 0xffffffff; |
---|
607 | | - return 0; |
---|
608 | | - } else { |
---|
609 | | - break; |
---|
610 | | - } |
---|
611 | | - } |
---|
| 796 | + /* no device there, let's get out of here */ |
---|
| 797 | + if ((devs_in_pkg & 0x1fffffff) == 0x1fffffff) |
---|
| 798 | + return -ENODEV; |
---|
612 | 799 | } |
---|
613 | 800 | |
---|
614 | 801 | /* Now probe Device Identifiers for each device present. */ |
---|
615 | 802 | for (i = 1; i < num_ids; i++) { |
---|
616 | | - if (!(c45_ids->devices_in_package & (1 << i))) |
---|
| 803 | + if (!(devs_in_pkg & (1 << i))) |
---|
617 | 804 | continue; |
---|
618 | 805 | |
---|
619 | | - reg_addr = MII_ADDR_C45 | i << 16 | MII_PHYSID1; |
---|
620 | | - phy_reg = mdiobus_read(bus, addr, reg_addr); |
---|
621 | | - if (phy_reg < 0) |
---|
622 | | - return -EIO; |
---|
623 | | - c45_ids->device_ids[i] = (phy_reg & 0xffff) << 16; |
---|
| 806 | + if (i == MDIO_MMD_VEND1 || i == MDIO_MMD_VEND2) { |
---|
| 807 | + /* Probe the "Device Present" bits for the vendor MMDs |
---|
| 808 | + * to ignore these if they do not contain IEEE 802.3 |
---|
| 809 | + * registers. |
---|
| 810 | + */ |
---|
| 811 | + ret = phy_c45_probe_present(bus, addr, i); |
---|
| 812 | + if (ret < 0) |
---|
| 813 | + return ret; |
---|
624 | 814 | |
---|
625 | | - reg_addr = MII_ADDR_C45 | i << 16 | MII_PHYSID2; |
---|
626 | | - phy_reg = mdiobus_read(bus, addr, reg_addr); |
---|
| 815 | + if (!ret) |
---|
| 816 | + continue; |
---|
| 817 | + } |
---|
| 818 | + |
---|
| 819 | + phy_reg = mdiobus_c45_read(bus, addr, i, MII_PHYSID1); |
---|
627 | 820 | if (phy_reg < 0) |
---|
628 | 821 | return -EIO; |
---|
629 | | - c45_ids->device_ids[i] |= (phy_reg & 0xffff); |
---|
| 822 | + c45_ids->device_ids[i] = phy_reg << 16; |
---|
| 823 | + |
---|
| 824 | + phy_reg = mdiobus_c45_read(bus, addr, i, MII_PHYSID2); |
---|
| 825 | + if (phy_reg < 0) |
---|
| 826 | + return -EIO; |
---|
| 827 | + c45_ids->device_ids[i] |= phy_reg; |
---|
630 | 828 | } |
---|
631 | | - *phy_id = 0; |
---|
| 829 | + |
---|
| 830 | + c45_ids->devices_in_package = devs_in_pkg; |
---|
| 831 | + /* Bit 0 doesn't represent a device, it indicates c22 regs presence */ |
---|
| 832 | + c45_ids->mmds_present = devs_in_pkg & ~BIT(0); |
---|
| 833 | + |
---|
632 | 834 | return 0; |
---|
633 | 835 | } |
---|
634 | 836 | |
---|
635 | 837 | /** |
---|
636 | | - * get_phy_id - reads the specified addr for its ID. |
---|
| 838 | + * get_phy_c22_id - reads the specified addr for its clause 22 ID. |
---|
637 | 839 | * @bus: the target MII bus |
---|
638 | 840 | * @addr: PHY address on the MII bus |
---|
639 | 841 | * @phy_id: where to store the ID retrieved. |
---|
640 | | - * @is_c45: If true the PHY uses the 802.3 clause 45 protocol |
---|
641 | | - * @c45_ids: where to store the c45 ID information. |
---|
642 | 842 | * |
---|
643 | | - * Description: In the case of a 802.3-c22 PHY, reads the ID registers |
---|
644 | | - * of the PHY at @addr on the @bus, stores it in @phy_id and returns |
---|
645 | | - * zero on success. |
---|
646 | | - * |
---|
647 | | - * In the case of a 802.3-c45 PHY, get_phy_c45_ids() is invoked, and |
---|
648 | | - * its return value is in turn returned. |
---|
649 | | - * |
---|
| 843 | + * Read the 802.3 clause 22 PHY ID from the PHY at @addr on the @bus, |
---|
| 844 | + * placing it in @phy_id. Return zero on successful read and the ID is |
---|
| 845 | + * valid, %-EIO on bus access error, or %-ENODEV if no device responds |
---|
| 846 | + * or invalid ID. |
---|
650 | 847 | */ |
---|
651 | | -static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id, |
---|
652 | | - bool is_c45, struct phy_c45_device_ids *c45_ids) |
---|
| 848 | +static int get_phy_c22_id(struct mii_bus *bus, int addr, u32 *phy_id) |
---|
653 | 849 | { |
---|
654 | 850 | int phy_reg; |
---|
655 | | - |
---|
656 | | - if (is_c45) |
---|
657 | | - return get_phy_c45_ids(bus, addr, phy_id, c45_ids); |
---|
658 | 851 | |
---|
659 | 852 | /* Grab the bits from PHYIR1, and put them in the upper half */ |
---|
660 | 853 | phy_reg = mdiobus_read(bus, addr, MII_PHYSID1); |
---|
661 | 854 | if (phy_reg < 0) { |
---|
662 | | - /* if there is no device, return without an error so scanning |
---|
663 | | - * the bus works properly |
---|
664 | | - */ |
---|
665 | | - if (phy_reg == -EIO || phy_reg == -ENODEV) { |
---|
666 | | - *phy_id = 0xffffffff; |
---|
667 | | - return 0; |
---|
668 | | - } |
---|
669 | | - |
---|
670 | | - return -EIO; |
---|
| 855 | + /* returning -ENODEV doesn't stop bus scanning */ |
---|
| 856 | + return (phy_reg == -EIO || phy_reg == -ENODEV) ? -ENODEV : -EIO; |
---|
671 | 857 | } |
---|
672 | 858 | |
---|
673 | | - *phy_id = (phy_reg & 0xffff) << 16; |
---|
| 859 | + *phy_id = phy_reg << 16; |
---|
674 | 860 | |
---|
675 | 861 | /* Grab the bits from PHYIR2, and put them in the lower half */ |
---|
676 | 862 | phy_reg = mdiobus_read(bus, addr, MII_PHYSID2); |
---|
.. | .. |
---|
679 | 865 | return (phy_reg == -EIO || phy_reg == -ENODEV) ? -ENODEV : -EIO; |
---|
680 | 866 | } |
---|
681 | 867 | |
---|
682 | | - *phy_id |= (phy_reg & 0xffff); |
---|
| 868 | + *phy_id |= phy_reg; |
---|
| 869 | + |
---|
| 870 | + /* If the phy_id is mostly Fs, there is no device there */ |
---|
| 871 | + if ((*phy_id & 0x1fffffff) == 0x1fffffff) |
---|
| 872 | + return -ENODEV; |
---|
683 | 873 | |
---|
684 | 874 | return 0; |
---|
685 | 875 | } |
---|
.. | .. |
---|
691 | 881 | * @addr: PHY address on the MII bus |
---|
692 | 882 | * @is_c45: If true the PHY uses the 802.3 clause 45 protocol |
---|
693 | 883 | * |
---|
694 | | - * Description: Reads the ID registers of the PHY at @addr on the |
---|
695 | | - * @bus, then allocates and returns the phy_device to represent it. |
---|
| 884 | + * Probe for a PHY at @addr on @bus. |
---|
| 885 | + * |
---|
| 886 | + * When probing for a clause 22 PHY, then read the ID registers. If we find |
---|
| 887 | + * a valid ID, allocate and return a &struct phy_device. |
---|
| 888 | + * |
---|
| 889 | + * When probing for a clause 45 PHY, read the "devices in package" registers. |
---|
| 890 | + * If the "devices in package" appears valid, read the ID registers for each |
---|
| 891 | + * MMD, allocate and return a &struct phy_device. |
---|
| 892 | + * |
---|
| 893 | + * Returns an allocated &struct phy_device on success, %-ENODEV if there is |
---|
| 894 | + * no PHY present, or %-EIO on bus access error. |
---|
696 | 895 | */ |
---|
697 | 896 | struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45) |
---|
698 | 897 | { |
---|
699 | | - struct phy_c45_device_ids c45_ids = {0}; |
---|
| 898 | + struct phy_c45_device_ids c45_ids; |
---|
700 | 899 | u32 phy_id = 0; |
---|
701 | 900 | int r; |
---|
702 | 901 | |
---|
703 | | - r = get_phy_id(bus, addr, &phy_id, is_c45, &c45_ids); |
---|
| 902 | + c45_ids.devices_in_package = 0; |
---|
| 903 | + c45_ids.mmds_present = 0; |
---|
| 904 | + memset(c45_ids.device_ids, 0xff, sizeof(c45_ids.device_ids)); |
---|
| 905 | + |
---|
| 906 | + if (is_c45) |
---|
| 907 | + r = get_phy_c45_ids(bus, addr, &c45_ids); |
---|
| 908 | + else |
---|
| 909 | + r = get_phy_c22_id(bus, addr, &phy_id); |
---|
| 910 | + |
---|
704 | 911 | if (r) |
---|
705 | 912 | return ERR_PTR(r); |
---|
706 | | - |
---|
707 | | - /* If the phy_id is mostly Fs, there is no device there */ |
---|
708 | | - if ((phy_id & 0x1fffffff) == 0x1fffffff) |
---|
709 | | - return ERR_PTR(-ENODEV); |
---|
710 | 913 | |
---|
711 | 914 | return phy_device_create(bus, addr, phy_id, is_c45, &c45_ids); |
---|
712 | 915 | } |
---|
.. | .. |
---|
730 | 933 | /* Run all of the fixups for this PHY */ |
---|
731 | 934 | err = phy_scan_fixups(phydev); |
---|
732 | 935 | if (err) { |
---|
733 | | - pr_err("PHY %d failed to initialize\n", phydev->mdio.addr); |
---|
| 936 | + phydev_err(phydev, "failed to initialize\n"); |
---|
734 | 937 | goto out; |
---|
735 | 938 | } |
---|
736 | 939 | |
---|
737 | 940 | err = device_add(&phydev->mdio.dev); |
---|
738 | 941 | if (err) { |
---|
739 | | - pr_err("PHY %d failed to add\n", phydev->mdio.addr); |
---|
| 942 | + phydev_err(phydev, "failed to add\n"); |
---|
740 | 943 | goto out; |
---|
741 | 944 | } |
---|
742 | 945 | |
---|
.. | .. |
---|
761 | 964 | */ |
---|
762 | 965 | void phy_device_remove(struct phy_device *phydev) |
---|
763 | 966 | { |
---|
| 967 | + if (phydev->mii_ts) |
---|
| 968 | + unregister_mii_timestamper(phydev->mii_ts); |
---|
| 969 | + |
---|
764 | 970 | device_del(&phydev->mdio.dev); |
---|
765 | 971 | |
---|
766 | 972 | /* Assert the reset signal */ |
---|
.. | .. |
---|
788 | 994 | } |
---|
789 | 995 | EXPORT_SYMBOL(phy_find_first); |
---|
790 | 996 | |
---|
791 | | -static void phy_link_change(struct phy_device *phydev, bool up, bool do_carrier) |
---|
| 997 | +static void phy_link_change(struct phy_device *phydev, bool up) |
---|
792 | 998 | { |
---|
793 | 999 | struct net_device *netdev = phydev->attached_dev; |
---|
794 | 1000 | |
---|
795 | | - if (do_carrier) { |
---|
796 | | - if (up) |
---|
797 | | - netif_carrier_on(netdev); |
---|
798 | | - else |
---|
799 | | - netif_carrier_off(netdev); |
---|
800 | | - } |
---|
| 1001 | + if (up) |
---|
| 1002 | + netif_carrier_on(netdev); |
---|
| 1003 | + else |
---|
| 1004 | + netif_carrier_off(netdev); |
---|
801 | 1005 | phydev->adjust_link(netdev); |
---|
| 1006 | + if (phydev->mii_ts && phydev->mii_ts->link_state) |
---|
| 1007 | + phydev->mii_ts->link_state(phydev->mii_ts, phydev); |
---|
802 | 1008 | } |
---|
803 | 1009 | |
---|
804 | 1010 | /** |
---|
.. | .. |
---|
840 | 1046 | return rc; |
---|
841 | 1047 | |
---|
842 | 1048 | phy_prepare_link(phydev, handler); |
---|
843 | | - phy_start_machine(phydev); |
---|
844 | | - if (phydev->irq > 0) |
---|
845 | | - phy_start_interrupts(phydev); |
---|
| 1049 | + if (phy_interrupt_is_valid(phydev)) |
---|
| 1050 | + phy_request_interrupt(phydev); |
---|
846 | 1051 | |
---|
847 | 1052 | return 0; |
---|
848 | 1053 | } |
---|
.. | .. |
---|
897 | 1102 | */ |
---|
898 | 1103 | void phy_disconnect(struct phy_device *phydev) |
---|
899 | 1104 | { |
---|
900 | | - if (phydev->irq > 0) |
---|
901 | | - phy_stop_interrupts(phydev); |
---|
| 1105 | + if (phy_is_started(phydev)) |
---|
| 1106 | + phy_stop(phydev); |
---|
902 | 1107 | |
---|
903 | | - phy_stop_machine(phydev); |
---|
| 1108 | + if (phy_interrupt_is_valid(phydev)) |
---|
| 1109 | + phy_free_interrupt(phydev); |
---|
904 | 1110 | |
---|
905 | 1111 | phydev->adjust_link = NULL; |
---|
906 | 1112 | |
---|
.. | .. |
---|
929 | 1135 | static int phy_poll_reset(struct phy_device *phydev) |
---|
930 | 1136 | { |
---|
931 | 1137 | /* Poll until the reset bit clears (50ms per retry == 0.6 sec) */ |
---|
932 | | - unsigned int retries = 12; |
---|
933 | | - int ret; |
---|
| 1138 | + int ret, val; |
---|
934 | 1139 | |
---|
935 | | - do { |
---|
936 | | - msleep(50); |
---|
937 | | - ret = phy_read(phydev, MII_BMCR); |
---|
938 | | - if (ret < 0) |
---|
939 | | - return ret; |
---|
940 | | - } while (ret & BMCR_RESET && --retries); |
---|
941 | | - if (ret & BMCR_RESET) |
---|
942 | | - return -ETIMEDOUT; |
---|
943 | | - |
---|
| 1140 | + ret = phy_read_poll_timeout(phydev, MII_BMCR, val, !(val & BMCR_RESET), |
---|
| 1141 | + 50000, 600000, true); |
---|
| 1142 | + if (ret) |
---|
| 1143 | + return ret; |
---|
944 | 1144 | /* Some chips (smsc911x) may still need up to another 1ms after the |
---|
945 | 1145 | * BMCR_RESET bit is cleared before they are usable. |
---|
946 | 1146 | */ |
---|
.. | .. |
---|
955 | 1155 | /* Deassert the reset signal */ |
---|
956 | 1156 | phy_device_reset(phydev, 0); |
---|
957 | 1157 | |
---|
958 | | - if (!phydev->drv || !phydev->drv->config_init) |
---|
| 1158 | + if (!phydev->drv) |
---|
959 | 1159 | return 0; |
---|
960 | 1160 | |
---|
961 | | - if (phydev->drv->soft_reset) |
---|
| 1161 | + if (phydev->drv->soft_reset) { |
---|
962 | 1162 | ret = phydev->drv->soft_reset(phydev); |
---|
963 | | - else |
---|
964 | | - ret = genphy_soft_reset(phydev); |
---|
| 1163 | + /* see comment in genphy_soft_reset for an explanation */ |
---|
| 1164 | + if (!ret) |
---|
| 1165 | + phydev->suspended = 0; |
---|
| 1166 | + } |
---|
965 | 1167 | |
---|
966 | 1168 | if (ret < 0) |
---|
967 | 1169 | return ret; |
---|
.. | .. |
---|
970 | 1172 | if (ret < 0) |
---|
971 | 1173 | return ret; |
---|
972 | 1174 | |
---|
973 | | - return phydev->drv->config_init(phydev); |
---|
| 1175 | + if (phydev->drv->config_init) { |
---|
| 1176 | + ret = phydev->drv->config_init(phydev); |
---|
| 1177 | + if (ret < 0) |
---|
| 1178 | + return ret; |
---|
| 1179 | + } |
---|
| 1180 | + |
---|
| 1181 | + if (phydev->drv->config_intr) { |
---|
| 1182 | + ret = phydev->drv->config_intr(phydev); |
---|
| 1183 | + if (ret < 0) |
---|
| 1184 | + return ret; |
---|
| 1185 | + } |
---|
| 1186 | + |
---|
| 1187 | + return 0; |
---|
974 | 1188 | } |
---|
975 | 1189 | EXPORT_SYMBOL(phy_init_hw); |
---|
976 | 1190 | |
---|
.. | .. |
---|
981 | 1195 | EXPORT_SYMBOL(phy_attached_info); |
---|
982 | 1196 | |
---|
983 | 1197 | #define ATTACHED_FMT "attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%s)" |
---|
984 | | -void phy_attached_print(struct phy_device *phydev, const char *fmt, ...) |
---|
| 1198 | +char *phy_attached_info_irq(struct phy_device *phydev) |
---|
985 | 1199 | { |
---|
986 | | - const char *drv_name = phydev->drv ? phydev->drv->name : "unbound"; |
---|
987 | 1200 | char *irq_str; |
---|
988 | 1201 | char irq_num[8]; |
---|
989 | 1202 | |
---|
.. | .. |
---|
1000 | 1213 | break; |
---|
1001 | 1214 | } |
---|
1002 | 1215 | |
---|
| 1216 | + return kasprintf(GFP_KERNEL, "%s", irq_str); |
---|
| 1217 | +} |
---|
| 1218 | +EXPORT_SYMBOL(phy_attached_info_irq); |
---|
| 1219 | + |
---|
| 1220 | +void phy_attached_print(struct phy_device *phydev, const char *fmt, ...) |
---|
| 1221 | +{ |
---|
| 1222 | + const char *drv_name = phydev->drv ? phydev->drv->name : "unbound"; |
---|
| 1223 | + char *irq_str = phy_attached_info_irq(phydev); |
---|
1003 | 1224 | |
---|
1004 | 1225 | if (!fmt) { |
---|
1005 | | - dev_info(&phydev->mdio.dev, ATTACHED_FMT "\n", |
---|
| 1226 | + phydev_info(phydev, ATTACHED_FMT "\n", |
---|
1006 | 1227 | drv_name, phydev_name(phydev), |
---|
1007 | 1228 | irq_str); |
---|
1008 | 1229 | } else { |
---|
1009 | 1230 | va_list ap; |
---|
1010 | 1231 | |
---|
1011 | | - dev_info(&phydev->mdio.dev, ATTACHED_FMT, |
---|
| 1232 | + phydev_info(phydev, ATTACHED_FMT, |
---|
1012 | 1233 | drv_name, phydev_name(phydev), |
---|
1013 | 1234 | irq_str); |
---|
1014 | 1235 | |
---|
.. | .. |
---|
1016 | 1237 | vprintk(fmt, ap); |
---|
1017 | 1238 | va_end(ap); |
---|
1018 | 1239 | } |
---|
| 1240 | + kfree(irq_str); |
---|
1019 | 1241 | } |
---|
1020 | 1242 | EXPORT_SYMBOL(phy_attached_print); |
---|
| 1243 | + |
---|
| 1244 | +static void phy_sysfs_create_links(struct phy_device *phydev) |
---|
| 1245 | +{ |
---|
| 1246 | + struct net_device *dev = phydev->attached_dev; |
---|
| 1247 | + int err; |
---|
| 1248 | + |
---|
| 1249 | + if (!dev) |
---|
| 1250 | + return; |
---|
| 1251 | + |
---|
| 1252 | + err = sysfs_create_link(&phydev->mdio.dev.kobj, &dev->dev.kobj, |
---|
| 1253 | + "attached_dev"); |
---|
| 1254 | + if (err) |
---|
| 1255 | + return; |
---|
| 1256 | + |
---|
| 1257 | + err = sysfs_create_link_nowarn(&dev->dev.kobj, |
---|
| 1258 | + &phydev->mdio.dev.kobj, |
---|
| 1259 | + "phydev"); |
---|
| 1260 | + if (err) { |
---|
| 1261 | + dev_err(&dev->dev, "could not add device link to %s err %d\n", |
---|
| 1262 | + kobject_name(&phydev->mdio.dev.kobj), |
---|
| 1263 | + err); |
---|
| 1264 | + /* non-fatal - some net drivers can use one netdevice |
---|
| 1265 | + * with more then one phy |
---|
| 1266 | + */ |
---|
| 1267 | + } |
---|
| 1268 | + |
---|
| 1269 | + phydev->sysfs_links = true; |
---|
| 1270 | +} |
---|
| 1271 | + |
---|
| 1272 | +static ssize_t |
---|
| 1273 | +phy_standalone_show(struct device *dev, struct device_attribute *attr, |
---|
| 1274 | + char *buf) |
---|
| 1275 | +{ |
---|
| 1276 | + struct phy_device *phydev = to_phy_device(dev); |
---|
| 1277 | + |
---|
| 1278 | + return sprintf(buf, "%d\n", !phydev->attached_dev); |
---|
| 1279 | +} |
---|
| 1280 | +static DEVICE_ATTR_RO(phy_standalone); |
---|
| 1281 | + |
---|
| 1282 | +/** |
---|
| 1283 | + * phy_sfp_attach - attach the SFP bus to the PHY upstream network device |
---|
| 1284 | + * @upstream: pointer to the phy device |
---|
| 1285 | + * @bus: sfp bus representing cage being attached |
---|
| 1286 | + * |
---|
| 1287 | + * This is used to fill in the sfp_upstream_ops .attach member. |
---|
| 1288 | + */ |
---|
| 1289 | +void phy_sfp_attach(void *upstream, struct sfp_bus *bus) |
---|
| 1290 | +{ |
---|
| 1291 | + struct phy_device *phydev = upstream; |
---|
| 1292 | + |
---|
| 1293 | + if (phydev->attached_dev) |
---|
| 1294 | + phydev->attached_dev->sfp_bus = bus; |
---|
| 1295 | + phydev->sfp_bus_attached = true; |
---|
| 1296 | +} |
---|
| 1297 | +EXPORT_SYMBOL(phy_sfp_attach); |
---|
| 1298 | + |
---|
| 1299 | +/** |
---|
| 1300 | + * phy_sfp_detach - detach the SFP bus from the PHY upstream network device |
---|
| 1301 | + * @upstream: pointer to the phy device |
---|
| 1302 | + * @bus: sfp bus representing cage being attached |
---|
| 1303 | + * |
---|
| 1304 | + * This is used to fill in the sfp_upstream_ops .detach member. |
---|
| 1305 | + */ |
---|
| 1306 | +void phy_sfp_detach(void *upstream, struct sfp_bus *bus) |
---|
| 1307 | +{ |
---|
| 1308 | + struct phy_device *phydev = upstream; |
---|
| 1309 | + |
---|
| 1310 | + if (phydev->attached_dev) |
---|
| 1311 | + phydev->attached_dev->sfp_bus = NULL; |
---|
| 1312 | + phydev->sfp_bus_attached = false; |
---|
| 1313 | +} |
---|
| 1314 | +EXPORT_SYMBOL(phy_sfp_detach); |
---|
| 1315 | + |
---|
| 1316 | +/** |
---|
| 1317 | + * phy_sfp_probe - probe for a SFP cage attached to this PHY device |
---|
| 1318 | + * @phydev: Pointer to phy_device |
---|
| 1319 | + * @ops: SFP's upstream operations |
---|
| 1320 | + */ |
---|
| 1321 | +int phy_sfp_probe(struct phy_device *phydev, |
---|
| 1322 | + const struct sfp_upstream_ops *ops) |
---|
| 1323 | +{ |
---|
| 1324 | + struct sfp_bus *bus; |
---|
| 1325 | + int ret = 0; |
---|
| 1326 | + |
---|
| 1327 | + if (phydev->mdio.dev.fwnode) { |
---|
| 1328 | + bus = sfp_bus_find_fwnode(phydev->mdio.dev.fwnode); |
---|
| 1329 | + if (IS_ERR(bus)) |
---|
| 1330 | + return PTR_ERR(bus); |
---|
| 1331 | + |
---|
| 1332 | + phydev->sfp_bus = bus; |
---|
| 1333 | + |
---|
| 1334 | + ret = sfp_bus_add_upstream(bus, phydev, ops); |
---|
| 1335 | + sfp_bus_put(bus); |
---|
| 1336 | + } |
---|
| 1337 | + return ret; |
---|
| 1338 | +} |
---|
| 1339 | +EXPORT_SYMBOL(phy_sfp_probe); |
---|
1021 | 1340 | |
---|
1022 | 1341 | /** |
---|
1023 | 1342 | * phy_attach_direct - attach a network device to a given PHY device pointer |
---|
.. | .. |
---|
1037 | 1356 | int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, |
---|
1038 | 1357 | u32 flags, phy_interface_t interface) |
---|
1039 | 1358 | { |
---|
1040 | | - struct module *ndev_owner = dev->dev.parent->driver->owner; |
---|
1041 | 1359 | struct mii_bus *bus = phydev->mdio.bus; |
---|
1042 | 1360 | struct device *d = &phydev->mdio.dev; |
---|
| 1361 | + struct module *ndev_owner = NULL; |
---|
1043 | 1362 | bool using_genphy = false; |
---|
1044 | 1363 | int err; |
---|
1045 | 1364 | |
---|
.. | .. |
---|
1048 | 1367 | * our own module->refcnt here, otherwise we would not be able to |
---|
1049 | 1368 | * unload later on. |
---|
1050 | 1369 | */ |
---|
| 1370 | + if (dev) |
---|
| 1371 | + ndev_owner = dev->dev.parent->driver->owner; |
---|
1051 | 1372 | if (ndev_owner != bus->owner && !try_module_get(bus->owner)) { |
---|
1052 | | - dev_err(&dev->dev, "failed to get the bus module\n"); |
---|
| 1373 | + phydev_err(phydev, "failed to get the bus module\n"); |
---|
1053 | 1374 | return -EIO; |
---|
1054 | 1375 | } |
---|
1055 | 1376 | |
---|
.. | .. |
---|
1060 | 1381 | */ |
---|
1061 | 1382 | if (!d->driver) { |
---|
1062 | 1383 | if (phydev->is_c45) |
---|
1063 | | - d->driver = &genphy_10g_driver.mdiodrv.driver; |
---|
| 1384 | + d->driver = &genphy_c45_driver.mdiodrv.driver; |
---|
1064 | 1385 | else |
---|
1065 | 1386 | d->driver = &genphy_driver.mdiodrv.driver; |
---|
1066 | 1387 | |
---|
.. | .. |
---|
1068 | 1389 | } |
---|
1069 | 1390 | |
---|
1070 | 1391 | if (!try_module_get(d->driver->owner)) { |
---|
1071 | | - dev_err(&dev->dev, "failed to get the device driver module\n"); |
---|
| 1392 | + phydev_err(phydev, "failed to get the device driver module\n"); |
---|
1072 | 1393 | err = -EIO; |
---|
1073 | 1394 | goto error_put_device; |
---|
1074 | 1395 | } |
---|
.. | .. |
---|
1089 | 1410 | } |
---|
1090 | 1411 | |
---|
1091 | 1412 | phydev->phy_link_change = phy_link_change; |
---|
1092 | | - phydev->attached_dev = dev; |
---|
1093 | | - dev->phydev = phydev; |
---|
| 1413 | + if (dev) { |
---|
| 1414 | + phydev->attached_dev = dev; |
---|
| 1415 | + dev->phydev = phydev; |
---|
| 1416 | + |
---|
| 1417 | + if (phydev->sfp_bus_attached) |
---|
| 1418 | + dev->sfp_bus = phydev->sfp_bus; |
---|
| 1419 | + } |
---|
1094 | 1420 | |
---|
1095 | 1421 | /* Some Ethernet drivers try to connect to a PHY device before |
---|
1096 | 1422 | * calling register_netdevice() -> netdev_register_kobject() and |
---|
.. | .. |
---|
1102 | 1428 | */ |
---|
1103 | 1429 | phydev->sysfs_links = false; |
---|
1104 | 1430 | |
---|
1105 | | - err = sysfs_create_link(&phydev->mdio.dev.kobj, &dev->dev.kobj, |
---|
1106 | | - "attached_dev"); |
---|
1107 | | - if (!err) { |
---|
1108 | | - err = sysfs_create_link_nowarn(&dev->dev.kobj, |
---|
1109 | | - &phydev->mdio.dev.kobj, |
---|
1110 | | - "phydev"); |
---|
1111 | | - if (err) { |
---|
1112 | | - dev_err(&dev->dev, "could not add device link to %s err %d\n", |
---|
1113 | | - kobject_name(&phydev->mdio.dev.kobj), |
---|
1114 | | - err); |
---|
1115 | | - /* non-fatal - some net drivers can use one netdevice |
---|
1116 | | - * with more then one phy |
---|
1117 | | - */ |
---|
1118 | | - } |
---|
| 1431 | + phy_sysfs_create_links(phydev); |
---|
1119 | 1432 | |
---|
1120 | | - phydev->sysfs_links = true; |
---|
| 1433 | + if (!phydev->attached_dev) { |
---|
| 1434 | + err = sysfs_create_file(&phydev->mdio.dev.kobj, |
---|
| 1435 | + &dev_attr_phy_standalone.attr); |
---|
| 1436 | + if (err) |
---|
| 1437 | + phydev_err(phydev, "error creating 'phy_standalone' sysfs entry\n"); |
---|
1121 | 1438 | } |
---|
1122 | 1439 | |
---|
1123 | | - phydev->dev_flags = flags; |
---|
| 1440 | + phydev->dev_flags |= flags; |
---|
1124 | 1441 | |
---|
1125 | 1442 | phydev->interface = interface; |
---|
1126 | 1443 | |
---|
1127 | 1444 | phydev->state = PHY_READY; |
---|
1128 | 1445 | |
---|
| 1446 | + /* Port is set to PORT_TP by default and the actual PHY driver will set |
---|
| 1447 | + * it to different value depending on the PHY configuration. If we have |
---|
| 1448 | + * the generic PHY driver we can't figure it out, thus set the old |
---|
| 1449 | + * legacy PORT_MII value. |
---|
| 1450 | + */ |
---|
| 1451 | + if (using_genphy) |
---|
| 1452 | + phydev->port = PORT_MII; |
---|
| 1453 | + |
---|
1129 | 1454 | /* Initial carrier state is off as the phy is about to be |
---|
1130 | 1455 | * (re)initialized. |
---|
1131 | 1456 | */ |
---|
1132 | | - netif_carrier_off(phydev->attached_dev); |
---|
| 1457 | + if (dev) |
---|
| 1458 | + netif_carrier_off(phydev->attached_dev); |
---|
1133 | 1459 | |
---|
1134 | 1460 | /* Do initial configuration here, now that |
---|
1135 | 1461 | * we have certain key parameters |
---|
.. | .. |
---|
1138 | 1464 | err = phy_init_hw(phydev); |
---|
1139 | 1465 | if (err) |
---|
1140 | 1466 | goto error; |
---|
| 1467 | + |
---|
| 1468 | + err = phy_disable_interrupts(phydev); |
---|
| 1469 | + if (err) |
---|
| 1470 | + return err; |
---|
1141 | 1471 | |
---|
1142 | 1472 | phy_resume(phydev); |
---|
1143 | 1473 | phy_led_triggers_register(phydev); |
---|
.. | .. |
---|
1151 | 1481 | |
---|
1152 | 1482 | error_module_put: |
---|
1153 | 1483 | module_put(d->driver->owner); |
---|
| 1484 | + d->driver = NULL; |
---|
1154 | 1485 | error_put_device: |
---|
1155 | 1486 | put_device(d); |
---|
1156 | 1487 | if (ndev_owner != bus->owner) |
---|
.. | .. |
---|
1198 | 1529 | } |
---|
1199 | 1530 | EXPORT_SYMBOL(phy_attach); |
---|
1200 | 1531 | |
---|
| 1532 | +static bool phy_driver_is_genphy_kind(struct phy_device *phydev, |
---|
| 1533 | + struct device_driver *driver) |
---|
| 1534 | +{ |
---|
| 1535 | + struct device *d = &phydev->mdio.dev; |
---|
| 1536 | + bool ret = false; |
---|
| 1537 | + |
---|
| 1538 | + if (!phydev->drv) |
---|
| 1539 | + return ret; |
---|
| 1540 | + |
---|
| 1541 | + get_device(d); |
---|
| 1542 | + ret = d->driver == driver; |
---|
| 1543 | + put_device(d); |
---|
| 1544 | + |
---|
| 1545 | + return ret; |
---|
| 1546 | +} |
---|
| 1547 | + |
---|
| 1548 | +bool phy_driver_is_genphy(struct phy_device *phydev) |
---|
| 1549 | +{ |
---|
| 1550 | + return phy_driver_is_genphy_kind(phydev, |
---|
| 1551 | + &genphy_driver.mdiodrv.driver); |
---|
| 1552 | +} |
---|
| 1553 | +EXPORT_SYMBOL_GPL(phy_driver_is_genphy); |
---|
| 1554 | + |
---|
| 1555 | +bool phy_driver_is_genphy_10g(struct phy_device *phydev) |
---|
| 1556 | +{ |
---|
| 1557 | + return phy_driver_is_genphy_kind(phydev, |
---|
| 1558 | + &genphy_c45_driver.mdiodrv.driver); |
---|
| 1559 | +} |
---|
| 1560 | +EXPORT_SYMBOL_GPL(phy_driver_is_genphy_10g); |
---|
| 1561 | + |
---|
| 1562 | +/** |
---|
| 1563 | + * phy_package_join - join a common PHY group |
---|
| 1564 | + * @phydev: target phy_device struct |
---|
| 1565 | + * @addr: cookie and PHY address for global register access |
---|
| 1566 | + * @priv_size: if non-zero allocate this amount of bytes for private data |
---|
| 1567 | + * |
---|
| 1568 | + * This joins a PHY group and provides a shared storage for all phydevs in |
---|
| 1569 | + * this group. This is intended to be used for packages which contain |
---|
| 1570 | + * more than one PHY, for example a quad PHY transceiver. |
---|
| 1571 | + * |
---|
| 1572 | + * The addr parameter serves as a cookie which has to have the same value |
---|
| 1573 | + * for all members of one group and as a PHY address to access generic |
---|
| 1574 | + * registers of a PHY package. Usually, one of the PHY addresses of the |
---|
| 1575 | + * different PHYs in the package provides access to these global registers. |
---|
| 1576 | + * The address which is given here, will be used in the phy_package_read() |
---|
| 1577 | + * and phy_package_write() convenience functions. If your PHY doesn't have |
---|
| 1578 | + * global registers you can just pick any of the PHY addresses. |
---|
| 1579 | + * |
---|
| 1580 | + * This will set the shared pointer of the phydev to the shared storage. |
---|
| 1581 | + * If this is the first call for a this cookie the shared storage will be |
---|
| 1582 | + * allocated. If priv_size is non-zero, the given amount of bytes are |
---|
| 1583 | + * allocated for the priv member. |
---|
| 1584 | + * |
---|
| 1585 | + * Returns < 1 on error, 0 on success. Esp. calling phy_package_join() |
---|
| 1586 | + * with the same cookie but a different priv_size is an error. |
---|
| 1587 | + */ |
---|
| 1588 | +int phy_package_join(struct phy_device *phydev, int addr, size_t priv_size) |
---|
| 1589 | +{ |
---|
| 1590 | + struct mii_bus *bus = phydev->mdio.bus; |
---|
| 1591 | + struct phy_package_shared *shared; |
---|
| 1592 | + int ret; |
---|
| 1593 | + |
---|
| 1594 | + if (addr < 0 || addr >= PHY_MAX_ADDR) |
---|
| 1595 | + return -EINVAL; |
---|
| 1596 | + |
---|
| 1597 | + mutex_lock(&bus->shared_lock); |
---|
| 1598 | + shared = bus->shared[addr]; |
---|
| 1599 | + if (!shared) { |
---|
| 1600 | + ret = -ENOMEM; |
---|
| 1601 | + shared = kzalloc(sizeof(*shared), GFP_KERNEL); |
---|
| 1602 | + if (!shared) |
---|
| 1603 | + goto err_unlock; |
---|
| 1604 | + if (priv_size) { |
---|
| 1605 | + shared->priv = kzalloc(priv_size, GFP_KERNEL); |
---|
| 1606 | + if (!shared->priv) |
---|
| 1607 | + goto err_free; |
---|
| 1608 | + shared->priv_size = priv_size; |
---|
| 1609 | + } |
---|
| 1610 | + shared->addr = addr; |
---|
| 1611 | + refcount_set(&shared->refcnt, 1); |
---|
| 1612 | + bus->shared[addr] = shared; |
---|
| 1613 | + } else { |
---|
| 1614 | + ret = -EINVAL; |
---|
| 1615 | + if (priv_size && priv_size != shared->priv_size) |
---|
| 1616 | + goto err_unlock; |
---|
| 1617 | + refcount_inc(&shared->refcnt); |
---|
| 1618 | + } |
---|
| 1619 | + mutex_unlock(&bus->shared_lock); |
---|
| 1620 | + |
---|
| 1621 | + phydev->shared = shared; |
---|
| 1622 | + |
---|
| 1623 | + return 0; |
---|
| 1624 | + |
---|
| 1625 | +err_free: |
---|
| 1626 | + kfree(shared); |
---|
| 1627 | +err_unlock: |
---|
| 1628 | + mutex_unlock(&bus->shared_lock); |
---|
| 1629 | + return ret; |
---|
| 1630 | +} |
---|
| 1631 | +EXPORT_SYMBOL_GPL(phy_package_join); |
---|
| 1632 | + |
---|
| 1633 | +/** |
---|
| 1634 | + * phy_package_leave - leave a common PHY group |
---|
| 1635 | + * @phydev: target phy_device struct |
---|
| 1636 | + * |
---|
| 1637 | + * This leaves a PHY group created by phy_package_join(). If this phydev |
---|
| 1638 | + * was the last user of the shared data between the group, this data is |
---|
| 1639 | + * freed. Resets the phydev->shared pointer to NULL. |
---|
| 1640 | + */ |
---|
| 1641 | +void phy_package_leave(struct phy_device *phydev) |
---|
| 1642 | +{ |
---|
| 1643 | + struct phy_package_shared *shared = phydev->shared; |
---|
| 1644 | + struct mii_bus *bus = phydev->mdio.bus; |
---|
| 1645 | + |
---|
| 1646 | + if (!shared) |
---|
| 1647 | + return; |
---|
| 1648 | + |
---|
| 1649 | + if (refcount_dec_and_mutex_lock(&shared->refcnt, &bus->shared_lock)) { |
---|
| 1650 | + bus->shared[shared->addr] = NULL; |
---|
| 1651 | + mutex_unlock(&bus->shared_lock); |
---|
| 1652 | + kfree(shared->priv); |
---|
| 1653 | + kfree(shared); |
---|
| 1654 | + } |
---|
| 1655 | + |
---|
| 1656 | + phydev->shared = NULL; |
---|
| 1657 | +} |
---|
| 1658 | +EXPORT_SYMBOL_GPL(phy_package_leave); |
---|
| 1659 | + |
---|
| 1660 | +static void devm_phy_package_leave(struct device *dev, void *res) |
---|
| 1661 | +{ |
---|
| 1662 | + phy_package_leave(*(struct phy_device **)res); |
---|
| 1663 | +} |
---|
| 1664 | + |
---|
| 1665 | +/** |
---|
| 1666 | + * devm_phy_package_join - resource managed phy_package_join() |
---|
| 1667 | + * @dev: device that is registering this PHY package |
---|
| 1668 | + * @phydev: target phy_device struct |
---|
| 1669 | + * @addr: cookie and PHY address for global register access |
---|
| 1670 | + * @priv_size: if non-zero allocate this amount of bytes for private data |
---|
| 1671 | + * |
---|
| 1672 | + * Managed phy_package_join(). Shared storage fetched by this function, |
---|
| 1673 | + * phy_package_leave() is automatically called on driver detach. See |
---|
| 1674 | + * phy_package_join() for more information. |
---|
| 1675 | + */ |
---|
| 1676 | +int devm_phy_package_join(struct device *dev, struct phy_device *phydev, |
---|
| 1677 | + int addr, size_t priv_size) |
---|
| 1678 | +{ |
---|
| 1679 | + struct phy_device **ptr; |
---|
| 1680 | + int ret; |
---|
| 1681 | + |
---|
| 1682 | + ptr = devres_alloc(devm_phy_package_leave, sizeof(*ptr), |
---|
| 1683 | + GFP_KERNEL); |
---|
| 1684 | + if (!ptr) |
---|
| 1685 | + return -ENOMEM; |
---|
| 1686 | + |
---|
| 1687 | + ret = phy_package_join(phydev, addr, priv_size); |
---|
| 1688 | + |
---|
| 1689 | + if (!ret) { |
---|
| 1690 | + *ptr = phydev; |
---|
| 1691 | + devres_add(dev, ptr); |
---|
| 1692 | + } else { |
---|
| 1693 | + devres_free(ptr); |
---|
| 1694 | + } |
---|
| 1695 | + |
---|
| 1696 | + return ret; |
---|
| 1697 | +} |
---|
| 1698 | +EXPORT_SYMBOL_GPL(devm_phy_package_join); |
---|
| 1699 | + |
---|
1201 | 1700 | /** |
---|
1202 | 1701 | * phy_detach - detach a PHY device from its network device |
---|
1203 | 1702 | * @phydev: target phy_device struct |
---|
.. | .. |
---|
1208 | 1707 | void phy_detach(struct phy_device *phydev) |
---|
1209 | 1708 | { |
---|
1210 | 1709 | struct net_device *dev = phydev->attached_dev; |
---|
1211 | | - struct module *ndev_owner = dev->dev.parent->driver->owner; |
---|
| 1710 | + struct module *ndev_owner = NULL; |
---|
1212 | 1711 | struct mii_bus *bus; |
---|
1213 | 1712 | |
---|
1214 | 1713 | if (phydev->sysfs_links) { |
---|
1215 | | - sysfs_remove_link(&dev->dev.kobj, "phydev"); |
---|
| 1714 | + if (dev) |
---|
| 1715 | + sysfs_remove_link(&dev->dev.kobj, "phydev"); |
---|
1216 | 1716 | sysfs_remove_link(&phydev->mdio.dev.kobj, "attached_dev"); |
---|
1217 | 1717 | } |
---|
| 1718 | + |
---|
| 1719 | + if (!phydev->attached_dev) |
---|
| 1720 | + sysfs_remove_file(&phydev->mdio.dev.kobj, |
---|
| 1721 | + &dev_attr_phy_standalone.attr); |
---|
| 1722 | + |
---|
1218 | 1723 | phy_suspend(phydev); |
---|
1219 | | - phydev->attached_dev->phydev = NULL; |
---|
1220 | | - phydev->attached_dev = NULL; |
---|
| 1724 | + if (dev) { |
---|
| 1725 | + phydev->attached_dev->phydev = NULL; |
---|
| 1726 | + phydev->attached_dev = NULL; |
---|
| 1727 | + } |
---|
1221 | 1728 | phydev->phylink = NULL; |
---|
1222 | 1729 | |
---|
1223 | 1730 | phy_led_triggers_unregister(phydev); |
---|
.. | .. |
---|
1230 | 1737 | * from the generic driver so that there's a chance a |
---|
1231 | 1738 | * real driver could be loaded |
---|
1232 | 1739 | */ |
---|
1233 | | - if (phydev->mdio.dev.driver == &genphy_10g_driver.mdiodrv.driver || |
---|
1234 | | - phydev->mdio.dev.driver == &genphy_driver.mdiodrv.driver) |
---|
| 1740 | + if (phy_driver_is_genphy(phydev) || |
---|
| 1741 | + phy_driver_is_genphy_10g(phydev)) |
---|
1235 | 1742 | device_release_driver(&phydev->mdio.dev); |
---|
1236 | 1743 | |
---|
1237 | 1744 | /* Assert the reset signal */ |
---|
.. | .. |
---|
1244 | 1751 | bus = phydev->mdio.bus; |
---|
1245 | 1752 | |
---|
1246 | 1753 | put_device(&phydev->mdio.dev); |
---|
| 1754 | + if (dev) |
---|
| 1755 | + ndev_owner = dev->dev.parent->driver->owner; |
---|
1247 | 1756 | if (ndev_owner != bus->owner) |
---|
1248 | 1757 | module_put(bus->owner); |
---|
1249 | 1758 | } |
---|
.. | .. |
---|
1251 | 1760 | |
---|
1252 | 1761 | int phy_suspend(struct phy_device *phydev) |
---|
1253 | 1762 | { |
---|
1254 | | - struct phy_driver *phydrv = to_phy_driver(phydev->mdio.dev.driver); |
---|
1255 | | - struct net_device *netdev = phydev->attached_dev; |
---|
1256 | 1763 | struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL }; |
---|
1257 | | - int ret = 0; |
---|
| 1764 | + struct net_device *netdev = phydev->attached_dev; |
---|
| 1765 | + struct phy_driver *phydrv = phydev->drv; |
---|
| 1766 | + int ret; |
---|
| 1767 | + |
---|
| 1768 | + if (phydev->suspended) |
---|
| 1769 | + return 0; |
---|
1258 | 1770 | |
---|
1259 | 1771 | /* If the device has WOL enabled, we cannot suspend the PHY */ |
---|
1260 | 1772 | phy_ethtool_get_wol(phydev, &wol); |
---|
1261 | 1773 | if (wol.wolopts || (netdev && netdev->wol_enabled)) |
---|
1262 | 1774 | return -EBUSY; |
---|
1263 | 1775 | |
---|
1264 | | - if (phydev->drv && phydrv->suspend) |
---|
1265 | | - ret = phydrv->suspend(phydev); |
---|
| 1776 | + if (!phydrv || !phydrv->suspend) |
---|
| 1777 | + return 0; |
---|
1266 | 1778 | |
---|
1267 | | - if (ret) |
---|
1268 | | - return ret; |
---|
1269 | | - |
---|
1270 | | - phydev->suspended = true; |
---|
| 1779 | + ret = phydrv->suspend(phydev); |
---|
| 1780 | + if (!ret) |
---|
| 1781 | + phydev->suspended = true; |
---|
1271 | 1782 | |
---|
1272 | 1783 | return ret; |
---|
1273 | 1784 | } |
---|
.. | .. |
---|
1275 | 1786 | |
---|
1276 | 1787 | int __phy_resume(struct phy_device *phydev) |
---|
1277 | 1788 | { |
---|
1278 | | - struct phy_driver *phydrv = to_phy_driver(phydev->mdio.dev.driver); |
---|
1279 | | - int ret = 0; |
---|
| 1789 | + struct phy_driver *phydrv = phydev->drv; |
---|
| 1790 | + int ret; |
---|
1280 | 1791 | |
---|
1281 | 1792 | WARN_ON(!mutex_is_locked(&phydev->lock)); |
---|
1282 | 1793 | |
---|
1283 | | - if (phydev->drv && phydrv->resume) |
---|
1284 | | - ret = phydrv->resume(phydev); |
---|
| 1794 | + if (!phydrv || !phydrv->resume) |
---|
| 1795 | + return 0; |
---|
1285 | 1796 | |
---|
1286 | | - if (ret) |
---|
1287 | | - return ret; |
---|
1288 | | - |
---|
1289 | | - phydev->suspended = false; |
---|
| 1797 | + ret = phydrv->resume(phydev); |
---|
| 1798 | + if (!ret) |
---|
| 1799 | + phydev->suspended = false; |
---|
1290 | 1800 | |
---|
1291 | 1801 | return ret; |
---|
1292 | 1802 | } |
---|
.. | .. |
---|
1374 | 1884 | */ |
---|
1375 | 1885 | static int genphy_config_advert(struct phy_device *phydev) |
---|
1376 | 1886 | { |
---|
1377 | | - u32 advertise; |
---|
1378 | | - int oldadv, adv, bmsr; |
---|
1379 | | - int err, changed = 0; |
---|
| 1887 | + int err, bmsr, changed = 0; |
---|
| 1888 | + u32 adv; |
---|
1380 | 1889 | |
---|
1381 | 1890 | /* Only allow advertising what this PHY supports */ |
---|
1382 | | - phydev->advertising &= phydev->supported; |
---|
1383 | | - advertise = phydev->advertising; |
---|
| 1891 | + linkmode_and(phydev->advertising, phydev->advertising, |
---|
| 1892 | + phydev->supported); |
---|
| 1893 | + |
---|
| 1894 | + adv = linkmode_adv_to_mii_adv_t(phydev->advertising); |
---|
1384 | 1895 | |
---|
1385 | 1896 | /* Setup standard advertisement */ |
---|
1386 | | - adv = phy_read(phydev, MII_ADVERTISE); |
---|
1387 | | - if (adv < 0) |
---|
1388 | | - return adv; |
---|
1389 | | - |
---|
1390 | | - oldadv = adv; |
---|
1391 | | - adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP | |
---|
1392 | | - ADVERTISE_PAUSE_ASYM); |
---|
1393 | | - adv |= ethtool_adv_to_mii_adv_t(advertise); |
---|
1394 | | - |
---|
1395 | | - if (adv != oldadv) { |
---|
1396 | | - err = phy_write(phydev, MII_ADVERTISE, adv); |
---|
1397 | | - |
---|
1398 | | - if (err < 0) |
---|
1399 | | - return err; |
---|
| 1897 | + err = phy_modify_changed(phydev, MII_ADVERTISE, |
---|
| 1898 | + ADVERTISE_ALL | ADVERTISE_100BASE4 | |
---|
| 1899 | + ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM, |
---|
| 1900 | + adv); |
---|
| 1901 | + if (err < 0) |
---|
| 1902 | + return err; |
---|
| 1903 | + if (err > 0) |
---|
1400 | 1904 | changed = 1; |
---|
1401 | | - } |
---|
1402 | 1905 | |
---|
1403 | 1906 | bmsr = phy_read(phydev, MII_BMSR); |
---|
1404 | 1907 | if (bmsr < 0) |
---|
.. | .. |
---|
1411 | 1914 | if (!(bmsr & BMSR_ESTATEN)) |
---|
1412 | 1915 | return changed; |
---|
1413 | 1916 | |
---|
1414 | | - /* Configure gigabit if it's supported */ |
---|
1415 | | - adv = phy_read(phydev, MII_CTRL1000); |
---|
1416 | | - if (adv < 0) |
---|
1417 | | - return adv; |
---|
| 1917 | + adv = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising); |
---|
1418 | 1918 | |
---|
1419 | | - oldadv = adv; |
---|
1420 | | - adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); |
---|
1421 | | - |
---|
1422 | | - if (phydev->supported & (SUPPORTED_1000baseT_Half | |
---|
1423 | | - SUPPORTED_1000baseT_Full)) { |
---|
1424 | | - adv |= ethtool_adv_to_mii_ctrl1000_t(advertise); |
---|
1425 | | - } |
---|
1426 | | - |
---|
1427 | | - if (adv != oldadv) |
---|
1428 | | - changed = 1; |
---|
1429 | | - |
---|
1430 | | - err = phy_write(phydev, MII_CTRL1000, adv); |
---|
| 1919 | + err = phy_modify_changed(phydev, MII_CTRL1000, |
---|
| 1920 | + ADVERTISE_1000FULL | ADVERTISE_1000HALF, |
---|
| 1921 | + adv); |
---|
1431 | 1922 | if (err < 0) |
---|
1432 | 1923 | return err; |
---|
| 1924 | + if (err > 0) |
---|
| 1925 | + changed = 1; |
---|
1433 | 1926 | |
---|
1434 | 1927 | return changed; |
---|
| 1928 | +} |
---|
| 1929 | + |
---|
| 1930 | +/** |
---|
| 1931 | + * genphy_c37_config_advert - sanitize and advertise auto-negotiation parameters |
---|
| 1932 | + * @phydev: target phy_device struct |
---|
| 1933 | + * |
---|
| 1934 | + * Description: Writes MII_ADVERTISE with the appropriate values, |
---|
| 1935 | + * after sanitizing the values to make sure we only advertise |
---|
| 1936 | + * what is supported. Returns < 0 on error, 0 if the PHY's advertisement |
---|
| 1937 | + * hasn't changed, and > 0 if it has changed. This function is intended |
---|
| 1938 | + * for Clause 37 1000Base-X mode. |
---|
| 1939 | + */ |
---|
| 1940 | +static int genphy_c37_config_advert(struct phy_device *phydev) |
---|
| 1941 | +{ |
---|
| 1942 | + u16 adv = 0; |
---|
| 1943 | + |
---|
| 1944 | + /* Only allow advertising what this PHY supports */ |
---|
| 1945 | + linkmode_and(phydev->advertising, phydev->advertising, |
---|
| 1946 | + phydev->supported); |
---|
| 1947 | + |
---|
| 1948 | + if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, |
---|
| 1949 | + phydev->advertising)) |
---|
| 1950 | + adv |= ADVERTISE_1000XFULL; |
---|
| 1951 | + if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, |
---|
| 1952 | + phydev->advertising)) |
---|
| 1953 | + adv |= ADVERTISE_1000XPAUSE; |
---|
| 1954 | + if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, |
---|
| 1955 | + phydev->advertising)) |
---|
| 1956 | + adv |= ADVERTISE_1000XPSE_ASYM; |
---|
| 1957 | + |
---|
| 1958 | + return phy_modify_changed(phydev, MII_ADVERTISE, |
---|
| 1959 | + ADVERTISE_1000XFULL | ADVERTISE_1000XPAUSE | |
---|
| 1960 | + ADVERTISE_1000XHALF | ADVERTISE_1000XPSE_ASYM, |
---|
| 1961 | + adv); |
---|
1435 | 1962 | } |
---|
1436 | 1963 | |
---|
1437 | 1964 | /** |
---|
.. | .. |
---|
1442 | 1969 | * efficent ethernet modes. Returns 0 if the PHY's advertisement hasn't |
---|
1443 | 1970 | * changed, and 1 if it has changed. |
---|
1444 | 1971 | */ |
---|
1445 | | -static int genphy_config_eee_advert(struct phy_device *phydev) |
---|
| 1972 | +int genphy_config_eee_advert(struct phy_device *phydev) |
---|
1446 | 1973 | { |
---|
1447 | | - int broken = phydev->eee_broken_modes; |
---|
1448 | | - int old_adv, adv; |
---|
| 1974 | + int err; |
---|
1449 | 1975 | |
---|
1450 | 1976 | /* Nothing to disable */ |
---|
1451 | | - if (!broken) |
---|
| 1977 | + if (!phydev->eee_broken_modes) |
---|
1452 | 1978 | return 0; |
---|
1453 | 1979 | |
---|
1454 | | - /* If the following call fails, we assume that EEE is not |
---|
1455 | | - * supported by the phy. If we read 0, EEE is not advertised |
---|
1456 | | - * In both case, we don't need to continue |
---|
1457 | | - */ |
---|
1458 | | - adv = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV); |
---|
1459 | | - if (adv <= 0) |
---|
1460 | | - return 0; |
---|
1461 | | - |
---|
1462 | | - old_adv = adv; |
---|
1463 | | - adv &= ~broken; |
---|
1464 | | - |
---|
1465 | | - /* Advertising remains unchanged with the broken mask */ |
---|
1466 | | - if (old_adv == adv) |
---|
1467 | | - return 0; |
---|
1468 | | - |
---|
1469 | | - phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, adv); |
---|
1470 | | - |
---|
1471 | | - return 1; |
---|
| 1980 | + err = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, |
---|
| 1981 | + phydev->eee_broken_modes, 0); |
---|
| 1982 | + /* If the call failed, we assume that EEE is not supported */ |
---|
| 1983 | + return err < 0 ? 0 : err; |
---|
1472 | 1984 | } |
---|
| 1985 | +EXPORT_SYMBOL(genphy_config_eee_advert); |
---|
1473 | 1986 | |
---|
1474 | 1987 | /** |
---|
1475 | 1988 | * genphy_setup_forced - configures/forces speed/duplex from @phydev |
---|
.. | .. |
---|
1499 | 2012 | } |
---|
1500 | 2013 | EXPORT_SYMBOL(genphy_setup_forced); |
---|
1501 | 2014 | |
---|
| 2015 | +static int genphy_setup_master_slave(struct phy_device *phydev) |
---|
| 2016 | +{ |
---|
| 2017 | + u16 ctl = 0; |
---|
| 2018 | + |
---|
| 2019 | + if (!phydev->is_gigabit_capable) |
---|
| 2020 | + return 0; |
---|
| 2021 | + |
---|
| 2022 | + switch (phydev->master_slave_set) { |
---|
| 2023 | + case MASTER_SLAVE_CFG_MASTER_PREFERRED: |
---|
| 2024 | + ctl |= CTL1000_PREFER_MASTER; |
---|
| 2025 | + break; |
---|
| 2026 | + case MASTER_SLAVE_CFG_SLAVE_PREFERRED: |
---|
| 2027 | + break; |
---|
| 2028 | + case MASTER_SLAVE_CFG_MASTER_FORCE: |
---|
| 2029 | + ctl |= CTL1000_AS_MASTER; |
---|
| 2030 | + fallthrough; |
---|
| 2031 | + case MASTER_SLAVE_CFG_SLAVE_FORCE: |
---|
| 2032 | + ctl |= CTL1000_ENABLE_MASTER; |
---|
| 2033 | + break; |
---|
| 2034 | + case MASTER_SLAVE_CFG_UNKNOWN: |
---|
| 2035 | + case MASTER_SLAVE_CFG_UNSUPPORTED: |
---|
| 2036 | + return 0; |
---|
| 2037 | + default: |
---|
| 2038 | + phydev_warn(phydev, "Unsupported Master/Slave mode\n"); |
---|
| 2039 | + return -EOPNOTSUPP; |
---|
| 2040 | + } |
---|
| 2041 | + |
---|
| 2042 | + return phy_modify_changed(phydev, MII_CTRL1000, |
---|
| 2043 | + (CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER | |
---|
| 2044 | + CTL1000_PREFER_MASTER), ctl); |
---|
| 2045 | +} |
---|
| 2046 | + |
---|
| 2047 | +static int genphy_read_master_slave(struct phy_device *phydev) |
---|
| 2048 | +{ |
---|
| 2049 | + int cfg, state; |
---|
| 2050 | + int val; |
---|
| 2051 | + |
---|
| 2052 | + if (!phydev->is_gigabit_capable) { |
---|
| 2053 | + phydev->master_slave_get = MASTER_SLAVE_CFG_UNSUPPORTED; |
---|
| 2054 | + phydev->master_slave_state = MASTER_SLAVE_STATE_UNSUPPORTED; |
---|
| 2055 | + return 0; |
---|
| 2056 | + } |
---|
| 2057 | + |
---|
| 2058 | + phydev->master_slave_get = MASTER_SLAVE_CFG_UNKNOWN; |
---|
| 2059 | + phydev->master_slave_state = MASTER_SLAVE_STATE_UNKNOWN; |
---|
| 2060 | + |
---|
| 2061 | + val = phy_read(phydev, MII_CTRL1000); |
---|
| 2062 | + if (val < 0) |
---|
| 2063 | + return val; |
---|
| 2064 | + |
---|
| 2065 | + if (val & CTL1000_ENABLE_MASTER) { |
---|
| 2066 | + if (val & CTL1000_AS_MASTER) |
---|
| 2067 | + cfg = MASTER_SLAVE_CFG_MASTER_FORCE; |
---|
| 2068 | + else |
---|
| 2069 | + cfg = MASTER_SLAVE_CFG_SLAVE_FORCE; |
---|
| 2070 | + } else { |
---|
| 2071 | + if (val & CTL1000_PREFER_MASTER) |
---|
| 2072 | + cfg = MASTER_SLAVE_CFG_MASTER_PREFERRED; |
---|
| 2073 | + else |
---|
| 2074 | + cfg = MASTER_SLAVE_CFG_SLAVE_PREFERRED; |
---|
| 2075 | + } |
---|
| 2076 | + |
---|
| 2077 | + val = phy_read(phydev, MII_STAT1000); |
---|
| 2078 | + if (val < 0) |
---|
| 2079 | + return val; |
---|
| 2080 | + |
---|
| 2081 | + if (val & LPA_1000MSFAIL) { |
---|
| 2082 | + state = MASTER_SLAVE_STATE_ERR; |
---|
| 2083 | + } else if (phydev->link) { |
---|
| 2084 | + /* this bits are valid only for active link */ |
---|
| 2085 | + if (val & LPA_1000MSRES) |
---|
| 2086 | + state = MASTER_SLAVE_STATE_MASTER; |
---|
| 2087 | + else |
---|
| 2088 | + state = MASTER_SLAVE_STATE_SLAVE; |
---|
| 2089 | + } else { |
---|
| 2090 | + state = MASTER_SLAVE_STATE_UNKNOWN; |
---|
| 2091 | + } |
---|
| 2092 | + |
---|
| 2093 | + phydev->master_slave_get = cfg; |
---|
| 2094 | + phydev->master_slave_state = state; |
---|
| 2095 | + |
---|
| 2096 | + return 0; |
---|
| 2097 | +} |
---|
| 2098 | + |
---|
1502 | 2099 | /** |
---|
1503 | 2100 | * genphy_restart_aneg - Enable and Restart Autonegotiation |
---|
1504 | 2101 | * @phydev: target phy_device struct |
---|
.. | .. |
---|
1512 | 2109 | EXPORT_SYMBOL(genphy_restart_aneg); |
---|
1513 | 2110 | |
---|
1514 | 2111 | /** |
---|
1515 | | - * genphy_config_aneg - restart auto-negotiation or write BMCR |
---|
| 2112 | + * genphy_check_and_restart_aneg - Enable and restart auto-negotiation |
---|
1516 | 2113 | * @phydev: target phy_device struct |
---|
| 2114 | + * @restart: whether aneg restart is requested |
---|
| 2115 | + * |
---|
| 2116 | + * Check, and restart auto-negotiation if needed. |
---|
| 2117 | + */ |
---|
| 2118 | +int genphy_check_and_restart_aneg(struct phy_device *phydev, bool restart) |
---|
| 2119 | +{ |
---|
| 2120 | + int ret; |
---|
| 2121 | + |
---|
| 2122 | + if (!restart) { |
---|
| 2123 | + /* Advertisement hasn't changed, but maybe aneg was never on to |
---|
| 2124 | + * begin with? Or maybe phy was isolated? |
---|
| 2125 | + */ |
---|
| 2126 | + ret = phy_read(phydev, MII_BMCR); |
---|
| 2127 | + if (ret < 0) |
---|
| 2128 | + return ret; |
---|
| 2129 | + |
---|
| 2130 | + if (!(ret & BMCR_ANENABLE) || (ret & BMCR_ISOLATE)) |
---|
| 2131 | + restart = true; |
---|
| 2132 | + } |
---|
| 2133 | + |
---|
| 2134 | + if (restart) |
---|
| 2135 | + return genphy_restart_aneg(phydev); |
---|
| 2136 | + |
---|
| 2137 | + return 0; |
---|
| 2138 | +} |
---|
| 2139 | +EXPORT_SYMBOL(genphy_check_and_restart_aneg); |
---|
| 2140 | + |
---|
| 2141 | +/** |
---|
| 2142 | + * __genphy_config_aneg - restart auto-negotiation or write BMCR |
---|
| 2143 | + * @phydev: target phy_device struct |
---|
| 2144 | + * @changed: whether autoneg is requested |
---|
1517 | 2145 | * |
---|
1518 | 2146 | * Description: If auto-negotiation is enabled, we configure the |
---|
1519 | 2147 | * advertising, and then restart auto-negotiation. If it is not |
---|
1520 | 2148 | * enabled, then we write the BMCR. |
---|
1521 | 2149 | */ |
---|
1522 | | -int genphy_config_aneg(struct phy_device *phydev) |
---|
| 2150 | +int __genphy_config_aneg(struct phy_device *phydev, bool changed) |
---|
1523 | 2151 | { |
---|
1524 | | - int err, changed; |
---|
| 2152 | + int err; |
---|
1525 | 2153 | |
---|
1526 | | - changed = genphy_config_eee_advert(phydev); |
---|
| 2154 | + if (genphy_config_eee_advert(phydev)) |
---|
| 2155 | + changed = true; |
---|
| 2156 | + |
---|
| 2157 | + err = genphy_setup_master_slave(phydev); |
---|
| 2158 | + if (err < 0) |
---|
| 2159 | + return err; |
---|
| 2160 | + else if (err) |
---|
| 2161 | + changed = true; |
---|
1527 | 2162 | |
---|
1528 | 2163 | if (AUTONEG_ENABLE != phydev->autoneg) |
---|
1529 | 2164 | return genphy_setup_forced(phydev); |
---|
.. | .. |
---|
1531 | 2166 | err = genphy_config_advert(phydev); |
---|
1532 | 2167 | if (err < 0) /* error */ |
---|
1533 | 2168 | return err; |
---|
| 2169 | + else if (err) |
---|
| 2170 | + changed = true; |
---|
1534 | 2171 | |
---|
1535 | | - changed |= err; |
---|
| 2172 | + return genphy_check_and_restart_aneg(phydev, changed); |
---|
| 2173 | +} |
---|
| 2174 | +EXPORT_SYMBOL(__genphy_config_aneg); |
---|
1536 | 2175 | |
---|
1537 | | - if (changed == 0) { |
---|
| 2176 | +/** |
---|
| 2177 | + * genphy_c37_config_aneg - restart auto-negotiation or write BMCR |
---|
| 2178 | + * @phydev: target phy_device struct |
---|
| 2179 | + * |
---|
| 2180 | + * Description: If auto-negotiation is enabled, we configure the |
---|
| 2181 | + * advertising, and then restart auto-negotiation. If it is not |
---|
| 2182 | + * enabled, then we write the BMCR. This function is intended |
---|
| 2183 | + * for use with Clause 37 1000Base-X mode. |
---|
| 2184 | + */ |
---|
| 2185 | +int genphy_c37_config_aneg(struct phy_device *phydev) |
---|
| 2186 | +{ |
---|
| 2187 | + int err, changed; |
---|
| 2188 | + |
---|
| 2189 | + if (phydev->autoneg != AUTONEG_ENABLE) |
---|
| 2190 | + return genphy_setup_forced(phydev); |
---|
| 2191 | + |
---|
| 2192 | + err = phy_modify(phydev, MII_BMCR, BMCR_SPEED1000 | BMCR_SPEED100, |
---|
| 2193 | + BMCR_SPEED1000); |
---|
| 2194 | + if (err) |
---|
| 2195 | + return err; |
---|
| 2196 | + |
---|
| 2197 | + changed = genphy_c37_config_advert(phydev); |
---|
| 2198 | + if (changed < 0) /* error */ |
---|
| 2199 | + return changed; |
---|
| 2200 | + |
---|
| 2201 | + if (!changed) { |
---|
1538 | 2202 | /* Advertisement hasn't changed, but maybe aneg was never on to |
---|
1539 | 2203 | * begin with? Or maybe phy was isolated? |
---|
1540 | 2204 | */ |
---|
.. | .. |
---|
1555 | 2219 | |
---|
1556 | 2220 | return 0; |
---|
1557 | 2221 | } |
---|
1558 | | -EXPORT_SYMBOL(genphy_config_aneg); |
---|
| 2222 | +EXPORT_SYMBOL(genphy_c37_config_aneg); |
---|
1559 | 2223 | |
---|
1560 | 2224 | /** |
---|
1561 | 2225 | * genphy_aneg_done - return auto-negotiation status |
---|
.. | .. |
---|
1583 | 2247 | */ |
---|
1584 | 2248 | int genphy_update_link(struct phy_device *phydev) |
---|
1585 | 2249 | { |
---|
1586 | | - int status; |
---|
| 2250 | + int status = 0, bmcr; |
---|
| 2251 | + |
---|
| 2252 | + bmcr = phy_read(phydev, MII_BMCR); |
---|
| 2253 | + if (bmcr < 0) |
---|
| 2254 | + return bmcr; |
---|
| 2255 | + |
---|
| 2256 | + /* Autoneg is being started, therefore disregard BMSR value and |
---|
| 2257 | + * report link as down. |
---|
| 2258 | + */ |
---|
| 2259 | + if (bmcr & BMCR_ANRESTART) |
---|
| 2260 | + goto done; |
---|
1587 | 2261 | |
---|
1588 | 2262 | /* The link state is latched low so that momentary link |
---|
1589 | 2263 | * drops can be detected. Do not double-read the status |
---|
1590 | | - * in polling mode to detect such short link drops. |
---|
| 2264 | + * in polling mode to detect such short link drops except |
---|
| 2265 | + * the link was already down. |
---|
1591 | 2266 | */ |
---|
1592 | | - if (!phy_polling_mode(phydev)) { |
---|
| 2267 | + if (!phy_polling_mode(phydev) || !phydev->link) { |
---|
1593 | 2268 | status = phy_read(phydev, MII_BMSR); |
---|
1594 | 2269 | if (status < 0) |
---|
1595 | 2270 | return status; |
---|
| 2271 | + else if (status & BMSR_LSTATUS) |
---|
| 2272 | + goto done; |
---|
1596 | 2273 | } |
---|
1597 | 2274 | |
---|
1598 | 2275 | /* Read link and autonegotiation status */ |
---|
1599 | 2276 | status = phy_read(phydev, MII_BMSR); |
---|
1600 | 2277 | if (status < 0) |
---|
1601 | 2278 | return status; |
---|
| 2279 | +done: |
---|
| 2280 | + phydev->link = status & BMSR_LSTATUS ? 1 : 0; |
---|
| 2281 | + phydev->autoneg_complete = status & BMSR_ANEGCOMPLETE ? 1 : 0; |
---|
1602 | 2282 | |
---|
1603 | | - if ((status & BMSR_LSTATUS) == 0) |
---|
| 2283 | + /* Consider the case that autoneg was started and "aneg complete" |
---|
| 2284 | + * bit has been reset, but "link up" bit not yet. |
---|
| 2285 | + */ |
---|
| 2286 | + if (phydev->autoneg == AUTONEG_ENABLE && !phydev->autoneg_complete) |
---|
1604 | 2287 | phydev->link = 0; |
---|
1605 | | - else |
---|
1606 | | - phydev->link = 1; |
---|
1607 | 2288 | |
---|
1608 | 2289 | return 0; |
---|
1609 | 2290 | } |
---|
1610 | 2291 | EXPORT_SYMBOL(genphy_update_link); |
---|
| 2292 | + |
---|
| 2293 | +int genphy_read_lpa(struct phy_device *phydev) |
---|
| 2294 | +{ |
---|
| 2295 | + int lpa, lpagb; |
---|
| 2296 | + |
---|
| 2297 | + if (phydev->autoneg == AUTONEG_ENABLE) { |
---|
| 2298 | + if (!phydev->autoneg_complete) { |
---|
| 2299 | + mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, |
---|
| 2300 | + 0); |
---|
| 2301 | + mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, 0); |
---|
| 2302 | + return 0; |
---|
| 2303 | + } |
---|
| 2304 | + |
---|
| 2305 | + if (phydev->is_gigabit_capable) { |
---|
| 2306 | + lpagb = phy_read(phydev, MII_STAT1000); |
---|
| 2307 | + if (lpagb < 0) |
---|
| 2308 | + return lpagb; |
---|
| 2309 | + |
---|
| 2310 | + if (lpagb & LPA_1000MSFAIL) { |
---|
| 2311 | + int adv = phy_read(phydev, MII_CTRL1000); |
---|
| 2312 | + |
---|
| 2313 | + if (adv < 0) |
---|
| 2314 | + return adv; |
---|
| 2315 | + |
---|
| 2316 | + if (adv & CTL1000_ENABLE_MASTER) |
---|
| 2317 | + phydev_err(phydev, "Master/Slave resolution failed, maybe conflicting manual settings?\n"); |
---|
| 2318 | + else |
---|
| 2319 | + phydev_err(phydev, "Master/Slave resolution failed\n"); |
---|
| 2320 | + return -ENOLINK; |
---|
| 2321 | + } |
---|
| 2322 | + |
---|
| 2323 | + mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, |
---|
| 2324 | + lpagb); |
---|
| 2325 | + } |
---|
| 2326 | + |
---|
| 2327 | + lpa = phy_read(phydev, MII_LPA); |
---|
| 2328 | + if (lpa < 0) |
---|
| 2329 | + return lpa; |
---|
| 2330 | + |
---|
| 2331 | + mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, lpa); |
---|
| 2332 | + } else { |
---|
| 2333 | + linkmode_zero(phydev->lp_advertising); |
---|
| 2334 | + } |
---|
| 2335 | + |
---|
| 2336 | + return 0; |
---|
| 2337 | +} |
---|
| 2338 | +EXPORT_SYMBOL(genphy_read_lpa); |
---|
| 2339 | + |
---|
| 2340 | +/** |
---|
| 2341 | + * genphy_read_status_fixed - read the link parameters for !aneg mode |
---|
| 2342 | + * @phydev: target phy_device struct |
---|
| 2343 | + * |
---|
| 2344 | + * Read the current duplex and speed state for a PHY operating with |
---|
| 2345 | + * autonegotiation disabled. |
---|
| 2346 | + */ |
---|
| 2347 | +int genphy_read_status_fixed(struct phy_device *phydev) |
---|
| 2348 | +{ |
---|
| 2349 | + int bmcr = phy_read(phydev, MII_BMCR); |
---|
| 2350 | + |
---|
| 2351 | + if (bmcr < 0) |
---|
| 2352 | + return bmcr; |
---|
| 2353 | + |
---|
| 2354 | + if (bmcr & BMCR_FULLDPLX) |
---|
| 2355 | + phydev->duplex = DUPLEX_FULL; |
---|
| 2356 | + else |
---|
| 2357 | + phydev->duplex = DUPLEX_HALF; |
---|
| 2358 | + |
---|
| 2359 | + if (bmcr & BMCR_SPEED1000) |
---|
| 2360 | + phydev->speed = SPEED_1000; |
---|
| 2361 | + else if (bmcr & BMCR_SPEED100) |
---|
| 2362 | + phydev->speed = SPEED_100; |
---|
| 2363 | + else |
---|
| 2364 | + phydev->speed = SPEED_10; |
---|
| 2365 | + |
---|
| 2366 | + return 0; |
---|
| 2367 | +} |
---|
| 2368 | +EXPORT_SYMBOL(genphy_read_status_fixed); |
---|
1611 | 2369 | |
---|
1612 | 2370 | /** |
---|
1613 | 2371 | * genphy_read_status - check the link status and update current link state |
---|
.. | .. |
---|
1620 | 2378 | */ |
---|
1621 | 2379 | int genphy_read_status(struct phy_device *phydev) |
---|
1622 | 2380 | { |
---|
1623 | | - int adv; |
---|
1624 | | - int err; |
---|
1625 | | - int lpa; |
---|
1626 | | - int lpagb = 0; |
---|
1627 | | - int common_adv; |
---|
1628 | | - int common_adv_gb = 0; |
---|
| 2381 | + int err, old_link = phydev->link; |
---|
1629 | 2382 | |
---|
1630 | 2383 | /* Update the link, but return if there was an error */ |
---|
1631 | 2384 | err = genphy_update_link(phydev); |
---|
1632 | 2385 | if (err) |
---|
1633 | 2386 | return err; |
---|
1634 | 2387 | |
---|
1635 | | - phydev->lp_advertising = 0; |
---|
| 2388 | + /* why bother the PHY if nothing can have changed */ |
---|
| 2389 | + if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) |
---|
| 2390 | + return 0; |
---|
1636 | 2391 | |
---|
1637 | | - if (AUTONEG_ENABLE == phydev->autoneg) { |
---|
1638 | | - if (phydev->supported & (SUPPORTED_1000baseT_Half |
---|
1639 | | - | SUPPORTED_1000baseT_Full)) { |
---|
1640 | | - lpagb = phy_read(phydev, MII_STAT1000); |
---|
1641 | | - if (lpagb < 0) |
---|
1642 | | - return lpagb; |
---|
| 2392 | + phydev->speed = SPEED_UNKNOWN; |
---|
| 2393 | + phydev->duplex = DUPLEX_UNKNOWN; |
---|
| 2394 | + phydev->pause = 0; |
---|
| 2395 | + phydev->asym_pause = 0; |
---|
1643 | 2396 | |
---|
1644 | | - adv = phy_read(phydev, MII_CTRL1000); |
---|
1645 | | - if (adv < 0) |
---|
1646 | | - return adv; |
---|
| 2397 | + err = genphy_read_master_slave(phydev); |
---|
| 2398 | + if (err < 0) |
---|
| 2399 | + return err; |
---|
1647 | 2400 | |
---|
1648 | | - if (lpagb & LPA_1000MSFAIL) { |
---|
1649 | | - if (adv & CTL1000_ENABLE_MASTER) |
---|
1650 | | - phydev_err(phydev, "Master/Slave resolution failed, maybe conflicting manual settings?\n"); |
---|
1651 | | - else |
---|
1652 | | - phydev_err(phydev, "Master/Slave resolution failed\n"); |
---|
1653 | | - return -ENOLINK; |
---|
1654 | | - } |
---|
| 2401 | + err = genphy_read_lpa(phydev); |
---|
| 2402 | + if (err < 0) |
---|
| 2403 | + return err; |
---|
1655 | 2404 | |
---|
1656 | | - phydev->lp_advertising = |
---|
1657 | | - mii_stat1000_to_ethtool_lpa_t(lpagb); |
---|
1658 | | - common_adv_gb = lpagb & adv << 2; |
---|
1659 | | - } |
---|
| 2405 | + if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) { |
---|
| 2406 | + phy_resolve_aneg_linkmode(phydev); |
---|
| 2407 | + } else if (phydev->autoneg == AUTONEG_DISABLE) { |
---|
| 2408 | + err = genphy_read_status_fixed(phydev); |
---|
| 2409 | + if (err < 0) |
---|
| 2410 | + return err; |
---|
| 2411 | + } |
---|
1660 | 2412 | |
---|
| 2413 | + return 0; |
---|
| 2414 | +} |
---|
| 2415 | +EXPORT_SYMBOL(genphy_read_status); |
---|
| 2416 | + |
---|
| 2417 | +/** |
---|
| 2418 | + * genphy_c37_read_status - check the link status and update current link state |
---|
| 2419 | + * @phydev: target phy_device struct |
---|
| 2420 | + * |
---|
| 2421 | + * Description: Check the link, then figure out the current state |
---|
| 2422 | + * by comparing what we advertise with what the link partner |
---|
| 2423 | + * advertises. This function is for Clause 37 1000Base-X mode. |
---|
| 2424 | + */ |
---|
| 2425 | +int genphy_c37_read_status(struct phy_device *phydev) |
---|
| 2426 | +{ |
---|
| 2427 | + int lpa, err, old_link = phydev->link; |
---|
| 2428 | + |
---|
| 2429 | + /* Update the link, but return if there was an error */ |
---|
| 2430 | + err = genphy_update_link(phydev); |
---|
| 2431 | + if (err) |
---|
| 2432 | + return err; |
---|
| 2433 | + |
---|
| 2434 | + /* why bother the PHY if nothing can have changed */ |
---|
| 2435 | + if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) |
---|
| 2436 | + return 0; |
---|
| 2437 | + |
---|
| 2438 | + phydev->duplex = DUPLEX_UNKNOWN; |
---|
| 2439 | + phydev->pause = 0; |
---|
| 2440 | + phydev->asym_pause = 0; |
---|
| 2441 | + |
---|
| 2442 | + if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) { |
---|
1661 | 2443 | lpa = phy_read(phydev, MII_LPA); |
---|
1662 | 2444 | if (lpa < 0) |
---|
1663 | 2445 | return lpa; |
---|
1664 | 2446 | |
---|
1665 | | - phydev->lp_advertising |= mii_lpa_to_ethtool_lpa_t(lpa); |
---|
| 2447 | + linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, |
---|
| 2448 | + phydev->lp_advertising, lpa & LPA_LPACK); |
---|
| 2449 | + linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, |
---|
| 2450 | + phydev->lp_advertising, lpa & LPA_1000XFULL); |
---|
| 2451 | + linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT, |
---|
| 2452 | + phydev->lp_advertising, lpa & LPA_1000XPAUSE); |
---|
| 2453 | + linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, |
---|
| 2454 | + phydev->lp_advertising, |
---|
| 2455 | + lpa & LPA_1000XPAUSE_ASYM); |
---|
1666 | 2456 | |
---|
1667 | | - adv = phy_read(phydev, MII_ADVERTISE); |
---|
1668 | | - if (adv < 0) |
---|
1669 | | - return adv; |
---|
1670 | | - |
---|
1671 | | - common_adv = lpa & adv; |
---|
1672 | | - |
---|
1673 | | - phydev->speed = SPEED_10; |
---|
1674 | | - phydev->duplex = DUPLEX_HALF; |
---|
1675 | | - phydev->pause = 0; |
---|
1676 | | - phydev->asym_pause = 0; |
---|
1677 | | - |
---|
1678 | | - if (common_adv_gb & (LPA_1000FULL | LPA_1000HALF)) { |
---|
1679 | | - phydev->speed = SPEED_1000; |
---|
1680 | | - |
---|
1681 | | - if (common_adv_gb & LPA_1000FULL) |
---|
1682 | | - phydev->duplex = DUPLEX_FULL; |
---|
1683 | | - } else if (common_adv & (LPA_100FULL | LPA_100HALF)) { |
---|
1684 | | - phydev->speed = SPEED_100; |
---|
1685 | | - |
---|
1686 | | - if (common_adv & LPA_100FULL) |
---|
1687 | | - phydev->duplex = DUPLEX_FULL; |
---|
1688 | | - } else |
---|
1689 | | - if (common_adv & LPA_10FULL) |
---|
1690 | | - phydev->duplex = DUPLEX_FULL; |
---|
1691 | | - |
---|
1692 | | - if (phydev->duplex == DUPLEX_FULL) { |
---|
1693 | | - phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0; |
---|
1694 | | - phydev->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0; |
---|
1695 | | - } |
---|
1696 | | - } else { |
---|
| 2457 | + phy_resolve_aneg_linkmode(phydev); |
---|
| 2458 | + } else if (phydev->autoneg == AUTONEG_DISABLE) { |
---|
1697 | 2459 | int bmcr = phy_read(phydev, MII_BMCR); |
---|
1698 | 2460 | |
---|
1699 | 2461 | if (bmcr < 0) |
---|
.. | .. |
---|
1703 | 2465 | phydev->duplex = DUPLEX_FULL; |
---|
1704 | 2466 | else |
---|
1705 | 2467 | phydev->duplex = DUPLEX_HALF; |
---|
1706 | | - |
---|
1707 | | - if (bmcr & BMCR_SPEED1000) |
---|
1708 | | - phydev->speed = SPEED_1000; |
---|
1709 | | - else if (bmcr & BMCR_SPEED100) |
---|
1710 | | - phydev->speed = SPEED_100; |
---|
1711 | | - else |
---|
1712 | | - phydev->speed = SPEED_10; |
---|
1713 | | - |
---|
1714 | | - phydev->pause = 0; |
---|
1715 | | - phydev->asym_pause = 0; |
---|
1716 | 2468 | } |
---|
1717 | 2469 | |
---|
1718 | 2470 | return 0; |
---|
1719 | 2471 | } |
---|
1720 | | -EXPORT_SYMBOL(genphy_read_status); |
---|
| 2472 | +EXPORT_SYMBOL(genphy_c37_read_status); |
---|
1721 | 2473 | |
---|
1722 | 2474 | /** |
---|
1723 | 2475 | * genphy_soft_reset - software reset the PHY via BMCR_RESET bit |
---|
.. | .. |
---|
1730 | 2482 | */ |
---|
1731 | 2483 | int genphy_soft_reset(struct phy_device *phydev) |
---|
1732 | 2484 | { |
---|
| 2485 | + u16 res = BMCR_RESET; |
---|
1733 | 2486 | int ret; |
---|
1734 | 2487 | |
---|
1735 | | - ret = phy_set_bits(phydev, MII_BMCR, BMCR_RESET); |
---|
| 2488 | + if (phydev->autoneg == AUTONEG_ENABLE) |
---|
| 2489 | + res |= BMCR_ANRESTART; |
---|
| 2490 | + |
---|
| 2491 | + ret = phy_modify(phydev, MII_BMCR, BMCR_ISOLATE, res); |
---|
1736 | 2492 | if (ret < 0) |
---|
1737 | 2493 | return ret; |
---|
1738 | 2494 | |
---|
1739 | | - return phy_poll_reset(phydev); |
---|
| 2495 | + /* Clause 22 states that setting bit BMCR_RESET sets control registers |
---|
| 2496 | + * to their default value. Therefore the POWER DOWN bit is supposed to |
---|
| 2497 | + * be cleared after soft reset. |
---|
| 2498 | + */ |
---|
| 2499 | + phydev->suspended = 0; |
---|
| 2500 | + |
---|
| 2501 | + ret = phy_poll_reset(phydev); |
---|
| 2502 | + if (ret) |
---|
| 2503 | + return ret; |
---|
| 2504 | + |
---|
| 2505 | + /* BMCR may be reset to defaults */ |
---|
| 2506 | + if (phydev->autoneg == AUTONEG_DISABLE) |
---|
| 2507 | + ret = genphy_setup_forced(phydev); |
---|
| 2508 | + |
---|
| 2509 | + return ret; |
---|
1740 | 2510 | } |
---|
1741 | 2511 | EXPORT_SYMBOL(genphy_soft_reset); |
---|
1742 | 2512 | |
---|
1743 | | -int genphy_config_init(struct phy_device *phydev) |
---|
| 2513 | +/** |
---|
| 2514 | + * genphy_read_abilities - read PHY abilities from Clause 22 registers |
---|
| 2515 | + * @phydev: target phy_device struct |
---|
| 2516 | + * |
---|
| 2517 | + * Description: Reads the PHY's abilities and populates |
---|
| 2518 | + * phydev->supported accordingly. |
---|
| 2519 | + * |
---|
| 2520 | + * Returns: 0 on success, < 0 on failure |
---|
| 2521 | + */ |
---|
| 2522 | +int genphy_read_abilities(struct phy_device *phydev) |
---|
1744 | 2523 | { |
---|
1745 | 2524 | int val; |
---|
1746 | | - u32 features; |
---|
1747 | 2525 | |
---|
1748 | | - features = (SUPPORTED_TP | SUPPORTED_MII |
---|
1749 | | - | SUPPORTED_AUI | SUPPORTED_FIBRE | |
---|
1750 | | - SUPPORTED_BNC | SUPPORTED_Pause | SUPPORTED_Asym_Pause); |
---|
| 2526 | + linkmode_set_bit_array(phy_basic_ports_array, |
---|
| 2527 | + ARRAY_SIZE(phy_basic_ports_array), |
---|
| 2528 | + phydev->supported); |
---|
1751 | 2529 | |
---|
1752 | | - /* Do we support autonegotiation? */ |
---|
1753 | 2530 | val = phy_read(phydev, MII_BMSR); |
---|
1754 | 2531 | if (val < 0) |
---|
1755 | 2532 | return val; |
---|
1756 | 2533 | |
---|
1757 | | - if (val & BMSR_ANEGCAPABLE) |
---|
1758 | | - features |= SUPPORTED_Autoneg; |
---|
| 2534 | + linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported, |
---|
| 2535 | + val & BMSR_ANEGCAPABLE); |
---|
1759 | 2536 | |
---|
1760 | | - if (val & BMSR_100FULL) |
---|
1761 | | - features |= SUPPORTED_100baseT_Full; |
---|
1762 | | - if (val & BMSR_100HALF) |
---|
1763 | | - features |= SUPPORTED_100baseT_Half; |
---|
1764 | | - if (val & BMSR_10FULL) |
---|
1765 | | - features |= SUPPORTED_10baseT_Full; |
---|
1766 | | - if (val & BMSR_10HALF) |
---|
1767 | | - features |= SUPPORTED_10baseT_Half; |
---|
| 2537 | + linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, phydev->supported, |
---|
| 2538 | + val & BMSR_100FULL); |
---|
| 2539 | + linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, phydev->supported, |
---|
| 2540 | + val & BMSR_100HALF); |
---|
| 2541 | + linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, phydev->supported, |
---|
| 2542 | + val & BMSR_10FULL); |
---|
| 2543 | + linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, phydev->supported, |
---|
| 2544 | + val & BMSR_10HALF); |
---|
1768 | 2545 | |
---|
1769 | 2546 | if (val & BMSR_ESTATEN) { |
---|
1770 | 2547 | val = phy_read(phydev, MII_ESTATUS); |
---|
1771 | 2548 | if (val < 0) |
---|
1772 | 2549 | return val; |
---|
1773 | 2550 | |
---|
1774 | | - if (val & ESTATUS_1000_TFULL) |
---|
1775 | | - features |= SUPPORTED_1000baseT_Full; |
---|
1776 | | - if (val & ESTATUS_1000_THALF) |
---|
1777 | | - features |= SUPPORTED_1000baseT_Half; |
---|
| 2551 | + linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, |
---|
| 2552 | + phydev->supported, val & ESTATUS_1000_TFULL); |
---|
| 2553 | + linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, |
---|
| 2554 | + phydev->supported, val & ESTATUS_1000_THALF); |
---|
| 2555 | + linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, |
---|
| 2556 | + phydev->supported, val & ESTATUS_1000_XFULL); |
---|
1778 | 2557 | } |
---|
1779 | | - |
---|
1780 | | - phydev->supported &= features; |
---|
1781 | | - phydev->advertising &= features; |
---|
1782 | 2558 | |
---|
1783 | 2559 | return 0; |
---|
1784 | 2560 | } |
---|
1785 | | -EXPORT_SYMBOL(genphy_config_init); |
---|
| 2561 | +EXPORT_SYMBOL(genphy_read_abilities); |
---|
1786 | 2562 | |
---|
1787 | 2563 | /* This is used for the phy device which doesn't support the MMD extended |
---|
1788 | 2564 | * register access, but it does have side effect when we are trying to access |
---|
.. | .. |
---|
1820 | 2596 | } |
---|
1821 | 2597 | EXPORT_SYMBOL(genphy_loopback); |
---|
1822 | 2598 | |
---|
1823 | | -static int __set_phy_supported(struct phy_device *phydev, u32 max_speed) |
---|
| 2599 | +/** |
---|
| 2600 | + * phy_remove_link_mode - Remove a supported link mode |
---|
| 2601 | + * @phydev: phy_device structure to remove link mode from |
---|
| 2602 | + * @link_mode: Link mode to be removed |
---|
| 2603 | + * |
---|
| 2604 | + * Description: Some MACs don't support all link modes which the PHY |
---|
| 2605 | + * does. e.g. a 1G MAC often does not support 1000Half. Add a helper |
---|
| 2606 | + * to remove a link mode. |
---|
| 2607 | + */ |
---|
| 2608 | +void phy_remove_link_mode(struct phy_device *phydev, u32 link_mode) |
---|
1824 | 2609 | { |
---|
1825 | | - switch (max_speed) { |
---|
1826 | | - case SPEED_10: |
---|
1827 | | - phydev->supported &= ~PHY_100BT_FEATURES; |
---|
1828 | | - /* fall through */ |
---|
1829 | | - case SPEED_100: |
---|
1830 | | - phydev->supported &= ~PHY_1000BT_FEATURES; |
---|
1831 | | - break; |
---|
1832 | | - case SPEED_1000: |
---|
1833 | | - break; |
---|
1834 | | - default: |
---|
1835 | | - return -ENOTSUPP; |
---|
| 2610 | + linkmode_clear_bit(link_mode, phydev->supported); |
---|
| 2611 | + phy_advertise_supported(phydev); |
---|
| 2612 | +} |
---|
| 2613 | +EXPORT_SYMBOL(phy_remove_link_mode); |
---|
| 2614 | + |
---|
| 2615 | +static void phy_copy_pause_bits(unsigned long *dst, unsigned long *src) |
---|
| 2616 | +{ |
---|
| 2617 | + linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, dst, |
---|
| 2618 | + linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, src)); |
---|
| 2619 | + linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT, dst, |
---|
| 2620 | + linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, src)); |
---|
| 2621 | +} |
---|
| 2622 | + |
---|
| 2623 | +/** |
---|
| 2624 | + * phy_advertise_supported - Advertise all supported modes |
---|
| 2625 | + * @phydev: target phy_device struct |
---|
| 2626 | + * |
---|
| 2627 | + * Description: Called to advertise all supported modes, doesn't touch |
---|
| 2628 | + * pause mode advertising. |
---|
| 2629 | + */ |
---|
| 2630 | +void phy_advertise_supported(struct phy_device *phydev) |
---|
| 2631 | +{ |
---|
| 2632 | + __ETHTOOL_DECLARE_LINK_MODE_MASK(new); |
---|
| 2633 | + |
---|
| 2634 | + linkmode_copy(new, phydev->supported); |
---|
| 2635 | + phy_copy_pause_bits(new, phydev->advertising); |
---|
| 2636 | + linkmode_copy(phydev->advertising, new); |
---|
| 2637 | +} |
---|
| 2638 | +EXPORT_SYMBOL(phy_advertise_supported); |
---|
| 2639 | + |
---|
| 2640 | +/** |
---|
| 2641 | + * phy_support_sym_pause - Enable support of symmetrical pause |
---|
| 2642 | + * @phydev: target phy_device struct |
---|
| 2643 | + * |
---|
| 2644 | + * Description: Called by the MAC to indicate is supports symmetrical |
---|
| 2645 | + * Pause, but not asym pause. |
---|
| 2646 | + */ |
---|
| 2647 | +void phy_support_sym_pause(struct phy_device *phydev) |
---|
| 2648 | +{ |
---|
| 2649 | + linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->supported); |
---|
| 2650 | + phy_copy_pause_bits(phydev->advertising, phydev->supported); |
---|
| 2651 | +} |
---|
| 2652 | +EXPORT_SYMBOL(phy_support_sym_pause); |
---|
| 2653 | + |
---|
| 2654 | +/** |
---|
| 2655 | + * phy_support_asym_pause - Enable support of asym pause |
---|
| 2656 | + * @phydev: target phy_device struct |
---|
| 2657 | + * |
---|
| 2658 | + * Description: Called by the MAC to indicate is supports Asym Pause. |
---|
| 2659 | + */ |
---|
| 2660 | +void phy_support_asym_pause(struct phy_device *phydev) |
---|
| 2661 | +{ |
---|
| 2662 | + phy_copy_pause_bits(phydev->advertising, phydev->supported); |
---|
| 2663 | +} |
---|
| 2664 | +EXPORT_SYMBOL(phy_support_asym_pause); |
---|
| 2665 | + |
---|
| 2666 | +/** |
---|
| 2667 | + * phy_set_sym_pause - Configure symmetric Pause |
---|
| 2668 | + * @phydev: target phy_device struct |
---|
| 2669 | + * @rx: Receiver Pause is supported |
---|
| 2670 | + * @tx: Transmit Pause is supported |
---|
| 2671 | + * @autoneg: Auto neg should be used |
---|
| 2672 | + * |
---|
| 2673 | + * Description: Configure advertised Pause support depending on if |
---|
| 2674 | + * receiver pause and pause auto neg is supported. Generally called |
---|
| 2675 | + * from the set_pauseparam .ndo. |
---|
| 2676 | + */ |
---|
| 2677 | +void phy_set_sym_pause(struct phy_device *phydev, bool rx, bool tx, |
---|
| 2678 | + bool autoneg) |
---|
| 2679 | +{ |
---|
| 2680 | + linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->supported); |
---|
| 2681 | + |
---|
| 2682 | + if (rx && tx && autoneg) |
---|
| 2683 | + linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, |
---|
| 2684 | + phydev->supported); |
---|
| 2685 | + |
---|
| 2686 | + linkmode_copy(phydev->advertising, phydev->supported); |
---|
| 2687 | +} |
---|
| 2688 | +EXPORT_SYMBOL(phy_set_sym_pause); |
---|
| 2689 | + |
---|
| 2690 | +/** |
---|
| 2691 | + * phy_set_asym_pause - Configure Pause and Asym Pause |
---|
| 2692 | + * @phydev: target phy_device struct |
---|
| 2693 | + * @rx: Receiver Pause is supported |
---|
| 2694 | + * @tx: Transmit Pause is supported |
---|
| 2695 | + * |
---|
| 2696 | + * Description: Configure advertised Pause support depending on if |
---|
| 2697 | + * transmit and receiver pause is supported. If there has been a |
---|
| 2698 | + * change in adverting, trigger a new autoneg. Generally called from |
---|
| 2699 | + * the set_pauseparam .ndo. |
---|
| 2700 | + */ |
---|
| 2701 | +void phy_set_asym_pause(struct phy_device *phydev, bool rx, bool tx) |
---|
| 2702 | +{ |
---|
| 2703 | + __ETHTOOL_DECLARE_LINK_MODE_MASK(oldadv); |
---|
| 2704 | + |
---|
| 2705 | + linkmode_copy(oldadv, phydev->advertising); |
---|
| 2706 | + linkmode_set_pause(phydev->advertising, tx, rx); |
---|
| 2707 | + |
---|
| 2708 | + if (!linkmode_equal(oldadv, phydev->advertising) && |
---|
| 2709 | + phydev->autoneg) |
---|
| 2710 | + phy_start_aneg(phydev); |
---|
| 2711 | +} |
---|
| 2712 | +EXPORT_SYMBOL(phy_set_asym_pause); |
---|
| 2713 | + |
---|
| 2714 | +/** |
---|
| 2715 | + * phy_validate_pause - Test if the PHY/MAC support the pause configuration |
---|
| 2716 | + * @phydev: phy_device struct |
---|
| 2717 | + * @pp: requested pause configuration |
---|
| 2718 | + * |
---|
| 2719 | + * Description: Test if the PHY/MAC combination supports the Pause |
---|
| 2720 | + * configuration the user is requesting. Returns True if it is |
---|
| 2721 | + * supported, false otherwise. |
---|
| 2722 | + */ |
---|
| 2723 | +bool phy_validate_pause(struct phy_device *phydev, |
---|
| 2724 | + struct ethtool_pauseparam *pp) |
---|
| 2725 | +{ |
---|
| 2726 | + if (!linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, |
---|
| 2727 | + phydev->supported) && pp->rx_pause) |
---|
| 2728 | + return false; |
---|
| 2729 | + |
---|
| 2730 | + if (!linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, |
---|
| 2731 | + phydev->supported) && |
---|
| 2732 | + pp->rx_pause != pp->tx_pause) |
---|
| 2733 | + return false; |
---|
| 2734 | + |
---|
| 2735 | + return true; |
---|
| 2736 | +} |
---|
| 2737 | +EXPORT_SYMBOL(phy_validate_pause); |
---|
| 2738 | + |
---|
| 2739 | +/** |
---|
| 2740 | + * phy_get_pause - resolve negotiated pause modes |
---|
| 2741 | + * @phydev: phy_device struct |
---|
| 2742 | + * @tx_pause: pointer to bool to indicate whether transmit pause should be |
---|
| 2743 | + * enabled. |
---|
| 2744 | + * @rx_pause: pointer to bool to indicate whether receive pause should be |
---|
| 2745 | + * enabled. |
---|
| 2746 | + * |
---|
| 2747 | + * Resolve and return the flow control modes according to the negotiation |
---|
| 2748 | + * result. This includes checking that we are operating in full duplex mode. |
---|
| 2749 | + * See linkmode_resolve_pause() for further details. |
---|
| 2750 | + */ |
---|
| 2751 | +void phy_get_pause(struct phy_device *phydev, bool *tx_pause, bool *rx_pause) |
---|
| 2752 | +{ |
---|
| 2753 | + if (phydev->duplex != DUPLEX_FULL) { |
---|
| 2754 | + *tx_pause = false; |
---|
| 2755 | + *rx_pause = false; |
---|
| 2756 | + return; |
---|
1836 | 2757 | } |
---|
1837 | 2758 | |
---|
1838 | | - return 0; |
---|
| 2759 | + return linkmode_resolve_pause(phydev->advertising, |
---|
| 2760 | + phydev->lp_advertising, |
---|
| 2761 | + tx_pause, rx_pause); |
---|
1839 | 2762 | } |
---|
| 2763 | +EXPORT_SYMBOL(phy_get_pause); |
---|
1840 | 2764 | |
---|
1841 | | -int phy_set_max_speed(struct phy_device *phydev, u32 max_speed) |
---|
| 2765 | +#if IS_ENABLED(CONFIG_OF_MDIO) |
---|
| 2766 | +static int phy_get_int_delay_property(struct device *dev, const char *name) |
---|
1842 | 2767 | { |
---|
1843 | | - int err; |
---|
| 2768 | + s32 int_delay; |
---|
| 2769 | + int ret; |
---|
1844 | 2770 | |
---|
1845 | | - err = __set_phy_supported(phydev, max_speed); |
---|
1846 | | - if (err) |
---|
1847 | | - return err; |
---|
| 2771 | + ret = device_property_read_u32(dev, name, &int_delay); |
---|
| 2772 | + if (ret) |
---|
| 2773 | + return ret; |
---|
1848 | 2774 | |
---|
1849 | | - phydev->advertising = phydev->supported; |
---|
1850 | | - |
---|
1851 | | - return 0; |
---|
| 2775 | + return int_delay; |
---|
1852 | 2776 | } |
---|
1853 | | -EXPORT_SYMBOL(phy_set_max_speed); |
---|
1854 | | - |
---|
1855 | | -static void of_set_phy_supported(struct phy_device *phydev) |
---|
| 2777 | +#else |
---|
| 2778 | +static int phy_get_int_delay_property(struct device *dev, const char *name) |
---|
1856 | 2779 | { |
---|
1857 | | - struct device_node *node = phydev->mdio.dev.of_node; |
---|
1858 | | - u32 max_speed; |
---|
1859 | | - |
---|
1860 | | - if (!IS_ENABLED(CONFIG_OF_MDIO)) |
---|
1861 | | - return; |
---|
1862 | | - |
---|
1863 | | - if (!node) |
---|
1864 | | - return; |
---|
1865 | | - |
---|
1866 | | - if (!of_property_read_u32(node, "max-speed", &max_speed)) |
---|
1867 | | - __set_phy_supported(phydev, max_speed); |
---|
| 2780 | + return -EINVAL; |
---|
1868 | 2781 | } |
---|
| 2782 | +#endif |
---|
1869 | 2783 | |
---|
1870 | | -static void of_set_phy_eee_broken(struct phy_device *phydev) |
---|
| 2784 | +/** |
---|
| 2785 | + * phy_get_delay_index - returns the index of the internal delay |
---|
| 2786 | + * @phydev: phy_device struct |
---|
| 2787 | + * @dev: pointer to the devices device struct |
---|
| 2788 | + * @delay_values: array of delays the PHY supports |
---|
| 2789 | + * @size: the size of the delay array |
---|
| 2790 | + * @is_rx: boolean to indicate to get the rx internal delay |
---|
| 2791 | + * |
---|
| 2792 | + * Returns the index within the array of internal delay passed in. |
---|
| 2793 | + * If the device property is not present then the interface type is checked |
---|
| 2794 | + * if the interface defines use of internal delay then a 1 is returned otherwise |
---|
| 2795 | + * a 0 is returned. |
---|
| 2796 | + * The array must be in ascending order. If PHY does not have an ascending order |
---|
| 2797 | + * array then size = 0 and the value of the delay property is returned. |
---|
| 2798 | + * Return -EINVAL if the delay is invalid or cannot be found. |
---|
| 2799 | + */ |
---|
| 2800 | +s32 phy_get_internal_delay(struct phy_device *phydev, struct device *dev, |
---|
| 2801 | + const int *delay_values, int size, bool is_rx) |
---|
1871 | 2802 | { |
---|
1872 | | - struct device_node *node = phydev->mdio.dev.of_node; |
---|
1873 | | - u32 broken = 0; |
---|
| 2803 | + s32 delay; |
---|
| 2804 | + int i; |
---|
1874 | 2805 | |
---|
1875 | | - if (!IS_ENABLED(CONFIG_OF_MDIO)) |
---|
1876 | | - return; |
---|
| 2806 | + if (is_rx) { |
---|
| 2807 | + delay = phy_get_int_delay_property(dev, "rx-internal-delay-ps"); |
---|
| 2808 | + if (delay < 0 && size == 0) { |
---|
| 2809 | + if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || |
---|
| 2810 | + phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) |
---|
| 2811 | + return 1; |
---|
| 2812 | + else |
---|
| 2813 | + return 0; |
---|
| 2814 | + } |
---|
1877 | 2815 | |
---|
1878 | | - if (!node) |
---|
1879 | | - return; |
---|
| 2816 | + } else { |
---|
| 2817 | + delay = phy_get_int_delay_property(dev, "tx-internal-delay-ps"); |
---|
| 2818 | + if (delay < 0 && size == 0) { |
---|
| 2819 | + if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || |
---|
| 2820 | + phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) |
---|
| 2821 | + return 1; |
---|
| 2822 | + else |
---|
| 2823 | + return 0; |
---|
| 2824 | + } |
---|
| 2825 | + } |
---|
1880 | 2826 | |
---|
1881 | | - if (of_property_read_bool(node, "eee-broken-100tx")) |
---|
1882 | | - broken |= MDIO_EEE_100TX; |
---|
1883 | | - if (of_property_read_bool(node, "eee-broken-1000t")) |
---|
1884 | | - broken |= MDIO_EEE_1000T; |
---|
1885 | | - if (of_property_read_bool(node, "eee-broken-10gt")) |
---|
1886 | | - broken |= MDIO_EEE_10GT; |
---|
1887 | | - if (of_property_read_bool(node, "eee-broken-1000kx")) |
---|
1888 | | - broken |= MDIO_EEE_1000KX; |
---|
1889 | | - if (of_property_read_bool(node, "eee-broken-10gkx4")) |
---|
1890 | | - broken |= MDIO_EEE_10GKX4; |
---|
1891 | | - if (of_property_read_bool(node, "eee-broken-10gkr")) |
---|
1892 | | - broken |= MDIO_EEE_10GKR; |
---|
| 2827 | + if (delay < 0) |
---|
| 2828 | + return delay; |
---|
1893 | 2829 | |
---|
1894 | | - phydev->eee_broken_modes = broken; |
---|
| 2830 | + if (delay && size == 0) |
---|
| 2831 | + return delay; |
---|
| 2832 | + |
---|
| 2833 | + if (delay < delay_values[0] || delay > delay_values[size - 1]) { |
---|
| 2834 | + phydev_err(phydev, "Delay %d is out of range\n", delay); |
---|
| 2835 | + return -EINVAL; |
---|
| 2836 | + } |
---|
| 2837 | + |
---|
| 2838 | + if (delay == delay_values[0]) |
---|
| 2839 | + return 0; |
---|
| 2840 | + |
---|
| 2841 | + for (i = 1; i < size; i++) { |
---|
| 2842 | + if (delay == delay_values[i]) |
---|
| 2843 | + return i; |
---|
| 2844 | + |
---|
| 2845 | + /* Find an approximate index by looking up the table */ |
---|
| 2846 | + if (delay > delay_values[i - 1] && |
---|
| 2847 | + delay < delay_values[i]) { |
---|
| 2848 | + if (delay - delay_values[i - 1] < |
---|
| 2849 | + delay_values[i] - delay) |
---|
| 2850 | + return i - 1; |
---|
| 2851 | + else |
---|
| 2852 | + return i; |
---|
| 2853 | + } |
---|
| 2854 | + } |
---|
| 2855 | + |
---|
| 2856 | + phydev_err(phydev, "error finding internal delay index for %d\n", |
---|
| 2857 | + delay); |
---|
| 2858 | + |
---|
| 2859 | + return -EINVAL; |
---|
| 2860 | +} |
---|
| 2861 | +EXPORT_SYMBOL(phy_get_internal_delay); |
---|
| 2862 | + |
---|
| 2863 | +static bool phy_drv_supports_irq(struct phy_driver *phydrv) |
---|
| 2864 | +{ |
---|
| 2865 | + return phydrv->config_intr && phydrv->ack_interrupt; |
---|
1895 | 2866 | } |
---|
1896 | 2867 | |
---|
1897 | 2868 | /** |
---|
.. | .. |
---|
1914 | 2885 | /* Disable the interrupt if the PHY doesn't support it |
---|
1915 | 2886 | * but the interrupt is still a valid one |
---|
1916 | 2887 | */ |
---|
1917 | | - if (!(phydrv->flags & PHY_HAS_INTERRUPT) && |
---|
1918 | | - phy_interrupt_is_valid(phydev)) |
---|
| 2888 | + if (!phy_drv_supports_irq(phydrv) && phy_interrupt_is_valid(phydev)) |
---|
1919 | 2889 | phydev->irq = PHY_POLL; |
---|
1920 | 2890 | |
---|
1921 | 2891 | if (phydrv->flags & PHY_IS_INTERNAL) |
---|
1922 | 2892 | phydev->is_internal = true; |
---|
1923 | 2893 | |
---|
1924 | | - mutex_lock(&phydev->lock); |
---|
| 2894 | + /* Deassert the reset signal */ |
---|
| 2895 | + phy_device_reset(phydev, 0); |
---|
| 2896 | + |
---|
| 2897 | + if (phydev->drv->probe) { |
---|
| 2898 | + err = phydev->drv->probe(phydev); |
---|
| 2899 | + if (err) |
---|
| 2900 | + goto out; |
---|
| 2901 | + } |
---|
1925 | 2902 | |
---|
1926 | 2903 | /* Start out supporting everything. Eventually, |
---|
1927 | 2904 | * a controller will attach, and may modify one |
---|
1928 | 2905 | * or both of these values |
---|
1929 | 2906 | */ |
---|
1930 | | - phydev->supported = phydrv->features; |
---|
| 2907 | + if (phydrv->features) { |
---|
| 2908 | + linkmode_copy(phydev->supported, phydrv->features); |
---|
| 2909 | + } else if (phydrv->get_features) { |
---|
| 2910 | + err = phydrv->get_features(phydev); |
---|
| 2911 | + } else if (phydev->is_c45) { |
---|
| 2912 | + err = genphy_c45_pma_read_abilities(phydev); |
---|
| 2913 | + } else { |
---|
| 2914 | + err = genphy_read_abilities(phydev); |
---|
| 2915 | + } |
---|
| 2916 | + |
---|
| 2917 | + if (err) |
---|
| 2918 | + goto out; |
---|
| 2919 | + |
---|
| 2920 | + if (!linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, |
---|
| 2921 | + phydev->supported)) |
---|
| 2922 | + phydev->autoneg = 0; |
---|
| 2923 | + |
---|
| 2924 | + if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, |
---|
| 2925 | + phydev->supported)) |
---|
| 2926 | + phydev->is_gigabit_capable = 1; |
---|
| 2927 | + if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, |
---|
| 2928 | + phydev->supported)) |
---|
| 2929 | + phydev->is_gigabit_capable = 1; |
---|
| 2930 | + |
---|
1931 | 2931 | of_set_phy_supported(phydev); |
---|
1932 | | - phydev->advertising = phydev->supported; |
---|
| 2932 | + phy_advertise_supported(phydev); |
---|
1933 | 2933 | |
---|
1934 | 2934 | /* Get the EEE modes we want to prohibit. We will ask |
---|
1935 | 2935 | * the PHY stop advertising these mode later on |
---|
.. | .. |
---|
1947 | 2947 | * (e.g. hardware erratum) where the driver wants to set only one |
---|
1948 | 2948 | * of these bits. |
---|
1949 | 2949 | */ |
---|
1950 | | - if (phydrv->features & (SUPPORTED_Pause | SUPPORTED_Asym_Pause)) { |
---|
1951 | | - phydev->supported &= ~(SUPPORTED_Pause | SUPPORTED_Asym_Pause); |
---|
1952 | | - phydev->supported |= phydrv->features & |
---|
1953 | | - (SUPPORTED_Pause | SUPPORTED_Asym_Pause); |
---|
1954 | | - } else { |
---|
1955 | | - phydev->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; |
---|
| 2950 | + if (!test_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->supported) && |
---|
| 2951 | + !test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->supported)) { |
---|
| 2952 | + linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, |
---|
| 2953 | + phydev->supported); |
---|
| 2954 | + linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, |
---|
| 2955 | + phydev->supported); |
---|
1956 | 2956 | } |
---|
1957 | 2957 | |
---|
1958 | 2958 | /* Set the state to READY by default */ |
---|
1959 | 2959 | phydev->state = PHY_READY; |
---|
1960 | 2960 | |
---|
1961 | | - if (phydev->drv->probe) { |
---|
1962 | | - /* Deassert the reset signal */ |
---|
1963 | | - phy_device_reset(phydev, 0); |
---|
1964 | | - |
---|
1965 | | - err = phydev->drv->probe(phydev); |
---|
1966 | | - if (err) { |
---|
1967 | | - /* Assert the reset signal */ |
---|
1968 | | - phy_device_reset(phydev, 1); |
---|
1969 | | - } |
---|
1970 | | - } |
---|
1971 | | - |
---|
1972 | | - mutex_unlock(&phydev->lock); |
---|
| 2961 | +out: |
---|
| 2962 | + /* Re-assert the reset signal on error */ |
---|
| 2963 | + if (err) |
---|
| 2964 | + phy_device_reset(phydev, 1); |
---|
1973 | 2965 | |
---|
1974 | 2966 | return err; |
---|
1975 | 2967 | } |
---|
.. | .. |
---|
1980 | 2972 | |
---|
1981 | 2973 | cancel_delayed_work_sync(&phydev->state_queue); |
---|
1982 | 2974 | |
---|
1983 | | - mutex_lock(&phydev->lock); |
---|
1984 | 2975 | phydev->state = PHY_DOWN; |
---|
1985 | | - mutex_unlock(&phydev->lock); |
---|
1986 | 2976 | |
---|
1987 | | - if (phydev->drv && phydev->drv->remove) { |
---|
| 2977 | + sfp_bus_del_upstream(phydev->sfp_bus); |
---|
| 2978 | + phydev->sfp_bus = NULL; |
---|
| 2979 | + |
---|
| 2980 | + if (phydev->drv && phydev->drv->remove) |
---|
1988 | 2981 | phydev->drv->remove(phydev); |
---|
1989 | 2982 | |
---|
1990 | | - /* Assert the reset signal */ |
---|
1991 | | - phy_device_reset(phydev, 1); |
---|
1992 | | - } |
---|
| 2983 | + /* Assert the reset signal */ |
---|
| 2984 | + phy_device_reset(phydev, 1); |
---|
| 2985 | + |
---|
1993 | 2986 | phydev->drv = NULL; |
---|
1994 | 2987 | |
---|
1995 | 2988 | return 0; |
---|
.. | .. |
---|
2004 | 2997 | { |
---|
2005 | 2998 | int retval; |
---|
2006 | 2999 | |
---|
| 3000 | + /* Either the features are hard coded, or dynamically |
---|
| 3001 | + * determined. It cannot be both. |
---|
| 3002 | + */ |
---|
| 3003 | + if (WARN_ON(new_driver->features && new_driver->get_features)) { |
---|
| 3004 | + pr_err("%s: features and get_features must not both be set\n", |
---|
| 3005 | + new_driver->name); |
---|
| 3006 | + return -EINVAL; |
---|
| 3007 | + } |
---|
| 3008 | + |
---|
2007 | 3009 | new_driver->mdiodrv.flags |= MDIO_DEVICE_IS_PHY; |
---|
2008 | 3010 | new_driver->mdiodrv.driver.name = new_driver->name; |
---|
2009 | 3011 | new_driver->mdiodrv.driver.bus = &mdio_bus_type; |
---|
2010 | 3012 | new_driver->mdiodrv.driver.probe = phy_probe; |
---|
2011 | 3013 | new_driver->mdiodrv.driver.remove = phy_remove; |
---|
2012 | 3014 | new_driver->mdiodrv.driver.owner = owner; |
---|
2013 | | - |
---|
2014 | | - /* The following works around an issue where the PHY driver doesn't bind |
---|
2015 | | - * to the device, resulting in the genphy driver being used instead of |
---|
2016 | | - * the dedicated driver. The root cause of the issue isn't known yet |
---|
2017 | | - * and seems to be in the base driver core. Once this is fixed we may |
---|
2018 | | - * remove this workaround. |
---|
2019 | | - */ |
---|
2020 | 3015 | new_driver->mdiodrv.driver.probe_type = PROBE_FORCE_SYNCHRONOUS; |
---|
2021 | 3016 | |
---|
2022 | 3017 | retval = driver_register(&new_driver->mdiodrv.driver); |
---|
.. | .. |
---|
2069 | 3064 | .phy_id = 0xffffffff, |
---|
2070 | 3065 | .phy_id_mask = 0xffffffff, |
---|
2071 | 3066 | .name = "Generic PHY", |
---|
2072 | | - .soft_reset = genphy_no_soft_reset, |
---|
2073 | | - .config_init = genphy_config_init, |
---|
2074 | | - .features = PHY_GBIT_FEATURES | SUPPORTED_MII | |
---|
2075 | | - SUPPORTED_AUI | SUPPORTED_FIBRE | |
---|
2076 | | - SUPPORTED_BNC, |
---|
2077 | | - .aneg_done = genphy_aneg_done, |
---|
| 3067 | + .get_features = genphy_read_abilities, |
---|
2078 | 3068 | .suspend = genphy_suspend, |
---|
2079 | 3069 | .resume = genphy_resume, |
---|
2080 | 3070 | .set_loopback = genphy_loopback, |
---|
| 3071 | +}; |
---|
| 3072 | + |
---|
| 3073 | +static const struct ethtool_phy_ops phy_ethtool_phy_ops = { |
---|
| 3074 | + .get_sset_count = phy_ethtool_get_sset_count, |
---|
| 3075 | + .get_strings = phy_ethtool_get_strings, |
---|
| 3076 | + .get_stats = phy_ethtool_get_stats, |
---|
| 3077 | + .start_cable_test = phy_start_cable_test, |
---|
| 3078 | + .start_cable_test_tdr = phy_start_cable_test_tdr, |
---|
2081 | 3079 | }; |
---|
2082 | 3080 | |
---|
2083 | 3081 | static int __init phy_init(void) |
---|
2084 | 3082 | { |
---|
2085 | 3083 | int rc; |
---|
2086 | 3084 | |
---|
| 3085 | + ethtool_set_ethtool_phy_ops(&phy_ethtool_phy_ops); |
---|
| 3086 | + |
---|
2087 | 3087 | rc = mdio_bus_init(); |
---|
2088 | 3088 | if (rc) |
---|
2089 | | - return rc; |
---|
| 3089 | + goto err_ethtool_phy_ops; |
---|
2090 | 3090 | |
---|
2091 | | - rc = phy_driver_register(&genphy_10g_driver, THIS_MODULE); |
---|
| 3091 | + features_init(); |
---|
| 3092 | + |
---|
| 3093 | + rc = phy_driver_register(&genphy_c45_driver, THIS_MODULE); |
---|
2092 | 3094 | if (rc) |
---|
2093 | | - goto err_10g; |
---|
| 3095 | + goto err_mdio_bus; |
---|
2094 | 3096 | |
---|
2095 | 3097 | rc = phy_driver_register(&genphy_driver, THIS_MODULE); |
---|
2096 | | - if (rc) { |
---|
2097 | | - phy_driver_unregister(&genphy_10g_driver); |
---|
2098 | | -err_10g: |
---|
2099 | | - mdio_bus_exit(); |
---|
2100 | | - } |
---|
| 3098 | + if (rc) |
---|
| 3099 | + goto err_c45; |
---|
| 3100 | + |
---|
| 3101 | + return 0; |
---|
| 3102 | + |
---|
| 3103 | +err_c45: |
---|
| 3104 | + phy_driver_unregister(&genphy_c45_driver); |
---|
| 3105 | +err_mdio_bus: |
---|
| 3106 | + mdio_bus_exit(); |
---|
| 3107 | +err_ethtool_phy_ops: |
---|
| 3108 | + ethtool_set_ethtool_phy_ops(NULL); |
---|
2101 | 3109 | |
---|
2102 | 3110 | return rc; |
---|
2103 | 3111 | } |
---|
2104 | 3112 | |
---|
2105 | 3113 | static void __exit phy_exit(void) |
---|
2106 | 3114 | { |
---|
2107 | | - phy_driver_unregister(&genphy_10g_driver); |
---|
| 3115 | + phy_driver_unregister(&genphy_c45_driver); |
---|
2108 | 3116 | phy_driver_unregister(&genphy_driver); |
---|
2109 | 3117 | mdio_bus_exit(); |
---|
| 3118 | + ethtool_set_ethtool_phy_ops(NULL); |
---|
2110 | 3119 | } |
---|
2111 | 3120 | |
---|
2112 | 3121 | subsys_initcall(phy_init); |
---|