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