aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAndy Fleming <afleming@freescale.com>2005-07-30 19:31:23 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-07-30 19:31:23 -0400
commit00db8189d984d6c51226dafbbe4a667ce9b7d5da (patch)
treef19468548c938523e3519670f8554e7a1b9c0c31 /drivers/net
parentb0825488a642cadcf39709961dde61440cb0731c (diff)
This patch adds a PHY Abstraction Layer to the Linux Kernel, enabling
ethernet drivers to remain as ignorant as is reasonable of the connected PHY's design and operation details. Signed-off-by: Andy Fleming <afleming@freescale.com> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/Kconfig2
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/phy/Kconfig57
-rw-r--r--drivers/net/phy/Makefile9
-rw-r--r--drivers/net/phy/cicada.c134
-rw-r--r--drivers/net/phy/davicom.c195
-rw-r--r--drivers/net/phy/lxt.c179
-rw-r--r--drivers/net/phy/marvell.c140
-rw-r--r--drivers/net/phy/mdio_bus.c173
-rw-r--r--drivers/net/phy/phy.c862
-rw-r--r--drivers/net/phy/phy.c.orig860
-rw-r--r--drivers/net/phy/phy_device.c682
-rw-r--r--drivers/net/phy/qsemi.c143
13 files changed, 3437 insertions, 0 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 8a835eb58808..1e50b8e32add 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -131,6 +131,8 @@ config NET_SB1000
131 131
132 source "drivers/net/arcnet/Kconfig" 132 source "drivers/net/arcnet/Kconfig"
133 133
134source "drivers/net/phy/Kconfig"
135
134# 136#
135# Ethernet 137# Ethernet
136# 138#
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 63c6d1e6d4d9..a369ae284a9a 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
65# 65#
66 66
67obj-$(CONFIG_MII) += mii.o 67obj-$(CONFIG_MII) += mii.o
68obj-$(CONFIG_PHYLIB) += phy/
68 69
69obj-$(CONFIG_SUNDANCE) += sundance.o 70obj-$(CONFIG_SUNDANCE) += sundance.o
70obj-$(CONFIG_HAMACHI) += hamachi.o 71obj-$(CONFIG_HAMACHI) += hamachi.o
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
new file mode 100644
index 000000000000..8b5db2343cc3
--- /dev/null
+++ b/drivers/net/phy/Kconfig
@@ -0,0 +1,57 @@
1#
2# PHY Layer Configuration
3#
4
5menu "PHY device support"
6
7config PHYLIB
8 bool "PHY Device support and infrastructure"
9 depends on NET_ETHERNET
10 help
11 Ethernet controllers are usually attached to PHY
12 devices. This option provides infrastructure for
13 managing PHY devices.
14
15config PHYCONTROL
16 bool "Support for automatically handling PHY state changes"
17 depends on PHYLIB
18 help
19 Adds code to perform all the work for keeping PHY link
20 state (speed/duplex/etc) up-to-date. Also handles
21 interrupts.
22
23comment "MII PHY device drivers"
24 depends on PHYLIB
25
26config MARVELL_PHY
27 bool "Drivers for Marvell PHYs"
28 depends on PHYLIB
29 ---help---
30 Currently has a driver for the 88E1011S
31
32config DAVICOM_PHY
33 bool "Drivers for Davicom PHYs"
34 depends on PHYLIB
35 ---help---
36 Currently supports dm9161e and dm9131
37
38config QSEMI_PHY
39 bool "Drivers for Quality Semiconductor PHYs"
40 depends on PHYLIB
41 ---help---
42 Currently supports the qs6612
43
44config LXT_PHY
45 bool "Drivers for the Intel LXT PHYs"
46 depends on PHYLIB
47 ---help---
48 Currently supports the lxt970, lxt971
49
50config CICADA_PHY
51 bool "Drivers for the Cicada PHYs"
52 depends on PHYLIB
53 ---help---
54 Currently supports the cis8204
55
56endmenu
57
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
new file mode 100644
index 000000000000..1af05de6ced0
--- /dev/null
+++ b/drivers/net/phy/Makefile
@@ -0,0 +1,9 @@
1# Makefile for Linux PHY drivers
2
3obj-$(CONFIG_PHYLIB) += phy.o phy_device.o mdio_bus.o
4
5obj-$(CONFIG_MARVELL_PHY) += marvell.o
6obj-$(CONFIG_DAVICOM_PHY) += davicom.o
7obj-$(CONFIG_CICADA_PHY) += cicada.o
8obj-$(CONFIG_LXT_PHY) += lxt.o
9obj-$(CONFIG_QSEMI_PHY) += qsemi.o
diff --git a/drivers/net/phy/cicada.c b/drivers/net/phy/cicada.c
new file mode 100644
index 000000000000..c47fb2ecd147
--- /dev/null
+++ b/drivers/net/phy/cicada.c
@@ -0,0 +1,134 @@
1/*
2 * drivers/net/phy/cicada.c
3 *
4 * Driver for Cicada PHYs
5 *
6 * Author: Andy Fleming
7 *
8 * Copyright (c) 2004 Freescale Semiconductor, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */
16#include <linux/config.h>
17#include <linux/kernel.h>
18#include <linux/sched.h>
19#include <linux/string.h>
20#include <linux/errno.h>
21#include <linux/unistd.h>
22#include <linux/slab.h>
23#include <linux/interrupt.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/netdevice.h>
27#include <linux/etherdevice.h>
28#include <linux/skbuff.h>
29#include <linux/spinlock.h>
30#include <linux/mm.h>
31#include <linux/module.h>
32#include <linux/version.h>
33#include <linux/mii.h>
34#include <linux/ethtool.h>
35#include <linux/phy.h>
36
37#include <asm/io.h>
38#include <asm/irq.h>
39#include <asm/uaccess.h>
40
41/* Cicada Extended Control Register 1 */
42#define MII_CIS8201_EXT_CON1 0x17
43#define MII_CIS8201_EXTCON1_INIT 0x0000
44
45/* Cicada Interrupt Mask Register */
46#define MII_CIS8201_IMASK 0x19
47#define MII_CIS8201_IMASK_IEN 0x8000
48#define MII_CIS8201_IMASK_SPEED 0x4000
49#define MII_CIS8201_IMASK_LINK 0x2000
50#define MII_CIS8201_IMASK_DUPLEX 0x1000
51#define MII_CIS8201_IMASK_MASK 0xf000
52
53/* Cicada Interrupt Status Register */
54#define MII_CIS8201_ISTAT 0x1a
55#define MII_CIS8201_ISTAT_STATUS 0x8000
56#define MII_CIS8201_ISTAT_SPEED 0x4000
57#define MII_CIS8201_ISTAT_LINK 0x2000
58#define MII_CIS8201_ISTAT_DUPLEX 0x1000
59
60/* Cicada Auxiliary Control/Status Register */
61#define MII_CIS8201_AUX_CONSTAT 0x1c
62#define MII_CIS8201_AUXCONSTAT_INIT 0x0004
63#define MII_CIS8201_AUXCONSTAT_DUPLEX 0x0020
64#define MII_CIS8201_AUXCONSTAT_SPEED 0x0018
65#define MII_CIS8201_AUXCONSTAT_GBIT 0x0010
66#define MII_CIS8201_AUXCONSTAT_100 0x0008
67
68MODULE_DESCRIPTION("Cicadia PHY driver");
69MODULE_AUTHOR("Andy Fleming");
70MODULE_LICENSE("GPL");
71
72static int cis820x_config_init(struct phy_device *phydev)
73{
74 int err;
75
76 err = phy_write(phydev, MII_CIS8201_AUX_CONSTAT,
77 MII_CIS8201_AUXCONSTAT_INIT);
78
79 if (err < 0)
80 return err;
81
82 err = phy_write(phydev, MII_CIS8201_EXT_CON1,
83 MII_CIS8201_EXTCON1_INIT);
84
85 return err;
86}
87
88static int cis820x_ack_interrupt(struct phy_device *phydev)
89{
90 int err = phy_read(phydev, MII_CIS8201_ISTAT);
91
92 return (err < 0) ? err : 0;
93}
94
95static int cis820x_config_intr(struct phy_device *phydev)
96{
97 int err;
98
99 if(phydev->interrupts == PHY_INTERRUPT_ENABLED)
100 err = phy_write(phydev, MII_CIS8201_IMASK,
101 MII_CIS8201_IMASK_MASK);
102 else
103 err = phy_write(phydev, MII_CIS8201_IMASK, 0);
104
105 return err;
106}
107
108/* Cicada 820x */
109static struct phy_driver cis8204_driver = {
110 .phy_id = 0x000fc440,
111 .name = "Cicada Cis8204",
112 .phy_id_mask = 0x000fffc0,
113 .features = PHY_GBIT_FEATURES,
114 .flags = PHY_HAS_INTERRUPT,
115 .config_init = &cis820x_config_init,
116 .config_aneg = &genphy_config_aneg,
117 .read_status = &genphy_read_status,
118 .ack_interrupt = &cis820x_ack_interrupt,
119 .config_intr = &cis820x_config_intr,
120 .driver = { .owner = THIS_MODULE,},
121};
122
123static int __init cis8204_init(void)
124{
125 return phy_driver_register(&cis8204_driver);
126}
127
128static void __exit cis8204_exit(void)
129{
130 phy_driver_unregister(&cis8204_driver);
131}
132
133module_init(cis8204_init);
134module_exit(cis8204_exit);
diff --git a/drivers/net/phy/davicom.c b/drivers/net/phy/davicom.c
new file mode 100644
index 000000000000..6caf499fae32
--- /dev/null
+++ b/drivers/net/phy/davicom.c
@@ -0,0 +1,195 @@
1/*
2 * drivers/net/phy/davicom.c
3 *
4 * Driver for Davicom PHYs
5 *
6 * Author: Andy Fleming
7 *
8 * Copyright (c) 2004 Freescale Semiconductor, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */
16#include <linux/config.h>
17#include <linux/kernel.h>
18#include <linux/sched.h>
19#include <linux/string.h>
20#include <linux/errno.h>
21#include <linux/unistd.h>
22#include <linux/slab.h>
23#include <linux/interrupt.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/netdevice.h>
27#include <linux/etherdevice.h>
28#include <linux/skbuff.h>
29#include <linux/spinlock.h>
30#include <linux/mm.h>
31#include <linux/module.h>
32#include <linux/version.h>
33#include <linux/mii.h>
34#include <linux/ethtool.h>
35#include <linux/phy.h>
36
37#include <asm/io.h>
38#include <asm/irq.h>
39#include <asm/uaccess.h>
40
41#define MII_DM9161_SCR 0x10
42#define MII_DM9161_SCR_INIT 0x0610
43
44/* DM9161 Interrupt Register */
45#define MII_DM9161_INTR 0x15
46#define MII_DM9161_INTR_PEND 0x8000
47#define MII_DM9161_INTR_DPLX_MASK 0x0800
48#define MII_DM9161_INTR_SPD_MASK 0x0400
49#define MII_DM9161_INTR_LINK_MASK 0x0200
50#define MII_DM9161_INTR_MASK 0x0100
51#define MII_DM9161_INTR_DPLX_CHANGE 0x0010
52#define MII_DM9161_INTR_SPD_CHANGE 0x0008
53#define MII_DM9161_INTR_LINK_CHANGE 0x0004
54#define MII_DM9161_INTR_INIT 0x0000
55#define MII_DM9161_INTR_STOP \
56(MII_DM9161_INTR_DPLX_MASK | MII_DM9161_INTR_SPD_MASK \
57 | MII_DM9161_INTR_LINK_MASK | MII_DM9161_INTR_MASK)
58
59/* DM9161 10BT Configuration/Status */
60#define MII_DM9161_10BTCSR 0x12
61#define MII_DM9161_10BTCSR_INIT 0x7800
62
63MODULE_DESCRIPTION("Davicom PHY driver");
64MODULE_AUTHOR("Andy Fleming");
65MODULE_LICENSE("GPL");
66
67
68#define DM9161_DELAY 1
69static int dm9161_config_intr(struct phy_device *phydev)
70{
71 int temp;
72
73 temp = phy_read(phydev, MII_DM9161_INTR);
74
75 if (temp < 0)
76 return temp;
77
78 if(PHY_INTERRUPT_ENABLED == phydev->interrupts )
79 temp &= ~(MII_DM9161_INTR_STOP);
80 else
81 temp |= MII_DM9161_INTR_STOP;
82
83 temp = phy_write(phydev, MII_DM9161_INTR, temp);
84
85 return temp;
86}
87
88static int dm9161_config_aneg(struct phy_device *phydev)
89{
90 int err;
91
92 /* Isolate the PHY */
93 err = phy_write(phydev, MII_BMCR, BMCR_ISOLATE);
94
95 if (err < 0)
96 return err;
97
98 /* Configure the new settings */
99 err = genphy_config_aneg(phydev);
100
101 if (err < 0)
102 return err;
103
104 return 0;
105}
106
107static int dm9161_config_init(struct phy_device *phydev)
108{
109 int err;
110
111 /* Isolate the PHY */
112 err = phy_write(phydev, MII_BMCR, BMCR_ISOLATE);
113
114 if (err < 0)
115 return err;
116
117 /* Do not bypass the scrambler/descrambler */
118 err = phy_write(phydev, MII_DM9161_SCR, MII_DM9161_SCR_INIT);
119
120 if (err < 0)
121 return err;
122
123 /* Clear 10BTCSR to default */
124 err = phy_write(phydev, MII_DM9161_10BTCSR, MII_DM9161_10BTCSR_INIT);
125
126 if (err < 0)
127 return err;
128
129 /* Reconnect the PHY, and enable Autonegotiation */
130 err = phy_write(phydev, MII_BMCR, BMCR_ANENABLE);
131
132 if (err < 0)
133 return err;
134
135 return 0;
136}
137
138static int dm9161_ack_interrupt(struct phy_device *phydev)
139{
140 int err = phy_read(phydev, MII_DM9161_INTR);
141
142 return (err < 0) ? err : 0;
143}
144
145static struct phy_driver dm9161_driver = {
146 .phy_id = 0x0181b880,
147 .name = "Davicom DM9161E",
148 .phy_id_mask = 0x0ffffff0,
149 .features = PHY_BASIC_FEATURES,
150 .config_init = dm9161_config_init,
151 .config_aneg = dm9161_config_aneg,
152 .read_status = genphy_read_status,
153 .driver = { .owner = THIS_MODULE,},
154};
155
156static struct phy_driver dm9131_driver = {
157 .phy_id = 0x00181b80,
158 .name = "Davicom DM9131",
159 .phy_id_mask = 0x0ffffff0,
160 .features = PHY_BASIC_FEATURES,
161 .flags = PHY_HAS_INTERRUPT,
162 .config_aneg = genphy_config_aneg,
163 .read_status = genphy_read_status,
164 .ack_interrupt = dm9161_ack_interrupt,
165 .config_intr = dm9161_config_intr,
166 .driver = { .owner = THIS_MODULE,},
167};
168
169static int __init davicom_init(void)
170{
171 int ret;
172
173 ret = phy_driver_register(&dm9161_driver);
174 if (ret)
175 goto err1;
176
177 ret = phy_driver_register(&dm9131_driver);
178 if (ret)
179 goto err2;
180 return 0;
181
182 err2:
183 phy_driver_unregister(&dm9161_driver);
184 err1:
185 return ret;
186}
187
188static void __exit davicom_exit(void)
189{
190 phy_driver_unregister(&dm9161_driver);
191 phy_driver_unregister(&dm9131_driver);
192}
193
194module_init(davicom_init);
195module_exit(davicom_exit);
diff --git a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c
new file mode 100644
index 000000000000..4c840448ec86
--- /dev/null
+++ b/drivers/net/phy/lxt.c
@@ -0,0 +1,179 @@
1/*
2 * drivers/net/phy/lxt.c
3 *
4 * Driver for Intel LXT PHYs
5 *
6 * Author: Andy Fleming
7 *
8 * Copyright (c) 2004 Freescale Semiconductor, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */
16#include <linux/config.h>
17#include <linux/kernel.h>
18#include <linux/sched.h>
19#include <linux/string.h>
20#include <linux/errno.h>
21#include <linux/unistd.h>
22#include <linux/slab.h>
23#include <linux/interrupt.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/netdevice.h>
27#include <linux/etherdevice.h>
28#include <linux/skbuff.h>
29#include <linux/spinlock.h>
30#include <linux/mm.h>
31#include <linux/module.h>
32#include <linux/version.h>
33#include <linux/mii.h>
34#include <linux/ethtool.h>
35#include <linux/phy.h>
36
37#include <asm/io.h>
38#include <asm/irq.h>
39#include <asm/uaccess.h>
40
41/* The Level one LXT970 is used by many boards */
42
43#define MII_LXT970_IER 17 /* Interrupt Enable Register */
44
45#define MII_LXT970_IER_IEN 0x0002
46
47#define MII_LXT970_ISR 18 /* Interrupt Status Register */
48
49#define MII_LXT970_CONFIG 19 /* Configuration Register */
50
51/* ------------------------------------------------------------------------- */
52/* The Level one LXT971 is used on some of my custom boards */
53
54/* register definitions for the 971 */
55#define MII_LXT971_IER 18 /* Interrupt Enable Register */
56#define MII_LXT971_IER_IEN 0x00f2
57
58#define MII_LXT971_ISR 19 /* Interrupt Status Register */
59
60
61MODULE_DESCRIPTION("Intel LXT PHY driver");
62MODULE_AUTHOR("Andy Fleming");
63MODULE_LICENSE("GPL");
64
65static int lxt970_ack_interrupt(struct phy_device *phydev)
66{
67 int err;
68
69 err = phy_read(phydev, MII_BMSR);
70
71 if (err < 0)
72 return err;
73
74 err = phy_read(phydev, MII_LXT970_ISR);
75
76 if (err < 0)
77 return err;
78
79 return 0;
80}
81
82static int lxt970_config_intr(struct phy_device *phydev)
83{
84 int err;
85
86 if(phydev->interrupts == PHY_INTERRUPT_ENABLED)
87 err = phy_write(phydev, MII_LXT970_IER, MII_LXT970_IER_IEN);
88 else
89 err = phy_write(phydev, MII_LXT970_IER, 0);
90
91 return err;
92}
93
94static int lxt970_config_init(struct phy_device *phydev)
95{
96 int err;
97
98 err = phy_write(phydev, MII_LXT970_CONFIG, 0);
99
100 return err;
101}
102
103
104static int lxt971_ack_interrupt(struct phy_device *phydev)
105{
106 int err = phy_read(phydev, MII_LXT971_ISR);
107
108 if (err < 0)
109 return err;
110
111 return 0;
112}
113
114static int lxt971_config_intr(struct phy_device *phydev)
115{
116 int err;
117
118 if(phydev->interrupts == PHY_INTERRUPT_ENABLED)
119 err = phy_write(phydev, MII_LXT971_IER, MII_LXT971_IER_IEN);
120 else
121 err = phy_write(phydev, MII_LXT971_IER, 0);
122
123 return err;
124}
125
126static struct phy_driver lxt970_driver = {
127 .phy_id = 0x07810000,
128 .name = "LXT970",
129 .phy_id_mask = 0x0fffffff,
130 .features = PHY_BASIC_FEATURES,
131 .flags = PHY_HAS_INTERRUPT,
132 .config_init = lxt970_config_init,
133 .config_aneg = genphy_config_aneg,
134 .read_status = genphy_read_status,
135 .ack_interrupt = lxt970_ack_interrupt,
136 .config_intr = lxt970_config_intr,
137 .driver = { .owner = THIS_MODULE,},
138};
139
140static struct phy_driver lxt971_driver = {
141 .phy_id = 0x0001378e,
142 .name = "LXT971",
143 .phy_id_mask = 0x0fffffff,
144 .features = PHY_BASIC_FEATURES,
145 .flags = PHY_HAS_INTERRUPT,
146 .config_aneg = genphy_config_aneg,
147 .read_status = genphy_read_status,
148 .ack_interrupt = lxt971_ack_interrupt,
149 .config_intr = lxt971_config_intr,
150 .driver = { .owner = THIS_MODULE,},
151};
152
153static int __init lxt_init(void)
154{
155 int ret;
156
157 ret = phy_driver_register(&lxt970_driver);
158 if (ret)
159 goto err1;
160
161 ret = phy_driver_register(&lxt971_driver);
162 if (ret)
163 goto err2;
164 return 0;
165
166 err2:
167 phy_driver_unregister(&lxt970_driver);
168 err1:
169 return ret;
170}
171
172static void __exit lxt_exit(void)
173{
174 phy_driver_unregister(&lxt970_driver);
175 phy_driver_unregister(&lxt971_driver);
176}
177
178module_init(lxt_init);
179module_exit(lxt_exit);
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
new file mode 100644
index 000000000000..4a72b025006b
--- /dev/null
+++ b/drivers/net/phy/marvell.c
@@ -0,0 +1,140 @@
1/*
2 * drivers/net/phy/marvell.c
3 *
4 * Driver for Marvell PHYs
5 *
6 * Author: Andy Fleming
7 *
8 * Copyright (c) 2004 Freescale Semiconductor, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */
16#include <linux/config.h>
17#include <linux/kernel.h>
18#include <linux/sched.h>
19#include <linux/string.h>
20#include <linux/errno.h>
21#include <linux/unistd.h>
22#include <linux/slab.h>
23#include <linux/interrupt.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/netdevice.h>
27#include <linux/etherdevice.h>
28#include <linux/skbuff.h>
29#include <linux/spinlock.h>
30#include <linux/mm.h>
31#include <linux/module.h>
32#include <linux/version.h>
33#include <linux/mii.h>
34#include <linux/ethtool.h>
35#include <linux/phy.h>
36
37#include <asm/io.h>
38#include <asm/irq.h>
39#include <asm/uaccess.h>
40
41#define MII_M1011_IEVENT 0x13
42#define MII_M1011_IEVENT_CLEAR 0x0000
43
44#define MII_M1011_IMASK 0x12
45#define MII_M1011_IMASK_INIT 0x6400
46#define MII_M1011_IMASK_CLEAR 0x0000
47
48MODULE_DESCRIPTION("Marvell PHY driver");
49MODULE_AUTHOR("Andy Fleming");
50MODULE_LICENSE("GPL");
51
52static int marvell_ack_interrupt(struct phy_device *phydev)
53{
54 int err;
55
56 /* Clear the interrupts by reading the reg */
57 err = phy_read(phydev, MII_M1011_IEVENT);
58
59 if (err < 0)
60 return err;
61
62 return 0;
63}
64
65static int marvell_config_intr(struct phy_device *phydev)
66{
67 int err;
68
69 if(phydev->interrupts == PHY_INTERRUPT_ENABLED)
70 err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_INIT);
71 else
72 err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR);
73
74 return err;
75}
76
77static int marvell_config_aneg(struct phy_device *phydev)
78{
79 int err;
80
81 /* The Marvell PHY has an errata which requires
82 * that certain registers get written in order
83 * to restart autonegotiation */
84 err = phy_write(phydev, MII_BMCR, BMCR_RESET);
85
86 if (err < 0)
87 return err;
88
89 err = phy_write(phydev, 0x1d, 0x1f);
90 if (err < 0)
91 return err;
92
93 err = phy_write(phydev, 0x1e, 0x200c);
94 if (err < 0)
95 return err;
96
97 err = phy_write(phydev, 0x1d, 0x5);
98 if (err < 0)
99 return err;
100
101 err = phy_write(phydev, 0x1e, 0);
102 if (err < 0)
103 return err;
104
105 err = phy_write(phydev, 0x1e, 0x100);
106 if (err < 0)
107 return err;
108
109
110 err = genphy_config_aneg(phydev);
111
112 return err;
113}
114
115
116static struct phy_driver m88e1101_driver = {
117 .phy_id = 0x01410c00,
118 .phy_id_mask = 0xffffff00,
119 .name = "Marvell 88E1101",
120 .features = PHY_GBIT_FEATURES,
121 .flags = PHY_HAS_INTERRUPT,
122 .config_aneg = &marvell_config_aneg,
123 .read_status = &genphy_read_status,
124 .ack_interrupt = &marvell_ack_interrupt,
125 .config_intr = &marvell_config_intr,
126 .driver = { .owner = THIS_MODULE,},
127};
128
129static int __init marvell_init(void)
130{
131 return phy_driver_register(&m88e1101_driver);
132}
133
134static void __exit marvell_exit(void)
135{
136 phy_driver_unregister(&m88e1101_driver);
137}
138
139module_init(marvell_init);
140module_exit(marvell_exit);
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
new file mode 100644
index 000000000000..e75103ba6f86
--- /dev/null
+++ b/drivers/net/phy/mdio_bus.c
@@ -0,0 +1,173 @@
1/*
2 * drivers/net/phy/mdio_bus.c
3 *
4 * MDIO Bus interface
5 *
6 * Author: Andy Fleming
7 *
8 * Copyright (c) 2004 Freescale Semiconductor, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */
16#include <linux/config.h>
17#include <linux/kernel.h>
18#include <linux/sched.h>
19#include <linux/string.h>
20#include <linux/errno.h>
21#include <linux/unistd.h>
22#include <linux/slab.h>
23#include <linux/interrupt.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/netdevice.h>
27#include <linux/etherdevice.h>
28#include <linux/skbuff.h>
29#include <linux/spinlock.h>
30#include <linux/mm.h>
31#include <linux/module.h>
32#include <linux/version.h>
33#include <linux/mii.h>
34#include <linux/ethtool.h>
35#include <linux/phy.h>
36
37#include <asm/io.h>
38#include <asm/irq.h>
39#include <asm/uaccess.h>
40
41/* mdiobus_register
42 *
43 * description: Called by a bus driver to bring up all the PHYs
44 * on a given bus, and attach them to the bus
45 */
46int mdiobus_register(struct mii_bus *bus)
47{
48 int i;
49 int err = 0;
50
51 spin_lock_init(&bus->mdio_lock);
52
53 if (NULL == bus || NULL == bus->name ||
54 NULL == bus->read ||
55 NULL == bus->write)
56 return -EINVAL;
57
58 if (bus->reset)
59 bus->reset(bus);
60
61 for (i = 0; i < PHY_MAX_ADDR; i++) {
62 struct phy_device *phydev;
63
64 phydev = get_phy_device(bus, i);
65
66 if (IS_ERR(phydev))
67 return PTR_ERR(phydev);
68
69 /* There's a PHY at this address
70 * We need to set:
71 * 1) IRQ
72 * 2) bus_id
73 * 3) parent
74 * 4) bus
75 * 5) mii_bus
76 * And, we need to register it */
77 if (phydev) {
78 phydev->irq = bus->irq[i];
79
80 phydev->dev.parent = bus->dev;
81 phydev->dev.bus = &mdio_bus_type;
82 sprintf(phydev->dev.bus_id, "phy%d:%d", bus->id, i);
83
84 phydev->bus = bus;
85
86 err = device_register(&phydev->dev);
87
88 if (err)
89 printk(KERN_ERR "phy %d failed to register\n",
90 i);
91 }
92
93 bus->phy_map[i] = phydev;
94 }
95
96 pr_info("%s: probed\n", bus->name);
97
98 return err;
99}
100EXPORT_SYMBOL(mdiobus_register);
101
102void mdiobus_unregister(struct mii_bus *bus)
103{
104 int i;
105
106 for (i = 0; i < PHY_MAX_ADDR; i++) {
107 if (bus->phy_map[i]) {
108 device_unregister(&bus->phy_map[i]->dev);
109 kfree(bus->phy_map[i]);
110 }
111 }
112}
113EXPORT_SYMBOL(mdiobus_unregister);
114
115/* mdio_bus_match
116 *
117 * description: Given a PHY device, and a PHY driver, return 1 if
118 * the driver supports the device. Otherwise, return 0
119 */
120static int mdio_bus_match(struct device *dev, struct device_driver *drv)
121{
122 struct phy_device *phydev = to_phy_device(dev);
123 struct phy_driver *phydrv = to_phy_driver(drv);
124
125 return (phydrv->phy_id == (phydev->phy_id & phydrv->phy_id_mask));
126}
127
128/* Suspend and resume. Copied from platform_suspend and
129 * platform_resume
130 */
131static int mdio_bus_suspend(struct device * dev, u32 state)
132{
133 int ret = 0;
134 struct device_driver *drv = dev->driver;
135
136 if (drv && drv->suspend) {
137 ret = drv->suspend(dev, state, SUSPEND_DISABLE);
138 if (ret == 0)
139 ret = drv->suspend(dev, state, SUSPEND_SAVE_STATE);
140 if (ret == 0)
141 ret = drv->suspend(dev, state, SUSPEND_POWER_DOWN);
142 }
143 return ret;
144}
145
146static int mdio_bus_resume(struct device * dev)
147{
148 int ret = 0;
149 struct device_driver *drv = dev->driver;
150
151 if (drv && drv->resume) {
152 ret = drv->resume(dev, RESUME_POWER_ON);
153 if (ret == 0)
154 ret = drv->resume(dev, RESUME_RESTORE_STATE);
155 if (ret == 0)
156 ret = drv->resume(dev, RESUME_ENABLE);
157 }
158 return ret;
159}
160
161struct bus_type mdio_bus_type = {
162 .name = "mdio_bus",
163 .match = mdio_bus_match,
164 .suspend = mdio_bus_suspend,
165 .resume = mdio_bus_resume,
166};
167
168static int __init mdio_bus_init(void)
169{
170 return bus_register(&mdio_bus_type);
171}
172
173subsys_initcall(mdio_bus_init);
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
new file mode 100644
index 000000000000..e2c6896b92d2
--- /dev/null
+++ b/drivers/net/phy/phy.c
@@ -0,0 +1,862 @@
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}
516EXPORT_SYMBOL(phy_enable_interrupts);
517
518/* Disable the PHY interrupts from the PHY side */
519int phy_disable_interrupts(struct phy_device *phydev)
520{
521 int err;
522
523 /* Disable PHY interrupts */
524 err = phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED);
525
526 if (err)
527 goto phy_err;
528
529 /* Clear the interrupt */
530 err = phy_clear_interrupt(phydev);
531
532 if (err)
533 goto phy_err;
534
535 return 0;
536
537phy_err:
538 phy_error(phydev);
539
540 return err;
541}
542EXPORT_SYMBOL(phy_disable_interrupts);
543
544/* phy_start_interrupts
545 *
546 * description: Request the interrupt for the given PHY. If
547 * this fails, then we set irq to PHY_POLL.
548 * Otherwise, we enable the interrupts in the PHY.
549 * Returns 0 on success.
550 * This should only be called with a valid IRQ number.
551 */
552int phy_start_interrupts(struct phy_device *phydev)
553{
554 int err = 0;
555
556 INIT_WORK(&phydev->phy_queue, phy_change, phydev);
557
558 if (request_irq(phydev->irq, phy_interrupt,
559 SA_SHIRQ,
560 "phy_interrupt",
561 phydev) < 0) {
562 printk(KERN_WARNING "%s: Can't get IRQ %d (PHY)\n",
563 phydev->bus->name,
564 phydev->irq);
565 phydev->irq = PHY_POLL;
566 return 0;
567 }
568
569 err = phy_enable_interrupts(phydev);
570
571 return err;
572}
573EXPORT_SYMBOL(phy_start_interrupts);
574
575int phy_stop_interrupts(struct phy_device *phydev)
576{
577 int err;
578
579 err = phy_disable_interrupts(phydev);
580
581 if (err)
582 phy_error(phydev);
583
584 free_irq(phydev->irq, phydev);
585
586 return err;
587}
588EXPORT_SYMBOL(phy_stop_interrupts);
589
590
591/* Scheduled by the phy_interrupt/timer to handle PHY changes */
592static void phy_change(void *data)
593{
594 int err;
595 struct phy_device *phydev = data;
596
597 err = phy_disable_interrupts(phydev);
598
599 if (err)
600 goto phy_err;
601
602 spin_lock(&phydev->lock);
603 if ((PHY_RUNNING == phydev->state) || (PHY_NOLINK == phydev->state))
604 phydev->state = PHY_CHANGELINK;
605 spin_unlock(&phydev->lock);
606
607 enable_irq(phydev->irq);
608
609 /* Reenable interrupts */
610 err = phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED);
611
612 if (err)
613 goto irq_enable_err;
614
615 return;
616
617irq_enable_err:
618 disable_irq(phydev->irq);
619phy_err:
620 phy_error(phydev);
621}
622
623/* Bring down the PHY link, and stop checking the status. */
624void phy_stop(struct phy_device *phydev)
625{
626 spin_lock(&phydev->lock);
627
628 if (PHY_HALTED == phydev->state)
629 goto out_unlock;
630
631 if (phydev->irq != PHY_POLL) {
632 /* Clear any pending interrupts */
633 phy_clear_interrupt(phydev);
634
635 /* Disable PHY Interrupts */
636 phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED);
637 }
638
639 phydev->state = PHY_HALTED;
640
641out_unlock:
642 spin_unlock(&phydev->lock);
643}
644
645
646/* phy_start
647 *
648 * description: Indicates the attached device's readiness to
649 * handle PHY-related work. Used during startup to start the
650 * PHY, and after a call to phy_stop() to resume operation.
651 * Also used to indicate the MDIO bus has cleared an error
652 * condition.
653 */
654void phy_start(struct phy_device *phydev)
655{
656 spin_lock(&phydev->lock);
657
658 switch (phydev->state) {
659 case PHY_STARTING:
660 phydev->state = PHY_PENDING;
661 break;
662 case PHY_READY:
663 phydev->state = PHY_UP;
664 break;
665 case PHY_HALTED:
666 phydev->state = PHY_RESUMING;
667 default:
668 break;
669 }
670 spin_unlock(&phydev->lock);
671}
672EXPORT_SYMBOL(phy_stop);
673EXPORT_SYMBOL(phy_start);
674
675/* PHY timer which handles the state machine */
676static void phy_timer(unsigned long data)
677{
678 struct phy_device *phydev = (struct phy_device *)data;
679 int needs_aneg = 0;
680 int err = 0;
681
682 spin_lock(&phydev->lock);
683
684 if (phydev->adjust_state)
685 phydev->adjust_state(phydev->attached_dev);
686
687 switch(phydev->state) {
688 case PHY_DOWN:
689 case PHY_STARTING:
690 case PHY_READY:
691 case PHY_PENDING:
692 break;
693 case PHY_UP:
694 needs_aneg = 1;
695
696 phydev->link_timeout = PHY_AN_TIMEOUT;
697
698 break;
699 case PHY_AN:
700 /* Check if negotiation is done. Break
701 * if there's an error */
702 err = phy_aneg_done(phydev);
703 if (err < 0)
704 break;
705
706 /* If auto-negotiation is done, we change to
707 * either RUNNING, or NOLINK */
708 if (err > 0) {
709 err = phy_read_status(phydev);
710
711 if (err)
712 break;
713
714 if (phydev->link) {
715 phydev->state = PHY_RUNNING;
716 netif_carrier_on(phydev->attached_dev);
717 } else {
718 phydev->state = PHY_NOLINK;
719 netif_carrier_off(phydev->attached_dev);
720 }
721
722 phydev->adjust_link(phydev->attached_dev);
723
724 } else if (0 == phydev->link_timeout--) {
725 /* The counter expired, so either we
726 * switch to forced mode, or the
727 * magic_aneg bit exists, and we try aneg
728 * again */
729 if (!(phydev->drv->flags & PHY_HAS_MAGICANEG)) {
730 int idx;
731
732 /* We'll start from the
733 * fastest speed, and work
734 * our way down */
735 idx = phy_find_valid(0,
736 phydev->supported);
737
738 phydev->speed = settings[idx].speed;
739 phydev->duplex = settings[idx].duplex;
740
741 phydev->autoneg = AUTONEG_DISABLE;
742 phydev->state = PHY_FORCING;
743 phydev->link_timeout =
744 PHY_FORCE_TIMEOUT;
745
746 pr_info("Trying %d/%s\n",
747 phydev->speed,
748 DUPLEX_FULL ==
749 phydev->duplex ?
750 "FULL" : "HALF");
751 }
752
753 needs_aneg = 1;
754 }
755 break;
756 case PHY_NOLINK:
757 err = phy_read_status(phydev);
758
759 if (err)
760 break;
761
762 if (phydev->link) {
763 phydev->state = PHY_RUNNING;
764 netif_carrier_on(phydev->attached_dev);
765 phydev->adjust_link(phydev->attached_dev);
766 }
767 break;
768 case PHY_FORCING:
769 err = phy_read_status(phydev);
770
771 if (err)
772 break;
773
774 if (phydev->link) {
775 phydev->state = PHY_RUNNING;
776 netif_carrier_on(phydev->attached_dev);
777 } else {
778 if (0 == phydev->link_timeout--) {
779 phy_force_reduction(phydev);
780 needs_aneg = 1;
781 }
782 }
783
784 phydev->adjust_link(phydev->attached_dev);
785 break;
786 case PHY_RUNNING:
787 /* Only register a CHANGE if we are
788 * polling */
789 if (PHY_POLL == phydev->irq)
790 phydev->state = PHY_CHANGELINK;
791 break;
792 case PHY_CHANGELINK:
793 err = phy_read_status(phydev);
794
795 if (err)
796 break;
797
798 if (phydev->link) {
799 phydev->state = PHY_RUNNING;
800 netif_carrier_on(phydev->attached_dev);
801 } else {
802 phydev->state = PHY_NOLINK;
803 netif_carrier_off(phydev->attached_dev);
804 }
805
806 phydev->adjust_link(phydev->attached_dev);
807
808 if (PHY_POLL != phydev->irq)
809 err = phy_config_interrupt(phydev,
810 PHY_INTERRUPT_ENABLED);
811 break;
812 case PHY_HALTED:
813 if (phydev->link) {
814 phydev->link = 0;
815 netif_carrier_off(phydev->attached_dev);
816 phydev->adjust_link(phydev->attached_dev);
817 }
818 break;
819 case PHY_RESUMING:
820
821 err = phy_clear_interrupt(phydev);
822
823 if (err)
824 break;
825
826 err = phy_config_interrupt(phydev,
827 PHY_INTERRUPT_ENABLED);
828
829 if (err)
830 break;
831
832 if (AUTONEG_ENABLE == phydev->autoneg) {
833 err = phy_aneg_done(phydev);
834 if (err < 0)
835 break;
836
837 /* err > 0 if AN is done.
838 * Otherwise, it's 0, and we're
839 * still waiting for AN */
840 if (err > 0) {
841 phydev->state = PHY_RUNNING;
842 } else {
843 phydev->state = PHY_AN;
844 phydev->link_timeout = PHY_AN_TIMEOUT;
845 }
846 } else
847 phydev->state = PHY_RUNNING;
848 break;
849 }
850
851 spin_unlock(&phydev->lock);
852
853 if (needs_aneg)
854 err = phy_start_aneg(phydev);
855
856 if (err < 0)
857 phy_error(phydev);
858
859 mod_timer(&phydev->phy_timer, jiffies + PHY_STATE_TIME * HZ);
860}
861
862#endif /* CONFIG_PHYCONTROL */
diff --git a/drivers/net/phy/phy.c.orig b/drivers/net/phy/phy.c.orig
new file mode 100644
index 000000000000..6af17cec9ace
--- /dev/null
+++ b/drivers/net/phy/phy.c.orig
@@ -0,0 +1,860 @@
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
new file mode 100644
index 000000000000..f0595af4c837
--- /dev/null
+++ b/drivers/net/phy/phy_device.c
@@ -0,0 +1,682 @@
1/*
2 * drivers/net/phy/phy_device.c
3 *
4 * Framework for finding and configuring PHYs.
5 * Also contains generic PHY driver
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
42/* get_phy_device
43 *
44 * description: Reads the ID registers of the PHY at addr on the
45 * bus, then allocates and returns the phy_device to
46 * represent it.
47 */
48struct phy_device * get_phy_device(struct mii_bus *bus, int addr)
49{
50 int phy_reg;
51 u32 phy_id;
52 struct phy_device *dev = NULL;
53
54 /* Grab the bits from PHYIR1, and put them
55 * in the upper half */
56 phy_reg = bus->read(bus, addr, MII_PHYSID1);
57
58 if (phy_reg < 0)
59 return ERR_PTR(phy_reg);
60
61 phy_id = (phy_reg & 0xffff) << 16;
62
63 /* Grab the bits from PHYIR2, and put them in the lower half */
64 phy_reg = bus->read(bus, addr, MII_PHYSID2);
65
66 if (phy_reg < 0)
67 return ERR_PTR(phy_reg);
68
69 phy_id |= (phy_reg & 0xffff);
70
71 /* If the phy_id is all Fs, there is no device there */
72 if (0xffffffff == phy_id)
73 return NULL;
74
75 /* Otherwise, we allocate the device, and initialize the
76 * default values */
77 dev = kcalloc(1, sizeof(*dev), GFP_KERNEL);
78
79 if (NULL == dev)
80 return ERR_PTR(-ENOMEM);
81
82 dev->speed = 0;
83 dev->duplex = -1;
84 dev->pause = dev->asym_pause = 0;
85 dev->link = 1;
86
87 dev->autoneg = AUTONEG_ENABLE;
88
89 dev->addr = addr;
90 dev->phy_id = phy_id;
91 dev->bus = bus;
92
93 dev->state = PHY_DOWN;
94
95 spin_lock_init(&dev->lock);
96
97 return dev;
98}
99
100/* phy_prepare_link:
101 *
102 * description: Tells the PHY infrastructure to handle the
103 * gory details on monitoring link status (whether through
104 * polling or an interrupt), and to call back to the
105 * connected device driver when the link status changes.
106 * If you want to monitor your own link state, don't call
107 * this function */
108void phy_prepare_link(struct phy_device *phydev,
109 void (*handler)(struct net_device *))
110{
111 phydev->adjust_link = handler;
112}
113
114#ifdef CONFIG_PHYCONTROL
115/* phy_connect:
116 *
117 * description: Convenience function for connecting ethernet
118 * devices to PHY devices. The default behavior is for
119 * the PHY infrastructure to handle everything, and only notify
120 * the connected driver when the link status changes. If you
121 * don't want, or can't use the provided functionality, you may
122 * choose to call only the subset of functions which provide
123 * the desired functionality.
124 */
125struct phy_device * phy_connect(struct net_device *dev, const char *phy_id,
126 void (*handler)(struct net_device *), u32 flags)
127{
128 struct phy_device *phydev;
129
130 phydev = phy_attach(dev, phy_id, flags);
131
132 if (IS_ERR(phydev))
133 return phydev;
134
135 phy_prepare_link(phydev, handler);
136
137 phy_start_machine(phydev, NULL);
138
139 if (phydev->irq > 0)
140 phy_start_interrupts(phydev);
141
142 return phydev;
143}
144EXPORT_SYMBOL(phy_connect);
145
146void phy_disconnect(struct phy_device *phydev)
147{
148 if (phydev->irq > 0)
149 phy_stop_interrupts(phydev);
150
151 phy_stop_machine(phydev);
152
153 phydev->adjust_link = NULL;
154
155 phy_detach(phydev);
156}
157EXPORT_SYMBOL(phy_disconnect);
158
159#endif /* CONFIG_PHYCONTROL */
160
161/* phy_attach:
162 *
163 * description: Called by drivers to attach to a particular PHY
164 * device. The phy_device is found, and properly hooked up
165 * to the phy_driver. If no driver is attached, then the
166 * genphy_driver is used. The phy_device is given a ptr to
167 * the attaching device, and given a callback for link status
168 * change. The phy_device is returned to the attaching
169 * driver.
170 */
171static int phy_compare_id(struct device *dev, void *data)
172{
173 return strcmp((char *)data, dev->bus_id) ? 0 : 1;
174}
175
176struct phy_device *phy_attach(struct net_device *dev,
177 const char *phy_id, u32 flags)
178{
179 struct bus_type *bus = &mdio_bus_type;
180 struct phy_device *phydev;
181 struct device *d;
182
183 /* Search the list of PHY devices on the mdio bus for the
184 * PHY with the requested name */
185 d = bus_find_device(bus, NULL, (void *)phy_id, phy_compare_id);
186
187 if (d) {
188 phydev = to_phy_device(d);
189 } else {
190 printk(KERN_ERR "%s not found\n", phy_id);
191 return ERR_PTR(-ENODEV);
192 }
193
194 /* Assume that if there is no driver, that it doesn't
195 * exist, and we should use the genphy driver. */
196 if (NULL == d->driver) {
197 int err;
198 down_write(&d->bus->subsys.rwsem);
199 d->driver = &genphy_driver.driver;
200
201 err = d->driver->probe(d);
202
203 if (err < 0)
204 return ERR_PTR(err);
205
206 device_bind_driver(d);
207 up_write(&d->bus->subsys.rwsem);
208 }
209
210 if (phydev->attached_dev) {
211 printk(KERN_ERR "%s: %s already attached\n",
212 dev->name, phy_id);
213 return ERR_PTR(-EBUSY);
214 }
215
216 phydev->attached_dev = dev;
217
218 phydev->dev_flags = flags;
219
220 return phydev;
221}
222EXPORT_SYMBOL(phy_attach);
223
224void phy_detach(struct phy_device *phydev)
225{
226 phydev->attached_dev = NULL;
227
228 /* If the device had no specific driver before (i.e. - it
229 * was using the generic driver), we unbind the device
230 * from the generic driver so that there's a chance a
231 * real driver could be loaded */
232 if (phydev->dev.driver == &genphy_driver.driver) {
233 down_write(&phydev->dev.bus->subsys.rwsem);
234 device_release_driver(&phydev->dev);
235 up_write(&phydev->dev.bus->subsys.rwsem);
236 }
237}
238EXPORT_SYMBOL(phy_detach);
239
240
241/* Generic PHY support and helper functions */
242
243/* genphy_config_advert
244 *
245 * description: Writes MII_ADVERTISE with the appropriate values,
246 * after sanitizing the values to make sure we only advertise
247 * what is supported
248 */
249int genphy_config_advert(struct phy_device *phydev)
250{
251 u32 advertise;
252 int adv;
253 int err;
254
255 /* Only allow advertising what
256 * this PHY supports */
257 phydev->advertising &= phydev->supported;
258 advertise = phydev->advertising;
259
260 /* Setup standard advertisement */
261 adv = phy_read(phydev, MII_ADVERTISE);
262
263 if (adv < 0)
264 return adv;
265
266 adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
267 ADVERTISE_PAUSE_ASYM);
268 if (advertise & ADVERTISED_10baseT_Half)
269 adv |= ADVERTISE_10HALF;
270 if (advertise & ADVERTISED_10baseT_Full)
271 adv |= ADVERTISE_10FULL;
272 if (advertise & ADVERTISED_100baseT_Half)
273 adv |= ADVERTISE_100HALF;
274 if (advertise & ADVERTISED_100baseT_Full)
275 adv |= ADVERTISE_100FULL;
276 if (advertise & ADVERTISED_Pause)
277 adv |= ADVERTISE_PAUSE_CAP;
278 if (advertise & ADVERTISED_Asym_Pause)
279 adv |= ADVERTISE_PAUSE_ASYM;
280
281 err = phy_write(phydev, MII_ADVERTISE, adv);
282
283 if (err < 0)
284 return err;
285
286 /* Configure gigabit if it's supported */
287 if (phydev->supported & (SUPPORTED_1000baseT_Half |
288 SUPPORTED_1000baseT_Full)) {
289 adv = phy_read(phydev, MII_CTRL1000);
290
291 if (adv < 0)
292 return adv;
293
294 adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
295 if (advertise & SUPPORTED_1000baseT_Half)
296 adv |= ADVERTISE_1000HALF;
297 if (advertise & SUPPORTED_1000baseT_Full)
298 adv |= ADVERTISE_1000FULL;
299 err = phy_write(phydev, MII_CTRL1000, adv);
300
301 if (err < 0)
302 return err;
303 }
304
305 return adv;
306}
307EXPORT_SYMBOL(genphy_config_advert);
308
309/* genphy_setup_forced
310 *
311 * description: Configures MII_BMCR to force speed/duplex
312 * to the values in phydev. Assumes that the values are valid.
313 * Please see phy_sanitize_settings() */
314int genphy_setup_forced(struct phy_device *phydev)
315{
316 int ctl = BMCR_RESET;
317
318 phydev->pause = phydev->asym_pause = 0;
319
320 if (SPEED_1000 == phydev->speed)
321 ctl |= BMCR_SPEED1000;
322 else if (SPEED_100 == phydev->speed)
323 ctl |= BMCR_SPEED100;
324
325 if (DUPLEX_FULL == phydev->duplex)
326 ctl |= BMCR_FULLDPLX;
327
328 ctl = phy_write(phydev, MII_BMCR, ctl);
329
330 if (ctl < 0)
331 return ctl;
332
333 /* We just reset the device, so we'd better configure any
334 * settings the PHY requires to operate */
335 if (phydev->drv->config_init)
336 ctl = phydev->drv->config_init(phydev);
337
338 return ctl;
339}
340
341
342/* Enable and Restart Autonegotiation */
343int genphy_restart_aneg(struct phy_device *phydev)
344{
345 int ctl;
346
347 ctl = phy_read(phydev, MII_BMCR);
348
349 if (ctl < 0)
350 return ctl;
351
352 ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
353
354 /* Don't isolate the PHY if we're negotiating */
355 ctl &= ~(BMCR_ISOLATE);
356
357 ctl = phy_write(phydev, MII_BMCR, ctl);
358
359 return ctl;
360}
361
362
363/* genphy_config_aneg
364 *
365 * description: If auto-negotiation is enabled, we configure the
366 * advertising, and then restart auto-negotiation. If it is not
367 * enabled, then we write the BMCR
368 */
369int genphy_config_aneg(struct phy_device *phydev)
370{
371 int err = 0;
372
373 if (AUTONEG_ENABLE == phydev->autoneg) {
374 err = genphy_config_advert(phydev);
375
376 if (err < 0)
377 return err;
378
379 err = genphy_restart_aneg(phydev);
380 } else
381 err = genphy_setup_forced(phydev);
382
383 return err;
384}
385EXPORT_SYMBOL(genphy_config_aneg);
386
387/* genphy_update_link
388 *
389 * description: Update the value in phydev->link to reflect the
390 * current link value. In order to do this, we need to read
391 * the status register twice, keeping the second value
392 */
393int genphy_update_link(struct phy_device *phydev)
394{
395 int status;
396
397 /* Do a fake read */
398 status = phy_read(phydev, MII_BMSR);
399
400 if (status < 0)
401 return status;
402
403 /* Read link and autonegotiation status */
404 status = phy_read(phydev, MII_BMSR);
405
406 if (status < 0)
407 return status;
408
409 if ((status & BMSR_LSTATUS) == 0)
410 phydev->link = 0;
411 else
412 phydev->link = 1;
413
414 return 0;
415}
416
417/* genphy_read_status
418 *
419 * description: Check the link, then figure out the current state
420 * by comparing what we advertise with what the link partner
421 * advertises. Start by checking the gigabit possibilities,
422 * then move on to 10/100.
423 */
424int genphy_read_status(struct phy_device *phydev)
425{
426 int adv;
427 int err;
428 int lpa;
429 int lpagb = 0;
430
431 /* Update the link, but return if there
432 * was an error */
433 err = genphy_update_link(phydev);
434 if (err)
435 return err;
436
437 if (AUTONEG_ENABLE == phydev->autoneg) {
438 if (phydev->supported & (SUPPORTED_1000baseT_Half
439 | SUPPORTED_1000baseT_Full)) {
440 lpagb = phy_read(phydev, MII_STAT1000);
441
442 if (lpagb < 0)
443 return lpagb;
444
445 adv = phy_read(phydev, MII_CTRL1000);
446
447 if (adv < 0)
448 return adv;
449
450 lpagb &= adv << 2;
451 }
452
453 lpa = phy_read(phydev, MII_LPA);
454
455 if (lpa < 0)
456 return lpa;
457
458 adv = phy_read(phydev, MII_ADVERTISE);
459
460 if (adv < 0)
461 return adv;
462
463 lpa &= adv;
464
465 phydev->speed = SPEED_10;
466 phydev->duplex = DUPLEX_HALF;
467 phydev->pause = phydev->asym_pause = 0;
468
469 if (lpagb & (LPA_1000FULL | LPA_1000HALF)) {
470 phydev->speed = SPEED_1000;
471
472 if (lpagb & LPA_1000FULL)
473 phydev->duplex = DUPLEX_FULL;
474 } else if (lpa & (LPA_100FULL | LPA_100HALF)) {
475 phydev->speed = SPEED_100;
476
477 if (lpa & LPA_100FULL)
478 phydev->duplex = DUPLEX_FULL;
479 } else
480 if (lpa & LPA_10FULL)
481 phydev->duplex = DUPLEX_FULL;
482
483 if (phydev->duplex == DUPLEX_FULL){
484 phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0;
485 phydev->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0;
486 }
487 } else {
488 int bmcr = phy_read(phydev, MII_BMCR);
489 if (bmcr < 0)
490 return bmcr;
491
492 if (bmcr & BMCR_FULLDPLX)
493 phydev->duplex = DUPLEX_FULL;
494 else
495 phydev->duplex = DUPLEX_HALF;
496
497 if (bmcr & BMCR_SPEED1000)
498 phydev->speed = SPEED_1000;
499 else if (bmcr & BMCR_SPEED100)
500 phydev->speed = SPEED_100;
501 else
502 phydev->speed = SPEED_10;
503
504 phydev->pause = phydev->asym_pause = 0;
505 }
506
507 return 0;
508}
509EXPORT_SYMBOL(genphy_read_status);
510
511static int genphy_config_init(struct phy_device *phydev)
512{
513 u32 val;
514 u32 features;
515
516 /* For now, I'll claim that the generic driver supports
517 * all possible port types */
518 features = (SUPPORTED_TP | SUPPORTED_MII
519 | SUPPORTED_AUI | SUPPORTED_FIBRE |
520 SUPPORTED_BNC);
521
522 /* Do we support autonegotiation? */
523 val = phy_read(phydev, MII_BMSR);
524
525 if (val < 0)
526 return val;
527
528 if (val & BMSR_ANEGCAPABLE)
529 features |= SUPPORTED_Autoneg;
530
531 if (val & BMSR_100FULL)
532 features |= SUPPORTED_100baseT_Full;
533 if (val & BMSR_100HALF)
534 features |= SUPPORTED_100baseT_Half;
535 if (val & BMSR_10FULL)
536 features |= SUPPORTED_10baseT_Full;
537 if (val & BMSR_10HALF)
538 features |= SUPPORTED_10baseT_Half;
539
540 if (val & BMSR_ESTATEN) {
541 val = phy_read(phydev, MII_ESTATUS);
542
543 if (val < 0)
544 return val;
545
546 if (val & ESTATUS_1000_TFULL)
547 features |= SUPPORTED_1000baseT_Full;
548 if (val & ESTATUS_1000_THALF)
549 features |= SUPPORTED_1000baseT_Half;
550 }
551
552 phydev->supported = features;
553 phydev->advertising = features;
554
555 return 0;
556}
557
558
559/* phy_probe
560 *
561 * description: Take care of setting up the phy_device structure,
562 * set the state to READY (the driver's init function should
563 * set it to STARTING if needed).
564 */
565static int phy_probe(struct device *dev)
566{
567 struct phy_device *phydev;
568 struct phy_driver *phydrv;
569 struct device_driver *drv;
570 int err = 0;
571
572 phydev = to_phy_device(dev);
573
574 /* Make sure the driver is held.
575 * XXX -- Is this correct? */
576 drv = get_driver(phydev->dev.driver);
577 phydrv = to_phy_driver(drv);
578 phydev->drv = phydrv;
579
580 /* Disable the interrupt if the PHY doesn't support it */
581 if (!(phydrv->flags & PHY_HAS_INTERRUPT))
582 phydev->irq = PHY_POLL;
583
584 spin_lock(&phydev->lock);
585
586 /* Start out supporting everything. Eventually,
587 * a controller will attach, and may modify one
588 * or both of these values */
589 phydev->supported = phydrv->features;
590 phydev->advertising = phydrv->features;
591
592 /* Set the state to READY by default */
593 phydev->state = PHY_READY;
594
595 if (phydev->drv->probe)
596 err = phydev->drv->probe(phydev);
597
598 spin_unlock(&phydev->lock);
599
600 if (err < 0)
601 return err;
602
603 if (phydev->drv->config_init)
604 err = phydev->drv->config_init(phydev);
605
606 return err;
607}
608
609static int phy_remove(struct device *dev)
610{
611 struct phy_device *phydev;
612
613 phydev = to_phy_device(dev);
614
615 spin_lock(&phydev->lock);
616 phydev->state = PHY_DOWN;
617 spin_unlock(&phydev->lock);
618
619 if (phydev->drv->remove)
620 phydev->drv->remove(phydev);
621
622 put_driver(dev->driver);
623 phydev->drv = NULL;
624
625 return 0;
626}
627
628int phy_driver_register(struct phy_driver *new_driver)
629{
630 int retval;
631
632 memset(&new_driver->driver, 0, sizeof(new_driver->driver));
633 new_driver->driver.name = new_driver->name;
634 new_driver->driver.bus = &mdio_bus_type;
635 new_driver->driver.probe = phy_probe;
636 new_driver->driver.remove = phy_remove;
637
638 retval = driver_register(&new_driver->driver);
639
640 if (retval) {
641 printk(KERN_ERR "%s: Error %d in registering driver\n",
642 new_driver->name, retval);
643
644 return retval;
645 }
646
647 pr_info("%s: Registered new driver\n", new_driver->name);
648
649 return 0;
650}
651EXPORT_SYMBOL(phy_driver_register);
652
653void phy_driver_unregister(struct phy_driver *drv)
654{
655 driver_unregister(&drv->driver);
656}
657EXPORT_SYMBOL(phy_driver_unregister);
658
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
670static int __init genphy_init(void)
671{
672 return phy_driver_register(&genphy_driver);
673
674}
675
676static void __exit genphy_exit(void)
677{
678 phy_driver_unregister(&genphy_driver);
679}
680
681module_init(genphy_init);
682module_exit(genphy_exit);
diff --git a/drivers/net/phy/qsemi.c b/drivers/net/phy/qsemi.c
new file mode 100644
index 000000000000..d461ba457631
--- /dev/null
+++ b/drivers/net/phy/qsemi.c
@@ -0,0 +1,143 @@
1/*
2 * drivers/net/phy/qsemi.c
3 *
4 * Driver for Quality Semiconductor PHYs
5 *
6 * Author: Andy Fleming
7 *
8 * Copyright (c) 2004 Freescale Semiconductor, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */
16#include <linux/config.h>
17#include <linux/kernel.h>
18#include <linux/sched.h>
19#include <linux/string.h>
20#include <linux/errno.h>
21#include <linux/unistd.h>
22#include <linux/slab.h>
23#include <linux/interrupt.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/netdevice.h>
27#include <linux/etherdevice.h>
28#include <linux/skbuff.h>
29#include <linux/spinlock.h>
30#include <linux/mm.h>
31#include <linux/module.h>
32#include <linux/version.h>
33#include <linux/mii.h>
34#include <linux/ethtool.h>
35#include <linux/phy.h>
36
37#include <asm/io.h>
38#include <asm/irq.h>
39#include <asm/uaccess.h>
40
41/* ------------------------------------------------------------------------- */
42/* The Quality Semiconductor QS6612 is used on the RPX CLLF */
43
44/* register definitions */
45
46#define MII_QS6612_MCR 17 /* Mode Control Register */
47#define MII_QS6612_FTR 27 /* Factory Test Register */
48#define MII_QS6612_MCO 28 /* Misc. Control Register */
49#define MII_QS6612_ISR 29 /* Interrupt Source Register */
50#define MII_QS6612_IMR 30 /* Interrupt Mask Register */
51#define MII_QS6612_IMR_INIT 0x003a
52#define MII_QS6612_PCR 31 /* 100BaseTx PHY Control Reg. */
53
54#define QS6612_PCR_AN_COMPLETE 0x1000
55#define QS6612_PCR_RLBEN 0x0200
56#define QS6612_PCR_DCREN 0x0100
57#define QS6612_PCR_4B5BEN 0x0040
58#define QS6612_PCR_TX_ISOLATE 0x0020
59#define QS6612_PCR_MLT3_DIS 0x0002
60#define QS6612_PCR_SCRM_DESCRM 0x0001
61
62MODULE_DESCRIPTION("Quality Semiconductor PHY driver");
63MODULE_AUTHOR("Andy Fleming");
64MODULE_LICENSE("GPL");
65
66/* Returns 0, unless there's a write error */
67static int qs6612_config_init(struct phy_device *phydev)
68{
69 /* The PHY powers up isolated on the RPX,
70 * so send a command to allow operation.
71 * XXX - My docs indicate this should be 0x0940
72 * ...or something. The current value sets three
73 * reserved bits, bit 11, which specifies it should be
74 * set to one, bit 10, which specifies it should be set
75 * to 0, and bit 7, which doesn't specify. However, my
76 * docs are preliminary, and I will leave it like this
77 * until someone more knowledgable corrects me or it.
78 * -- Andy Fleming
79 */
80 return phy_write(phydev, MII_QS6612_PCR, 0x0dc0);
81}
82
83static int qs6612_ack_interrupt(struct phy_device *phydev)
84{
85 int err;
86
87 err = phy_read(phydev, MII_QS6612_ISR);
88
89 if (err < 0)
90 return err;
91
92 err = phy_read(phydev, MII_BMSR);
93
94 if (err < 0)
95 return err;
96
97 err = phy_read(phydev, MII_EXPANSION);
98
99 if (err < 0)
100 return err;
101
102 return 0;
103}
104
105static int qs6612_config_intr(struct phy_device *phydev)
106{
107 int err;
108 if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
109 err = phy_write(phydev, MII_QS6612_IMR,
110 MII_QS6612_IMR_INIT);
111 else
112 err = phy_write(phydev, MII_QS6612_IMR, 0);
113
114 return err;
115
116}
117
118static struct phy_driver qs6612_driver = {
119 .phy_id = 0x00181440,
120 .name = "QS6612",
121 .phy_id_mask = 0xfffffff0,
122 .features = PHY_BASIC_FEATURES,
123 .flags = PHY_HAS_INTERRUPT,
124 .config_init = qs6612_config_init,
125 .config_aneg = genphy_config_aneg,
126 .read_status = genphy_read_status,
127 .ack_interrupt = qs6612_ack_interrupt,
128 .config_intr = qs6612_config_intr,
129 .driver = { .owner = THIS_MODULE,},
130};
131
132static int __init qs6612_init(void)
133{
134 return phy_driver_register(&qs6612_driver);
135}
136
137static void __exit qs6612_exit(void)
138{
139 phy_driver_unregister(&qs6612_driver);
140}
141
142module_init(qs6612_init);
143module_exit(qs6612_exit);