aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAndy Fleming <afleming@freescale.com>2006-11-08 01:11:29 -0500
committerJeff Garzik <jeff@garzik.org>2006-12-02 00:12:03 -0500
commit95d21ff4c64592bdee7f1af2925145bed849c994 (patch)
tree1ccbe1639e1253ee5386e1fe673334dbedf717fb /drivers/net
parentf2d71c2d800e68f158a5949e38b23f5140948548 (diff)
[PATCH] Add support for Marvell 88e1111S and 88e1145
This patch requires the new support for configurable PHY interfaces. Changes include: * New support for 88e1145 * New support for 88e111s * Fixing 88e1101 driver to not match non-88e1101 PHYs * Increases in feature support across Marvell PHY product line * Fixes a bunch of whitespace issues found by Lindent Signed-off-by: Andrew Fleming <afleming@freescale.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/phy/marvell.c156
1 files changed, 144 insertions, 12 deletions
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 0ad253282d0d..5320ab9fe018 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -43,6 +43,19 @@
43#define MII_M1011_IMASK_INIT 0x6400 43#define MII_M1011_IMASK_INIT 0x6400
44#define MII_M1011_IMASK_CLEAR 0x0000 44#define MII_M1011_IMASK_CLEAR 0x0000
45 45
46#define MII_M1011_PHY_SCR 0x10
47#define MII_M1011_PHY_SCR_AUTO_CROSS 0x0060
48
49#define MII_M1145_PHY_EXT_CR 0x14
50#define MII_M1145_RGMII_RX_DELAY 0x0080
51#define MII_M1145_RGMII_TX_DELAY 0x0002
52
53#define M1145_DEV_FLAGS_RESISTANCE 0x00000001
54
55#define MII_M1111_PHY_LED_CONTROL 0x18
56#define MII_M1111_PHY_LED_DIRECT 0x4100
57#define MII_M1111_PHY_LED_COMBINE 0x411c
58
46MODULE_DESCRIPTION("Marvell PHY driver"); 59MODULE_DESCRIPTION("Marvell PHY driver");
47MODULE_AUTHOR("Andy Fleming"); 60MODULE_AUTHOR("Andy Fleming");
48MODULE_LICENSE("GPL"); 61MODULE_LICENSE("GPL");
@@ -64,7 +77,7 @@ static int marvell_config_intr(struct phy_device *phydev)
64{ 77{
65 int err; 78 int err;
66 79
67 if(phydev->interrupts == PHY_INTERRUPT_ENABLED) 80 if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
68 err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_INIT); 81 err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_INIT);
69 else 82 else
70 err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR); 83 err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR);
@@ -104,34 +117,153 @@ static int marvell_config_aneg(struct phy_device *phydev)
104 if (err < 0) 117 if (err < 0)
105 return err; 118 return err;
106 119
120 err = phy_write(phydev, MII_M1011_PHY_SCR,
121 MII_M1011_PHY_SCR_AUTO_CROSS);
122 if (err < 0)
123 return err;
124
125 err = phy_write(phydev, MII_M1111_PHY_LED_CONTROL,
126 MII_M1111_PHY_LED_DIRECT);
127 if (err < 0)
128 return err;
107 129
108 err = genphy_config_aneg(phydev); 130 err = genphy_config_aneg(phydev);
109 131
110 return err; 132 return err;
111} 133}
112 134
135static int m88e1145_config_init(struct phy_device *phydev)
136{
137 int err;
138
139 /* Take care of errata E0 & E1 */
140 err = phy_write(phydev, 0x1d, 0x001b);
141 if (err < 0)
142 return err;
143
144 err = phy_write(phydev, 0x1e, 0x418f);
145 if (err < 0)
146 return err;
147
148 err = phy_write(phydev, 0x1d, 0x0016);
149 if (err < 0)
150 return err;
151
152 err = phy_write(phydev, 0x1e, 0xa2da);
153 if (err < 0)
154 return err;
155
156 if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
157 int temp = phy_read(phydev, MII_M1145_PHY_EXT_CR);
158 if (temp < 0)
159 return temp;
160
161 temp |= (MII_M1145_RGMII_RX_DELAY | MII_M1145_RGMII_TX_DELAY);
162
163 err = phy_write(phydev, MII_M1145_PHY_EXT_CR, temp);
164 if (err < 0)
165 return err;
166
167 if (phydev->dev_flags & M1145_DEV_FLAGS_RESISTANCE) {
168 err = phy_write(phydev, 0x1d, 0x0012);
169 if (err < 0)
170 return err;
171
172 temp = phy_read(phydev, 0x1e);
173 if (temp < 0)
174 return temp;
175
176 temp &= 0xf03f;
177 temp |= 2 << 9; /* 36 ohm */
178 temp |= 2 << 6; /* 39 ohm */
179
180 err = phy_write(phydev, 0x1e, temp);
181 if (err < 0)
182 return err;
183
184 err = phy_write(phydev, 0x1d, 0x3);
185 if (err < 0)
186 return err;
187
188 err = phy_write(phydev, 0x1e, 0x8000);
189 if (err < 0)
190 return err;
191 }
192 }
193
194 return 0;
195}
113 196
114static struct phy_driver m88e1101_driver = { 197static struct phy_driver m88e1101_driver = {
115 .phy_id = 0x01410c00, 198 .phy_id = 0x01410c60,
116 .phy_id_mask = 0xffffff00, 199 .phy_id_mask = 0xfffffff0,
117 .name = "Marvell 88E1101", 200 .name = "Marvell 88E1101",
118 .features = PHY_GBIT_FEATURES, 201 .features = PHY_GBIT_FEATURES,
119 .flags = PHY_HAS_INTERRUPT, 202 .flags = PHY_HAS_INTERRUPT,
120 .config_aneg = &marvell_config_aneg, 203 .config_aneg = &marvell_config_aneg,
121 .read_status = &genphy_read_status, 204 .read_status = &genphy_read_status,
122 .ack_interrupt = &marvell_ack_interrupt, 205 .ack_interrupt = &marvell_ack_interrupt,
123 .config_intr = &marvell_config_intr, 206 .config_intr = &marvell_config_intr,
124 .driver = { .owner = THIS_MODULE,}, 207 .driver = {.owner = THIS_MODULE,},
208};
209
210static struct phy_driver m88e1111s_driver = {
211 .phy_id = 0x01410cc0,
212 .phy_id_mask = 0xfffffff0,
213 .name = "Marvell 88E1111",
214 .features = PHY_GBIT_FEATURES,
215 .flags = PHY_HAS_INTERRUPT,
216 .config_aneg = &marvell_config_aneg,
217 .read_status = &genphy_read_status,
218 .ack_interrupt = &marvell_ack_interrupt,
219 .config_intr = &marvell_config_intr,
220 .driver = {.owner = THIS_MODULE,},
221};
222
223static struct phy_driver m88e1145_driver = {
224 .phy_id = 0x01410cd0,
225 .phy_id_mask = 0xfffffff0,
226 .name = "Marvell 88E1145",
227 .features = PHY_GBIT_FEATURES,
228 .flags = PHY_HAS_INTERRUPT,
229 .config_init = &m88e1145_config_init,
230 .config_aneg = &marvell_config_aneg,
231 .read_status = &genphy_read_status,
232 .ack_interrupt = &marvell_ack_interrupt,
233 .config_intr = &marvell_config_intr,
234 .driver = {.owner = THIS_MODULE,},
125}; 235};
126 236
127static int __init marvell_init(void) 237static int __init marvell_init(void)
128{ 238{
129 return phy_driver_register(&m88e1101_driver); 239 int ret;
240
241 ret = phy_driver_register(&m88e1101_driver);
242 if (ret)
243 return ret;
244
245 ret = phy_driver_register(&m88e1111s_driver);
246 if (ret)
247 goto err1111s;
248
249 ret = phy_driver_register(&m88e1145_driver);
250 if (ret)
251 goto err1145;
252
253 return 0;
254
255 err1145:
256 phy_driver_unregister(&m88e1111s_driver);
257 err1111s:
258 phy_driver_unregister(&m88e1101_driver);
259 return ret;
130} 260}
131 261
132static void __exit marvell_exit(void) 262static void __exit marvell_exit(void)
133{ 263{
134 phy_driver_unregister(&m88e1101_driver); 264 phy_driver_unregister(&m88e1101_driver);
265 phy_driver_unregister(&m88e1111s_driver);
266 phy_driver_unregister(&m88e1145_driver);
135} 267}
136 268
137module_init(marvell_init); 269module_init(marvell_init);