aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2005-08-11 02:07:25 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-08-11 02:07:25 -0400
commit67c4f3fa25502ce7ed82fb0307e09cf36f1f81da (patch)
treed368d796618d52361f6aced3dcf2c1beb26ceec3 /drivers/net/phy
parent303bcb4b675d7284a1097dd1c18c995c0179883a (diff)
Fix numerous minor problems with new phy subsystem.
Includes fixes for problems noted by Adrian Bunk, Andrew Morton, and one other person lost in the annals of history (and email folders).
Diffstat (limited to 'drivers/net/phy')
-rw-r--r--drivers/net/phy/Kconfig12
-rw-r--r--drivers/net/phy/Makefile12
-rw-r--r--drivers/net/phy/mdio_bus.c4
-rw-r--r--drivers/net/phy/phy.c9
-rw-r--r--drivers/net/phy/phy.c.orig860
-rw-r--r--drivers/net/phy/phy_device.c48
6 files changed, 53 insertions, 892 deletions
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 8b5db2343cc3..c2f1bf1d02d2 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -5,7 +5,7 @@
5menu "PHY device support" 5menu "PHY device support"
6 6
7config PHYLIB 7config PHYLIB
8 bool "PHY Device support and infrastructure" 8 tristate "PHY Device support and infrastructure"
9 depends on NET_ETHERNET 9 depends on NET_ETHERNET
10 help 10 help
11 Ethernet controllers are usually attached to PHY 11 Ethernet controllers are usually attached to PHY
@@ -24,31 +24,31 @@ comment "MII PHY device drivers"
24 depends on PHYLIB 24 depends on PHYLIB
25 25
26config MARVELL_PHY 26config MARVELL_PHY
27 bool "Drivers for Marvell PHYs" 27 tristate "Drivers for Marvell PHYs"
28 depends on PHYLIB 28 depends on PHYLIB
29 ---help--- 29 ---help---
30 Currently has a driver for the 88E1011S 30 Currently has a driver for the 88E1011S
31 31
32config DAVICOM_PHY 32config DAVICOM_PHY
33 bool "Drivers for Davicom PHYs" 33 tristate "Drivers for Davicom PHYs"
34 depends on PHYLIB 34 depends on PHYLIB
35 ---help--- 35 ---help---
36 Currently supports dm9161e and dm9131 36 Currently supports dm9161e and dm9131
37 37
38config QSEMI_PHY 38config QSEMI_PHY
39 bool "Drivers for Quality Semiconductor PHYs" 39 tristate "Drivers for Quality Semiconductor PHYs"
40 depends on PHYLIB 40 depends on PHYLIB
41 ---help--- 41 ---help---
42 Currently supports the qs6612 42 Currently supports the qs6612
43 43
44config LXT_PHY 44config LXT_PHY
45 bool "Drivers for the Intel LXT PHYs" 45 tristate "Drivers for the Intel LXT PHYs"
46 depends on PHYLIB 46 depends on PHYLIB
47 ---help--- 47 ---help---
48 Currently supports the lxt970, lxt971 48 Currently supports the lxt970, lxt971
49 49
50config CICADA_PHY 50config CICADA_PHY
51 bool "Drivers for the Cicada PHYs" 51 tristate "Drivers for the Cicada PHYs"
52 depends on PHYLIB 52 depends on PHYLIB
53 ---help--- 53 ---help---
54 Currently supports the cis8204 54 Currently supports the cis8204
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 1af05de6ced0..fb7cb385a659 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -1,9 +1,9 @@
1# Makefile for Linux PHY drivers 1# Makefile for Linux PHY drivers
2 2
3obj-$(CONFIG_PHYLIB) += phy.o phy_device.o mdio_bus.o 3libphy-objs := phy.o phy_device.o mdio_bus.o
4 4
5obj-$(CONFIG_MARVELL_PHY) += marvell.o 5obj-$(CONFIG_MARVELL_PHY) += libphy.o marvell.o
6obj-$(CONFIG_DAVICOM_PHY) += davicom.o 6obj-$(CONFIG_DAVICOM_PHY) += libphy.o davicom.o
7obj-$(CONFIG_CICADA_PHY) += cicada.o 7obj-$(CONFIG_CICADA_PHY) += libphy.o cicada.o
8obj-$(CONFIG_LXT_PHY) += lxt.o 8obj-$(CONFIG_LXT_PHY) += libphy.o lxt.o
9obj-$(CONFIG_QSEMI_PHY) += qsemi.o 9obj-$(CONFIG_QSEMI_PHY) += libphy.o qsemi.o
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index e75103ba6f86..5fbea6acfe80 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -165,9 +165,9 @@ struct bus_type mdio_bus_type = {
165 .resume = mdio_bus_resume, 165 .resume = mdio_bus_resume,
166}; 166};
167 167
168static int __init mdio_bus_init(void) 168int __init mdio_bus_init(void)
169{ 169{
170 return bus_register(&mdio_bus_type); 170 return bus_register(&mdio_bus_type);
171} 171}
172 172
173subsys_initcall(mdio_bus_init); 173
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index e2c6896b92d2..934065dd6371 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -39,7 +39,6 @@
39#include <asm/irq.h> 39#include <asm/irq.h>
40#include <asm/uaccess.h> 40#include <asm/uaccess.h>
41 41
42static void phy_change(void *data);
43static void phy_timer(unsigned long data); 42static void phy_timer(unsigned long data);
44 43
45/* Convenience function to print out the current phy status 44/* Convenience function to print out the current phy status
@@ -464,7 +463,6 @@ void phy_stop_machine(struct phy_device *phydev)
464 phydev->adjust_state = NULL; 463 phydev->adjust_state = NULL;
465} 464}
466 465
467#ifdef CONFIG_PHYCONTROL
468/* phy_error: 466/* phy_error:
469 * 467 *
470 * Moves the PHY to the HALTED state in response to a read 468 * Moves the PHY to the HALTED state in response to a read
@@ -479,6 +477,10 @@ void phy_error(struct phy_device *phydev)
479 spin_unlock(&phydev->lock); 477 spin_unlock(&phydev->lock);
480} 478}
481 479
480#ifdef CONFIG_PHYCONTROL
481
482static void phy_change(void *data);
483
482/* phy_interrupt 484/* phy_interrupt
483 * 485 *
484 * description: When a PHY interrupt occurs, the handler disables 486 * description: When a PHY interrupt occurs, the handler disables
@@ -672,6 +674,8 @@ void phy_start(struct phy_device *phydev)
672EXPORT_SYMBOL(phy_stop); 674EXPORT_SYMBOL(phy_stop);
673EXPORT_SYMBOL(phy_start); 675EXPORT_SYMBOL(phy_start);
674 676
677#endif /* CONFIG_PHYCONTROL */
678
675/* PHY timer which handles the state machine */ 679/* PHY timer which handles the state machine */
676static void phy_timer(unsigned long data) 680static void phy_timer(unsigned long data)
677{ 681{
@@ -859,4 +863,3 @@ static void phy_timer(unsigned long data)
859 mod_timer(&phydev->phy_timer, jiffies + PHY_STATE_TIME * HZ); 863 mod_timer(&phydev->phy_timer, jiffies + PHY_STATE_TIME * HZ);
860} 864}
861 865
862#endif /* CONFIG_PHYCONTROL */
diff --git a/drivers/net/phy/phy.c.orig b/drivers/net/phy/phy.c.orig
deleted file mode 100644
index 6af17cec9ace..000000000000
--- a/drivers/net/phy/phy.c.orig
+++ /dev/null
@@ -1,860 +0,0 @@
1/*
2 * drivers/net/phy/phy.c
3 *
4 * Framework for configuring and reading PHY devices
5 * Based on code in sungem_phy.c and gianfar_phy.c
6 *
7 * Author: Andy Fleming
8 *
9 * Copyright (c) 2004 Freescale Semiconductor, Inc.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 */
17#include <linux/config.h>
18#include <linux/kernel.h>
19#include <linux/sched.h>
20#include <linux/string.h>
21#include <linux/errno.h>
22#include <linux/unistd.h>
23#include <linux/slab.h>
24#include <linux/interrupt.h>
25#include <linux/init.h>
26#include <linux/delay.h>
27#include <linux/netdevice.h>
28#include <linux/etherdevice.h>
29#include <linux/skbuff.h>
30#include <linux/spinlock.h>
31#include <linux/mm.h>
32#include <linux/module.h>
33#include <linux/version.h>
34#include <linux/mii.h>
35#include <linux/ethtool.h>
36#include <linux/phy.h>
37
38#include <asm/io.h>
39#include <asm/irq.h>
40#include <asm/uaccess.h>
41
42static void phy_change(void *data);
43static void phy_timer(unsigned long data);
44
45/* Convenience function to print out the current phy status
46 */
47void phy_print_status(struct phy_device *phydev)
48{
49 pr_info("%s: Link is %s", phydev->dev.bus_id,
50 phydev->link ? "Up" : "Down");
51 if (phydev->link)
52 printk(" - %d/%s", phydev->speed,
53 DUPLEX_FULL == phydev->duplex ?
54 "Full" : "Half");
55
56 printk("\n");
57}
58EXPORT_SYMBOL(phy_print_status);
59
60
61/* Convenience functions for reading/writing a given PHY
62 * register. They MUST NOT be called from interrupt context,
63 * because the bus read/write functions may wait for an interrupt
64 * to conclude the operation. */
65int phy_read(struct phy_device *phydev, u16 regnum)
66{
67 int retval;
68 struct mii_bus *bus = phydev->bus;
69
70 spin_lock_bh(&bus->mdio_lock);
71 retval = bus->read(bus, phydev->addr, regnum);
72 spin_unlock_bh(&bus->mdio_lock);
73
74 return retval;
75}
76EXPORT_SYMBOL(phy_read);
77
78int phy_write(struct phy_device *phydev, u16 regnum, u16 val)
79{
80 int err;
81 struct mii_bus *bus = phydev->bus;
82
83 spin_lock_bh(&bus->mdio_lock);
84 err = bus->write(bus, phydev->addr, regnum, val);
85 spin_unlock_bh(&bus->mdio_lock);
86
87 return err;
88}
89EXPORT_SYMBOL(phy_write);
90
91
92int phy_clear_interrupt(struct phy_device *phydev)
93{
94 int err = 0;
95
96 if (phydev->drv->ack_interrupt)
97 err = phydev->drv->ack_interrupt(phydev);
98
99 return err;
100}
101
102
103int phy_config_interrupt(struct phy_device *phydev, u32 interrupts)
104{
105 int err = 0;
106
107 phydev->interrupts = interrupts;
108 if (phydev->drv->config_intr)
109 err = phydev->drv->config_intr(phydev);
110
111 return err;
112}
113
114
115/* phy_aneg_done
116 *
117 * description: Reads the status register and returns 0 either if
118 * auto-negotiation is incomplete, or if there was an error.
119 * Returns BMSR_ANEGCOMPLETE if auto-negotiation is done.
120 */
121static inline int phy_aneg_done(struct phy_device *phydev)
122{
123 int retval;
124
125 retval = phy_read(phydev, MII_BMSR);
126
127 return (retval < 0) ? retval : (retval & BMSR_ANEGCOMPLETE);
128}
129
130/* phy_start_aneg
131 *
132 * description: Calls the PHY driver's config_aneg, and then
133 * sets the PHY state to PHY_AN if auto-negotiation is enabled,
134 * and to PHY_FORCING if auto-negotiation is disabled. Unless
135 * the PHY is currently HALTED.
136 */
137int phy_start_aneg(struct phy_device *phydev)
138{
139 int err;
140
141 spin_lock(&phydev->lock);
142
143 if (AUTONEG_DISABLE == phydev->autoneg)
144 phy_sanitize_settings(phydev);
145
146 err = phydev->drv->config_aneg(phydev);
147
148 if (err < 0)
149 goto out_unlock;
150
151 if (phydev->state != PHY_HALTED) {
152 if (AUTONEG_ENABLE == phydev->autoneg) {
153 phydev->state = PHY_AN;
154 phydev->link_timeout = PHY_AN_TIMEOUT;
155 } else {
156 phydev->state = PHY_FORCING;
157 phydev->link_timeout = PHY_FORCE_TIMEOUT;
158 }
159 }
160
161out_unlock:
162 spin_unlock(&phydev->lock);
163 return err;
164}
165EXPORT_SYMBOL(phy_start_aneg);
166
167
168/* A structure for mapping a particular speed and duplex
169 * combination to a particular SUPPORTED and ADVERTISED value */
170struct phy_setting {
171 int speed;
172 int duplex;
173 u32 setting;
174};
175
176/* A mapping of all SUPPORTED settings to speed/duplex */
177static struct phy_setting settings[] = {
178 {
179 .speed = 10000,
180 .duplex = DUPLEX_FULL,
181 .setting = SUPPORTED_10000baseT_Full,
182 },
183 {
184 .speed = SPEED_1000,
185 .duplex = DUPLEX_FULL,
186 .setting = SUPPORTED_1000baseT_Full,
187 },
188 {
189 .speed = SPEED_1000,
190 .duplex = DUPLEX_HALF,
191 .setting = SUPPORTED_1000baseT_Half,
192 },
193 {
194 .speed = SPEED_100,
195 .duplex = DUPLEX_FULL,
196 .setting = SUPPORTED_100baseT_Full,
197 },
198 {
199 .speed = SPEED_100,
200 .duplex = DUPLEX_HALF,
201 .setting = SUPPORTED_100baseT_Half,
202 },
203 {
204 .speed = SPEED_10,
205 .duplex = DUPLEX_FULL,
206 .setting = SUPPORTED_10baseT_Full,
207 },
208 {
209 .speed = SPEED_10,
210 .duplex = DUPLEX_HALF,
211 .setting = SUPPORTED_10baseT_Half,
212 },
213};
214
215#define MAX_NUM_SETTINGS (sizeof(settings)/sizeof(struct phy_setting))
216
217/* phy_find_setting
218 *
219 * description: Searches the settings array for the setting which
220 * matches the desired speed and duplex, and returns the index
221 * of that setting. Returns the index of the last setting if
222 * none of the others match.
223 */
224static inline int phy_find_setting(int speed, int duplex)
225{
226 int idx = 0;
227
228 while (idx < ARRAY_SIZE(settings) &&
229 (settings[idx].speed != speed ||
230 settings[idx].duplex != duplex))
231 idx++;
232
233 return idx < MAX_NUM_SETTINGS ? idx : MAX_NUM_SETTINGS - 1;
234}
235
236/* phy_find_valid
237 * idx: The first index in settings[] to search
238 * features: A mask of the valid settings
239 *
240 * description: Returns the index of the first valid setting less
241 * than or equal to the one pointed to by idx, as determined by
242 * the mask in features. Returns the index of the last setting
243 * if nothing else matches.
244 */
245static inline int phy_find_valid(int idx, u32 features)
246{
247 while (idx < MAX_NUM_SETTINGS && !(settings[idx].setting & features))
248 idx++;
249
250 return idx < MAX_NUM_SETTINGS ? idx : MAX_NUM_SETTINGS - 1;
251}
252
253/* phy_sanitize_settings
254 *
255 * description: Make sure the PHY is set to supported speeds and
256 * duplexes. Drop down by one in this order: 1000/FULL,
257 * 1000/HALF, 100/FULL, 100/HALF, 10/FULL, 10/HALF
258 */
259void phy_sanitize_settings(struct phy_device *phydev)
260{
261 u32 features = phydev->supported;
262 int idx;
263
264 /* Sanitize settings based on PHY capabilities */
265 if ((features & SUPPORTED_Autoneg) == 0)
266 phydev->autoneg = 0;
267
268 idx = phy_find_valid(phy_find_setting(phydev->speed, phydev->duplex),
269 features);
270
271 phydev->speed = settings[idx].speed;
272 phydev->duplex = settings[idx].duplex;
273}
274EXPORT_SYMBOL(phy_sanitize_settings);
275
276/* phy_force_reduction
277 *
278 * description: Reduces the speed/duplex settings by
279 * one notch. The order is so:
280 * 1000/FULL, 1000/HALF, 100/FULL, 100/HALF,
281 * 10/FULL, 10/HALF. The function bottoms out at 10/HALF.
282 */
283static void phy_force_reduction(struct phy_device *phydev)
284{
285 int idx;
286
287 idx = phy_find_setting(phydev->speed, phydev->duplex);
288
289 idx++;
290
291 idx = phy_find_valid(idx, phydev->supported);
292
293 phydev->speed = settings[idx].speed;
294 phydev->duplex = settings[idx].duplex;
295
296 pr_info("Trying %d/%s\n", phydev->speed,
297 DUPLEX_FULL == phydev->duplex ?
298 "FULL" : "HALF");
299}
300
301/* phy_ethtool_sset:
302 * A generic ethtool sset function. Handles all the details
303 *
304 * A few notes about parameter checking:
305 * - We don't set port or transceiver, so we don't care what they
306 * were set to.
307 * - phy_start_aneg() will make sure forced settings are sane, and
308 * choose the next best ones from the ones selected, so we don't
309 * care if ethtool tries to give us bad values
310 */
311int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd)
312{
313 if (cmd->phy_address != phydev->addr)
314 return -EINVAL;
315
316 /* We make sure that we don't pass unsupported
317 * values in to the PHY */
318 cmd->advertising &= phydev->supported;
319
320 /* Verify the settings we care about. */
321 if (cmd->autoneg != AUTONEG_ENABLE && cmd->autoneg != AUTONEG_DISABLE)
322 return -EINVAL;
323
324 if (cmd->autoneg == AUTONEG_ENABLE && cmd->advertising == 0)
325 return -EINVAL;
326
327 if (cmd->autoneg == AUTONEG_DISABLE
328 && ((cmd->speed != SPEED_1000
329 && cmd->speed != SPEED_100
330 && cmd->speed != SPEED_10)
331 || (cmd->duplex != DUPLEX_HALF
332 && cmd->duplex != DUPLEX_FULL)))
333 return -EINVAL;
334
335 phydev->autoneg = cmd->autoneg;
336
337 phydev->speed = cmd->speed;
338
339 phydev->advertising = cmd->advertising;
340
341 if (AUTONEG_ENABLE == cmd->autoneg)
342 phydev->advertising |= ADVERTISED_Autoneg;
343 else
344 phydev->advertising &= ~ADVERTISED_Autoneg;
345
346 phydev->duplex = cmd->duplex;
347
348 /* Restart the PHY */
349 phy_start_aneg(phydev);
350
351 return 0;
352}
353
354int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd)
355{
356 cmd->supported = phydev->supported;
357
358 cmd->advertising = phydev->advertising;
359
360 cmd->speed = phydev->speed;
361 cmd->duplex = phydev->duplex;
362 cmd->port = PORT_MII;
363 cmd->phy_address = phydev->addr;
364 cmd->transceiver = XCVR_EXTERNAL;
365 cmd->autoneg = phydev->autoneg;
366
367 return 0;
368}
369
370
371/* Note that this function is currently incompatible with the
372 * PHYCONTROL layer. It changes registers without regard to
373 * current state. Use at own risk
374 */
375int phy_mii_ioctl(struct phy_device *phydev,
376 struct mii_ioctl_data *mii_data, int cmd)
377{
378 u16 val = mii_data->val_in;
379
380 switch (cmd) {
381 case SIOCGMIIPHY:
382 mii_data->phy_id = phydev->addr;
383 break;
384 case SIOCGMIIREG:
385 mii_data->val_out = phy_read(phydev, mii_data->reg_num);
386 break;
387
388 case SIOCSMIIREG:
389 if (!capable(CAP_NET_ADMIN))
390 return -EPERM;
391
392 if (mii_data->phy_id == phydev->addr) {
393 switch(mii_data->reg_num) {
394 case MII_BMCR:
395 if (val & (BMCR_RESET|BMCR_ANENABLE))
396 phydev->autoneg = AUTONEG_DISABLE;
397 else
398 phydev->autoneg = AUTONEG_ENABLE;
399 if ((!phydev->autoneg) && (val & BMCR_FULLDPLX))
400 phydev->duplex = DUPLEX_FULL;
401 else
402 phydev->duplex = DUPLEX_HALF;
403 break;
404 case MII_ADVERTISE:
405 phydev->advertising = val;
406 break;
407 default:
408 /* do nothing */
409 break;
410 }
411 }
412
413 phy_write(phydev, mii_data->reg_num, val);
414
415 if (mii_data->reg_num == MII_BMCR
416 && val & BMCR_RESET
417 && phydev->drv->config_init)
418 phydev->drv->config_init(phydev);
419 break;
420 }
421
422 return 0;
423}
424
425/* phy_start_machine:
426 *
427 * description: The PHY infrastructure can run a state machine
428 * which tracks whether the PHY is starting up, negotiating,
429 * etc. This function starts the timer which tracks the state
430 * of the PHY. If you want to be notified when the state
431 * changes, pass in the callback, otherwise, pass NULL. If you
432 * want to maintain your own state machine, do not call this
433 * function. */
434void phy_start_machine(struct phy_device *phydev,
435 void (*handler)(struct net_device *))
436{
437 phydev->adjust_state = handler;
438
439 init_timer(&phydev->phy_timer);
440 phydev->phy_timer.function = &phy_timer;
441 phydev->phy_timer.data = (unsigned long) phydev;
442 mod_timer(&phydev->phy_timer, jiffies + HZ);
443}
444
445/* phy_stop_machine
446 *
447 * description: Stops the state machine timer, sets the state to
448 * UP (unless it wasn't up yet), and then frees the interrupt,
449 * if it is in use. This function must be called BEFORE
450 * phy_detach.
451 */
452void phy_stop_machine(struct phy_device *phydev)
453{
454 del_timer_sync(&phydev->phy_timer);
455
456 spin_lock(&phydev->lock);
457 if (phydev->state > PHY_UP)
458 phydev->state = PHY_UP;
459 spin_unlock(&phydev->lock);
460
461 if (phydev->irq != PHY_POLL)
462 phy_stop_interrupts(phydev);
463
464 phydev->adjust_state = NULL;
465}
466
467#ifdef CONFIG_PHYCONTROL
468/* phy_error:
469 *
470 * Moves the PHY to the HALTED state in response to a read
471 * or write error, and tells the controller the link is down.
472 * Must not be called from interrupt context, or while the
473 * phydev->lock is held.
474 */
475void phy_error(struct phy_device *phydev)
476{
477 spin_lock(&phydev->lock);
478 phydev->state = PHY_HALTED;
479 spin_unlock(&phydev->lock);
480}
481
482/* phy_interrupt
483 *
484 * description: When a PHY interrupt occurs, the handler disables
485 * interrupts, and schedules a work task to clear the interrupt.
486 */
487static irqreturn_t phy_interrupt(int irq, void *phy_dat, struct pt_regs *regs)
488{
489 struct phy_device *phydev = phy_dat;
490
491 /* The MDIO bus is not allowed to be written in interrupt
492 * context, so we need to disable the irq here. A work
493 * queue will write the PHY to disable and clear the
494 * interrupt, and then reenable the irq line. */
495 disable_irq_nosync(irq);
496
497 schedule_work(&phydev->phy_queue);
498
499 return IRQ_HANDLED;
500}
501
502/* Enable the interrupts from the PHY side */
503int phy_enable_interrupts(struct phy_device *phydev)
504{
505 int err;
506
507 err = phy_clear_interrupt(phydev);
508
509 if (err < 0)
510 return err;
511
512 err = phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED);
513
514 return err;
515}
516
517/* Disable the PHY interrupts from the PHY side */
518int phy_disable_interrupts(struct phy_device *phydev)
519{
520 int err;
521
522 /* Disable PHY interrupts */
523 err = phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED);
524
525 if (err)
526 goto phy_err;
527
528 /* Clear the interrupt */
529 err = phy_clear_interrupt(phydev);
530
531 if (err)
532 goto phy_err;
533
534 return 0;
535
536phy_err:
537 phy_error(phydev);
538
539 return err;
540}
541
542/* phy_start_interrupts
543 *
544 * description: Request the interrupt for the given PHY. If
545 * this fails, then we set irq to PHY_POLL.
546 * Otherwise, we enable the interrupts in the PHY.
547 * Returns 0 on success.
548 * This should only be called with a valid IRQ number.
549 */
550int phy_start_interrupts(struct phy_device *phydev)
551{
552 int err = 0;
553
554 INIT_WORK(&phydev->phy_queue, phy_change, phydev);
555
556 if (request_irq(phydev->irq, phy_interrupt,
557 SA_SHIRQ,
558 "phy_interrupt",
559 phydev) < 0) {
560 printk(KERN_WARNING "%s: Can't get IRQ %d (PHY)\n",
561 phydev->bus->name,
562 phydev->irq);
563 phydev->irq = PHY_POLL;
564 return 0;
565 }
566
567 err = phy_enable_interrupts(phydev);
568
569 return err;
570}
571EXPORT_SYMBOL(phy_start_interrupts);
572
573int phy_stop_interrupts(struct phy_device *phydev)
574{
575 int err;
576
577 err = phy_disable_interrupts(phydev);
578
579 if (err)
580 phy_error(phydev);
581
582 free_irq(phydev->irq, phydev);
583
584 return err;
585}
586EXPORT_SYMBOL(phy_stop_interrupts);
587
588
589/* Scheduled by the phy_interrupt/timer to handle PHY changes */
590static void phy_change(void *data)
591{
592 int err;
593 struct phy_device *phydev = data;
594
595 err = phy_disable_interrupts(phydev);
596
597 if (err)
598 goto phy_err;
599
600 spin_lock(&phydev->lock);
601 if ((PHY_RUNNING == phydev->state) || (PHY_NOLINK == phydev->state))
602 phydev->state = PHY_CHANGELINK;
603 spin_unlock(&phydev->lock);
604
605 enable_irq(phydev->irq);
606
607 /* Reenable interrupts */
608 err = phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED);
609
610 if (err)
611 goto irq_enable_err;
612
613 return;
614
615irq_enable_err:
616 disable_irq(phydev->irq);
617phy_err:
618 phy_error(phydev);
619}
620
621/* Bring down the PHY link, and stop checking the status. */
622void phy_stop(struct phy_device *phydev)
623{
624 spin_lock(&phydev->lock);
625
626 if (PHY_HALTED == phydev->state)
627 goto out_unlock;
628
629 if (phydev->irq != PHY_POLL) {
630 /* Clear any pending interrupts */
631 phy_clear_interrupt(phydev);
632
633 /* Disable PHY Interrupts */
634 phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED);
635 }
636
637 phydev->state = PHY_HALTED;
638
639out_unlock:
640 spin_unlock(&phydev->lock);
641}
642
643
644/* phy_start
645 *
646 * description: Indicates the attached device's readiness to
647 * handle PHY-related work. Used during startup to start the
648 * PHY, and after a call to phy_stop() to resume operation.
649 * Also used to indicate the MDIO bus has cleared an error
650 * condition.
651 */
652void phy_start(struct phy_device *phydev)
653{
654 spin_lock(&phydev->lock);
655
656 switch (phydev->state) {
657 case PHY_STARTING:
658 phydev->state = PHY_PENDING;
659 break;
660 case PHY_READY:
661 phydev->state = PHY_UP;
662 break;
663 case PHY_HALTED:
664 phydev->state = PHY_RESUMING;
665 default:
666 break;
667 }
668 spin_unlock(&phydev->lock);
669}
670EXPORT_SYMBOL(phy_stop);
671EXPORT_SYMBOL(phy_start);
672
673/* PHY timer which handles the state machine */
674static void phy_timer(unsigned long data)
675{
676 struct phy_device *phydev = (struct phy_device *)data;
677 int needs_aneg = 0;
678 int err = 0;
679
680 spin_lock(&phydev->lock);
681
682 if (phydev->adjust_state)
683 phydev->adjust_state(phydev->attached_dev);
684
685 switch(phydev->state) {
686 case PHY_DOWN:
687 case PHY_STARTING:
688 case PHY_READY:
689 case PHY_PENDING:
690 break;
691 case PHY_UP:
692 needs_aneg = 1;
693
694 phydev->link_timeout = PHY_AN_TIMEOUT;
695
696 break;
697 case PHY_AN:
698 /* Check if negotiation is done. Break
699 * if there's an error */
700 err = phy_aneg_done(phydev);
701 if (err < 0)
702 break;
703
704 /* If auto-negotiation is done, we change to
705 * either RUNNING, or NOLINK */
706 if (err > 0) {
707 err = phy_read_status(phydev);
708
709 if (err)
710 break;
711
712 if (phydev->link) {
713 phydev->state = PHY_RUNNING;
714 netif_carrier_on(phydev->attached_dev);
715 } else {
716 phydev->state = PHY_NOLINK;
717 netif_carrier_off(phydev->attached_dev);
718 }
719
720 phydev->adjust_link(phydev->attached_dev);
721
722 } else if (0 == phydev->link_timeout--) {
723 /* The counter expired, so either we
724 * switch to forced mode, or the
725 * magic_aneg bit exists, and we try aneg
726 * again */
727 if (!(phydev->drv->flags & PHY_HAS_MAGICANEG)) {
728 int idx;
729
730 /* We'll start from the
731 * fastest speed, and work
732 * our way down */
733 idx = phy_find_valid(0,
734 phydev->supported);
735
736 phydev->speed = settings[idx].speed;
737 phydev->duplex = settings[idx].duplex;
738
739 phydev->autoneg = AUTONEG_DISABLE;
740 phydev->state = PHY_FORCING;
741 phydev->link_timeout =
742 PHY_FORCE_TIMEOUT;
743
744 pr_info("Trying %d/%s\n",
745 phydev->speed,
746 DUPLEX_FULL ==
747 phydev->duplex ?
748 "FULL" : "HALF");
749 }
750
751 needs_aneg = 1;
752 }
753 break;
754 case PHY_NOLINK:
755 err = phy_read_status(phydev);
756
757 if (err)
758 break;
759
760 if (phydev->link) {
761 phydev->state = PHY_RUNNING;
762 netif_carrier_on(phydev->attached_dev);
763 phydev->adjust_link(phydev->attached_dev);
764 }
765 break;
766 case PHY_FORCING:
767 err = phy_read_status(phydev);
768
769 if (err)
770 break;
771
772 if (phydev->link) {
773 phydev->state = PHY_RUNNING;
774 netif_carrier_on(phydev->attached_dev);
775 } else {
776 if (0 == phydev->link_timeout--) {
777 phy_force_reduction(phydev);
778 needs_aneg = 1;
779 }
780 }
781
782 phydev->adjust_link(phydev->attached_dev);
783 break;
784 case PHY_RUNNING:
785 /* Only register a CHANGE if we are
786 * polling */
787 if (PHY_POLL == phydev->irq)
788 phydev->state = PHY_CHANGELINK;
789 break;
790 case PHY_CHANGELINK:
791 err = phy_read_status(phydev);
792
793 if (err)
794 break;
795
796 if (phydev->link) {
797 phydev->state = PHY_RUNNING;
798 netif_carrier_on(phydev->attached_dev);
799 } else {
800 phydev->state = PHY_NOLINK;
801 netif_carrier_off(phydev->attached_dev);
802 }
803
804 phydev->adjust_link(phydev->attached_dev);
805
806 if (PHY_POLL != phydev->irq)
807 err = phy_config_interrupt(phydev,
808 PHY_INTERRUPT_ENABLED);
809 break;
810 case PHY_HALTED:
811 if (phydev->link) {
812 phydev->link = 0;
813 netif_carrier_off(phydev->attached_dev);
814 phydev->adjust_link(phydev->attached_dev);
815 }
816 break;
817 case PHY_RESUMING:
818
819 err = phy_clear_interrupt(phydev);
820
821 if (err)
822 break;
823
824 err = phy_config_interrupt(phydev,
825 PHY_INTERRUPT_ENABLED);
826
827 if (err)
828 break;
829
830 if (AUTONEG_ENABLE == phydev->autoneg) {
831 err = phy_aneg_done(phydev);
832 if (err < 0)
833 break;
834
835 /* err > 0 if AN is done.
836 * Otherwise, it's 0, and we're
837 * still waiting for AN */
838 if (err > 0) {
839 phydev->state = PHY_RUNNING;
840 } else {
841 phydev->state = PHY_AN;
842 phydev->link_timeout = PHY_AN_TIMEOUT;
843 }
844 } else
845 phydev->state = PHY_RUNNING;
846 break;
847 }
848
849 spin_unlock(&phydev->lock);
850
851 if (needs_aneg)
852 err = phy_start_aneg(phydev);
853
854 if (err < 0)
855 phy_error(phydev);
856
857 mod_timer(&phydev->phy_timer, jiffies + PHY_STATE_TIME * HZ);
858}
859
860#endif /* CONFIG_PHYCONTROL */
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index f0595af4c837..c11138330fed 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -39,6 +39,19 @@
39#include <asm/irq.h> 39#include <asm/irq.h>
40#include <asm/uaccess.h> 40#include <asm/uaccess.h>
41 41
42static int genphy_config_init(struct phy_device *phydev);
43
44static struct phy_driver genphy_driver = {
45 .phy_id = 0xffffffff,
46 .phy_id_mask = 0xffffffff,
47 .name = "Generic PHY",
48 .config_init = genphy_config_init,
49 .features = 0,
50 .config_aneg = genphy_config_aneg,
51 .read_status = genphy_read_status,
52 .driver = {.owner = THIS_MODULE, },
53};
54
42/* get_phy_device 55/* get_phy_device
43 * 56 *
44 * description: Reads the ID registers of the PHY at addr on the 57 * description: Reads the ID registers of the PHY at addr on the
@@ -656,27 +669,32 @@ void phy_driver_unregister(struct phy_driver *drv)
656} 669}
657EXPORT_SYMBOL(phy_driver_unregister); 670EXPORT_SYMBOL(phy_driver_unregister);
658 671
659static struct phy_driver genphy_driver = {
660 .phy_id = 0xffffffff,
661 .phy_id_mask = 0xffffffff,
662 .name = "Generic PHY",
663 .config_init = genphy_config_init,
664 .features = 0,
665 .config_aneg = genphy_config_aneg,
666 .read_status = genphy_read_status,
667 .driver = {.owner = THIS_MODULE, },
668};
669 672
670static int __init genphy_init(void) 673static int __init phy_init(void)
671{ 674{
672 return phy_driver_register(&genphy_driver); 675 int rc;
676 extern int mdio_bus_init(void);
677
678 rc = phy_driver_register(&genphy_driver);
679 if (rc)
680 goto out;
681
682 rc = mdio_bus_init();
683 if (rc)
684 goto out_unreg;
673 685
686 return 0;
687
688out_unreg:
689 phy_driver_unregister(&genphy_driver);
690out:
691 return rc;
674} 692}
675 693
676static void __exit genphy_exit(void) 694static void __exit phy_exit(void)
677{ 695{
678 phy_driver_unregister(&genphy_driver); 696 phy_driver_unregister(&genphy_driver);
679} 697}
680 698
681module_init(genphy_init); 699module_init(phy_init);
682module_exit(genphy_exit); 700module_exit(phy_exit);