xref: /openbmc/u-boot/drivers/net/tsec.c (revision 907519108cd6f45aa067feea6fedd2743739342b)
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 
2003