]> git.sur5r.net Git - u-boot/blob - drivers/net/tsec.c
phylib: Add a bunch of PHY drivers from tsec
[u-boot] / drivers / net / tsec.c
1 /*
2  * Freescale Three Speed Ethernet Controller driver
3  *
4  * This software may be used and distributed according to the
5  * terms of the GNU Public License, Version 2, incorporated
6  * herein by reference.
7  *
8  * Copyright 2004-2011 Freescale Semiconductor, Inc.
9  * (C) Copyright 2003, Motorola, Inc.
10  * author Andy Fleming
11  *
12  */
13
14 #include <config.h>
15 #include <common.h>
16 #include <malloc.h>
17 #include <net.h>
18 #include <command.h>
19 #include <tsec.h>
20 #include <asm/errno.h>
21
22 #include "miiphy.h"
23
24 DECLARE_GLOBAL_DATA_PTR;
25
26 #define TX_BUF_CNT              2
27
28 static uint rxIdx;              /* index of the current RX buffer */
29 static uint txIdx;              /* index of the current TX buffer */
30
31 typedef volatile struct rtxbd {
32         txbd8_t txbd[TX_BUF_CNT];
33         rxbd8_t rxbd[PKTBUFSRX];
34 } RTXBD;
35
36 #define MAXCONTROLLERS  (8)
37
38 static struct tsec_private *privlist[MAXCONTROLLERS];
39 static int num_tsecs = 0;
40
41 #ifdef __GNUC__
42 static RTXBD rtx __attribute__ ((aligned(8)));
43 #else
44 #error "rtx must be 64-bit aligned"
45 #endif
46
47 /* Default initializations for TSEC controllers. */
48
49 static struct tsec_info_struct tsec_info[] = {
50 #ifdef CONFIG_TSEC1
51         STD_TSEC_INFO(1),       /* TSEC1 */
52 #endif
53 #ifdef CONFIG_TSEC2
54         STD_TSEC_INFO(2),       /* TSEC2 */
55 #endif
56 #ifdef CONFIG_MPC85XX_FEC
57         {
58                 .regs = (tsec_t *)(TSEC_BASE_ADDR + 0x2000),
59                 .miiregs = (tsec_mdio_t *)(MDIO_BASE_ADDR),
60                 .devname = CONFIG_MPC85XX_FEC_NAME,
61                 .phyaddr = FEC_PHY_ADDR,
62                 .flags = FEC_FLAGS
63         },                      /* FEC */
64 #endif
65 #ifdef CONFIG_TSEC3
66         STD_TSEC_INFO(3),       /* TSEC3 */
67 #endif
68 #ifdef CONFIG_TSEC4
69         STD_TSEC_INFO(4),       /* TSEC4 */
70 #endif
71 };
72
73 /* Writes the given phy's reg with value, using the specified MDIO regs */
74 static void tsec_local_mdio_write(tsec_mdio_t *phyregs, uint addr,
75                 uint reg, uint value)
76 {
77         int timeout = 1000000;
78
79         out_be32(&phyregs->miimadd, (addr << 8) | reg);
80         out_be32(&phyregs->miimcon, value);
81
82         timeout = 1000000;
83         while ((in_be32(&phyregs->miimind) & MIIMIND_BUSY) && timeout--)
84                 ;
85 }
86
87 /* Provide the default behavior of writing the PHY of this ethernet device */
88 #define write_phy_reg(priv, regnum, value) \
89         tsec_local_mdio_write(priv->phyregs,priv->phyaddr,regnum,value)
90
91 /* Reads register regnum on the device's PHY through the
92  * specified registers.  It lowers and raises the read
93  * command, and waits for the data to become valid (miimind
94  * notvalid bit cleared), and the bus to cease activity (miimind
95  * busy bit cleared), and then returns the value
96  */
97 static uint tsec_local_mdio_read(tsec_mdio_t *phyregs, uint phyid, uint regnum)
98 {
99         uint value;
100
101         /* Put the address of the phy, and the register
102          * number into MIIMADD */
103         out_be32(&phyregs->miimadd, (phyid << 8) | regnum);
104
105         /* Clear the command register, and wait */
106         out_be32(&phyregs->miimcom, 0);
107
108         /* Initiate a read command, and wait */
109         out_be32(&phyregs->miimcom, MIIM_READ_COMMAND);
110
111         /* Wait for the the indication that the read is done */
112         while ((in_be32(&phyregs->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY)))
113                 ;
114
115         /* Grab the value read from the PHY */
116         value = in_be32(&phyregs->miimstat);
117
118         return value;
119 }
120
121 /* #define to provide old read_phy_reg functionality without duplicating code */
122 #define read_phy_reg(priv,regnum) \
123         tsec_local_mdio_read(priv->phyregs,priv->phyaddr,regnum)
124
125 #define TBIANA_SETTINGS ( \
126                 TBIANA_ASYMMETRIC_PAUSE \
127                 | TBIANA_SYMMETRIC_PAUSE \
128                 | TBIANA_FULL_DUPLEX \
129                 )
130
131 /* By default force the TBI PHY into 1000Mbps full duplex when in SGMII mode */
132 #ifndef CONFIG_TSEC_TBICR_SETTINGS
133 #define CONFIG_TSEC_TBICR_SETTINGS ( \
134                 TBICR_PHY_RESET \
135                 | TBICR_ANEG_ENABLE \
136                 | TBICR_FULL_DUPLEX \
137                 | TBICR_SPEED1_SET \
138                 )
139 #endif /* CONFIG_TSEC_TBICR_SETTINGS */
140
141 /* Configure the TBI for SGMII operation */
142 static void tsec_configure_serdes(struct tsec_private *priv)
143 {
144         /* Access TBI PHY registers at given TSEC register offset as opposed
145          * to the register offset used for external PHY accesses */
146         tsec_local_mdio_write(priv->phyregs_sgmii, priv->regs->tbipa, TBI_ANA,
147                         TBIANA_SETTINGS);
148         tsec_local_mdio_write(priv->phyregs_sgmii, priv->regs->tbipa, TBI_TBICON,
149                         TBICON_CLK_SELECT);
150         tsec_local_mdio_write(priv->phyregs_sgmii, priv->regs->tbipa, TBI_CR,
151                         CONFIG_TSEC_TBICR_SETTINGS);
152 }
153
154 /*
155  * Returns which value to write to the control register.
156  * For 10/100, the value is slightly different
157  */
158 static uint mii_cr_init(uint mii_reg, struct tsec_private * priv)
159 {
160         if (priv->flags & TSEC_GIGABIT)
161                 return MIIM_CONTROL_INIT;
162         else
163                 return MIIM_CR_INIT;
164 }
165
166 /*
167  * Wait for auto-negotiation to complete, then determine link
168  */
169 static uint mii_parse_sr(uint mii_reg, struct tsec_private * priv)
170 {
171         /*
172          * Wait if the link is up, and autonegotiation is in progress
173          * (ie - we're capable and it's not done)
174          */
175         mii_reg = read_phy_reg(priv, MIIM_STATUS);
176         if ((mii_reg & BMSR_ANEGCAPABLE) && !(mii_reg & BMSR_ANEGCOMPLETE)) {
177                 int i = 0;
178
179                 puts("Waiting for PHY auto negotiation to complete");
180                 while (!(mii_reg & BMSR_ANEGCOMPLETE)) {
181                         /*
182                          * Timeout reached ?
183                          */
184                         if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
185                                 puts(" TIMEOUT !\n");
186                                 priv->link = 0;
187                                 return 0;
188                         }
189
190                         if (ctrlc()) {
191                                 puts("user interrupt!\n");
192                                 priv->link = 0;
193                                 return -EINTR;
194                         }
195
196                         if ((i++ % 1000) == 0) {
197                                 putc('.');
198                         }
199                         udelay(1000);   /* 1 ms */
200                         mii_reg = read_phy_reg(priv, MIIM_STATUS);
201                 }
202                 puts(" done\n");
203
204                 /* Link status bit is latched low, read it again */
205                 mii_reg = read_phy_reg(priv, MIIM_STATUS);
206
207                 udelay(500000); /* another 500 ms (results in faster booting) */
208         }
209
210         priv->link = mii_reg & MIIM_STATUS_LINK ? 1 : 0;
211
212         return 0;
213 }
214
215 /* Generic function which updates the speed and duplex.  If
216  * autonegotiation is enabled, it uses the AND of the link
217  * partner's advertised capabilities and our advertised
218  * capabilities.  If autonegotiation is disabled, we use the
219  * appropriate bits in the control register.
220  *
221  * Stolen from Linux's mii.c and phy_device.c
222  */
223 static uint mii_parse_link(uint mii_reg, struct tsec_private *priv)
224 {
225         /* We're using autonegotiation */
226         if (mii_reg & BMSR_ANEGCAPABLE) {
227                 uint lpa = 0;
228                 uint gblpa = 0;
229
230                 /* Check for gigabit capability */
231                 if (mii_reg & BMSR_ERCAP) {
232                         /* We want a list of states supported by
233                          * both PHYs in the link
234                          */
235                         gblpa = read_phy_reg(priv, MII_STAT1000);
236                         gblpa &= read_phy_reg(priv, MII_CTRL1000) << 2;
237                 }
238
239                 /* Set the baseline so we only have to set them
240                  * if they're different
241                  */
242                 priv->speed = 10;
243                 priv->duplexity = 0;
244
245                 /* Check the gigabit fields */
246                 if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
247                         priv->speed = 1000;
248
249                         if (gblpa & PHY_1000BTSR_1000FD)
250                                 priv->duplexity = 1;
251
252                         /* We're done! */
253                         return 0;
254                 }
255
256                 lpa = read_phy_reg(priv, MII_ADVERTISE);
257                 lpa &= read_phy_reg(priv, MII_LPA);
258
259                 if (lpa & (LPA_100FULL | LPA_100HALF)) {
260                         priv->speed = 100;
261
262                         if (lpa & LPA_100FULL)
263                                 priv->duplexity = 1;
264
265                 } else if (lpa & LPA_10FULL)
266                         priv->duplexity = 1;
267         } else {
268                 uint bmcr = read_phy_reg(priv, MII_BMCR);
269
270                 priv->speed = 10;
271                 priv->duplexity = 0;
272
273                 if (bmcr & BMCR_FULLDPLX)
274                         priv->duplexity = 1;
275
276                 if (bmcr & BMCR_SPEED1000)
277                         priv->speed = 1000;
278                 else if (bmcr & BMCR_SPEED100)
279                         priv->speed = 100;
280         }
281
282         return 0;
283 }
284
285 /*
286  * "Ethernet@Wirespeed" needs to be enabled to achieve link in certain
287  * circumstances.  eg a gigabit TSEC connected to a gigabit switch with
288  * a 4-wire ethernet cable.  Both ends advertise gigabit, but can't
289  * link.  "Ethernet@Wirespeed" reduces advertised speed until link
290  * can be achieved.
291  */
292 static uint mii_BCM54xx_wirespeed(uint mii_reg, struct tsec_private *priv)
293 {
294         return (read_phy_reg(priv, mii_reg) & 0x8FFF) | 0x8010;
295 }
296
297 /*
298  * Parse the BCM54xx status register for speed and duplex information.
299  * The linux sungem_phy has this information, but in a table format.
300  */
301 static uint mii_parse_BCM54xx_sr(uint mii_reg, struct tsec_private *priv)
302 {
303         /* If there is no link, speed and duplex don't matter */
304         if (!priv->link)
305                 return 0;
306
307         switch ((mii_reg & MIIM_BCM54xx_AUXSTATUS_LINKMODE_MASK) >>
308                 MIIM_BCM54xx_AUXSTATUS_LINKMODE_SHIFT) {
309         case 1:
310                 priv->duplexity = 0;
311                 priv->speed = 10;
312                 break;
313         case 2:
314                 priv->duplexity = 1;
315                 priv->speed = 10;
316                 break;
317         case 3:
318                 priv->duplexity = 0;
319                 priv->speed = 100;
320                 break;
321         case 5:
322                 priv->duplexity = 1;
323                 priv->speed = 100;
324                 break;
325         case 6:
326                 priv->duplexity = 0;
327                 priv->speed = 1000;
328                 break;
329         case 7:
330                 priv->duplexity = 1;
331                 priv->speed = 1000;
332                 break;
333         default:
334                 printf("Auto-neg error, defaulting to 10BT/HD\n");
335                 priv->duplexity = 0;
336                 priv->speed = 10;
337                 break;
338         }
339
340         return 0;
341 }
342
343 /*
344  * Find out if PHY is in copper or serdes mode by looking at Expansion Reg
345  * 0x42 - "Operating Mode Status Register"
346  */
347 static int BCM8482_is_serdes(struct tsec_private *priv)
348 {
349         u16 val;
350         int serdes = 0;
351
352         write_phy_reg(priv, MIIM_BCM54XX_EXP_SEL, MIIM_BCM54XX_EXP_SEL_ER | 0x42);
353         val = read_phy_reg(priv, MIIM_BCM54XX_EXP_DATA);
354
355         switch (val & 0x1f) {
356         case 0x0d:      /* RGMII-to-100Base-FX */
357         case 0x0e:      /* RGMII-to-SGMII */
358         case 0x0f:      /* RGMII-to-SerDes */
359         case 0x12:      /* SGMII-to-SerDes */
360         case 0x13:      /* SGMII-to-100Base-FX */
361         case 0x16:      /* SerDes-to-Serdes */
362                 serdes = 1;
363                 break;
364         case 0x6:       /* RGMII-to-Copper */
365         case 0x14:      /* SGMII-to-Copper */
366         case 0x17:      /* SerDes-to-Copper */
367                 break;
368         default:
369                 printf("ERROR, invalid PHY mode (0x%x\n)", val);
370                 break;
371         }
372
373         return serdes;
374 }
375
376 /*
377  * Determine SerDes link speed and duplex from Expansion reg 0x42 "Operating
378  * Mode Status Register"
379  */
380 uint mii_parse_BCM5482_serdes_sr(struct tsec_private *priv)
381 {
382         u16 val;
383         int i = 0;
384
385         /* Wait 1s for link - Clause 37 autonegotiation happens very fast */
386         while (1) {
387                 write_phy_reg(priv, MIIM_BCM54XX_EXP_SEL,
388                                 MIIM_BCM54XX_EXP_SEL_ER | 0x42);
389                 val = read_phy_reg(priv, MIIM_BCM54XX_EXP_DATA);
390
391                 if (val & 0x8000)
392                         break;
393
394                 if (i++ > 1000) {
395                         priv->link = 0;
396                         return 1;
397                 }
398
399                 udelay(1000);   /* 1 ms */
400         }
401
402         priv->link = 1;
403         switch ((val >> 13) & 0x3) {
404         case (0x00):
405                 priv->speed = 10;
406                 break;
407         case (0x01):
408                 priv->speed = 100;
409                 break;
410         case (0x02):
411                 priv->speed = 1000;
412                 break;
413         }
414
415         priv->duplexity = (val & 0x1000) == 0x1000;
416
417         return 0;
418 }
419
420 /*
421  * Figure out if BCM5482 is in serdes or copper mode and determine link
422  * configuration accordingly
423  */
424 static uint mii_parse_BCM5482_sr(uint mii_reg, struct tsec_private *priv)
425 {
426         if (BCM8482_is_serdes(priv)) {
427                 mii_parse_BCM5482_serdes_sr(priv);
428                 priv->flags |= TSEC_FIBER;
429         } else {
430                 /* Wait for auto-negotiation to complete or fail */
431                 mii_parse_sr(mii_reg, priv);
432
433                 /* Parse BCM54xx copper aux status register */
434                 mii_reg = read_phy_reg(priv, MIIM_BCM54xx_AUXSTATUS);
435                 mii_parse_BCM54xx_sr(mii_reg, priv);
436         }
437
438         return 0;
439 }
440
441 /* Parse the 88E1011's status register for speed and duplex
442  * information
443  */
444 static uint mii_parse_88E1011_psr(uint mii_reg, struct tsec_private * priv)
445 {
446         uint speed;
447
448         mii_reg = read_phy_reg(priv, MIIM_88E1011_PHY_STATUS);
449
450         if ((mii_reg & MIIM_88E1011_PHYSTAT_LINK) &&
451                 !(mii_reg & MIIM_88E1011_PHYSTAT_SPDDONE)) {
452                 int i = 0;
453
454                 puts("Waiting for PHY realtime link");
455                 while (!(mii_reg & MIIM_88E1011_PHYSTAT_SPDDONE)) {
456                         /* Timeout reached ? */
457                         if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
458                                 puts(" TIMEOUT !\n");
459                                 priv->link = 0;
460                                 break;
461                         }
462
463                         if ((i++ % 1000) == 0) {
464                                 putc('.');
465                         }
466                         udelay(1000);   /* 1 ms */
467                         mii_reg = read_phy_reg(priv, MIIM_88E1011_PHY_STATUS);
468                 }
469                 puts(" done\n");
470                 udelay(500000); /* another 500 ms (results in faster booting) */
471         } else {
472                 if (mii_reg & MIIM_88E1011_PHYSTAT_LINK)
473                         priv->link = 1;
474                 else
475                         priv->link = 0;
476         }
477
478         if (mii_reg & MIIM_88E1011_PHYSTAT_DUPLEX)
479                 priv->duplexity = 1;
480         else
481                 priv->duplexity = 0;
482
483         speed = (mii_reg & MIIM_88E1011_PHYSTAT_SPEED);
484
485         switch (speed) {
486         case MIIM_88E1011_PHYSTAT_GBIT:
487                 priv->speed = 1000;
488                 break;
489         case MIIM_88E1011_PHYSTAT_100:
490                 priv->speed = 100;
491                 break;
492         default:
493                 priv->speed = 10;
494         }
495
496         return 0;
497 }
498
499 /* Parse the RTL8211B's status register for speed and duplex
500  * information
501  */
502 static uint mii_parse_RTL8211B_sr(uint mii_reg, struct tsec_private * priv)
503 {
504         uint speed;
505
506         mii_reg = read_phy_reg(priv, MIIM_RTL8211B_PHY_STATUS);
507         if (!(mii_reg & MIIM_RTL8211B_PHYSTAT_SPDDONE)) {
508                 int i = 0;
509
510                 /* in case of timeout ->link is cleared */
511                 priv->link = 1;
512                 puts("Waiting for PHY realtime link");
513                 while (!(mii_reg & MIIM_RTL8211B_PHYSTAT_SPDDONE)) {
514                         /* Timeout reached ? */
515                         if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
516                                 puts(" TIMEOUT !\n");
517                                 priv->link = 0;
518                                 break;
519                         }
520
521                         if ((i++ % 1000) == 0) {
522                                 putc('.');
523                         }
524                         udelay(1000);   /* 1 ms */
525                         mii_reg = read_phy_reg(priv, MIIM_RTL8211B_PHY_STATUS);
526                 }
527                 puts(" done\n");
528                 udelay(500000); /* another 500 ms (results in faster booting) */
529         } else {
530                 if (mii_reg & MIIM_RTL8211B_PHYSTAT_LINK)
531                         priv->link = 1;
532                 else
533                         priv->link = 0;
534         }
535
536         if (mii_reg & MIIM_RTL8211B_PHYSTAT_DUPLEX)
537                 priv->duplexity = 1;
538         else
539                 priv->duplexity = 0;
540
541         speed = (mii_reg & MIIM_RTL8211B_PHYSTAT_SPEED);
542
543         switch (speed) {
544         case MIIM_RTL8211B_PHYSTAT_GBIT:
545                 priv->speed = 1000;
546                 break;
547         case MIIM_RTL8211B_PHYSTAT_100:
548                 priv->speed = 100;
549                 break;
550         default:
551                 priv->speed = 10;
552         }
553
554         return 0;
555 }
556
557 /* Parse the cis8201's status register for speed and duplex
558  * information
559  */
560 static uint mii_parse_cis8201(uint mii_reg, struct tsec_private * priv)
561 {
562         uint speed;
563
564         if (mii_reg & MIIM_CIS8201_AUXCONSTAT_DUPLEX)
565                 priv->duplexity = 1;
566         else
567                 priv->duplexity = 0;
568
569         speed = mii_reg & MIIM_CIS8201_AUXCONSTAT_SPEED;
570         switch (speed) {
571         case MIIM_CIS8201_AUXCONSTAT_GBIT:
572                 priv->speed = 1000;
573                 break;
574         case MIIM_CIS8201_AUXCONSTAT_100:
575                 priv->speed = 100;
576                 break;
577         default:
578                 priv->speed = 10;
579                 break;
580         }
581
582         return 0;
583 }
584
585 /* Parse the vsc8244's status register for speed and duplex
586  * information
587  */
588 static uint mii_parse_vsc8244(uint mii_reg, struct tsec_private * priv)
589 {
590         uint speed;
591
592         if (mii_reg & MIIM_VSC8244_AUXCONSTAT_DUPLEX)
593                 priv->duplexity = 1;
594         else
595                 priv->duplexity = 0;
596
597         speed = mii_reg & MIIM_VSC8244_AUXCONSTAT_SPEED;
598         switch (speed) {
599         case MIIM_VSC8244_AUXCONSTAT_GBIT:
600                 priv->speed = 1000;
601                 break;
602         case MIIM_VSC8244_AUXCONSTAT_100:
603                 priv->speed = 100;
604                 break;
605         default:
606                 priv->speed = 10;
607                 break;
608         }
609
610         return 0;
611 }
612
613 /* Parse the DM9161's status register for speed and duplex
614  * information
615  */
616 static uint mii_parse_dm9161_scsr(uint mii_reg, struct tsec_private * priv)
617 {
618         if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_100H))
619                 priv->speed = 100;
620         else
621                 priv->speed = 10;
622
623         if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_10F))
624                 priv->duplexity = 1;
625         else
626                 priv->duplexity = 0;
627
628         return 0;
629 }
630
631 /*
632  * Hack to write all 4 PHYs with the LED values
633  */
634 static uint mii_cis8204_fixled(uint mii_reg, struct tsec_private * priv)
635 {
636         uint phyid;
637         tsec_mdio_t *regbase = priv->phyregs;
638         int timeout = 1000000;
639
640         for (phyid = 0; phyid < 4; phyid++) {
641                 out_be32(&regbase->miimadd, (phyid << 8) | mii_reg);
642                 out_be32(&regbase->miimcon, MIIM_CIS8204_SLEDCON_INIT);
643
644                 timeout = 1000000;
645                 while ((in_be32(&regbase->miimind) & MIIMIND_BUSY) && timeout--)
646                         ;
647         }
648
649         return MIIM_CIS8204_SLEDCON_INIT;
650 }
651
652 static uint mii_cis8204_setmode(uint mii_reg, struct tsec_private * priv)
653 {
654         if (priv->flags & TSEC_REDUCED)
655                 return MIIM_CIS8204_EPHYCON_INIT | MIIM_CIS8204_EPHYCON_RGMII;
656         else
657                 return MIIM_CIS8204_EPHYCON_INIT;
658 }
659
660 static uint mii_m88e1111s_setmode(uint mii_reg, struct tsec_private *priv)
661 {
662         uint mii_data = read_phy_reg(priv, mii_reg);
663
664         if (priv->flags & TSEC_REDUCED)
665                 mii_data = (mii_data & 0xfff0) | 0x000b;
666         return mii_data;
667 }
668
669 static struct phy_info phy_info_M88E1149S = {
670         0x1410ca,
671         "Marvell 88E1149S",
672         4,
673         (struct phy_cmd[]) {     /* config */
674                 /* Reset and configure the PHY */
675                 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
676                 {0x1d, 0x1f, NULL},
677                 {0x1e, 0x200c, NULL},
678                 {0x1d, 0x5, NULL},
679                 {0x1e, 0x0, NULL},
680                 {0x1e, 0x100, NULL},
681                 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
682                 {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
683                 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
684                 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
685                 {miim_end,}
686         },
687         (struct phy_cmd[]) {     /* startup */
688                 /* Status is read once to clear old link state */
689                 {MIIM_STATUS, miim_read, NULL},
690                 /* Auto-negotiate */
691                 {MIIM_STATUS, miim_read, &mii_parse_sr},
692                 /* Read the status */
693                 {MIIM_88E1011_PHY_STATUS, miim_read, &mii_parse_88E1011_psr},
694                 {miim_end,}
695         },
696         (struct phy_cmd[]) {     /* shutdown */
697                 {miim_end,}
698         },
699 };
700
701 /* The 5411 id is 0x206070, the 5421 is 0x2060e0 */
702 static struct phy_info phy_info_BCM5461S = {
703         0x02060c1,      /* 5461 ID */
704         "Broadcom BCM5461S",
705         0, /* not clear to me what minor revisions we can shift away */
706         (struct phy_cmd[]) { /* config */
707                 /* Reset and configure the PHY */
708                 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
709                 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
710                 {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
711                 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
712                 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
713                 {miim_end,}
714         },
715         (struct phy_cmd[]) { /* startup */
716                 /* Status is read once to clear old link state */
717                 {MIIM_STATUS, miim_read, NULL},
718                 /* Auto-negotiate */
719                 {MIIM_STATUS, miim_read, &mii_parse_sr},
720                 /* Read the status */
721                 {MIIM_BCM54xx_AUXSTATUS, miim_read, &mii_parse_BCM54xx_sr},
722                 {miim_end,}
723         },
724         (struct phy_cmd[]) { /* shutdown */
725                 {miim_end,}
726         },
727 };
728
729 static struct phy_info phy_info_BCM5464S = {
730         0x02060b1,      /* 5464 ID */
731         "Broadcom BCM5464S",
732         0, /* not clear to me what minor revisions we can shift away */
733         (struct phy_cmd[]) { /* config */
734                 /* Reset and configure the PHY */
735                 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
736                 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
737                 {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
738                 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
739                 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
740                 {miim_end,}
741         },
742         (struct phy_cmd[]) { /* startup */
743                 /* Status is read once to clear old link state */
744                 {MIIM_STATUS, miim_read, NULL},
745                 /* Auto-negotiate */
746                 {MIIM_STATUS, miim_read, &mii_parse_sr},
747                 /* Read the status */
748                 {MIIM_BCM54xx_AUXSTATUS, miim_read, &mii_parse_BCM54xx_sr},
749                 {miim_end,}
750         },
751         (struct phy_cmd[]) { /* shutdown */
752                 {miim_end,}
753         },
754 };
755
756 static struct phy_info phy_info_BCM5482S =  {
757         0x0143bcb,
758         "Broadcom BCM5482S",
759         4,
760         (struct phy_cmd[]) { /* config */
761                 /* Reset and configure the PHY */
762                 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
763                 /* Setup read from auxilary control shadow register 7 */
764                 {MIIM_BCM54xx_AUXCNTL, MIIM_BCM54xx_AUXCNTL_ENCODE(7), NULL},
765                 /* Read Misc Control register and or in Ethernet@Wirespeed */
766                 {MIIM_BCM54xx_AUXCNTL, 0, &mii_BCM54xx_wirespeed},
767                 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
768                 /* Initial config/enable of secondary SerDes interface */
769                 {MIIM_BCM54XX_SHD, MIIM_BCM54XX_SHD_WR_ENCODE(0x14, 0xf), NULL},
770                 /* Write intial value to secondary SerDes Contol */
771                 {MIIM_BCM54XX_EXP_SEL, MIIM_BCM54XX_EXP_SEL_SSD | 0, NULL},
772                 {MIIM_BCM54XX_EXP_DATA, MIIM_CONTROL_RESTART, NULL},
773                 /* Enable copper/fiber auto-detect */
774                 {MIIM_BCM54XX_SHD, MIIM_BCM54XX_SHD_WR_ENCODE(0x1e, 0x201)},
775                 {miim_end,}
776         },
777         (struct phy_cmd[]) { /* startup */
778                 /* Status is read once to clear old link state */
779                 {MIIM_STATUS, miim_read, NULL},
780                 /* Determine copper/fiber, auto-negotiate, and read the result */
781                 {MIIM_STATUS, miim_read, &mii_parse_BCM5482_sr},
782                 {miim_end,}
783         },
784         (struct phy_cmd[]) { /* shutdown */
785                 {miim_end,}
786         },
787 };
788
789 static struct phy_info phy_info_M88E1011S = {
790         0x01410c6,
791         "Marvell 88E1011S",
792         4,
793         (struct phy_cmd[]) {    /* config */
794                 /* Reset and configure the PHY */
795                 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
796                 {0x1d, 0x1f, NULL},
797                 {0x1e, 0x200c, NULL},
798                 {0x1d, 0x5, NULL},
799                 {0x1e, 0x0, NULL},
800                 {0x1e, 0x100, NULL},
801                 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
802                 {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
803                 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
804                 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
805                 {miim_end,}
806         },
807         (struct phy_cmd[]) {    /* startup */
808                 /* Status is read once to clear old link state */
809                 {MIIM_STATUS, miim_read, NULL},
810                 /* Auto-negotiate */
811                 {MIIM_STATUS, miim_read, &mii_parse_sr},
812                 /* Read the status */
813                 {MIIM_88E1011_PHY_STATUS, miim_read, &mii_parse_88E1011_psr},
814                 {miim_end,}
815         },
816         (struct phy_cmd[]) {    /* shutdown */
817                 {miim_end,}
818         },
819 };
820
821 static struct phy_info phy_info_M88E1111S = {
822         0x01410cc,
823         "Marvell 88E1111S",
824         4,
825         (struct phy_cmd[]) {    /* config */
826                 /* Reset and configure the PHY */
827                 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
828                 {0x1b, 0x848f, &mii_m88e1111s_setmode},
829                 {0x14, 0x0cd2, NULL}, /* Delay RGMII TX and RX */
830                 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
831                 {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
832                 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
833                 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
834                 {miim_end,}
835         },
836         (struct phy_cmd[]) {    /* startup */
837                 /* Status is read once to clear old link state */
838                 {MIIM_STATUS, miim_read, NULL},
839                 /* Auto-negotiate */
840                 {MIIM_STATUS, miim_read, &mii_parse_sr},
841                 /* Read the status */
842                 {MIIM_88E1011_PHY_STATUS, miim_read, &mii_parse_88E1011_psr},
843                 {miim_end,}
844         },
845         (struct phy_cmd[]) {    /* shutdown */
846                 {miim_end,}
847         },
848 };
849
850 static struct phy_info phy_info_M88E1118 = {
851         0x01410e1,
852         "Marvell 88E1118",
853         4,
854         (struct phy_cmd[]) {    /* config */
855                 /* Reset and configure the PHY */
856                 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
857                 {0x16, 0x0002, NULL}, /* Change Page Number */
858                 {0x15, 0x1070, NULL}, /* Delay RGMII TX and RX */
859                 {0x16, 0x0003, NULL}, /* Change Page Number */
860                 {0x10, 0x021e, NULL}, /* Adjust LED control */
861                 {0x16, 0x0000, NULL}, /* Change Page Number */
862                 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
863                 {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
864                 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
865                 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
866                 {miim_end,}
867         },
868         (struct phy_cmd[]) {    /* startup */
869                 {0x16, 0x0000, NULL}, /* Change Page Number */
870                 /* Status is read once to clear old link state */
871                 {MIIM_STATUS, miim_read, NULL},
872                 /* Auto-negotiate */
873                 {MIIM_STATUS, miim_read, &mii_parse_sr},
874                 /* Read the status */
875                 {MIIM_88E1011_PHY_STATUS, miim_read,
876                  &mii_parse_88E1011_psr},
877                 {miim_end,}
878         },
879         (struct phy_cmd[]) {    /* shutdown */
880                 {miim_end,}
881         },
882 };
883
884 /*
885  *  Since to access LED register we need do switch the page, we
886  * do LED configuring in the miim_read-like function as follows
887  */
888 static uint mii_88E1121_set_led (uint mii_reg, struct tsec_private *priv)
889 {
890         uint pg;
891
892         /* Switch the page to access the led register */
893         pg = read_phy_reg(priv, MIIM_88E1121_PHY_PAGE);
894         write_phy_reg(priv, MIIM_88E1121_PHY_PAGE, MIIM_88E1121_PHY_LED_PAGE);
895
896         /* Configure leds */
897         write_phy_reg(priv, MIIM_88E1121_PHY_LED_CTRL,
898                       MIIM_88E1121_PHY_LED_DEF);
899
900         /* Restore the page pointer */
901         write_phy_reg(priv, MIIM_88E1121_PHY_PAGE, pg);
902         return 0;
903 }
904
905 static struct phy_info phy_info_M88E1121R = {
906         0x01410cb,
907         "Marvell 88E1121R",
908         4,
909         (struct phy_cmd[]) {    /* config */
910                 /* Reset and configure the PHY */
911                 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
912                 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
913                 {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
914                 /* Configure leds */
915                 {MIIM_88E1121_PHY_LED_CTRL, miim_read, &mii_88E1121_set_led},
916                 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
917                 /* Disable IRQs and de-assert interrupt */
918                 {MIIM_88E1121_PHY_IRQ_EN, 0, NULL},
919                 {MIIM_88E1121_PHY_IRQ_STATUS, miim_read, NULL},
920                 {miim_end,}
921         },
922         (struct phy_cmd[]) {    /* startup */
923                 /* Status is read once to clear old link state */
924                 {MIIM_STATUS, miim_read, NULL},
925                 {MIIM_STATUS, miim_read, &mii_parse_sr},
926                 {MIIM_STATUS, miim_read, &mii_parse_link},
927                 {miim_end,}
928         },
929         (struct phy_cmd[]) {    /* shutdown */
930                 {miim_end,}
931         },
932 };
933
934 static unsigned int m88e1145_setmode(uint mii_reg, struct tsec_private *priv)
935 {
936         uint mii_data = read_phy_reg(priv, mii_reg);
937
938         /* Setting MIIM_88E1145_PHY_EXT_CR */
939         if (priv->flags & TSEC_REDUCED)
940                 return mii_data |
941                     MIIM_M88E1145_RGMII_RX_DELAY | MIIM_M88E1145_RGMII_TX_DELAY;
942         else
943                 return mii_data;
944 }
945
946 static struct phy_info phy_info_M88E1145 = {
947         0x01410cd,
948         "Marvell 88E1145",
949         4,
950         (struct phy_cmd[]) {    /* config */
951                 /* Reset the PHY */
952                 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
953
954                 /* Errata E0, E1 */
955                 {29, 0x001b, NULL},
956                 {30, 0x418f, NULL},
957                 {29, 0x0016, NULL},
958                 {30, 0xa2da, NULL},
959
960                 /* Configure the PHY */
961                 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
962                 {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
963                 {MIIM_88E1011_PHY_SCR, MIIM_88E1011_PHY_MDI_X_AUTO, NULL},
964                 {MIIM_88E1145_PHY_EXT_CR, 0, &m88e1145_setmode},
965                 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
966                 {MIIM_CONTROL, MIIM_CONTROL_INIT, NULL},
967                 {miim_end,}
968         },
969         (struct phy_cmd[]) {    /* startup */
970                 /* Status is read once to clear old link state */
971                 {MIIM_STATUS, miim_read, NULL},
972                 /* Auto-negotiate */
973                 {MIIM_STATUS, miim_read, &mii_parse_sr},
974                 {MIIM_88E1111_PHY_LED_CONTROL, MIIM_88E1111_PHY_LED_DIRECT, NULL},
975                 /* Read the Status */
976                 {MIIM_88E1011_PHY_STATUS, miim_read, &mii_parse_88E1011_psr},
977                 {miim_end,}
978         },
979         (struct phy_cmd[]) {    /* shutdown */
980                 {miim_end,}
981         },
982 };
983
984 static struct phy_info phy_info_cis8204 = {
985         0x3f11,
986         "Cicada Cis8204",
987         6,
988         (struct phy_cmd[]) {    /* config */
989                 /* Override PHY config settings */
990                 {MIIM_CIS8201_AUX_CONSTAT, MIIM_CIS8201_AUXCONSTAT_INIT, NULL},
991                 /* Configure some basic stuff */
992                 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
993                 {MIIM_CIS8204_SLED_CON, MIIM_CIS8204_SLEDCON_INIT,
994                  &mii_cis8204_fixled},
995                 {MIIM_CIS8204_EPHY_CON, MIIM_CIS8204_EPHYCON_INIT,
996                  &mii_cis8204_setmode},
997                 {miim_end,}
998         },
999         (struct phy_cmd[]) {    /* startup */
1000                 /* Read the Status (2x to make sure link is right) */
1001                 {MIIM_STATUS, miim_read, NULL},
1002                 /* Auto-negotiate */
1003                 {MIIM_STATUS, miim_read, &mii_parse_sr},
1004                 /* Read the status */
1005                 {MIIM_CIS8201_AUX_CONSTAT, miim_read, &mii_parse_cis8201},
1006                 {miim_end,}
1007         },
1008         (struct phy_cmd[]) {    /* shutdown */
1009                 {miim_end,}
1010         },
1011 };
1012
1013 /* Cicada 8201 */
1014 static struct phy_info phy_info_cis8201 = {
1015         0xfc41,
1016         "CIS8201",
1017         4,
1018         (struct phy_cmd[]) {    /* config */
1019                 /* Override PHY config settings */
1020                 {MIIM_CIS8201_AUX_CONSTAT, MIIM_CIS8201_AUXCONSTAT_INIT, NULL},
1021                 /* Set up the interface mode */
1022                 {MIIM_CIS8201_EXT_CON1, MIIM_CIS8201_EXTCON1_INIT, NULL},
1023                 /* Configure some basic stuff */
1024                 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
1025                 {miim_end,}
1026         },
1027         (struct phy_cmd[]) {    /* startup */
1028                 /* Read the Status (2x to make sure link is right) */
1029                 {MIIM_STATUS, miim_read, NULL},
1030                 /* Auto-negotiate */
1031                 {MIIM_STATUS, miim_read, &mii_parse_sr},
1032                 /* Read the status */
1033                 {MIIM_CIS8201_AUX_CONSTAT, miim_read, &mii_parse_cis8201},
1034                 {miim_end,}
1035         },
1036         (struct phy_cmd[]) {    /* shutdown */
1037                 {miim_end,}
1038         },
1039 };
1040
1041 static struct phy_info phy_info_VSC8211 = {
1042         0xfc4b,
1043         "Vitesse VSC8211",
1044         4,
1045         (struct phy_cmd[]) { /* config */
1046                 /* Override PHY config settings */
1047                 {MIIM_CIS8201_AUX_CONSTAT, MIIM_CIS8201_AUXCONSTAT_INIT, NULL},
1048                 /* Set up the interface mode */
1049                 {MIIM_CIS8201_EXT_CON1, MIIM_CIS8201_EXTCON1_INIT, NULL},
1050                 /* Configure some basic stuff */
1051                 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
1052                 {miim_end,}
1053         },
1054         (struct phy_cmd[]) { /* startup */
1055                 /* Read the Status (2x to make sure link is right) */
1056                 {MIIM_STATUS, miim_read, NULL},
1057                 /* Auto-negotiate */
1058                 {MIIM_STATUS, miim_read, &mii_parse_sr},
1059                 /* Read the status */
1060                 {MIIM_CIS8201_AUX_CONSTAT, miim_read, &mii_parse_cis8201},
1061                 {miim_end,}
1062         },
1063         (struct phy_cmd[]) { /* shutdown */
1064                 {miim_end,}
1065         },
1066 };
1067
1068 static struct phy_info phy_info_VSC8244 = {
1069         0x3f1b,
1070         "Vitesse VSC8244",
1071         6,
1072         (struct phy_cmd[]) {    /* config */
1073                 /* Override PHY config settings */
1074                 /* Configure some basic stuff */
1075                 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
1076                 {miim_end,}
1077         },
1078         (struct phy_cmd[]) {    /* startup */
1079                 /* Read the Status (2x to make sure link is right) */
1080                 {MIIM_STATUS, miim_read, NULL},
1081                 /* Auto-negotiate */
1082                 {MIIM_STATUS, miim_read, &mii_parse_sr},
1083                 /* Read the status */
1084                 {MIIM_VSC8244_AUX_CONSTAT, miim_read, &mii_parse_vsc8244},
1085                 {miim_end,}
1086         },
1087         (struct phy_cmd[]) {    /* shutdown */
1088                 {miim_end,}
1089         },
1090 };
1091
1092 static struct phy_info phy_info_VSC8641 = {
1093         0x7043,
1094         "Vitesse VSC8641",
1095         4,
1096         (struct phy_cmd[]) {    /* config */
1097                 /* Configure some basic stuff */
1098                 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
1099                 {miim_end,}
1100         },
1101         (struct phy_cmd[]) {    /* startup */
1102                 /* Read the Status (2x to make sure link is right) */
1103                 {MIIM_STATUS, miim_read, NULL},
1104                 /* Auto-negotiate */
1105                 {MIIM_STATUS, miim_read, &mii_parse_sr},
1106                 /* Read the status */
1107                 {MIIM_VSC8244_AUX_CONSTAT, miim_read, &mii_parse_vsc8244},
1108                 {miim_end,}
1109         },
1110         (struct phy_cmd[]) {    /* shutdown */
1111                 {miim_end,}
1112         },
1113 };
1114
1115 static struct phy_info phy_info_VSC8221 = {
1116         0xfc55,
1117         "Vitesse VSC8221",
1118         4,
1119         (struct phy_cmd[]) {    /* config */
1120                 /* Configure some basic stuff */
1121                 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
1122                 {miim_end,}
1123         },
1124         (struct phy_cmd[]) {    /* startup */
1125                 /* Read the Status (2x to make sure link is right) */
1126                 {MIIM_STATUS, miim_read, NULL},
1127                 /* Auto-negotiate */
1128                 {MIIM_STATUS, miim_read, &mii_parse_sr},
1129                 /* Read the status */
1130                 {MIIM_VSC8244_AUX_CONSTAT, miim_read, &mii_parse_vsc8244},
1131                 {miim_end,}
1132         },
1133         (struct phy_cmd[]) {    /* shutdown */
1134                 {miim_end,}
1135         },
1136 };
1137
1138 static struct phy_info phy_info_VSC8601 = {
1139         0x00007042,
1140         "Vitesse VSC8601",
1141         4,
1142         (struct phy_cmd[]) {     /* config */
1143                 /* Override PHY config settings */
1144                 /* Configure some basic stuff */
1145                 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
1146 #ifdef CONFIG_SYS_VSC8601_SKEWFIX
1147                 {MIIM_VSC8601_EPHY_CON,MIIM_VSC8601_EPHY_CON_INIT_SKEW,NULL},
1148 #if defined(CONFIG_SYS_VSC8601_SKEW_TX) && defined(CONFIG_SYS_VSC8601_SKEW_RX)
1149                 {MIIM_EXT_PAGE_ACCESS,1,NULL},
1150 #define VSC8101_SKEW \
1151         (CONFIG_SYS_VSC8601_SKEW_TX << 14) | (CONFIG_SYS_VSC8601_SKEW_RX << 12)
1152                 {MIIM_VSC8601_SKEW_CTRL,VSC8101_SKEW,NULL},
1153                 {MIIM_EXT_PAGE_ACCESS,0,NULL},
1154 #endif
1155 #endif
1156                 {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
1157                 {MIIM_CONTROL, MIIM_CONTROL_RESTART, &mii_cr_init},
1158                 {miim_end,}
1159         },
1160         (struct phy_cmd[]) {     /* startup */
1161                 /* Read the Status (2x to make sure link is right) */
1162                 {MIIM_STATUS, miim_read, NULL},
1163                 /* Auto-negotiate */
1164                 {MIIM_STATUS, miim_read, &mii_parse_sr},
1165                 /* Read the status */
1166                 {MIIM_VSC8244_AUX_CONSTAT, miim_read, &mii_parse_vsc8244},
1167                 {miim_end,}
1168         },
1169         (struct phy_cmd[]) {     /* shutdown */
1170                 {miim_end,}
1171         },
1172 };
1173
1174 static struct phy_info phy_info_dm9161 = {
1175         0x0181b88,
1176         "Davicom DM9161E",
1177         4,
1178         (struct phy_cmd[]) {    /* config */
1179                 {MIIM_CONTROL, MIIM_DM9161_CR_STOP, NULL},
1180                 /* Do not bypass the scrambler/descrambler */
1181                 {MIIM_DM9161_SCR, MIIM_DM9161_SCR_INIT, NULL},
1182                 /* Clear 10BTCSR to default */
1183                 {MIIM_DM9161_10BTCSR, MIIM_DM9161_10BTCSR_INIT, NULL},
1184                 /* Configure some basic stuff */
1185                 {MIIM_CONTROL, MIIM_CR_INIT, NULL},
1186                 /* Restart Auto Negotiation */
1187                 {MIIM_CONTROL, MIIM_DM9161_CR_RSTAN, NULL},
1188                 {miim_end,}
1189         },
1190         (struct phy_cmd[]) {    /* startup */
1191                 /* Status is read once to clear old link state */
1192                 {MIIM_STATUS, miim_read, NULL},
1193                 /* Auto-negotiate */
1194                 {MIIM_STATUS, miim_read, &mii_parse_sr},
1195                 /* Read the status */
1196                 {MIIM_DM9161_SCSR, miim_read, &mii_parse_dm9161_scsr},
1197                 {miim_end,}
1198         },
1199         (struct phy_cmd[]) {    /* shutdown */
1200                 {miim_end,}
1201         },
1202 };
1203
1204 /* micrel KSZ804  */
1205 static struct phy_info phy_info_ksz804 =  {
1206         0x0022151,
1207         "Micrel KSZ804 PHY",
1208         4,
1209         (struct phy_cmd[]) { /* config */
1210                 {MII_BMCR, BMCR_RESET, NULL},
1211                 {MII_BMCR, BMCR_ANENABLE|BMCR_ANRESTART, NULL},
1212                 {miim_end,}
1213         },
1214         (struct phy_cmd[]) { /* startup */
1215                 {MII_BMSR, miim_read, NULL},
1216                 {MII_BMSR, miim_read, &mii_parse_sr},
1217                 {MII_BMSR, miim_read, &mii_parse_link},
1218                 {miim_end,}
1219         },
1220         (struct phy_cmd[]) { /* shutdown */
1221                 {miim_end,}
1222         }
1223 };
1224
1225 /* a generic flavor.  */
1226 static struct phy_info phy_info_generic =  {
1227         0,
1228         "Unknown/Generic PHY",
1229         32,
1230         (struct phy_cmd[]) { /* config */
1231                 {MII_BMCR, BMCR_RESET, NULL},
1232                 {MII_BMCR, BMCR_ANENABLE|BMCR_ANRESTART, NULL},
1233                 {miim_end,}
1234         },
1235         (struct phy_cmd[]) { /* startup */
1236                 {MII_BMSR, miim_read, NULL},
1237                 {MII_BMSR, miim_read, &mii_parse_sr},
1238                 {MII_BMSR, miim_read, &mii_parse_link},
1239                 {miim_end,}
1240         },
1241         (struct phy_cmd[]) { /* shutdown */
1242                 {miim_end,}
1243         }
1244 };
1245
1246 static uint mii_parse_lxt971_sr2(uint mii_reg, struct tsec_private *priv)
1247 {
1248         unsigned int speed;
1249         if (priv->link) {
1250                 speed = mii_reg & MIIM_LXT971_SR2_SPEED_MASK;
1251
1252                 switch (speed) {
1253                 case MIIM_LXT971_SR2_10HDX:
1254                         priv->speed = 10;
1255                         priv->duplexity = 0;
1256                         break;
1257                 case MIIM_LXT971_SR2_10FDX:
1258                         priv->speed = 10;
1259                         priv->duplexity = 1;
1260                         break;
1261                 case MIIM_LXT971_SR2_100HDX:
1262                         priv->speed = 100;
1263                         priv->duplexity = 0;
1264                         break;
1265                 default:
1266                         priv->speed = 100;
1267                         priv->duplexity = 1;
1268                 }
1269         } else {
1270                 priv->speed = 0;
1271                 priv->duplexity = 0;
1272         }
1273
1274         return 0;
1275 }
1276
1277 static struct phy_info phy_info_lxt971 = {
1278         0x0001378e,
1279         "LXT971",
1280         4,
1281         (struct phy_cmd[]) {    /* config */
1282                 {MIIM_CR, MIIM_CR_INIT, mii_cr_init},   /* autonegotiate */
1283                 {miim_end,}
1284         },
1285         (struct phy_cmd[]) {    /* startup - enable interrupts */
1286                 /* { 0x12, 0x00f2, NULL }, */
1287                 {MIIM_STATUS, miim_read, NULL},
1288                 {MIIM_STATUS, miim_read, &mii_parse_sr},
1289                 {MIIM_LXT971_SR2, miim_read, &mii_parse_lxt971_sr2},
1290                 {miim_end,}
1291         },
1292         (struct phy_cmd[]) {    /* shutdown - disable interrupts */
1293                 {miim_end,}
1294         },
1295 };
1296
1297 /* Parse the DP83865's link and auto-neg status register for speed and duplex
1298  * information
1299  */
1300 static uint mii_parse_dp83865_lanr(uint mii_reg, struct tsec_private *priv)
1301 {
1302         switch (mii_reg & MIIM_DP83865_SPD_MASK) {
1303
1304         case MIIM_DP83865_SPD_1000:
1305                 priv->speed = 1000;
1306                 break;
1307
1308         case MIIM_DP83865_SPD_100:
1309                 priv->speed = 100;
1310                 break;
1311
1312         default:
1313                 priv->speed = 10;
1314                 break;
1315
1316         }
1317
1318         if (mii_reg & MIIM_DP83865_DPX_FULL)
1319                 priv->duplexity = 1;
1320         else
1321                 priv->duplexity = 0;
1322
1323         return 0;
1324 }
1325
1326 static struct phy_info phy_info_dp83865 = {
1327         0x20005c7,
1328         "NatSemi DP83865",
1329         4,
1330         (struct phy_cmd[]) {    /* config */
1331                 {MIIM_CONTROL, MIIM_DP83865_CR_INIT, NULL},
1332                 {miim_end,}
1333         },
1334         (struct phy_cmd[]) {    /* startup */
1335                 /* Status is read once to clear old link state */
1336                 {MIIM_STATUS, miim_read, NULL},
1337                 /* Auto-negotiate */
1338                 {MIIM_STATUS, miim_read, &mii_parse_sr},
1339                 /* Read the link and auto-neg status */
1340                 {MIIM_DP83865_LANR, miim_read, &mii_parse_dp83865_lanr},
1341                 {miim_end,}
1342         },
1343         (struct phy_cmd[]) {    /* shutdown */
1344                 {miim_end,}
1345         },
1346 };
1347
1348 static struct phy_info phy_info_rtl8211b = {
1349         0x001cc91,
1350         "RealTek RTL8211B",
1351         4,
1352         (struct phy_cmd[]) {    /* config */
1353                 /* Reset and configure the PHY */
1354                 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
1355                 {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
1356                 {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
1357                 {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
1358                 {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
1359                 {miim_end,}
1360         },
1361         (struct phy_cmd[]) {    /* startup */
1362                 /* Status is read once to clear old link state */
1363                 {MIIM_STATUS, miim_read, NULL},
1364                 /* Auto-negotiate */
1365                 {MIIM_STATUS, miim_read, &mii_parse_sr},
1366                 /* Read the status */
1367                 {MIIM_RTL8211B_PHY_STATUS, miim_read, &mii_parse_RTL8211B_sr},
1368                 {miim_end,}
1369         },
1370         (struct phy_cmd[]) {    /* shutdown */
1371                 {miim_end,}
1372         },
1373 };
1374
1375 struct phy_info phy_info_AR8021 =  {
1376         0x4dd04,
1377         "AR8021",
1378         4,
1379         (struct phy_cmd[]) { /* config */
1380                 {MII_BMCR, BMCR_RESET, NULL},
1381                 {MII_BMCR, BMCR_ANENABLE|BMCR_ANRESTART, NULL},
1382                 {0x1d, 0x05, NULL},
1383                 {0x1e, 0x3D47, NULL},
1384                 {miim_end,}
1385         },
1386         (struct phy_cmd[]) { /* startup */
1387                 {MII_BMSR, miim_read, NULL},
1388                 {MII_BMSR, miim_read, &mii_parse_sr},
1389                 {MII_BMSR, miim_read, &mii_parse_link},
1390                 {miim_end,}
1391         },
1392         (struct phy_cmd[]) { /* shutdown */
1393                 {miim_end,}
1394         }
1395 };
1396
1397 static struct phy_info *phy_info[] = {
1398         &phy_info_cis8204,
1399         &phy_info_cis8201,
1400         &phy_info_BCM5461S,
1401         &phy_info_BCM5464S,
1402         &phy_info_BCM5482S,
1403         &phy_info_M88E1011S,
1404         &phy_info_M88E1111S,
1405         &phy_info_M88E1118,
1406         &phy_info_M88E1121R,
1407         &phy_info_M88E1145,
1408         &phy_info_M88E1149S,
1409         &phy_info_dm9161,
1410         &phy_info_ksz804,
1411         &phy_info_lxt971,
1412         &phy_info_VSC8211,
1413         &phy_info_VSC8244,
1414         &phy_info_VSC8601,
1415         &phy_info_VSC8641,
1416         &phy_info_VSC8221,
1417         &phy_info_dp83865,
1418         &phy_info_rtl8211b,
1419         &phy_info_AR8021,
1420         &phy_info_generic,      /* must be last; has ID 0 and 32 bit mask */
1421         NULL
1422 };
1423
1424 /* Grab the identifier of the device's PHY, and search through
1425  * all of the known PHYs to see if one matches.  If so, return
1426  * it, if not, return NULL
1427  */
1428 static struct phy_info *get_phy_info(struct eth_device *dev)
1429 {
1430         struct tsec_private *priv = (struct tsec_private *)dev->priv;
1431         uint phy_reg, phy_ID;
1432         int i;
1433         struct phy_info *theInfo = NULL;
1434
1435         /* Grab the bits from PHYIR1, and put them in the upper half */
1436         phy_reg = read_phy_reg(priv, MIIM_PHYIR1);
1437         phy_ID = (phy_reg & 0xffff) << 16;
1438
1439         /* Grab the bits from PHYIR2, and put them in the lower half */
1440         phy_reg = read_phy_reg(priv, MIIM_PHYIR2);
1441         phy_ID |= (phy_reg & 0xffff);
1442
1443         /* loop through all the known PHY types, and find one that */
1444         /* matches the ID we read from the PHY. */
1445         for (i = 0; phy_info[i]; i++) {
1446                 if (phy_info[i]->id == (phy_ID >> phy_info[i]->shift)) {
1447                         theInfo = phy_info[i];
1448                         break;
1449                 }
1450         }
1451
1452         if (theInfo == &phy_info_generic) {
1453                 printf("%s: No support for PHY id %x; assuming generic\n",
1454                         dev->name, phy_ID);
1455         } else {
1456                 debug("%s: PHY is %s (%x)\n", dev->name, theInfo->name, phy_ID);
1457         }
1458
1459         return theInfo;
1460 }
1461
1462 /* Execute the given series of commands on the given device's
1463  * PHY, running functions as necessary
1464  */
1465 static void phy_run_commands(struct tsec_private *priv, struct phy_cmd *cmd)
1466 {
1467         int i;
1468         uint result;
1469         tsec_mdio_t *phyregs = priv->phyregs;
1470
1471         out_be32(&phyregs->miimcfg, MIIMCFG_RESET);
1472
1473         out_be32(&phyregs->miimcfg, MIIMCFG_INIT_VALUE);
1474
1475         while (in_be32(&phyregs->miimind) & MIIMIND_BUSY)
1476                 ;
1477
1478         for (i = 0; cmd->mii_reg != miim_end; i++) {
1479                 if (cmd->mii_data == miim_read) {
1480                         result = read_phy_reg(priv, cmd->mii_reg);
1481
1482                         if (cmd->funct != NULL)
1483                                 (*(cmd->funct)) (result, priv);
1484
1485                 } else {
1486                         if (cmd->funct != NULL)
1487                                 result = (*(cmd->funct)) (cmd->mii_reg, priv);
1488                         else
1489                                 result = cmd->mii_data;
1490
1491                         write_phy_reg(priv, cmd->mii_reg, result);
1492
1493                 }
1494                 cmd++;
1495         }
1496 }
1497
1498 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
1499         && !defined(BITBANGMII)
1500
1501 /*
1502  * Read a MII PHY register.
1503  *
1504  * Returns:
1505  *  0 on success
1506  */
1507 static int tsec_miiphy_read(const char *devname, unsigned char addr,
1508                             unsigned char reg, unsigned short *value)
1509 {
1510         unsigned short ret;
1511         struct tsec_private *priv = privlist[0];
1512
1513         if (NULL == priv) {
1514                 printf("Can't read PHY at address %d\n", addr);
1515                 return -1;
1516         }
1517
1518         ret = (unsigned short)tsec_local_mdio_read(priv->phyregs, addr, reg);
1519         *value = ret;
1520
1521         return 0;
1522 }
1523
1524 /*
1525  * Write a MII PHY register.
1526  *
1527  * Returns:
1528  *  0 on success
1529  */
1530 static int tsec_miiphy_write(const char *devname, unsigned char addr,
1531                              unsigned char reg, unsigned short value)
1532 {
1533         struct tsec_private *priv = privlist[0];
1534
1535         if (NULL == priv) {
1536                 printf("Can't write PHY at address %d\n", addr);
1537                 return -1;
1538         }
1539
1540         tsec_local_mdio_write(priv->phyregs, addr, reg, value);
1541
1542         return 0;
1543 }
1544
1545 #endif
1546
1547 #ifdef CONFIG_MCAST_TFTP
1548
1549 /* CREDITS: linux gianfar driver, slightly adjusted... thanx. */
1550
1551 /* Set the appropriate hash bit for the given addr */
1552
1553 /* The algorithm works like so:
1554  * 1) Take the Destination Address (ie the multicast address), and
1555  * do a CRC on it (little endian), and reverse the bits of the
1556  * result.
1557  * 2) Use the 8 most significant bits as a hash into a 256-entry
1558  * table.  The table is controlled through 8 32-bit registers:
1559  * gaddr0-7.  gaddr0's MSB is entry 0, and gaddr7's LSB is
1560  * gaddr7.  This means that the 3 most significant bits in the
1561  * hash index which gaddr register to use, and the 5 other bits
1562  * indicate which bit (assuming an IBM numbering scheme, which
1563  * for PowerPC (tm) is usually the case) in the tregister holds
1564  * the entry. */
1565 static int
1566 tsec_mcast_addr (struct eth_device *dev, u8 mcast_mac, u8 set)
1567 {
1568         struct tsec_private *priv = privlist[1];
1569         volatile tsec_t *regs = priv->regs;
1570         volatile u32  *reg_array, value;
1571         u8 result, whichbit, whichreg;
1572
1573         result = (u8)((ether_crc(MAC_ADDR_LEN,mcast_mac) >> 24) & 0xff);
1574         whichbit = result & 0x1f;       /* the 5 LSB = which bit to set */
1575         whichreg = result >> 5;         /* the 3 MSB = which reg to set it in */
1576         value = (1 << (31-whichbit));
1577
1578         reg_array = &(regs->hash.gaddr0);
1579
1580         if (set) {
1581                 reg_array[whichreg] |= value;
1582         } else {
1583                 reg_array[whichreg] &= ~value;
1584         }
1585         return 0;
1586 }
1587 #endif /* Multicast TFTP ? */
1588
1589 /* Initialized required registers to appropriate values, zeroing
1590  * those we don't care about (unless zero is bad, in which case,
1591  * choose a more appropriate value)
1592  */
1593 static void init_registers(tsec_t *regs)
1594 {
1595         /* Clear IEVENT */
1596         out_be32(&regs->ievent, IEVENT_INIT_CLEAR);
1597
1598         out_be32(&regs->imask, IMASK_INIT_CLEAR);
1599
1600         out_be32(&regs->hash.iaddr0, 0);
1601         out_be32(&regs->hash.iaddr1, 0);
1602         out_be32(&regs->hash.iaddr2, 0);
1603         out_be32(&regs->hash.iaddr3, 0);
1604         out_be32(&regs->hash.iaddr4, 0);
1605         out_be32(&regs->hash.iaddr5, 0);
1606         out_be32(&regs->hash.iaddr6, 0);
1607         out_be32(&regs->hash.iaddr7, 0);
1608
1609         out_be32(&regs->hash.gaddr0, 0);
1610         out_be32(&regs->hash.gaddr1, 0);
1611         out_be32(&regs->hash.gaddr2, 0);
1612         out_be32(&regs->hash.gaddr3, 0);
1613         out_be32(&regs->hash.gaddr4, 0);
1614         out_be32(&regs->hash.gaddr5, 0);
1615         out_be32(&regs->hash.gaddr6, 0);
1616         out_be32(&regs->hash.gaddr7, 0);
1617
1618         out_be32(&regs->rctrl, 0x00000000);
1619
1620         /* Init RMON mib registers */
1621         memset((void *)&(regs->rmon), 0, sizeof(rmon_mib_t));
1622
1623         out_be32(&regs->rmon.cam1, 0xffffffff);
1624         out_be32(&regs->rmon.cam2, 0xffffffff);
1625
1626         out_be32(&regs->mrblr, MRBLR_INIT_SETTINGS);
1627
1628         out_be32(&regs->minflr, MINFLR_INIT_SETTINGS);
1629
1630         out_be32(&regs->attr, ATTR_INIT_SETTINGS);
1631         out_be32(&regs->attreli, ATTRELI_INIT_SETTINGS);
1632
1633 }
1634
1635 /* Configure maccfg2 based on negotiated speed and duplex
1636  * reported by PHY handling code
1637  */
1638 static void adjust_link(struct eth_device *dev)
1639 {
1640         struct tsec_private *priv = (struct tsec_private *)dev->priv;
1641         tsec_t *regs = priv->regs;
1642         u32 ecntrl, maccfg2;
1643
1644         if (!priv->link) {
1645                 printf("%s: No link.\n", dev->name);
1646                 return;
1647         }
1648
1649         /* clear all bits relative with interface mode */
1650         ecntrl = in_be32(&regs->ecntrl);
1651         ecntrl &= ~ECNTRL_R100;
1652
1653         maccfg2 = in_be32(&regs->maccfg2);
1654         maccfg2 &= ~(MACCFG2_IF | MACCFG2_FULL_DUPLEX);
1655
1656         if (priv->duplexity)
1657                 maccfg2 |= MACCFG2_FULL_DUPLEX;
1658
1659         switch (priv->speed) {
1660         case 1000:
1661                 maccfg2 |= MACCFG2_GMII;
1662                 break;
1663         case 100:
1664         case 10:
1665                 maccfg2 |= MACCFG2_MII;
1666
1667                 /* Set R100 bit in all modes although
1668                  * it is only used in RGMII mode
1669                  */
1670                 if (priv->speed == 100)
1671                         ecntrl |= ECNTRL_R100;
1672                 break;
1673         default:
1674                 printf("%s: Speed was bad\n", dev->name);
1675                 break;
1676         }
1677
1678         out_be32(&regs->ecntrl, ecntrl);
1679         out_be32(&regs->maccfg2, maccfg2);
1680
1681         printf("Speed: %d, %s duplex%s\n", priv->speed,
1682                         (priv->duplexity) ? "full" : "half",
1683                         (priv->flags & TSEC_FIBER) ? ", fiber mode" : "");
1684 }
1685
1686 /* Set up the buffers and their descriptors, and bring up the
1687  * interface
1688  */
1689 static void startup_tsec(struct eth_device *dev)
1690 {
1691         int i;
1692         struct tsec_private *priv = (struct tsec_private *)dev->priv;
1693         tsec_t *regs = priv->regs;
1694
1695         /* Point to the buffer descriptors */
1696         out_be32(&regs->tbase, (unsigned int)(&rtx.txbd[txIdx]));
1697         out_be32(&regs->rbase, (unsigned int)(&rtx.rxbd[rxIdx]));
1698
1699         /* Initialize the Rx Buffer descriptors */
1700         for (i = 0; i < PKTBUFSRX; i++) {
1701                 rtx.rxbd[i].status = RXBD_EMPTY;
1702                 rtx.rxbd[i].length = 0;
1703                 rtx.rxbd[i].bufPtr = (uint) NetRxPackets[i];
1704         }
1705         rtx.rxbd[PKTBUFSRX - 1].status |= RXBD_WRAP;
1706
1707         /* Initialize the TX Buffer Descriptors */
1708         for (i = 0; i < TX_BUF_CNT; i++) {
1709                 rtx.txbd[i].status = 0;
1710                 rtx.txbd[i].length = 0;
1711                 rtx.txbd[i].bufPtr = 0;
1712         }
1713         rtx.txbd[TX_BUF_CNT - 1].status |= TXBD_WRAP;
1714
1715         /* Start up the PHY */
1716         if (priv->phyinfo)
1717                 phy_run_commands(priv, priv->phyinfo->startup);
1718
1719         adjust_link(dev);
1720
1721         /* Enable Transmit and Receive */
1722         setbits_be32(&regs->maccfg1, MACCFG1_RX_EN | MACCFG1_TX_EN);
1723
1724         /* Tell the DMA it is clear to go */
1725         setbits_be32(&regs->dmactrl, DMACTRL_INIT_SETTINGS);
1726         out_be32(&regs->tstat, TSTAT_CLEAR_THALT);
1727         out_be32(&regs->rstat, RSTAT_CLEAR_RHALT);
1728         clrbits_be32(&regs->dmactrl, DMACTRL_GRS | DMACTRL_GTS);
1729 }
1730
1731 /* This returns the status bits of the device.  The return value
1732  * is never checked, and this is what the 8260 driver did, so we
1733  * do the same.  Presumably, this would be zero if there were no
1734  * errors
1735  */
1736 static int tsec_send(struct eth_device *dev, volatile void *packet, int length)
1737 {
1738         int i;
1739         int result = 0;
1740         struct tsec_private *priv = (struct tsec_private *)dev->priv;
1741         tsec_t *regs = priv->regs;
1742
1743         /* Find an empty buffer descriptor */
1744         for (i = 0; rtx.txbd[txIdx].status & TXBD_READY; i++) {
1745                 if (i >= TOUT_LOOP) {
1746                         debug("%s: tsec: tx buffers full\n", dev->name);
1747                         return result;
1748                 }
1749         }
1750
1751         rtx.txbd[txIdx].bufPtr = (uint) packet;
1752         rtx.txbd[txIdx].length = length;
1753         rtx.txbd[txIdx].status |=
1754             (TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT);
1755
1756         /* Tell the DMA to go */
1757         out_be32(&regs->tstat, TSTAT_CLEAR_THALT);
1758
1759         /* Wait for buffer to be transmitted */
1760         for (i = 0; rtx.txbd[txIdx].status & TXBD_READY; i++) {
1761                 if (i >= TOUT_LOOP) {
1762                         debug("%s: tsec: tx error\n", dev->name);
1763                         return result;
1764                 }
1765         }
1766
1767         txIdx = (txIdx + 1) % TX_BUF_CNT;
1768         result = rtx.txbd[txIdx].status & TXBD_STATS;
1769
1770         return result;
1771 }
1772
1773 static int tsec_recv(struct eth_device *dev)
1774 {
1775         int length;
1776         struct tsec_private *priv = (struct tsec_private *)dev->priv;
1777         tsec_t *regs = priv->regs;
1778
1779         while (!(rtx.rxbd[rxIdx].status & RXBD_EMPTY)) {
1780
1781                 length = rtx.rxbd[rxIdx].length;
1782
1783                 /* Send the packet up if there were no errors */
1784                 if (!(rtx.rxbd[rxIdx].status & RXBD_STATS)) {
1785                         NetReceive(NetRxPackets[rxIdx], length - 4);
1786                 } else {
1787                         printf("Got error %x\n",
1788                                (rtx.rxbd[rxIdx].status & RXBD_STATS));
1789                 }
1790
1791                 rtx.rxbd[rxIdx].length = 0;
1792
1793                 /* Set the wrap bit if this is the last element in the list */
1794                 rtx.rxbd[rxIdx].status =
1795                     RXBD_EMPTY | (((rxIdx + 1) == PKTBUFSRX) ? RXBD_WRAP : 0);
1796
1797                 rxIdx = (rxIdx + 1) % PKTBUFSRX;
1798         }
1799
1800         if (in_be32(&regs->ievent) & IEVENT_BSY) {
1801                 out_be32(&regs->ievent, IEVENT_BSY);
1802                 out_be32(&regs->rstat, RSTAT_CLEAR_RHALT);
1803         }
1804
1805         return -1;
1806
1807 }
1808
1809 /* Stop the interface */
1810 static void tsec_halt(struct eth_device *dev)
1811 {
1812         struct tsec_private *priv = (struct tsec_private *)dev->priv;
1813         tsec_t *regs = priv->regs;
1814
1815         clrbits_be32(&regs->dmactrl, DMACTRL_GRS | DMACTRL_GTS);
1816         setbits_be32(&regs->dmactrl, DMACTRL_GRS | DMACTRL_GTS);
1817
1818         while ((in_be32(&regs->ievent) & (IEVENT_GRSC | IEVENT_GTSC))
1819                         != (IEVENT_GRSC | IEVENT_GTSC))
1820                 ;
1821
1822         clrbits_be32(&regs->maccfg1, MACCFG1_TX_EN | MACCFG1_RX_EN);
1823
1824         /* Shut down the PHY, as needed */
1825         if (priv->phyinfo)
1826                 phy_run_commands(priv, priv->phyinfo->shutdown);
1827 }
1828
1829 /* Initializes data structures and registers for the controller,
1830  * and brings the interface up.  Returns the link status, meaning
1831  * that it returns success if the link is up, failure otherwise.
1832  * This allows u-boot to find the first active controller.
1833  */
1834 static int tsec_init(struct eth_device *dev, bd_t * bd)
1835 {
1836         uint tempval;
1837         char tmpbuf[MAC_ADDR_LEN];
1838         int i;
1839         struct tsec_private *priv = (struct tsec_private *)dev->priv;
1840         tsec_t *regs = priv->regs;
1841
1842         /* Make sure the controller is stopped */
1843         tsec_halt(dev);
1844
1845         /* Init MACCFG2.  Defaults to GMII */
1846         out_be32(&regs->maccfg2, MACCFG2_INIT_SETTINGS);
1847
1848         /* Init ECNTRL */
1849         out_be32(&regs->ecntrl, ECNTRL_INIT_SETTINGS);
1850
1851         /* Copy the station address into the address registers.
1852          * Backwards, because little endian MACS are dumb */
1853         for (i = 0; i < MAC_ADDR_LEN; i++)
1854                 tmpbuf[MAC_ADDR_LEN - 1 - i] = dev->enetaddr[i];
1855
1856         tempval = (tmpbuf[0] << 24) | (tmpbuf[1] << 16) | (tmpbuf[2] << 8) |
1857                   tmpbuf[3];
1858
1859         out_be32(&regs->macstnaddr1, tempval);
1860
1861         tempval = *((uint *) (tmpbuf + 4));
1862
1863         out_be32(&regs->macstnaddr2, tempval);
1864
1865         /* reset the indices to zero */
1866         rxIdx = 0;
1867         txIdx = 0;
1868
1869         /* Clear out (for the most part) the other registers */
1870         init_registers(regs);
1871
1872         /* Ready the device for tx/rx */
1873         startup_tsec(dev);
1874
1875         /* If there's no link, fail */
1876         return priv->link ? 0 : -1;
1877 }
1878
1879 /* Discover which PHY is attached to the device, and configure it
1880  * properly.  If the PHY is not recognized, then return 0
1881  * (failure).  Otherwise, return 1
1882  */
1883 static int init_phy(struct eth_device *dev)
1884 {
1885         struct tsec_private *priv = (struct tsec_private *)dev->priv;
1886         struct phy_info *curphy;
1887         tsec_t *regs = priv->regs;
1888
1889         /* Assign a Physical address to the TBI */
1890         out_be32(&regs->tbipa, CONFIG_SYS_TBIPA_VALUE);
1891
1892         /* Reset MII (due to new addresses) */
1893         out_be32(&priv->phyregs->miimcfg, MIIMCFG_RESET);
1894         out_be32(&priv->phyregs->miimcfg, MIIMCFG_INIT_VALUE);
1895         while (in_be32(&priv->phyregs->miimind) & MIIMIND_BUSY)
1896                 ;
1897
1898         /* Get the cmd structure corresponding to the attached
1899          * PHY */
1900         curphy = get_phy_info(dev);
1901
1902         if (curphy == NULL) {
1903                 priv->phyinfo = NULL;
1904                 printf("%s: No PHY found\n", dev->name);
1905
1906                 return 0;
1907         }
1908
1909         if (in_be32(&regs->ecntrl) & ECNTRL_SGMII_MODE)
1910                 tsec_configure_serdes(priv);
1911
1912         priv->phyinfo = curphy;
1913
1914         phy_run_commands(priv, priv->phyinfo->config);
1915
1916         return 1;
1917 }
1918
1919 /* Initialize device structure. Returns success if PHY
1920  * initialization succeeded (i.e. if it recognizes the PHY)
1921  */
1922 static int tsec_initialize(bd_t *bis, struct tsec_info_struct *tsec_info)
1923 {
1924         struct eth_device *dev;
1925         int i;
1926         struct tsec_private *priv;
1927
1928         dev = (struct eth_device *)malloc(sizeof *dev);
1929
1930         if (NULL == dev)
1931                 return 0;
1932
1933         memset(dev, 0, sizeof *dev);
1934
1935         priv = (struct tsec_private *)malloc(sizeof(*priv));
1936
1937         if (NULL == priv)
1938                 return 0;
1939
1940         privlist[num_tsecs++] = priv;
1941         priv->regs = tsec_info->regs;
1942         priv->phyregs = tsec_info->miiregs;
1943         priv->phyregs_sgmii = tsec_info->miiregs_sgmii;
1944
1945         priv->phyaddr = tsec_info->phyaddr;
1946         priv->flags = tsec_info->flags;
1947
1948         sprintf(dev->name, tsec_info->devname);
1949         dev->iobase = 0;
1950         dev->priv = priv;
1951         dev->init = tsec_init;
1952         dev->halt = tsec_halt;
1953         dev->send = tsec_send;
1954         dev->recv = tsec_recv;
1955 #ifdef CONFIG_MCAST_TFTP
1956         dev->mcast = tsec_mcast_addr;
1957 #endif
1958
1959         /* Tell u-boot to get the addr from the env */
1960         for (i = 0; i < 6; i++)
1961                 dev->enetaddr[i] = 0;
1962
1963         eth_register(dev);
1964
1965         /* Reset the MAC */
1966         setbits_be32(&priv->regs->maccfg1, MACCFG1_SOFT_RESET);
1967         udelay(2);  /* Soft Reset must be asserted for 3 TX clocks */
1968         clrbits_be32(&priv->regs->maccfg1, MACCFG1_SOFT_RESET);
1969
1970 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
1971         && !defined(BITBANGMII)
1972         miiphy_register(dev->name, tsec_miiphy_read, tsec_miiphy_write);
1973 #endif
1974
1975         /* Try to initialize PHY here, and return */
1976         return init_phy(dev);
1977 }
1978
1979 /*
1980  * Initialize all the TSEC devices
1981  *
1982  * Returns the number of TSEC devices that were initialized
1983  */
1984 int tsec_eth_init(bd_t *bis, struct tsec_info_struct *tsecs, int num)
1985 {
1986         int i;
1987         int ret, count = 0;
1988
1989         for (i = 0; i < num; i++) {
1990                 ret = tsec_initialize(bis, &tsecs[i]);
1991                 if (ret > 0)
1992                         count += ret;
1993         }
1994
1995         return count;
1996 }
1997
1998 int tsec_standard_init(bd_t *bis)
1999 {
2000         return tsec_eth_init(bis, tsec_info, ARRAY_SIZE(tsec_info));
2001 }
2002