xref: /linux/drivers/net/sungem_phy.c (revision cd354f1ae75e6466a7e31b727faede57a1f89ca5)
1 /*
2  * PHY drivers for the sungem ethernet driver.
3  *
4  * This file could be shared with other drivers.
5  *
6  * (c) 2002-2007, Benjamin Herrenscmidt (benh@kernel.crashing.org)
7  *
8  * TODO:
9  *  - Add support for PHYs that provide an IRQ line
10  *  - Eventually moved the entire polling state machine in
11  *    there (out of the eth driver), so that it can easily be
12  *    skipped on PHYs that implement it in hardware.
13  *  - On LXT971 & BCM5201, Apple uses some chip specific regs
14  *    to read the link status. Figure out why and if it makes
15  *    sense to do the same (magic aneg ?)
16  *  - Apple has some additional power management code for some
17  *    Broadcom PHYs that they "hide" from the OpenSource version
18  *    of darwin, still need to reverse engineer that
19  */
20 
21 
22 #include <linux/module.h>
23 
24 #include <linux/kernel.h>
25 #include <linux/types.h>
26 #include <linux/netdevice.h>
27 #include <linux/etherdevice.h>
28 #include <linux/mii.h>
29 #include <linux/ethtool.h>
30 #include <linux/delay.h>
31 
32 #ifdef CONFIG_PPC_PMAC
33 #include <asm/prom.h>
34 #endif
35 
36 #include "sungem_phy.h"
37 
38 /* Link modes of the BCM5400 PHY */
39 static const int phy_BCM5400_link_table[8][3] = {
40 	{ 0, 0, 0 },	/* No link */
41 	{ 0, 0, 0 },	/* 10BT Half Duplex */
42 	{ 1, 0, 0 },	/* 10BT Full Duplex */
43 	{ 0, 1, 0 },	/* 100BT Half Duplex */
44 	{ 0, 1, 0 },	/* 100BT Half Duplex */
45 	{ 1, 1, 0 },	/* 100BT Full Duplex*/
46 	{ 1, 0, 1 },	/* 1000BT */
47 	{ 1, 0, 1 },	/* 1000BT */
48 };
49 
50 static inline int __phy_read(struct mii_phy* phy, int id, int reg)
51 {
52 	return phy->mdio_read(phy->dev, id, reg);
53 }
54 
55 static inline void __phy_write(struct mii_phy* phy, int id, int reg, int val)
56 {
57 	phy->mdio_write(phy->dev, id, reg, val);
58 }
59 
60 static inline int phy_read(struct mii_phy* phy, int reg)
61 {
62 	return phy->mdio_read(phy->dev, phy->mii_id, reg);
63 }
64 
65 static inline void phy_write(struct mii_phy* phy, int reg, int val)
66 {
67 	phy->mdio_write(phy->dev, phy->mii_id, reg, val);
68 }
69 
70 static int reset_one_mii_phy(struct mii_phy* phy, int phy_id)
71 {
72 	u16 val;
73 	int limit = 10000;
74 
75 	val = __phy_read(phy, phy_id, MII_BMCR);
76 	val &= ~(BMCR_ISOLATE | BMCR_PDOWN);
77 	val |= BMCR_RESET;
78 	__phy_write(phy, phy_id, MII_BMCR, val);
79 
80 	udelay(100);
81 
82 	while (limit--) {
83 		val = __phy_read(phy, phy_id, MII_BMCR);
84 		if ((val & BMCR_RESET) == 0)
85 			break;
86 		udelay(10);
87 	}
88 	if ((val & BMCR_ISOLATE) && limit > 0)
89 		__phy_write(phy, phy_id, MII_BMCR, val & ~BMCR_ISOLATE);
90 
91 	return (limit <= 0);
92 }
93 
94 static int bcm5201_init(struct mii_phy* phy)
95 {
96 	u16 data;
97 
98 	data = phy_read(phy, MII_BCM5201_MULTIPHY);
99 	data &= ~MII_BCM5201_MULTIPHY_SUPERISOLATE;
100 	phy_write(phy, MII_BCM5201_MULTIPHY, data);
101 
102 	phy_write(phy, MII_BCM5201_INTERRUPT, 0);
103 
104 	return 0;
105 }
106 
107 static int bcm5201_suspend(struct mii_phy* phy)
108 {
109 	phy_write(phy, MII_BCM5201_INTERRUPT, 0);
110 	phy_write(phy, MII_BCM5201_MULTIPHY, MII_BCM5201_MULTIPHY_SUPERISOLATE);
111 
112 	return 0;
113 }
114 
115 static int bcm5221_init(struct mii_phy* phy)
116 {
117 	u16 data;
118 
119 	data = phy_read(phy, MII_BCM5221_TEST);
120 	phy_write(phy, MII_BCM5221_TEST,
121 		data | MII_BCM5221_TEST_ENABLE_SHADOWS);
122 
123 	data = phy_read(phy, MII_BCM5221_SHDOW_AUX_STAT2);
124 	phy_write(phy, MII_BCM5221_SHDOW_AUX_STAT2,
125 		data | MII_BCM5221_SHDOW_AUX_STAT2_APD);
126 
127 	data = phy_read(phy, MII_BCM5221_SHDOW_AUX_MODE4);
128 	phy_write(phy, MII_BCM5221_SHDOW_AUX_MODE4,
129 		data | MII_BCM5221_SHDOW_AUX_MODE4_CLKLOPWR);
130 
131 	data = phy_read(phy, MII_BCM5221_TEST);
132 	phy_write(phy, MII_BCM5221_TEST,
133 		data & ~MII_BCM5221_TEST_ENABLE_SHADOWS);
134 
135 	return 0;
136 }
137 
138 static int bcm5221_suspend(struct mii_phy* phy)
139 {
140 	u16 data;
141 
142 	data = phy_read(phy, MII_BCM5221_TEST);
143 	phy_write(phy, MII_BCM5221_TEST,
144 		data | MII_BCM5221_TEST_ENABLE_SHADOWS);
145 
146 	data = phy_read(phy, MII_BCM5221_SHDOW_AUX_MODE4);
147 	phy_write(phy, MII_BCM5221_SHDOW_AUX_MODE4,
148 		  data | MII_BCM5221_SHDOW_AUX_MODE4_IDDQMODE);
149 
150 	return 0;
151 }
152 
153 static int bcm5241_init(struct mii_phy* phy)
154 {
155 	u16 data;
156 
157 	data = phy_read(phy, MII_BCM5221_TEST);
158 	phy_write(phy, MII_BCM5221_TEST,
159 		data | MII_BCM5221_TEST_ENABLE_SHADOWS);
160 
161 	data = phy_read(phy, MII_BCM5221_SHDOW_AUX_STAT2);
162 	phy_write(phy, MII_BCM5221_SHDOW_AUX_STAT2,
163 		data | MII_BCM5221_SHDOW_AUX_STAT2_APD);
164 
165 	data = phy_read(phy, MII_BCM5221_SHDOW_AUX_MODE4);
166 	phy_write(phy, MII_BCM5221_SHDOW_AUX_MODE4,
167 		data & ~MII_BCM5241_SHDOW_AUX_MODE4_STANDBYPWR);
168 
169 	data = phy_read(phy, MII_BCM5221_TEST);
170 	phy_write(phy, MII_BCM5221_TEST,
171 		data & ~MII_BCM5221_TEST_ENABLE_SHADOWS);
172 
173 	return 0;
174 }
175 
176 static int bcm5241_suspend(struct mii_phy* phy)
177 {
178 	u16 data;
179 
180 	data = phy_read(phy, MII_BCM5221_TEST);
181 	phy_write(phy, MII_BCM5221_TEST,
182 		data | MII_BCM5221_TEST_ENABLE_SHADOWS);
183 
184 	data = phy_read(phy, MII_BCM5221_SHDOW_AUX_MODE4);
185 	phy_write(phy, MII_BCM5221_SHDOW_AUX_MODE4,
186 		  data | MII_BCM5241_SHDOW_AUX_MODE4_STANDBYPWR);
187 
188 	return 0;
189 }
190 
191 static int bcm5400_init(struct mii_phy* phy)
192 {
193 	u16 data;
194 
195 	/* Configure for gigabit full duplex */
196 	data = phy_read(phy, MII_BCM5400_AUXCONTROL);
197 	data |= MII_BCM5400_AUXCONTROL_PWR10BASET;
198 	phy_write(phy, MII_BCM5400_AUXCONTROL, data);
199 
200 	data = phy_read(phy, MII_BCM5400_GB_CONTROL);
201 	data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP;
202 	phy_write(phy, MII_BCM5400_GB_CONTROL, data);
203 
204 	udelay(100);
205 
206 	/* Reset and configure cascaded 10/100 PHY */
207 	(void)reset_one_mii_phy(phy, 0x1f);
208 
209 	data = __phy_read(phy, 0x1f, MII_BCM5201_MULTIPHY);
210 	data |= MII_BCM5201_MULTIPHY_SERIALMODE;
211 	__phy_write(phy, 0x1f, MII_BCM5201_MULTIPHY, data);
212 
213 	data = phy_read(phy, MII_BCM5400_AUXCONTROL);
214 	data &= ~MII_BCM5400_AUXCONTROL_PWR10BASET;
215 	phy_write(phy, MII_BCM5400_AUXCONTROL, data);
216 
217 	return 0;
218 }
219 
220 static int bcm5400_suspend(struct mii_phy* phy)
221 {
222 #if 0 /* Commented out in Darwin... someone has those dawn docs ? */
223 	phy_write(phy, MII_BMCR, BMCR_PDOWN);
224 #endif
225 	return 0;
226 }
227 
228 static int bcm5401_init(struct mii_phy* phy)
229 {
230 	u16 data;
231 	int rev;
232 
233 	rev = phy_read(phy, MII_PHYSID2) & 0x000f;
234 	if (rev == 0 || rev == 3) {
235 		/* Some revisions of 5401 appear to need this
236 		 * initialisation sequence to disable, according
237 		 * to OF, "tap power management"
238 		 *
239 		 * WARNING ! OF and Darwin don't agree on the
240 		 * register addresses. OF seem to interpret the
241 		 * register numbers below as decimal
242 		 *
243 		 * Note: This should (and does) match tg3_init_5401phy_dsp
244 		 *       in the tg3.c driver. -DaveM
245 		 */
246 		phy_write(phy, 0x18, 0x0c20);
247 		phy_write(phy, 0x17, 0x0012);
248 		phy_write(phy, 0x15, 0x1804);
249 		phy_write(phy, 0x17, 0x0013);
250 		phy_write(phy, 0x15, 0x1204);
251 		phy_write(phy, 0x17, 0x8006);
252 		phy_write(phy, 0x15, 0x0132);
253 		phy_write(phy, 0x17, 0x8006);
254 		phy_write(phy, 0x15, 0x0232);
255 		phy_write(phy, 0x17, 0x201f);
256 		phy_write(phy, 0x15, 0x0a20);
257 	}
258 
259 	/* Configure for gigabit full duplex */
260 	data = phy_read(phy, MII_BCM5400_GB_CONTROL);
261 	data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP;
262 	phy_write(phy, MII_BCM5400_GB_CONTROL, data);
263 
264 	udelay(10);
265 
266 	/* Reset and configure cascaded 10/100 PHY */
267 	(void)reset_one_mii_phy(phy, 0x1f);
268 
269 	data = __phy_read(phy, 0x1f, MII_BCM5201_MULTIPHY);
270 	data |= MII_BCM5201_MULTIPHY_SERIALMODE;
271 	__phy_write(phy, 0x1f, MII_BCM5201_MULTIPHY, data);
272 
273 	return 0;
274 }
275 
276 static int bcm5401_suspend(struct mii_phy* phy)
277 {
278 #if 0 /* Commented out in Darwin... someone has those dawn docs ? */
279 	phy_write(phy, MII_BMCR, BMCR_PDOWN);
280 #endif
281 	return 0;
282 }
283 
284 static int bcm5411_init(struct mii_phy* phy)
285 {
286 	u16 data;
287 
288 	/* Here's some more Apple black magic to setup
289 	 * some voltage stuffs.
290 	 */
291 	phy_write(phy, 0x1c, 0x8c23);
292 	phy_write(phy, 0x1c, 0x8ca3);
293 	phy_write(phy, 0x1c, 0x8c23);
294 
295 	/* Here, Apple seems to want to reset it, do
296 	 * it as well
297 	 */
298 	phy_write(phy, MII_BMCR, BMCR_RESET);
299 	phy_write(phy, MII_BMCR, 0x1340);
300 
301 	data = phy_read(phy, MII_BCM5400_GB_CONTROL);
302 	data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP;
303 	phy_write(phy, MII_BCM5400_GB_CONTROL, data);
304 
305 	udelay(10);
306 
307 	/* Reset and configure cascaded 10/100 PHY */
308 	(void)reset_one_mii_phy(phy, 0x1f);
309 
310 	return 0;
311 }
312 
313 static int generic_suspend(struct mii_phy* phy)
314 {
315 	phy_write(phy, MII_BMCR, BMCR_PDOWN);
316 
317 	return 0;
318 }
319 
320 static int bcm5421_init(struct mii_phy* phy)
321 {
322 	u16 data;
323 	unsigned int id;
324 
325 	id = (phy_read(phy, MII_PHYSID1) << 16 | phy_read(phy, MII_PHYSID2));
326 
327 	/* Revision 0 of 5421 needs some fixups */
328 	if (id == 0x002060e0) {
329 		/* This is borrowed from MacOS
330 		 */
331 		phy_write(phy, 0x18, 0x1007);
332 		data = phy_read(phy, 0x18);
333 		phy_write(phy, 0x18, data | 0x0400);
334 		phy_write(phy, 0x18, 0x0007);
335 		data = phy_read(phy, 0x18);
336 		phy_write(phy, 0x18, data | 0x0800);
337 		phy_write(phy, 0x17, 0x000a);
338 		data = phy_read(phy, 0x15);
339 		phy_write(phy, 0x15, data | 0x0200);
340 	}
341 
342 	/* Pick up some init code from OF for K2 version */
343 	if ((id & 0xfffffff0) == 0x002062e0) {
344 		phy_write(phy, 4, 0x01e1);
345 		phy_write(phy, 9, 0x0300);
346 	}
347 
348 	/* Check if we can enable automatic low power */
349 #ifdef CONFIG_PPC_PMAC
350 	if (phy->platform_data) {
351 		struct device_node *np = of_get_parent(phy->platform_data);
352 		int can_low_power = 1;
353 		if (np == NULL || get_property(np, "no-autolowpower", NULL))
354 			can_low_power = 0;
355 		if (can_low_power) {
356 			/* Enable automatic low-power */
357 			phy_write(phy, 0x1c, 0x9002);
358 			phy_write(phy, 0x1c, 0xa821);
359 			phy_write(phy, 0x1c, 0x941d);
360 		}
361 	}
362 #endif /* CONFIG_PPC_PMAC */
363 
364 	return 0;
365 }
366 
367 static int bcm5421_enable_fiber(struct mii_phy* phy)
368 {
369 	/* enable fiber mode */
370 	phy_write(phy, MII_NCONFIG, 0x9020);
371 	/* LEDs active in both modes, autosense prio = fiber */
372 	phy_write(phy, MII_NCONFIG, 0x945f);
373 
374 	/* switch off fibre autoneg */
375 	phy_write(phy, MII_NCONFIG, 0xfc01);
376 	phy_write(phy, 0x0b, 0x0004);
377 
378 	return 0;
379 }
380 
381 static int bcm5461_enable_fiber(struct mii_phy* phy)
382 {
383 	phy_write(phy, MII_NCONFIG, 0xfc0c);
384 	phy_write(phy, MII_BMCR, 0x4140);
385 	phy_write(phy, MII_NCONFIG, 0xfc0b);
386 	phy_write(phy, MII_BMCR, 0x0140);
387 
388 	return 0;
389 }
390 
391 static int bcm54xx_setup_aneg(struct mii_phy *phy, u32 advertise)
392 {
393 	u16 ctl, adv;
394 
395 	phy->autoneg = 1;
396 	phy->speed = SPEED_10;
397 	phy->duplex = DUPLEX_HALF;
398 	phy->pause = 0;
399 	phy->advertising = advertise;
400 
401 	/* Setup standard advertise */
402 	adv = phy_read(phy, MII_ADVERTISE);
403 	adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
404 	if (advertise & ADVERTISED_10baseT_Half)
405 		adv |= ADVERTISE_10HALF;
406 	if (advertise & ADVERTISED_10baseT_Full)
407 		adv |= ADVERTISE_10FULL;
408 	if (advertise & ADVERTISED_100baseT_Half)
409 		adv |= ADVERTISE_100HALF;
410 	if (advertise & ADVERTISED_100baseT_Full)
411 		adv |= ADVERTISE_100FULL;
412 	if (advertise & ADVERTISED_Pause)
413 		adv |= ADVERTISE_PAUSE_CAP;
414 	if (advertise & ADVERTISED_Asym_Pause)
415 		adv |= ADVERTISE_PAUSE_ASYM;
416 	phy_write(phy, MII_ADVERTISE, adv);
417 
418 	/* Setup 1000BT advertise */
419 	adv = phy_read(phy, MII_1000BASETCONTROL);
420 	adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP|MII_1000BASETCONTROL_HALFDUPLEXCAP);
421 	if (advertise & SUPPORTED_1000baseT_Half)
422 		adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP;
423 	if (advertise & SUPPORTED_1000baseT_Full)
424 		adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP;
425 	phy_write(phy, MII_1000BASETCONTROL, adv);
426 
427 	/* Start/Restart aneg */
428 	ctl = phy_read(phy, MII_BMCR);
429 	ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
430 	phy_write(phy, MII_BMCR, ctl);
431 
432 	return 0;
433 }
434 
435 static int bcm54xx_setup_forced(struct mii_phy *phy, int speed, int fd)
436 {
437 	u16 ctl;
438 
439 	phy->autoneg = 0;
440 	phy->speed = speed;
441 	phy->duplex = fd;
442 	phy->pause = 0;
443 
444 	ctl = phy_read(phy, MII_BMCR);
445 	ctl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_SPD2|BMCR_ANENABLE);
446 
447 	/* First reset the PHY */
448 	phy_write(phy, MII_BMCR, ctl | BMCR_RESET);
449 
450 	/* Select speed & duplex */
451 	switch(speed) {
452 	case SPEED_10:
453 		break;
454 	case SPEED_100:
455 		ctl |= BMCR_SPEED100;
456 		break;
457 	case SPEED_1000:
458 		ctl |= BMCR_SPD2;
459 	}
460 	if (fd == DUPLEX_FULL)
461 		ctl |= BMCR_FULLDPLX;
462 
463 	// XXX Should we set the sungem to GII now on 1000BT ?
464 
465 	phy_write(phy, MII_BMCR, ctl);
466 
467 	return 0;
468 }
469 
470 static int bcm54xx_read_link(struct mii_phy *phy)
471 {
472 	int link_mode;
473 	u16 val;
474 
475 	if (phy->autoneg) {
476 	    	val = phy_read(phy, MII_BCM5400_AUXSTATUS);
477 		link_mode = ((val & MII_BCM5400_AUXSTATUS_LINKMODE_MASK) >>
478 			     MII_BCM5400_AUXSTATUS_LINKMODE_SHIFT);
479 		phy->duplex = phy_BCM5400_link_table[link_mode][0] ?
480 			DUPLEX_FULL : DUPLEX_HALF;
481 		phy->speed = phy_BCM5400_link_table[link_mode][2] ?
482 				SPEED_1000 :
483 				(phy_BCM5400_link_table[link_mode][1] ?
484 				 SPEED_100 : SPEED_10);
485 		val = phy_read(phy, MII_LPA);
486 		phy->pause = (phy->duplex == DUPLEX_FULL) &&
487 			((val & LPA_PAUSE) != 0);
488 	}
489 	/* On non-aneg, we assume what we put in BMCR is the speed,
490 	 * though magic-aneg shouldn't prevent this case from occurring
491 	 */
492 
493 	return 0;
494 }
495 
496 static int marvell88e1111_init(struct mii_phy* phy)
497 {
498 	u16 rev;
499 
500 	/* magic init sequence for rev 0 */
501 	rev = phy_read(phy, MII_PHYSID2) & 0x000f;
502 	if (rev == 0) {
503 		phy_write(phy, 0x1d, 0x000a);
504 		phy_write(phy, 0x1e, 0x0821);
505 
506 		phy_write(phy, 0x1d, 0x0006);
507 		phy_write(phy, 0x1e, 0x8600);
508 
509 		phy_write(phy, 0x1d, 0x000b);
510 		phy_write(phy, 0x1e, 0x0100);
511 
512 		phy_write(phy, 0x1d, 0x0004);
513 		phy_write(phy, 0x1e, 0x4850);
514 	}
515 	return 0;
516 }
517 
518 static int marvell_setup_aneg(struct mii_phy *phy, u32 advertise)
519 {
520 	u16 ctl, adv;
521 
522 	phy->autoneg = 1;
523 	phy->speed = SPEED_10;
524 	phy->duplex = DUPLEX_HALF;
525 	phy->pause = 0;
526 	phy->advertising = advertise;
527 
528 	/* Setup standard advertise */
529 	adv = phy_read(phy, MII_ADVERTISE);
530 	adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
531 	if (advertise & ADVERTISED_10baseT_Half)
532 		adv |= ADVERTISE_10HALF;
533 	if (advertise & ADVERTISED_10baseT_Full)
534 		adv |= ADVERTISE_10FULL;
535 	if (advertise & ADVERTISED_100baseT_Half)
536 		adv |= ADVERTISE_100HALF;
537 	if (advertise & ADVERTISED_100baseT_Full)
538 		adv |= ADVERTISE_100FULL;
539 	if (advertise & ADVERTISED_Pause)
540 		adv |= ADVERTISE_PAUSE_CAP;
541 	if (advertise & ADVERTISED_Asym_Pause)
542 		adv |= ADVERTISE_PAUSE_ASYM;
543 	phy_write(phy, MII_ADVERTISE, adv);
544 
545 	/* Setup 1000BT advertise & enable crossover detect
546 	 * XXX How do we advertise 1000BT ? Darwin source is
547 	 * confusing here, they read from specific control and
548 	 * write to control... Someone has specs for those
549 	 * beasts ?
550 	 */
551 	adv = phy_read(phy, MII_M1011_PHY_SPEC_CONTROL);
552 	adv |= MII_M1011_PHY_SPEC_CONTROL_AUTO_MDIX;
553 	adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP |
554 			MII_1000BASETCONTROL_HALFDUPLEXCAP);
555 	if (advertise & SUPPORTED_1000baseT_Half)
556 		adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP;
557 	if (advertise & SUPPORTED_1000baseT_Full)
558 		adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP;
559 	phy_write(phy, MII_1000BASETCONTROL, adv);
560 
561 	/* Start/Restart aneg */
562 	ctl = phy_read(phy, MII_BMCR);
563 	ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
564 	phy_write(phy, MII_BMCR, ctl);
565 
566 	return 0;
567 }
568 
569 static int marvell_setup_forced(struct mii_phy *phy, int speed, int fd)
570 {
571 	u16 ctl, ctl2;
572 
573 	phy->autoneg = 0;
574 	phy->speed = speed;
575 	phy->duplex = fd;
576 	phy->pause = 0;
577 
578 	ctl = phy_read(phy, MII_BMCR);
579 	ctl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_SPD2|BMCR_ANENABLE);
580 	ctl |= BMCR_RESET;
581 
582 	/* Select speed & duplex */
583 	switch(speed) {
584 	case SPEED_10:
585 		break;
586 	case SPEED_100:
587 		ctl |= BMCR_SPEED100;
588 		break;
589 	/* I'm not sure about the one below, again, Darwin source is
590 	 * quite confusing and I lack chip specs
591 	 */
592 	case SPEED_1000:
593 		ctl |= BMCR_SPD2;
594 	}
595 	if (fd == DUPLEX_FULL)
596 		ctl |= BMCR_FULLDPLX;
597 
598 	/* Disable crossover. Again, the way Apple does it is strange,
599 	 * though I don't assume they are wrong ;)
600 	 */
601 	ctl2 = phy_read(phy, MII_M1011_PHY_SPEC_CONTROL);
602 	ctl2 &= ~(MII_M1011_PHY_SPEC_CONTROL_MANUAL_MDIX |
603 		MII_M1011_PHY_SPEC_CONTROL_AUTO_MDIX |
604 		MII_1000BASETCONTROL_FULLDUPLEXCAP |
605 		MII_1000BASETCONTROL_HALFDUPLEXCAP);
606 	if (speed == SPEED_1000)
607 		ctl2 |= (fd == DUPLEX_FULL) ?
608 			MII_1000BASETCONTROL_FULLDUPLEXCAP :
609 			MII_1000BASETCONTROL_HALFDUPLEXCAP;
610 	phy_write(phy, MII_1000BASETCONTROL, ctl2);
611 
612 	// XXX Should we set the sungem to GII now on 1000BT ?
613 
614 	phy_write(phy, MII_BMCR, ctl);
615 
616 	return 0;
617 }
618 
619 static int marvell_read_link(struct mii_phy *phy)
620 {
621 	u16 status, pmask;
622 
623 	if (phy->autoneg) {
624 		status = phy_read(phy, MII_M1011_PHY_SPEC_STATUS);
625 		if ((status & MII_M1011_PHY_SPEC_STATUS_RESOLVED) == 0)
626 			return -EAGAIN;
627 		if (status & MII_M1011_PHY_SPEC_STATUS_1000)
628 			phy->speed = SPEED_1000;
629 		else if (status & MII_M1011_PHY_SPEC_STATUS_100)
630 			phy->speed = SPEED_100;
631 		else
632 			phy->speed = SPEED_10;
633 		if (status & MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX)
634 			phy->duplex = DUPLEX_FULL;
635 		else
636 			phy->duplex = DUPLEX_HALF;
637 		pmask = MII_M1011_PHY_SPEC_STATUS_TX_PAUSE |
638 			MII_M1011_PHY_SPEC_STATUS_RX_PAUSE;
639 		phy->pause = (status & pmask) == pmask;
640 	}
641 	/* On non-aneg, we assume what we put in BMCR is the speed,
642 	 * though magic-aneg shouldn't prevent this case from occurring
643 	 */
644 
645 	return 0;
646 }
647 
648 static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise)
649 {
650 	u16 ctl, adv;
651 
652 	phy->autoneg = 1;
653 	phy->speed = SPEED_10;
654 	phy->duplex = DUPLEX_HALF;
655 	phy->pause = 0;
656 	phy->advertising = advertise;
657 
658 	/* Setup standard advertise */
659 	adv = phy_read(phy, MII_ADVERTISE);
660 	adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
661 	if (advertise & ADVERTISED_10baseT_Half)
662 		adv |= ADVERTISE_10HALF;
663 	if (advertise & ADVERTISED_10baseT_Full)
664 		adv |= ADVERTISE_10FULL;
665 	if (advertise & ADVERTISED_100baseT_Half)
666 		adv |= ADVERTISE_100HALF;
667 	if (advertise & ADVERTISED_100baseT_Full)
668 		adv |= ADVERTISE_100FULL;
669 	if (advertise & ADVERTISED_Pause)
670 		adv |= ADVERTISE_PAUSE_CAP;
671 	if (advertise & ADVERTISED_Asym_Pause)
672 		adv |= ADVERTISE_PAUSE_ASYM;
673 	phy_write(phy, MII_ADVERTISE, adv);
674 
675 	/* Start/Restart aneg */
676 	ctl = phy_read(phy, MII_BMCR);
677 	ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
678 	phy_write(phy, MII_BMCR, ctl);
679 
680 	return 0;
681 }
682 
683 static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd)
684 {
685 	u16 ctl;
686 
687 	phy->autoneg = 0;
688 	phy->speed = speed;
689 	phy->duplex = fd;
690 	phy->pause = 0;
691 
692 	ctl = phy_read(phy, MII_BMCR);
693 	ctl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_ANENABLE);
694 
695 	/* First reset the PHY */
696 	phy_write(phy, MII_BMCR, ctl | BMCR_RESET);
697 
698 	/* Select speed & duplex */
699 	switch(speed) {
700 	case SPEED_10:
701 		break;
702 	case SPEED_100:
703 		ctl |= BMCR_SPEED100;
704 		break;
705 	case SPEED_1000:
706 	default:
707 		return -EINVAL;
708 	}
709 	if (fd == DUPLEX_FULL)
710 		ctl |= BMCR_FULLDPLX;
711 	phy_write(phy, MII_BMCR, ctl);
712 
713 	return 0;
714 }
715 
716 static int genmii_poll_link(struct mii_phy *phy)
717 {
718 	u16 status;
719 
720 	(void)phy_read(phy, MII_BMSR);
721 	status = phy_read(phy, MII_BMSR);
722 	if ((status & BMSR_LSTATUS) == 0)
723 		return 0;
724 	if (phy->autoneg && !(status & BMSR_ANEGCOMPLETE))
725 		return 0;
726 	return 1;
727 }
728 
729 static int genmii_read_link(struct mii_phy *phy)
730 {
731 	u16 lpa;
732 
733 	if (phy->autoneg) {
734 		lpa = phy_read(phy, MII_LPA);
735 
736 		if (lpa & (LPA_10FULL | LPA_100FULL))
737 			phy->duplex = DUPLEX_FULL;
738 		else
739 			phy->duplex = DUPLEX_HALF;
740 		if (lpa & (LPA_100FULL | LPA_100HALF))
741 			phy->speed = SPEED_100;
742 		else
743 			phy->speed = SPEED_10;
744 		phy->pause = (phy->duplex == DUPLEX_FULL) &&
745 			((lpa & LPA_PAUSE) != 0);
746 	}
747 	/* On non-aneg, we assume what we put in BMCR is the speed,
748 	 * though magic-aneg shouldn't prevent this case from occurring
749 	 */
750 
751 	 return 0;
752 }
753 
754 
755 #define MII_BASIC_FEATURES \
756 	(SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |	\
757 	 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |	\
758 	 SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII |	\
759 	 SUPPORTED_Pause)
760 
761 /* On gigabit capable PHYs, we advertise Pause support but not asym pause
762  * support for now as I'm not sure it's supported and Darwin doesn't do
763  * it neither. --BenH.
764  */
765 #define MII_GBIT_FEATURES \
766 	(MII_BASIC_FEATURES |	\
767 	 SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full)
768 
769 /* Broadcom BCM 5201 */
770 static struct mii_phy_ops bcm5201_phy_ops = {
771 	.init		= bcm5201_init,
772 	.suspend	= bcm5201_suspend,
773 	.setup_aneg	= genmii_setup_aneg,
774 	.setup_forced	= genmii_setup_forced,
775 	.poll_link	= genmii_poll_link,
776 	.read_link	= genmii_read_link,
777 };
778 
779 static struct mii_phy_def bcm5201_phy_def = {
780 	.phy_id		= 0x00406210,
781 	.phy_id_mask	= 0xfffffff0,
782 	.name		= "BCM5201",
783 	.features	= MII_BASIC_FEATURES,
784 	.magic_aneg	= 1,
785 	.ops		= &bcm5201_phy_ops
786 };
787 
788 /* Broadcom BCM 5221 */
789 static struct mii_phy_ops bcm5221_phy_ops = {
790 	.suspend	= bcm5221_suspend,
791 	.init		= bcm5221_init,
792 	.setup_aneg	= genmii_setup_aneg,
793 	.setup_forced	= genmii_setup_forced,
794 	.poll_link	= genmii_poll_link,
795 	.read_link	= genmii_read_link,
796 };
797 
798 static struct mii_phy_def bcm5221_phy_def = {
799 	.phy_id		= 0x004061e0,
800 	.phy_id_mask	= 0xfffffff0,
801 	.name		= "BCM5221",
802 	.features	= MII_BASIC_FEATURES,
803 	.magic_aneg	= 1,
804 	.ops		= &bcm5221_phy_ops
805 };
806 
807 /* Broadcom BCM 5241 */
808 static struct mii_phy_ops bcm5241_phy_ops = {
809 	.suspend	= bcm5241_suspend,
810 	.init		= bcm5241_init,
811 	.setup_aneg	= genmii_setup_aneg,
812 	.setup_forced	= genmii_setup_forced,
813 	.poll_link	= genmii_poll_link,
814 	.read_link	= genmii_read_link,
815 };
816 static struct mii_phy_def bcm5241_phy_def = {
817 	.phy_id		= 0x0143bc30,
818 	.phy_id_mask	= 0xfffffff0,
819 	.name		= "BCM5241",
820 	.features	= MII_BASIC_FEATURES,
821 	.magic_aneg	= 1,
822 	.ops		= &bcm5241_phy_ops
823 };
824 
825 /* Broadcom BCM 5400 */
826 static struct mii_phy_ops bcm5400_phy_ops = {
827 	.init		= bcm5400_init,
828 	.suspend	= bcm5400_suspend,
829 	.setup_aneg	= bcm54xx_setup_aneg,
830 	.setup_forced	= bcm54xx_setup_forced,
831 	.poll_link	= genmii_poll_link,
832 	.read_link	= bcm54xx_read_link,
833 };
834 
835 static struct mii_phy_def bcm5400_phy_def = {
836 	.phy_id		= 0x00206040,
837 	.phy_id_mask	= 0xfffffff0,
838 	.name		= "BCM5400",
839 	.features	= MII_GBIT_FEATURES,
840 	.magic_aneg	= 1,
841 	.ops		= &bcm5400_phy_ops
842 };
843 
844 /* Broadcom BCM 5401 */
845 static struct mii_phy_ops bcm5401_phy_ops = {
846 	.init		= bcm5401_init,
847 	.suspend	= bcm5401_suspend,
848 	.setup_aneg	= bcm54xx_setup_aneg,
849 	.setup_forced	= bcm54xx_setup_forced,
850 	.poll_link	= genmii_poll_link,
851 	.read_link	= bcm54xx_read_link,
852 };
853 
854 static struct mii_phy_def bcm5401_phy_def = {
855 	.phy_id		= 0x00206050,
856 	.phy_id_mask	= 0xfffffff0,
857 	.name		= "BCM5401",
858 	.features	= MII_GBIT_FEATURES,
859 	.magic_aneg	= 1,
860 	.ops		= &bcm5401_phy_ops
861 };
862 
863 /* Broadcom BCM 5411 */
864 static struct mii_phy_ops bcm5411_phy_ops = {
865 	.init		= bcm5411_init,
866 	.suspend	= generic_suspend,
867 	.setup_aneg	= bcm54xx_setup_aneg,
868 	.setup_forced	= bcm54xx_setup_forced,
869 	.poll_link	= genmii_poll_link,
870 	.read_link	= bcm54xx_read_link,
871 };
872 
873 static struct mii_phy_def bcm5411_phy_def = {
874 	.phy_id		= 0x00206070,
875 	.phy_id_mask	= 0xfffffff0,
876 	.name		= "BCM5411",
877 	.features	= MII_GBIT_FEATURES,
878 	.magic_aneg	= 1,
879 	.ops		= &bcm5411_phy_ops
880 };
881 
882 /* Broadcom BCM 5421 */
883 static struct mii_phy_ops bcm5421_phy_ops = {
884 	.init		= bcm5421_init,
885 	.suspend	= generic_suspend,
886 	.setup_aneg	= bcm54xx_setup_aneg,
887 	.setup_forced	= bcm54xx_setup_forced,
888 	.poll_link	= genmii_poll_link,
889 	.read_link	= bcm54xx_read_link,
890 	.enable_fiber   = bcm5421_enable_fiber,
891 };
892 
893 static struct mii_phy_def bcm5421_phy_def = {
894 	.phy_id		= 0x002060e0,
895 	.phy_id_mask	= 0xfffffff0,
896 	.name		= "BCM5421",
897 	.features	= MII_GBIT_FEATURES,
898 	.magic_aneg	= 1,
899 	.ops		= &bcm5421_phy_ops
900 };
901 
902 /* Broadcom BCM 5421 built-in K2 */
903 static struct mii_phy_ops bcm5421k2_phy_ops = {
904 	.init		= bcm5421_init,
905 	.suspend	= generic_suspend,
906 	.setup_aneg	= bcm54xx_setup_aneg,
907 	.setup_forced	= bcm54xx_setup_forced,
908 	.poll_link	= genmii_poll_link,
909 	.read_link	= bcm54xx_read_link,
910 };
911 
912 static struct mii_phy_def bcm5421k2_phy_def = {
913 	.phy_id		= 0x002062e0,
914 	.phy_id_mask	= 0xfffffff0,
915 	.name		= "BCM5421-K2",
916 	.features	= MII_GBIT_FEATURES,
917 	.magic_aneg	= 1,
918 	.ops		= &bcm5421k2_phy_ops
919 };
920 
921 static struct mii_phy_ops bcm5461_phy_ops = {
922 	.init		= bcm5421_init,
923 	.suspend	= generic_suspend,
924 	.setup_aneg	= bcm54xx_setup_aneg,
925 	.setup_forced	= bcm54xx_setup_forced,
926 	.poll_link	= genmii_poll_link,
927 	.read_link	= bcm54xx_read_link,
928 	.enable_fiber   = bcm5461_enable_fiber,
929 };
930 
931 static struct mii_phy_def bcm5461_phy_def = {
932 	.phy_id		= 0x002060c0,
933 	.phy_id_mask	= 0xfffffff0,
934 	.name		= "BCM5461",
935 	.features	= MII_GBIT_FEATURES,
936 	.magic_aneg	= 1,
937 	.ops		= &bcm5461_phy_ops
938 };
939 
940 /* Broadcom BCM 5462 built-in Vesta */
941 static struct mii_phy_ops bcm5462V_phy_ops = {
942 	.init		= bcm5421_init,
943 	.suspend	= generic_suspend,
944 	.setup_aneg	= bcm54xx_setup_aneg,
945 	.setup_forced	= bcm54xx_setup_forced,
946 	.poll_link	= genmii_poll_link,
947 	.read_link	= bcm54xx_read_link,
948 };
949 
950 static struct mii_phy_def bcm5462V_phy_def = {
951 	.phy_id		= 0x002060d0,
952 	.phy_id_mask	= 0xfffffff0,
953 	.name		= "BCM5462-Vesta",
954 	.features	= MII_GBIT_FEATURES,
955 	.magic_aneg	= 1,
956 	.ops		= &bcm5462V_phy_ops
957 };
958 
959 /* Marvell 88E1101 amd 88E1111 */
960 static struct mii_phy_ops marvell88e1101_phy_ops = {
961 	.suspend	= generic_suspend,
962 	.setup_aneg	= marvell_setup_aneg,
963 	.setup_forced	= marvell_setup_forced,
964 	.poll_link	= genmii_poll_link,
965 	.read_link	= marvell_read_link
966 };
967 
968 static struct mii_phy_ops marvell88e1111_phy_ops = {
969 	.init		= marvell88e1111_init,
970 	.suspend	= generic_suspend,
971 	.setup_aneg	= marvell_setup_aneg,
972 	.setup_forced	= marvell_setup_forced,
973 	.poll_link	= genmii_poll_link,
974 	.read_link	= marvell_read_link
975 };
976 
977 /* two revs in darwin for the 88e1101 ... I could use a datasheet
978  * to get the proper names...
979  */
980 static struct mii_phy_def marvell88e1101v1_phy_def = {
981 	.phy_id		= 0x01410c20,
982 	.phy_id_mask	= 0xfffffff0,
983 	.name		= "Marvell 88E1101v1",
984 	.features	= MII_GBIT_FEATURES,
985 	.magic_aneg	= 1,
986 	.ops		= &marvell88e1101_phy_ops
987 };
988 static struct mii_phy_def marvell88e1101v2_phy_def = {
989 	.phy_id		= 0x01410c60,
990 	.phy_id_mask	= 0xfffffff0,
991 	.name		= "Marvell 88E1101v2",
992 	.features	= MII_GBIT_FEATURES,
993 	.magic_aneg	= 1,
994 	.ops		= &marvell88e1101_phy_ops
995 };
996 static struct mii_phy_def marvell88e1111_phy_def = {
997 	.phy_id		= 0x01410cc0,
998 	.phy_id_mask	= 0xfffffff0,
999 	.name		= "Marvell 88E1111",
1000 	.features	= MII_GBIT_FEATURES,
1001 	.magic_aneg	= 1,
1002 	.ops		= &marvell88e1111_phy_ops
1003 };
1004 
1005 /* Generic implementation for most 10/100 PHYs */
1006 static struct mii_phy_ops generic_phy_ops = {
1007 	.setup_aneg	= genmii_setup_aneg,
1008 	.setup_forced	= genmii_setup_forced,
1009 	.poll_link	= genmii_poll_link,
1010 	.read_link	= genmii_read_link
1011 };
1012 
1013 static struct mii_phy_def genmii_phy_def = {
1014 	.phy_id		= 0x00000000,
1015 	.phy_id_mask	= 0x00000000,
1016 	.name		= "Generic MII",
1017 	.features	= MII_BASIC_FEATURES,
1018 	.magic_aneg	= 0,
1019 	.ops		= &generic_phy_ops
1020 };
1021 
1022 static struct mii_phy_def* mii_phy_table[] = {
1023 	&bcm5201_phy_def,
1024 	&bcm5221_phy_def,
1025 	&bcm5241_phy_def,
1026 	&bcm5400_phy_def,
1027 	&bcm5401_phy_def,
1028 	&bcm5411_phy_def,
1029 	&bcm5421_phy_def,
1030 	&bcm5421k2_phy_def,
1031 	&bcm5461_phy_def,
1032 	&bcm5462V_phy_def,
1033 	&marvell88e1101v1_phy_def,
1034 	&marvell88e1101v2_phy_def,
1035 	&marvell88e1111_phy_def,
1036 	&genmii_phy_def,
1037 	NULL
1038 };
1039 
1040 int mii_phy_probe(struct mii_phy *phy, int mii_id)
1041 {
1042 	int rc;
1043 	u32 id;
1044 	struct mii_phy_def* def;
1045 	int i;
1046 
1047 	/* We do not reset the mii_phy structure as the driver
1048 	 * may re-probe the PHY regulary
1049 	 */
1050 	phy->mii_id = mii_id;
1051 
1052 	/* Take PHY out of isloate mode and reset it. */
1053 	rc = reset_one_mii_phy(phy, mii_id);
1054 	if (rc)
1055 		goto fail;
1056 
1057 	/* Read ID and find matching entry */
1058 	id = (phy_read(phy, MII_PHYSID1) << 16 | phy_read(phy, MII_PHYSID2));
1059 	printk(KERN_DEBUG "PHY ID: %x, addr: %x\n", id, mii_id);
1060 	for (i=0; (def = mii_phy_table[i]) != NULL; i++)
1061 		if ((id & def->phy_id_mask) == def->phy_id)
1062 			break;
1063 	/* Should never be NULL (we have a generic entry), but... */
1064 	if (def == NULL)
1065 		goto fail;
1066 
1067 	phy->def = def;
1068 
1069 	return 0;
1070 fail:
1071 	phy->speed = 0;
1072 	phy->duplex = 0;
1073 	phy->pause = 0;
1074 	phy->advertising = 0;
1075 	return -ENODEV;
1076 }
1077 
1078 EXPORT_SYMBOL(mii_phy_probe);
1079 MODULE_LICENSE("GPL");
1080 
1081