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