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