diff options
Diffstat (limited to 'drivers/net/phy/phy_device.c')
-rw-r--r-- | drivers/net/phy/phy_device.c | 466 |
1 files changed, 304 insertions, 162 deletions
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index d6447b3f7409..2f6989b1e0dc 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
@@ -1,7 +1,4 @@ | |||
1 | /* | 1 | /* Framework for finding and configuring PHYs. |
2 | * drivers/net/phy/phy_device.c | ||
3 | * | ||
4 | * Framework for finding and configuring PHYs. | ||
5 | * Also contains generic PHY driver | 2 | * Also contains generic PHY driver |
6 | * | 3 | * |
7 | * Author: Andy Fleming | 4 | * Author: Andy Fleming |
@@ -33,10 +30,11 @@ | |||
33 | #include <linux/mii.h> | 30 | #include <linux/mii.h> |
34 | #include <linux/ethtool.h> | 31 | #include <linux/ethtool.h> |
35 | #include <linux/phy.h> | 32 | #include <linux/phy.h> |
33 | #include <linux/mdio.h> | ||
34 | #include <linux/io.h> | ||
35 | #include <linux/uaccess.h> | ||
36 | 36 | ||
37 | #include <asm/io.h> | ||
38 | #include <asm/irq.h> | 37 | #include <asm/irq.h> |
39 | #include <asm/uaccess.h> | ||
40 | 38 | ||
41 | MODULE_DESCRIPTION("PHY library"); | 39 | MODULE_DESCRIPTION("PHY library"); |
42 | MODULE_AUTHOR("Andy Fleming"); | 40 | MODULE_AUTHOR("Andy Fleming"); |
@@ -53,31 +51,31 @@ static void phy_device_release(struct device *dev) | |||
53 | kfree(to_phy_device(dev)); | 51 | kfree(to_phy_device(dev)); |
54 | } | 52 | } |
55 | 53 | ||
56 | static struct phy_driver genphy_driver; | 54 | enum genphy_driver { |
57 | extern int mdio_bus_init(void); | 55 | GENPHY_DRV_1G, |
58 | extern void mdio_bus_exit(void); | 56 | GENPHY_DRV_10G, |
57 | GENPHY_DRV_MAX | ||
58 | }; | ||
59 | |||
60 | static struct phy_driver genphy_driver[GENPHY_DRV_MAX]; | ||
59 | 61 | ||
60 | static LIST_HEAD(phy_fixup_list); | 62 | static LIST_HEAD(phy_fixup_list); |
61 | static DEFINE_MUTEX(phy_fixup_lock); | 63 | static DEFINE_MUTEX(phy_fixup_lock); |
62 | 64 | ||
63 | static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, | 65 | /** |
64 | u32 flags, phy_interface_t interface); | 66 | * phy_register_fixup - creates a new phy_fixup and adds it to the list |
65 | |||
66 | /* | ||
67 | * Creates a new phy_fixup and adds it to the list | ||
68 | * @bus_id: A string which matches phydev->dev.bus_id (or PHY_ANY_ID) | 67 | * @bus_id: A string which matches phydev->dev.bus_id (or PHY_ANY_ID) |
69 | * @phy_uid: Used to match against phydev->phy_id (the UID of the PHY) | 68 | * @phy_uid: Used to match against phydev->phy_id (the UID of the PHY) |
70 | * It can also be PHY_ANY_UID | 69 | * It can also be PHY_ANY_UID |
71 | * @phy_uid_mask: Applied to phydev->phy_id and fixup->phy_uid before | 70 | * @phy_uid_mask: Applied to phydev->phy_id and fixup->phy_uid before |
72 | * comparison | 71 | * comparison |
73 | * @run: The actual code to be run when a matching PHY is found | 72 | * @run: The actual code to be run when a matching PHY is found |
74 | */ | 73 | */ |
75 | int phy_register_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask, | 74 | int phy_register_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask, |
76 | int (*run)(struct phy_device *)) | 75 | int (*run)(struct phy_device *)) |
77 | { | 76 | { |
78 | struct phy_fixup *fixup; | 77 | struct phy_fixup *fixup = kzalloc(sizeof(*fixup), GFP_KERNEL); |
79 | 78 | ||
80 | fixup = kzalloc(sizeof(struct phy_fixup), GFP_KERNEL); | ||
81 | if (!fixup) | 79 | if (!fixup) |
82 | return -ENOMEM; | 80 | return -ENOMEM; |
83 | 81 | ||
@@ -96,7 +94,7 @@ EXPORT_SYMBOL(phy_register_fixup); | |||
96 | 94 | ||
97 | /* Registers a fixup to be run on any PHY with the UID in phy_uid */ | 95 | /* Registers a fixup to be run on any PHY with the UID in phy_uid */ |
98 | int phy_register_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask, | 96 | int phy_register_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask, |
99 | int (*run)(struct phy_device *)) | 97 | int (*run)(struct phy_device *)) |
100 | { | 98 | { |
101 | return phy_register_fixup(PHY_ANY_ID, phy_uid, phy_uid_mask, run); | 99 | return phy_register_fixup(PHY_ANY_ID, phy_uid, phy_uid_mask, run); |
102 | } | 100 | } |
@@ -104,14 +102,13 @@ EXPORT_SYMBOL(phy_register_fixup_for_uid); | |||
104 | 102 | ||
105 | /* Registers a fixup to be run on the PHY with id string bus_id */ | 103 | /* Registers a fixup to be run on the PHY with id string bus_id */ |
106 | int phy_register_fixup_for_id(const char *bus_id, | 104 | int phy_register_fixup_for_id(const char *bus_id, |
107 | int (*run)(struct phy_device *)) | 105 | int (*run)(struct phy_device *)) |
108 | { | 106 | { |
109 | return phy_register_fixup(bus_id, PHY_ANY_UID, 0xffffffff, run); | 107 | return phy_register_fixup(bus_id, PHY_ANY_UID, 0xffffffff, run); |
110 | } | 108 | } |
111 | EXPORT_SYMBOL(phy_register_fixup_for_id); | 109 | EXPORT_SYMBOL(phy_register_fixup_for_id); |
112 | 110 | ||
113 | /* | 111 | /* Returns 1 if fixup matches phydev in bus_id and phy_uid. |
114 | * Returns 1 if fixup matches phydev in bus_id and phy_uid. | ||
115 | * Fixups can be set to match any in one or more fields. | 112 | * Fixups can be set to match any in one or more fields. |
116 | */ | 113 | */ |
117 | static int phy_needs_fixup(struct phy_device *phydev, struct phy_fixup *fixup) | 114 | static int phy_needs_fixup(struct phy_device *phydev, struct phy_fixup *fixup) |
@@ -121,7 +118,7 @@ static int phy_needs_fixup(struct phy_device *phydev, struct phy_fixup *fixup) | |||
121 | return 0; | 118 | return 0; |
122 | 119 | ||
123 | if ((fixup->phy_uid & fixup->phy_uid_mask) != | 120 | if ((fixup->phy_uid & fixup->phy_uid_mask) != |
124 | (phydev->phy_id & fixup->phy_uid_mask)) | 121 | (phydev->phy_id & fixup->phy_uid_mask)) |
125 | if (fixup->phy_uid != PHY_ANY_UID) | 122 | if (fixup->phy_uid != PHY_ANY_UID) |
126 | return 0; | 123 | return 0; |
127 | 124 | ||
@@ -129,16 +126,14 @@ static int phy_needs_fixup(struct phy_device *phydev, struct phy_fixup *fixup) | |||
129 | } | 126 | } |
130 | 127 | ||
131 | /* Runs any matching fixups for this phydev */ | 128 | /* Runs any matching fixups for this phydev */ |
132 | int phy_scan_fixups(struct phy_device *phydev) | 129 | static int phy_scan_fixups(struct phy_device *phydev) |
133 | { | 130 | { |
134 | struct phy_fixup *fixup; | 131 | struct phy_fixup *fixup; |
135 | 132 | ||
136 | mutex_lock(&phy_fixup_lock); | 133 | mutex_lock(&phy_fixup_lock); |
137 | list_for_each_entry(fixup, &phy_fixup_list, list) { | 134 | list_for_each_entry(fixup, &phy_fixup_list, list) { |
138 | if (phy_needs_fixup(phydev, fixup)) { | 135 | if (phy_needs_fixup(phydev, fixup)) { |
139 | int err; | 136 | int err = fixup->run(phydev); |
140 | |||
141 | err = fixup->run(phydev); | ||
142 | 137 | ||
143 | if (err < 0) { | 138 | if (err < 0) { |
144 | mutex_unlock(&phy_fixup_lock); | 139 | mutex_unlock(&phy_fixup_lock); |
@@ -150,25 +145,24 @@ int phy_scan_fixups(struct phy_device *phydev) | |||
150 | 145 | ||
151 | return 0; | 146 | return 0; |
152 | } | 147 | } |
153 | EXPORT_SYMBOL(phy_scan_fixups); | ||
154 | 148 | ||
155 | struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id, | 149 | struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id, |
156 | bool is_c45, struct phy_c45_device_ids *c45_ids) | 150 | bool is_c45, |
151 | struct phy_c45_device_ids *c45_ids) | ||
157 | { | 152 | { |
158 | struct phy_device *dev; | 153 | struct phy_device *dev; |
159 | 154 | ||
160 | /* We allocate the device, and initialize the | 155 | /* We allocate the device, and initialize the default values */ |
161 | * default values */ | ||
162 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 156 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
163 | |||
164 | if (NULL == dev) | 157 | if (NULL == dev) |
165 | return (struct phy_device*) PTR_ERR((void*)-ENOMEM); | 158 | return (struct phy_device *)PTR_ERR((void *)-ENOMEM); |
166 | 159 | ||
167 | dev->dev.release = phy_device_release; | 160 | dev->dev.release = phy_device_release; |
168 | 161 | ||
169 | dev->speed = 0; | 162 | dev->speed = 0; |
170 | dev->duplex = -1; | 163 | dev->duplex = -1; |
171 | dev->pause = dev->asym_pause = 0; | 164 | dev->pause = 0; |
165 | dev->asym_pause = 0; | ||
172 | dev->link = 1; | 166 | dev->link = 1; |
173 | dev->interface = PHY_INTERFACE_MODE_GMII; | 167 | dev->interface = PHY_INTERFACE_MODE_GMII; |
174 | 168 | ||
@@ -192,14 +186,15 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id, | |||
192 | INIT_WORK(&dev->phy_queue, phy_change); | 186 | INIT_WORK(&dev->phy_queue, phy_change); |
193 | 187 | ||
194 | /* Request the appropriate module unconditionally; don't | 188 | /* Request the appropriate module unconditionally; don't |
195 | bother trying to do so only if it isn't already loaded, | 189 | * bother trying to do so only if it isn't already loaded, |
196 | because that gets complicated. A hotplug event would have | 190 | * because that gets complicated. A hotplug event would have |
197 | done an unconditional modprobe anyway. | 191 | * done an unconditional modprobe anyway. |
198 | We don't do normal hotplug because it won't work for MDIO | 192 | * We don't do normal hotplug because it won't work for MDIO |
199 | -- because it relies on the device staying around for long | 193 | * -- because it relies on the device staying around for long |
200 | enough for the driver to get loaded. With MDIO, the NIC | 194 | * enough for the driver to get loaded. With MDIO, the NIC |
201 | driver will get bored and give up as soon as it finds that | 195 | * driver will get bored and give up as soon as it finds that |
202 | there's no driver _already_ loaded. */ | 196 | * there's no driver _already_ loaded. |
197 | */ | ||
203 | request_module(MDIO_MODULE_PREFIX MDIO_ID_FMT, MDIO_ID_ARGS(phy_id)); | 198 | request_module(MDIO_MODULE_PREFIX MDIO_ID_FMT, MDIO_ID_ARGS(phy_id)); |
204 | 199 | ||
205 | device_initialize(&dev->dev); | 200 | device_initialize(&dev->dev); |
@@ -299,10 +294,8 @@ static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id, | |||
299 | if (is_c45) | 294 | if (is_c45) |
300 | return get_phy_c45_ids(bus, addr, phy_id, c45_ids); | 295 | return get_phy_c45_ids(bus, addr, phy_id, c45_ids); |
301 | 296 | ||
302 | /* Grab the bits from PHYIR1, and put them | 297 | /* Grab the bits from PHYIR1, and put them in the upper half */ |
303 | * in the upper half */ | ||
304 | phy_reg = mdiobus_read(bus, addr, MII_PHYSID1); | 298 | phy_reg = mdiobus_read(bus, addr, MII_PHYSID1); |
305 | |||
306 | if (phy_reg < 0) | 299 | if (phy_reg < 0) |
307 | return -EIO; | 300 | return -EIO; |
308 | 301 | ||
@@ -310,7 +303,6 @@ static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id, | |||
310 | 303 | ||
311 | /* Grab the bits from PHYIR2, and put them in the lower half */ | 304 | /* Grab the bits from PHYIR2, and put them in the lower half */ |
312 | phy_reg = mdiobus_read(bus, addr, MII_PHYSID2); | 305 | phy_reg = mdiobus_read(bus, addr, MII_PHYSID2); |
313 | |||
314 | if (phy_reg < 0) | 306 | if (phy_reg < 0) |
315 | return -EIO; | 307 | return -EIO; |
316 | 308 | ||
@@ -320,7 +312,8 @@ static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id, | |||
320 | } | 312 | } |
321 | 313 | ||
322 | /** | 314 | /** |
323 | * get_phy_device - reads the specified PHY device and returns its @phy_device struct | 315 | * get_phy_device - reads the specified PHY device and returns its @phy_device |
316 | * struct | ||
324 | * @bus: the target MII bus | 317 | * @bus: the target MII bus |
325 | * @addr: PHY address on the MII bus | 318 | * @addr: PHY address on the MII bus |
326 | * @is_c45: If true the PHY uses the 802.3 clause 45 protocol | 319 | * @is_c45: If true the PHY uses the 802.3 clause 45 protocol |
@@ -331,7 +324,6 @@ static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id, | |||
331 | struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45) | 324 | struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45) |
332 | { | 325 | { |
333 | struct phy_c45_device_ids c45_ids = {0}; | 326 | struct phy_c45_device_ids c45_ids = {0}; |
334 | struct phy_device *dev = NULL; | ||
335 | u32 phy_id = 0; | 327 | u32 phy_id = 0; |
336 | int r; | 328 | int r; |
337 | 329 | ||
@@ -343,9 +335,7 @@ struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45) | |||
343 | if ((phy_id & 0x1fffffff) == 0x1fffffff) | 335 | if ((phy_id & 0x1fffffff) == 0x1fffffff) |
344 | return NULL; | 336 | return NULL; |
345 | 337 | ||
346 | dev = phy_device_create(bus, addr, phy_id, is_c45, &c45_ids); | 338 | return phy_device_create(bus, addr, phy_id, is_c45, &c45_ids); |
347 | |||
348 | return dev; | ||
349 | } | 339 | } |
350 | EXPORT_SYMBOL(get_phy_device); | 340 | EXPORT_SYMBOL(get_phy_device); |
351 | 341 | ||
@@ -357,14 +347,17 @@ int phy_device_register(struct phy_device *phydev) | |||
357 | { | 347 | { |
358 | int err; | 348 | int err; |
359 | 349 | ||
360 | /* Don't register a phy if one is already registered at this | 350 | /* Don't register a phy if one is already registered at this address */ |
361 | * address */ | ||
362 | if (phydev->bus->phy_map[phydev->addr]) | 351 | if (phydev->bus->phy_map[phydev->addr]) |
363 | return -EINVAL; | 352 | return -EINVAL; |
364 | phydev->bus->phy_map[phydev->addr] = phydev; | 353 | phydev->bus->phy_map[phydev->addr] = phydev; |
365 | 354 | ||
366 | /* Run all of the fixups for this PHY */ | 355 | /* Run all of the fixups for this PHY */ |
367 | phy_scan_fixups(phydev); | 356 | err = phy_init_hw(phydev); |
357 | if (err) { | ||
358 | pr_err("PHY %d failed to initialize\n", phydev->addr); | ||
359 | goto out; | ||
360 | } | ||
368 | 361 | ||
369 | err = device_add(&phydev->dev); | 362 | err = device_add(&phydev->dev); |
370 | if (err) { | 363 | if (err) { |
@@ -409,7 +402,7 @@ EXPORT_SYMBOL(phy_find_first); | |||
409 | * this function. | 402 | * this function. |
410 | */ | 403 | */ |
411 | static void phy_prepare_link(struct phy_device *phydev, | 404 | static void phy_prepare_link(struct phy_device *phydev, |
412 | void (*handler)(struct net_device *)) | 405 | void (*handler)(struct net_device *)) |
413 | { | 406 | { |
414 | phydev->adjust_link = handler; | 407 | phydev->adjust_link = handler; |
415 | } | 408 | } |
@@ -432,7 +425,7 @@ int phy_connect_direct(struct net_device *dev, struct phy_device *phydev, | |||
432 | return rc; | 425 | return rc; |
433 | 426 | ||
434 | phy_prepare_link(phydev, handler); | 427 | phy_prepare_link(phydev, handler); |
435 | phy_start_machine(phydev, NULL); | 428 | phy_start_machine(phydev); |
436 | if (phydev->irq > 0) | 429 | if (phydev->irq > 0) |
437 | phy_start_interrupts(phydev); | 430 | phy_start_interrupts(phydev); |
438 | 431 | ||
@@ -455,16 +448,17 @@ EXPORT_SYMBOL(phy_connect_direct); | |||
455 | * choose to call only the subset of functions which provide | 448 | * choose to call only the subset of functions which provide |
456 | * the desired functionality. | 449 | * the desired functionality. |
457 | */ | 450 | */ |
458 | struct phy_device * phy_connect(struct net_device *dev, const char *bus_id, | 451 | struct phy_device *phy_connect(struct net_device *dev, const char *bus_id, |
459 | void (*handler)(struct net_device *), | 452 | void (*handler)(struct net_device *), |
460 | phy_interface_t interface) | 453 | phy_interface_t interface) |
461 | { | 454 | { |
462 | struct phy_device *phydev; | 455 | struct phy_device *phydev; |
463 | struct device *d; | 456 | struct device *d; |
464 | int rc; | 457 | int rc; |
465 | 458 | ||
466 | /* Search the list of PHY devices on the mdio bus for the | 459 | /* Search the list of PHY devices on the mdio bus for the |
467 | * PHY with the requested name */ | 460 | * PHY with the requested name |
461 | */ | ||
468 | d = bus_find_device_by_name(&mdio_bus_type, NULL, bus_id); | 462 | d = bus_find_device_by_name(&mdio_bus_type, NULL, bus_id); |
469 | if (!d) { | 463 | if (!d) { |
470 | pr_err("PHY %s not found\n", bus_id); | 464 | pr_err("PHY %s not found\n", bus_id); |
@@ -481,7 +475,8 @@ struct phy_device * phy_connect(struct net_device *dev, const char *bus_id, | |||
481 | EXPORT_SYMBOL(phy_connect); | 475 | EXPORT_SYMBOL(phy_connect); |
482 | 476 | ||
483 | /** | 477 | /** |
484 | * phy_disconnect - disable interrupts, stop state machine, and detach a PHY device | 478 | * phy_disconnect - disable interrupts, stop state machine, and detach a PHY |
479 | * device | ||
485 | * @phydev: target phy_device struct | 480 | * @phydev: target phy_device struct |
486 | */ | 481 | */ |
487 | void phy_disconnect(struct phy_device *phydev) | 482 | void phy_disconnect(struct phy_device *phydev) |
@@ -490,13 +485,53 @@ void phy_disconnect(struct phy_device *phydev) | |||
490 | phy_stop_interrupts(phydev); | 485 | phy_stop_interrupts(phydev); |
491 | 486 | ||
492 | phy_stop_machine(phydev); | 487 | phy_stop_machine(phydev); |
493 | 488 | ||
494 | phydev->adjust_link = NULL; | 489 | phydev->adjust_link = NULL; |
495 | 490 | ||
496 | phy_detach(phydev); | 491 | phy_detach(phydev); |
497 | } | 492 | } |
498 | EXPORT_SYMBOL(phy_disconnect); | 493 | EXPORT_SYMBOL(phy_disconnect); |
499 | 494 | ||
495 | /** | ||
496 | * phy_poll_reset - Safely wait until a PHY reset has properly completed | ||
497 | * @phydev: The PHY device to poll | ||
498 | * | ||
499 | * Description: According to IEEE 802.3, Section 2, Subsection 22.2.4.1.1, as | ||
500 | * published in 2008, a PHY reset may take up to 0.5 seconds. The MII BMCR | ||
501 | * register must be polled until the BMCR_RESET bit clears. | ||
502 | * | ||
503 | * Furthermore, any attempts to write to PHY registers may have no effect | ||
504 | * or even generate MDIO bus errors until this is complete. | ||
505 | * | ||
506 | * Some PHYs (such as the Marvell 88E1111) don't entirely conform to the | ||
507 | * standard and do not fully reset after the BMCR_RESET bit is set, and may | ||
508 | * even *REQUIRE* a soft-reset to properly restart autonegotiation. In an | ||
509 | * effort to support such broken PHYs, this function is separate from the | ||
510 | * standard phy_init_hw() which will zero all the other bits in the BMCR | ||
511 | * and reapply all driver-specific and board-specific fixups. | ||
512 | */ | ||
513 | static int phy_poll_reset(struct phy_device *phydev) | ||
514 | { | ||
515 | /* Poll until the reset bit clears (50ms per retry == 0.6 sec) */ | ||
516 | unsigned int retries = 12; | ||
517 | int ret; | ||
518 | |||
519 | do { | ||
520 | msleep(50); | ||
521 | ret = phy_read(phydev, MII_BMCR); | ||
522 | if (ret < 0) | ||
523 | return ret; | ||
524 | } while (ret & BMCR_RESET && --retries); | ||
525 | if (ret & BMCR_RESET) | ||
526 | return -ETIMEDOUT; | ||
527 | |||
528 | /* Some chips (smsc911x) may still need up to another 1ms after the | ||
529 | * BMCR_RESET bit is cleared before they are usable. | ||
530 | */ | ||
531 | msleep(1); | ||
532 | return 0; | ||
533 | } | ||
534 | |||
500 | int phy_init_hw(struct phy_device *phydev) | 535 | int phy_init_hw(struct phy_device *phydev) |
501 | { | 536 | { |
502 | int ret; | 537 | int ret; |
@@ -504,12 +539,21 @@ int phy_init_hw(struct phy_device *phydev) | |||
504 | if (!phydev->drv || !phydev->drv->config_init) | 539 | if (!phydev->drv || !phydev->drv->config_init) |
505 | return 0; | 540 | return 0; |
506 | 541 | ||
542 | ret = phy_write(phydev, MII_BMCR, BMCR_RESET); | ||
543 | if (ret < 0) | ||
544 | return ret; | ||
545 | |||
546 | ret = phy_poll_reset(phydev); | ||
547 | if (ret < 0) | ||
548 | return ret; | ||
549 | |||
507 | ret = phy_scan_fixups(phydev); | 550 | ret = phy_scan_fixups(phydev); |
508 | if (ret < 0) | 551 | if (ret < 0) |
509 | return ret; | 552 | return ret; |
510 | 553 | ||
511 | return phydev->drv->config_init(phydev); | 554 | return phydev->drv->config_init(phydev); |
512 | } | 555 | } |
556 | EXPORT_SYMBOL(phy_init_hw); | ||
513 | 557 | ||
514 | /** | 558 | /** |
515 | * phy_attach_direct - attach a network device to a given PHY device pointer | 559 | * phy_attach_direct - attach a network device to a given PHY device pointer |
@@ -520,26 +564,25 @@ int phy_init_hw(struct phy_device *phydev) | |||
520 | * | 564 | * |
521 | * Description: Called by drivers to attach to a particular PHY | 565 | * Description: Called by drivers to attach to a particular PHY |
522 | * device. The phy_device is found, and properly hooked up | 566 | * device. The phy_device is found, and properly hooked up |
523 | * to the phy_driver. If no driver is attached, then the | 567 | * to the phy_driver. If no driver is attached, then a |
524 | * genphy_driver is used. The phy_device is given a ptr to | 568 | * generic driver is used. The phy_device is given a ptr to |
525 | * the attaching device, and given a callback for link status | 569 | * the attaching device, and given a callback for link status |
526 | * change. The phy_device is returned to the attaching driver. | 570 | * change. The phy_device is returned to the attaching driver. |
527 | */ | 571 | */ |
528 | static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, | 572 | int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, |
529 | u32 flags, phy_interface_t interface) | 573 | u32 flags, phy_interface_t interface) |
530 | { | 574 | { |
531 | struct device *d = &phydev->dev; | 575 | struct device *d = &phydev->dev; |
532 | int err; | 576 | int err; |
533 | 577 | ||
534 | /* Assume that if there is no driver, that it doesn't | 578 | /* Assume that if there is no driver, that it doesn't |
535 | * exist, and we should use the genphy driver. */ | 579 | * exist, and we should use the genphy driver. |
580 | */ | ||
536 | if (NULL == d->driver) { | 581 | if (NULL == d->driver) { |
537 | if (phydev->is_c45) { | 582 | if (phydev->is_c45) |
538 | pr_err("No driver for phy %x\n", phydev->phy_id); | 583 | d->driver = &genphy_driver[GENPHY_DRV_10G].driver; |
539 | return -ENODEV; | 584 | else |
540 | } | 585 | d->driver = &genphy_driver[GENPHY_DRV_1G].driver; |
541 | |||
542 | d->driver = &genphy_driver.driver; | ||
543 | 586 | ||
544 | err = d->driver->probe(d); | 587 | err = d->driver->probe(d); |
545 | if (err >= 0) | 588 | if (err >= 0) |
@@ -565,13 +608,17 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, | |||
565 | 608 | ||
566 | /* Do initial configuration here, now that | 609 | /* Do initial configuration here, now that |
567 | * we have certain key parameters | 610 | * we have certain key parameters |
568 | * (dev_flags and interface) */ | 611 | * (dev_flags and interface) |
612 | */ | ||
569 | err = phy_init_hw(phydev); | 613 | err = phy_init_hw(phydev); |
570 | if (err) | 614 | if (err) |
571 | phy_detach(phydev); | 615 | phy_detach(phydev); |
572 | 616 | ||
617 | phy_resume(phydev); | ||
618 | |||
573 | return err; | 619 | return err; |
574 | } | 620 | } |
621 | EXPORT_SYMBOL(phy_attach_direct); | ||
575 | 622 | ||
576 | /** | 623 | /** |
577 | * phy_attach - attach a network device to a particular PHY device | 624 | * phy_attach - attach a network device to a particular PHY device |
@@ -582,8 +629,8 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, | |||
582 | * Description: Same as phy_attach_direct() except that a PHY bus_id | 629 | * Description: Same as phy_attach_direct() except that a PHY bus_id |
583 | * string is passed instead of a pointer to a struct phy_device. | 630 | * string is passed instead of a pointer to a struct phy_device. |
584 | */ | 631 | */ |
585 | struct phy_device *phy_attach(struct net_device *dev, | 632 | struct phy_device *phy_attach(struct net_device *dev, const char *bus_id, |
586 | const char *bus_id, phy_interface_t interface) | 633 | phy_interface_t interface) |
587 | { | 634 | { |
588 | struct bus_type *bus = &mdio_bus_type; | 635 | struct bus_type *bus = &mdio_bus_type; |
589 | struct phy_device *phydev; | 636 | struct phy_device *phydev; |
@@ -591,7 +638,8 @@ struct phy_device *phy_attach(struct net_device *dev, | |||
591 | int rc; | 638 | int rc; |
592 | 639 | ||
593 | /* Search the list of PHY devices on the mdio bus for the | 640 | /* Search the list of PHY devices on the mdio bus for the |
594 | * PHY with the requested name */ | 641 | * PHY with the requested name |
642 | */ | ||
595 | d = bus_find_device_by_name(bus, NULL, bus_id); | 643 | d = bus_find_device_by_name(bus, NULL, bus_id); |
596 | if (!d) { | 644 | if (!d) { |
597 | pr_err("PHY %s not found\n", bus_id); | 645 | pr_err("PHY %s not found\n", bus_id); |
@@ -613,18 +661,48 @@ EXPORT_SYMBOL(phy_attach); | |||
613 | */ | 661 | */ |
614 | void phy_detach(struct phy_device *phydev) | 662 | void phy_detach(struct phy_device *phydev) |
615 | { | 663 | { |
664 | int i; | ||
616 | phydev->attached_dev->phydev = NULL; | 665 | phydev->attached_dev->phydev = NULL; |
617 | phydev->attached_dev = NULL; | 666 | phydev->attached_dev = NULL; |
667 | phy_suspend(phydev); | ||
618 | 668 | ||
619 | /* If the device had no specific driver before (i.e. - it | 669 | /* If the device had no specific driver before (i.e. - it |
620 | * was using the generic driver), we unbind the device | 670 | * was using the generic driver), we unbind the device |
621 | * from the generic driver so that there's a chance a | 671 | * from the generic driver so that there's a chance a |
622 | * real driver could be loaded */ | 672 | * real driver could be loaded |
623 | if (phydev->dev.driver == &genphy_driver.driver) | 673 | */ |
624 | device_release_driver(&phydev->dev); | 674 | for (i = 0; i < ARRAY_SIZE(genphy_driver); i++) { |
675 | if (phydev->dev.driver == &genphy_driver[i].driver) { | ||
676 | device_release_driver(&phydev->dev); | ||
677 | break; | ||
678 | } | ||
679 | } | ||
625 | } | 680 | } |
626 | EXPORT_SYMBOL(phy_detach); | 681 | EXPORT_SYMBOL(phy_detach); |
627 | 682 | ||
683 | int phy_suspend(struct phy_device *phydev) | ||
684 | { | ||
685 | struct phy_driver *phydrv = to_phy_driver(phydev->dev.driver); | ||
686 | struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL }; | ||
687 | |||
688 | /* If the device has WOL enabled, we cannot suspend the PHY */ | ||
689 | phy_ethtool_get_wol(phydev, &wol); | ||
690 | if (wol.wolopts) | ||
691 | return -EBUSY; | ||
692 | |||
693 | if (phydrv->suspend) | ||
694 | return phydrv->suspend(phydev); | ||
695 | return 0; | ||
696 | } | ||
697 | |||
698 | int phy_resume(struct phy_device *phydev) | ||
699 | { | ||
700 | struct phy_driver *phydrv = to_phy_driver(phydev->dev.driver); | ||
701 | |||
702 | if (phydrv->resume) | ||
703 | return phydrv->resume(phydev); | ||
704 | return 0; | ||
705 | } | ||
628 | 706 | ||
629 | /* Generic PHY support and helper functions */ | 707 | /* Generic PHY support and helper functions */ |
630 | 708 | ||
@@ -640,20 +718,19 @@ EXPORT_SYMBOL(phy_detach); | |||
640 | static int genphy_config_advert(struct phy_device *phydev) | 718 | static int genphy_config_advert(struct phy_device *phydev) |
641 | { | 719 | { |
642 | u32 advertise; | 720 | u32 advertise; |
643 | int oldadv, adv; | 721 | int oldadv, adv, bmsr; |
644 | int err, changed = 0; | 722 | int err, changed = 0; |
645 | 723 | ||
646 | /* Only allow advertising what | 724 | /* Only allow advertising what this PHY supports */ |
647 | * this PHY supports */ | ||
648 | phydev->advertising &= phydev->supported; | 725 | phydev->advertising &= phydev->supported; |
649 | advertise = phydev->advertising; | 726 | advertise = phydev->advertising; |
650 | 727 | ||
651 | /* Setup standard advertisement */ | 728 | /* Setup standard advertisement */ |
652 | oldadv = adv = phy_read(phydev, MII_ADVERTISE); | 729 | adv = phy_read(phydev, MII_ADVERTISE); |
653 | |||
654 | if (adv < 0) | 730 | if (adv < 0) |
655 | return adv; | 731 | return adv; |
656 | 732 | ||
733 | oldadv = adv; | ||
657 | adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP | | 734 | adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP | |
658 | ADVERTISE_PAUSE_ASYM); | 735 | ADVERTISE_PAUSE_ASYM); |
659 | adv |= ethtool_adv_to_mii_adv_t(advertise); | 736 | adv |= ethtool_adv_to_mii_adv_t(advertise); |
@@ -666,26 +743,36 @@ static int genphy_config_advert(struct phy_device *phydev) | |||
666 | changed = 1; | 743 | changed = 1; |
667 | } | 744 | } |
668 | 745 | ||
669 | /* Configure gigabit if it's supported */ | 746 | bmsr = phy_read(phydev, MII_BMSR); |
670 | if (phydev->supported & (SUPPORTED_1000baseT_Half | | 747 | if (bmsr < 0) |
671 | SUPPORTED_1000baseT_Full)) { | 748 | return bmsr; |
672 | oldadv = adv = phy_read(phydev, MII_CTRL1000); | ||
673 | 749 | ||
674 | if (adv < 0) | 750 | /* Per 802.3-2008, Section 22.2.4.2.16 Extended status all |
675 | return adv; | 751 | * 1000Mbits/sec capable PHYs shall have the BMSR_ESTATEN bit set to a |
752 | * logical 1. | ||
753 | */ | ||
754 | if (!(bmsr & BMSR_ESTATEN)) | ||
755 | return changed; | ||
676 | 756 | ||
677 | adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); | 757 | /* Configure gigabit if it's supported */ |
678 | adv |= ethtool_adv_to_mii_ctrl1000_t(advertise); | 758 | adv = phy_read(phydev, MII_CTRL1000); |
759 | if (adv < 0) | ||
760 | return adv; | ||
679 | 761 | ||
680 | if (adv != oldadv) { | 762 | oldadv = adv; |
681 | err = phy_write(phydev, MII_CTRL1000, adv); | 763 | adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); |
682 | 764 | ||
683 | if (err < 0) | 765 | if (phydev->supported & (SUPPORTED_1000baseT_Half | |
684 | return err; | 766 | SUPPORTED_1000baseT_Full)) { |
767 | adv |= ethtool_adv_to_mii_ctrl1000_t(advertise); | ||
768 | if (adv != oldadv) | ||
685 | changed = 1; | 769 | changed = 1; |
686 | } | ||
687 | } | 770 | } |
688 | 771 | ||
772 | err = phy_write(phydev, MII_CTRL1000, adv); | ||
773 | if (err < 0) | ||
774 | return err; | ||
775 | |||
689 | return changed; | 776 | return changed; |
690 | } | 777 | } |
691 | 778 | ||
@@ -699,10 +786,10 @@ static int genphy_config_advert(struct phy_device *phydev) | |||
699 | */ | 786 | */ |
700 | int genphy_setup_forced(struct phy_device *phydev) | 787 | int genphy_setup_forced(struct phy_device *phydev) |
701 | { | 788 | { |
702 | int err; | ||
703 | int ctl = 0; | 789 | int ctl = 0; |
704 | 790 | ||
705 | phydev->pause = phydev->asym_pause = 0; | 791 | phydev->pause = 0; |
792 | phydev->asym_pause = 0; | ||
706 | 793 | ||
707 | if (SPEED_1000 == phydev->speed) | 794 | if (SPEED_1000 == phydev->speed) |
708 | ctl |= BMCR_SPEED1000; | 795 | ctl |= BMCR_SPEED1000; |
@@ -711,10 +798,8 @@ int genphy_setup_forced(struct phy_device *phydev) | |||
711 | 798 | ||
712 | if (DUPLEX_FULL == phydev->duplex) | 799 | if (DUPLEX_FULL == phydev->duplex) |
713 | ctl |= BMCR_FULLDPLX; | 800 | ctl |= BMCR_FULLDPLX; |
714 | |||
715 | err = phy_write(phydev, MII_BMCR, ctl); | ||
716 | 801 | ||
717 | return err; | 802 | return phy_write(phydev, MII_BMCR, ctl); |
718 | } | 803 | } |
719 | EXPORT_SYMBOL(genphy_setup_forced); | 804 | EXPORT_SYMBOL(genphy_setup_forced); |
720 | 805 | ||
@@ -724,25 +809,20 @@ EXPORT_SYMBOL(genphy_setup_forced); | |||
724 | */ | 809 | */ |
725 | int genphy_restart_aneg(struct phy_device *phydev) | 810 | int genphy_restart_aneg(struct phy_device *phydev) |
726 | { | 811 | { |
727 | int ctl; | 812 | int ctl = phy_read(phydev, MII_BMCR); |
728 | |||
729 | ctl = phy_read(phydev, MII_BMCR); | ||
730 | 813 | ||
731 | if (ctl < 0) | 814 | if (ctl < 0) |
732 | return ctl; | 815 | return ctl; |
733 | 816 | ||
734 | ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); | 817 | ctl |= BMCR_ANENABLE | BMCR_ANRESTART; |
735 | 818 | ||
736 | /* Don't isolate the PHY if we're negotiating */ | 819 | /* Don't isolate the PHY if we're negotiating */ |
737 | ctl &= ~(BMCR_ISOLATE); | 820 | ctl &= ~BMCR_ISOLATE; |
738 | 821 | ||
739 | ctl = phy_write(phydev, MII_BMCR, ctl); | 822 | return phy_write(phydev, MII_BMCR, ctl); |
740 | |||
741 | return ctl; | ||
742 | } | 823 | } |
743 | EXPORT_SYMBOL(genphy_restart_aneg); | 824 | EXPORT_SYMBOL(genphy_restart_aneg); |
744 | 825 | ||
745 | |||
746 | /** | 826 | /** |
747 | * genphy_config_aneg - restart auto-negotiation or write BMCR | 827 | * genphy_config_aneg - restart auto-negotiation or write BMCR |
748 | * @phydev: target phy_device struct | 828 | * @phydev: target phy_device struct |
@@ -759,13 +839,12 @@ int genphy_config_aneg(struct phy_device *phydev) | |||
759 | return genphy_setup_forced(phydev); | 839 | return genphy_setup_forced(phydev); |
760 | 840 | ||
761 | result = genphy_config_advert(phydev); | 841 | result = genphy_config_advert(phydev); |
762 | |||
763 | if (result < 0) /* error */ | 842 | if (result < 0) /* error */ |
764 | return result; | 843 | return result; |
765 | |||
766 | if (result == 0) { | 844 | if (result == 0) { |
767 | /* Advertisement hasn't changed, but maybe aneg was never on to | 845 | /* Advertisement hasn't changed, but maybe aneg was never on to |
768 | * begin with? Or maybe phy was isolated? */ | 846 | * begin with? Or maybe phy was isolated? |
847 | */ | ||
769 | int ctl = phy_read(phydev, MII_BMCR); | 848 | int ctl = phy_read(phydev, MII_BMCR); |
770 | 849 | ||
771 | if (ctl < 0) | 850 | if (ctl < 0) |
@@ -776,7 +855,8 @@ int genphy_config_aneg(struct phy_device *phydev) | |||
776 | } | 855 | } |
777 | 856 | ||
778 | /* Only restart aneg if we are advertising something different | 857 | /* Only restart aneg if we are advertising something different |
779 | * than we were before. */ | 858 | * than we were before. |
859 | */ | ||
780 | if (result > 0) | 860 | if (result > 0) |
781 | result = genphy_restart_aneg(phydev); | 861 | result = genphy_restart_aneg(phydev); |
782 | 862 | ||
@@ -784,6 +864,11 @@ int genphy_config_aneg(struct phy_device *phydev) | |||
784 | } | 864 | } |
785 | EXPORT_SYMBOL(genphy_config_aneg); | 865 | EXPORT_SYMBOL(genphy_config_aneg); |
786 | 866 | ||
867 | static int gen10g_config_aneg(struct phy_device *phydev) | ||
868 | { | ||
869 | return 0; | ||
870 | } | ||
871 | |||
787 | /** | 872 | /** |
788 | * genphy_update_link - update link status in @phydev | 873 | * genphy_update_link - update link status in @phydev |
789 | * @phydev: target phy_device struct | 874 | * @phydev: target phy_device struct |
@@ -798,13 +883,11 @@ int genphy_update_link(struct phy_device *phydev) | |||
798 | 883 | ||
799 | /* Do a fake read */ | 884 | /* Do a fake read */ |
800 | status = phy_read(phydev, MII_BMSR); | 885 | status = phy_read(phydev, MII_BMSR); |
801 | |||
802 | if (status < 0) | 886 | if (status < 0) |
803 | return status; | 887 | return status; |
804 | 888 | ||
805 | /* Read link and autonegotiation status */ | 889 | /* Read link and autonegotiation status */ |
806 | status = phy_read(phydev, MII_BMSR); | 890 | status = phy_read(phydev, MII_BMSR); |
807 | |||
808 | if (status < 0) | 891 | if (status < 0) |
809 | return status; | 892 | return status; |
810 | 893 | ||
@@ -832,65 +915,70 @@ int genphy_read_status(struct phy_device *phydev) | |||
832 | int err; | 915 | int err; |
833 | int lpa; | 916 | int lpa; |
834 | int lpagb = 0; | 917 | int lpagb = 0; |
918 | int common_adv; | ||
919 | int common_adv_gb = 0; | ||
835 | 920 | ||
836 | /* Update the link, but return if there | 921 | /* Update the link, but return if there was an error */ |
837 | * was an error */ | ||
838 | err = genphy_update_link(phydev); | 922 | err = genphy_update_link(phydev); |
839 | if (err) | 923 | if (err) |
840 | return err; | 924 | return err; |
841 | 925 | ||
926 | phydev->lp_advertising = 0; | ||
927 | |||
842 | if (AUTONEG_ENABLE == phydev->autoneg) { | 928 | if (AUTONEG_ENABLE == phydev->autoneg) { |
843 | if (phydev->supported & (SUPPORTED_1000baseT_Half | 929 | if (phydev->supported & (SUPPORTED_1000baseT_Half |
844 | | SUPPORTED_1000baseT_Full)) { | 930 | | SUPPORTED_1000baseT_Full)) { |
845 | lpagb = phy_read(phydev, MII_STAT1000); | 931 | lpagb = phy_read(phydev, MII_STAT1000); |
846 | |||
847 | if (lpagb < 0) | 932 | if (lpagb < 0) |
848 | return lpagb; | 933 | return lpagb; |
849 | 934 | ||
850 | adv = phy_read(phydev, MII_CTRL1000); | 935 | adv = phy_read(phydev, MII_CTRL1000); |
851 | |||
852 | if (adv < 0) | 936 | if (adv < 0) |
853 | return adv; | 937 | return adv; |
854 | 938 | ||
855 | lpagb &= adv << 2; | 939 | phydev->lp_advertising = |
940 | mii_stat1000_to_ethtool_lpa_t(lpagb); | ||
941 | common_adv_gb = lpagb & adv << 2; | ||
856 | } | 942 | } |
857 | 943 | ||
858 | lpa = phy_read(phydev, MII_LPA); | 944 | lpa = phy_read(phydev, MII_LPA); |
859 | |||
860 | if (lpa < 0) | 945 | if (lpa < 0) |
861 | return lpa; | 946 | return lpa; |
862 | 947 | ||
863 | adv = phy_read(phydev, MII_ADVERTISE); | 948 | phydev->lp_advertising |= mii_lpa_to_ethtool_lpa_t(lpa); |
864 | 949 | ||
950 | adv = phy_read(phydev, MII_ADVERTISE); | ||
865 | if (adv < 0) | 951 | if (adv < 0) |
866 | return adv; | 952 | return adv; |
867 | 953 | ||
868 | lpa &= adv; | 954 | common_adv = lpa & adv; |
869 | 955 | ||
870 | phydev->speed = SPEED_10; | 956 | phydev->speed = SPEED_10; |
871 | phydev->duplex = DUPLEX_HALF; | 957 | phydev->duplex = DUPLEX_HALF; |
872 | phydev->pause = phydev->asym_pause = 0; | 958 | phydev->pause = 0; |
959 | phydev->asym_pause = 0; | ||
873 | 960 | ||
874 | if (lpagb & (LPA_1000FULL | LPA_1000HALF)) { | 961 | if (common_adv_gb & (LPA_1000FULL | LPA_1000HALF)) { |
875 | phydev->speed = SPEED_1000; | 962 | phydev->speed = SPEED_1000; |
876 | 963 | ||
877 | if (lpagb & LPA_1000FULL) | 964 | if (common_adv_gb & LPA_1000FULL) |
878 | phydev->duplex = DUPLEX_FULL; | 965 | phydev->duplex = DUPLEX_FULL; |
879 | } else if (lpa & (LPA_100FULL | LPA_100HALF)) { | 966 | } else if (common_adv & (LPA_100FULL | LPA_100HALF)) { |
880 | phydev->speed = SPEED_100; | 967 | phydev->speed = SPEED_100; |
881 | 968 | ||
882 | if (lpa & LPA_100FULL) | 969 | if (common_adv & LPA_100FULL) |
883 | phydev->duplex = DUPLEX_FULL; | 970 | phydev->duplex = DUPLEX_FULL; |
884 | } else | 971 | } else |
885 | if (lpa & LPA_10FULL) | 972 | if (common_adv & LPA_10FULL) |
886 | phydev->duplex = DUPLEX_FULL; | 973 | phydev->duplex = DUPLEX_FULL; |
887 | 974 | ||
888 | if (phydev->duplex == DUPLEX_FULL){ | 975 | if (phydev->duplex == DUPLEX_FULL) { |
889 | phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0; | 976 | phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0; |
890 | phydev->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0; | 977 | phydev->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0; |
891 | } | 978 | } |
892 | } else { | 979 | } else { |
893 | int bmcr = phy_read(phydev, MII_BMCR); | 980 | int bmcr = phy_read(phydev, MII_BMCR); |
981 | |||
894 | if (bmcr < 0) | 982 | if (bmcr < 0) |
895 | return bmcr; | 983 | return bmcr; |
896 | 984 | ||
@@ -906,27 +994,55 @@ int genphy_read_status(struct phy_device *phydev) | |||
906 | else | 994 | else |
907 | phydev->speed = SPEED_10; | 995 | phydev->speed = SPEED_10; |
908 | 996 | ||
909 | phydev->pause = phydev->asym_pause = 0; | 997 | phydev->pause = 0; |
998 | phydev->asym_pause = 0; | ||
910 | } | 999 | } |
911 | 1000 | ||
912 | return 0; | 1001 | return 0; |
913 | } | 1002 | } |
914 | EXPORT_SYMBOL(genphy_read_status); | 1003 | EXPORT_SYMBOL(genphy_read_status); |
915 | 1004 | ||
1005 | static int gen10g_read_status(struct phy_device *phydev) | ||
1006 | { | ||
1007 | int devad, reg; | ||
1008 | u32 mmd_mask = phydev->c45_ids.devices_in_package; | ||
1009 | |||
1010 | phydev->link = 1; | ||
1011 | |||
1012 | /* For now just lie and say it's 10G all the time */ | ||
1013 | phydev->speed = SPEED_10000; | ||
1014 | phydev->duplex = DUPLEX_FULL; | ||
1015 | |||
1016 | for (devad = 0; mmd_mask; devad++, mmd_mask = mmd_mask >> 1) { | ||
1017 | if (!(mmd_mask & 1)) | ||
1018 | continue; | ||
1019 | |||
1020 | /* Read twice because link state is latched and a | ||
1021 | * read moves the current state into the register | ||
1022 | */ | ||
1023 | phy_read_mmd(phydev, devad, MDIO_STAT1); | ||
1024 | reg = phy_read_mmd(phydev, devad, MDIO_STAT1); | ||
1025 | if (reg < 0 || !(reg & MDIO_STAT1_LSTATUS)) | ||
1026 | phydev->link = 0; | ||
1027 | } | ||
1028 | |||
1029 | return 0; | ||
1030 | } | ||
1031 | |||
916 | static int genphy_config_init(struct phy_device *phydev) | 1032 | static int genphy_config_init(struct phy_device *phydev) |
917 | { | 1033 | { |
918 | int val; | 1034 | int val; |
919 | u32 features; | 1035 | u32 features; |
920 | 1036 | ||
921 | /* For now, I'll claim that the generic driver supports | 1037 | /* For now, I'll claim that the generic driver supports |
922 | * all possible port types */ | 1038 | * all possible port types |
1039 | */ | ||
923 | features = (SUPPORTED_TP | SUPPORTED_MII | 1040 | features = (SUPPORTED_TP | SUPPORTED_MII |
924 | | SUPPORTED_AUI | SUPPORTED_FIBRE | | 1041 | | SUPPORTED_AUI | SUPPORTED_FIBRE | |
925 | SUPPORTED_BNC); | 1042 | SUPPORTED_BNC); |
926 | 1043 | ||
927 | /* Do we support autonegotiation? */ | 1044 | /* Do we support autonegotiation? */ |
928 | val = phy_read(phydev, MII_BMSR); | 1045 | val = phy_read(phydev, MII_BMSR); |
929 | |||
930 | if (val < 0) | 1046 | if (val < 0) |
931 | return val; | 1047 | return val; |
932 | 1048 | ||
@@ -944,7 +1060,6 @@ static int genphy_config_init(struct phy_device *phydev) | |||
944 | 1060 | ||
945 | if (val & BMSR_ESTATEN) { | 1061 | if (val & BMSR_ESTATEN) { |
946 | val = phy_read(phydev, MII_ESTATUS); | 1062 | val = phy_read(phydev, MII_ESTATUS); |
947 | |||
948 | if (val < 0) | 1063 | if (val < 0) |
949 | return val; | 1064 | return val; |
950 | 1065 | ||
@@ -959,6 +1074,16 @@ static int genphy_config_init(struct phy_device *phydev) | |||
959 | 1074 | ||
960 | return 0; | 1075 | return 0; |
961 | } | 1076 | } |
1077 | |||
1078 | static int gen10g_config_init(struct phy_device *phydev) | ||
1079 | { | ||
1080 | /* Temporarily just say we support everything */ | ||
1081 | phydev->supported = SUPPORTED_10000baseT_Full; | ||
1082 | phydev->advertising = SUPPORTED_10000baseT_Full; | ||
1083 | |||
1084 | return 0; | ||
1085 | } | ||
1086 | |||
962 | int genphy_suspend(struct phy_device *phydev) | 1087 | int genphy_suspend(struct phy_device *phydev) |
963 | { | 1088 | { |
964 | int value; | 1089 | int value; |
@@ -966,7 +1091,7 @@ int genphy_suspend(struct phy_device *phydev) | |||
966 | mutex_lock(&phydev->lock); | 1091 | mutex_lock(&phydev->lock); |
967 | 1092 | ||
968 | value = phy_read(phydev, MII_BMCR); | 1093 | value = phy_read(phydev, MII_BMCR); |
969 | phy_write(phydev, MII_BMCR, (value | BMCR_PDOWN)); | 1094 | phy_write(phydev, MII_BMCR, value | BMCR_PDOWN); |
970 | 1095 | ||
971 | mutex_unlock(&phydev->lock); | 1096 | mutex_unlock(&phydev->lock); |
972 | 1097 | ||
@@ -974,6 +1099,11 @@ int genphy_suspend(struct phy_device *phydev) | |||
974 | } | 1099 | } |
975 | EXPORT_SYMBOL(genphy_suspend); | 1100 | EXPORT_SYMBOL(genphy_suspend); |
976 | 1101 | ||
1102 | static int gen10g_suspend(struct phy_device *phydev) | ||
1103 | { | ||
1104 | return 0; | ||
1105 | } | ||
1106 | |||
977 | int genphy_resume(struct phy_device *phydev) | 1107 | int genphy_resume(struct phy_device *phydev) |
978 | { | 1108 | { |
979 | int value; | 1109 | int value; |
@@ -981,7 +1111,7 @@ int genphy_resume(struct phy_device *phydev) | |||
981 | mutex_lock(&phydev->lock); | 1111 | mutex_lock(&phydev->lock); |
982 | 1112 | ||
983 | value = phy_read(phydev, MII_BMCR); | 1113 | value = phy_read(phydev, MII_BMCR); |
984 | phy_write(phydev, MII_BMCR, (value & ~BMCR_PDOWN)); | 1114 | phy_write(phydev, MII_BMCR, value & ~BMCR_PDOWN); |
985 | 1115 | ||
986 | mutex_unlock(&phydev->lock); | 1116 | mutex_unlock(&phydev->lock); |
987 | 1117 | ||
@@ -989,6 +1119,11 @@ int genphy_resume(struct phy_device *phydev) | |||
989 | } | 1119 | } |
990 | EXPORT_SYMBOL(genphy_resume); | 1120 | EXPORT_SYMBOL(genphy_resume); |
991 | 1121 | ||
1122 | static int gen10g_resume(struct phy_device *phydev) | ||
1123 | { | ||
1124 | return 0; | ||
1125 | } | ||
1126 | |||
992 | /** | 1127 | /** |
993 | * phy_probe - probe and init a PHY device | 1128 | * phy_probe - probe and init a PHY device |
994 | * @dev: device to probe and init | 1129 | * @dev: device to probe and init |
@@ -999,22 +1134,18 @@ EXPORT_SYMBOL(genphy_resume); | |||
999 | */ | 1134 | */ |
1000 | static int phy_probe(struct device *dev) | 1135 | static int phy_probe(struct device *dev) |
1001 | { | 1136 | { |
1002 | struct phy_device *phydev; | 1137 | struct phy_device *phydev = to_phy_device(dev); |
1003 | struct phy_driver *phydrv; | 1138 | struct device_driver *drv = phydev->dev.driver; |
1004 | struct device_driver *drv; | 1139 | struct phy_driver *phydrv = to_phy_driver(drv); |
1005 | int err = 0; | 1140 | int err = 0; |
1006 | 1141 | ||
1007 | phydev = to_phy_device(dev); | ||
1008 | |||
1009 | drv = phydev->dev.driver; | ||
1010 | phydrv = to_phy_driver(drv); | ||
1011 | phydev->drv = phydrv; | 1142 | phydev->drv = phydrv; |
1012 | 1143 | ||
1013 | /* Disable the interrupt if the PHY doesn't support it | 1144 | /* Disable the interrupt if the PHY doesn't support it |
1014 | * but the interrupt is still a valid one | 1145 | * but the interrupt is still a valid one |
1015 | */ | 1146 | */ |
1016 | if (!(phydrv->flags & PHY_HAS_INTERRUPT) && | 1147 | if (!(phydrv->flags & PHY_HAS_INTERRUPT) && |
1017 | phy_interrupt_is_valid(phydev)) | 1148 | phy_interrupt_is_valid(phydev)) |
1018 | phydev->irq = PHY_POLL; | 1149 | phydev->irq = PHY_POLL; |
1019 | 1150 | ||
1020 | if (phydrv->flags & PHY_IS_INTERNAL) | 1151 | if (phydrv->flags & PHY_IS_INTERNAL) |
@@ -1024,7 +1155,8 @@ static int phy_probe(struct device *dev) | |||
1024 | 1155 | ||
1025 | /* Start out supporting everything. Eventually, | 1156 | /* Start out supporting everything. Eventually, |
1026 | * a controller will attach, and may modify one | 1157 | * a controller will attach, and may modify one |
1027 | * or both of these values */ | 1158 | * or both of these values |
1159 | */ | ||
1028 | phydev->supported = phydrv->features; | 1160 | phydev->supported = phydrv->features; |
1029 | phydev->advertising = phydrv->features; | 1161 | phydev->advertising = phydrv->features; |
1030 | 1162 | ||
@@ -1037,14 +1169,11 @@ static int phy_probe(struct device *dev) | |||
1037 | mutex_unlock(&phydev->lock); | 1169 | mutex_unlock(&phydev->lock); |
1038 | 1170 | ||
1039 | return err; | 1171 | return err; |
1040 | |||
1041 | } | 1172 | } |
1042 | 1173 | ||
1043 | static int phy_remove(struct device *dev) | 1174 | static int phy_remove(struct device *dev) |
1044 | { | 1175 | { |
1045 | struct phy_device *phydev; | 1176 | struct phy_device *phydev = to_phy_device(dev); |
1046 | |||
1047 | phydev = to_phy_device(dev); | ||
1048 | 1177 | ||
1049 | mutex_lock(&phydev->lock); | 1178 | mutex_lock(&phydev->lock); |
1050 | phydev->state = PHY_DOWN; | 1179 | phydev->state = PHY_DOWN; |
@@ -1071,7 +1200,6 @@ int phy_driver_register(struct phy_driver *new_driver) | |||
1071 | new_driver->driver.remove = phy_remove; | 1200 | new_driver->driver.remove = phy_remove; |
1072 | 1201 | ||
1073 | retval = driver_register(&new_driver->driver); | 1202 | retval = driver_register(&new_driver->driver); |
1074 | |||
1075 | if (retval) { | 1203 | if (retval) { |
1076 | pr_err("%s: Error %d in registering driver\n", | 1204 | pr_err("%s: Error %d in registering driver\n", |
1077 | new_driver->name, retval); | 1205 | new_driver->name, retval); |
@@ -1110,13 +1238,14 @@ EXPORT_SYMBOL(phy_driver_unregister); | |||
1110 | void phy_drivers_unregister(struct phy_driver *drv, int n) | 1238 | void phy_drivers_unregister(struct phy_driver *drv, int n) |
1111 | { | 1239 | { |
1112 | int i; | 1240 | int i; |
1113 | for (i = 0; i < n; i++) { | 1241 | |
1242 | for (i = 0; i < n; i++) | ||
1114 | phy_driver_unregister(drv + i); | 1243 | phy_driver_unregister(drv + i); |
1115 | } | ||
1116 | } | 1244 | } |
1117 | EXPORT_SYMBOL(phy_drivers_unregister); | 1245 | EXPORT_SYMBOL(phy_drivers_unregister); |
1118 | 1246 | ||
1119 | static struct phy_driver genphy_driver = { | 1247 | static struct phy_driver genphy_driver[] = { |
1248 | { | ||
1120 | .phy_id = 0xffffffff, | 1249 | .phy_id = 0xffffffff, |
1121 | .phy_id_mask = 0xffffffff, | 1250 | .phy_id_mask = 0xffffffff, |
1122 | .name = "Generic PHY", | 1251 | .name = "Generic PHY", |
@@ -1126,8 +1255,19 @@ static struct phy_driver genphy_driver = { | |||
1126 | .read_status = genphy_read_status, | 1255 | .read_status = genphy_read_status, |
1127 | .suspend = genphy_suspend, | 1256 | .suspend = genphy_suspend, |
1128 | .resume = genphy_resume, | 1257 | .resume = genphy_resume, |
1129 | .driver = {.owner= THIS_MODULE, }, | 1258 | .driver = { .owner = THIS_MODULE, }, |
1130 | }; | 1259 | }, { |
1260 | .phy_id = 0xffffffff, | ||
1261 | .phy_id_mask = 0xffffffff, | ||
1262 | .name = "Generic 10G PHY", | ||
1263 | .config_init = gen10g_config_init, | ||
1264 | .features = 0, | ||
1265 | .config_aneg = gen10g_config_aneg, | ||
1266 | .read_status = gen10g_read_status, | ||
1267 | .suspend = gen10g_suspend, | ||
1268 | .resume = gen10g_resume, | ||
1269 | .driver = {.owner = THIS_MODULE, }, | ||
1270 | } }; | ||
1131 | 1271 | ||
1132 | static int __init phy_init(void) | 1272 | static int __init phy_init(void) |
1133 | { | 1273 | { |
@@ -1137,7 +1277,8 @@ static int __init phy_init(void) | |||
1137 | if (rc) | 1277 | if (rc) |
1138 | return rc; | 1278 | return rc; |
1139 | 1279 | ||
1140 | rc = phy_driver_register(&genphy_driver); | 1280 | rc = phy_drivers_register(genphy_driver, |
1281 | ARRAY_SIZE(genphy_driver)); | ||
1141 | if (rc) | 1282 | if (rc) |
1142 | mdio_bus_exit(); | 1283 | mdio_bus_exit(); |
1143 | 1284 | ||
@@ -1146,7 +1287,8 @@ static int __init phy_init(void) | |||
1146 | 1287 | ||
1147 | static void __exit phy_exit(void) | 1288 | static void __exit phy_exit(void) |
1148 | { | 1289 | { |
1149 | phy_driver_unregister(&genphy_driver); | 1290 | phy_drivers_unregister(genphy_driver, |
1291 | ARRAY_SIZE(genphy_driver)); | ||
1150 | mdio_bus_exit(); | 1292 | mdio_bus_exit(); |
1151 | } | 1293 | } |
1152 | 1294 | ||