2 * (C) Copyright 2000-2004
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 * See file CREDITS for list of people who contributed to this
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 #include <asm/m5271.h>
30 #include <asm/immap_5271.h>
34 #include <asm/m5272.h>
35 #include <asm/immap_5272.h>
39 #include <asm/m5282.h>
40 #include <asm/immap_5282.h>
47 #define FEC_ADDR (CFG_MBAR + 0x840)
49 #if defined(CONFIG_M5282) || defined(CONFIG_M5271)
50 #define FEC_ADDR (CFG_MBAR + 0x1000)
56 #if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(FEC_ENET)
58 #ifdef CFG_DISCOVER_PHY
60 static void mii_discover_phy (void);
63 /* Ethernet Transmit and Receive Buffers */
64 #define DBUF_LENGTH 1520
70 #define PKT_MAXBUF_SIZE 1518
71 #define PKT_MINBUF_SIZE 64
72 #define PKT_MAXBLR_SIZE 1520
75 static char txbuf
[DBUF_LENGTH
];
77 static uint rxIdx
; /* index of the current RX buffer */
78 static uint txIdx
; /* index of the current TX buffer */
81 * FEC Ethernet Tx and Rx buffer descriptors allocated at the
82 * immr->udata_bd address on Dual-Port RAM
83 * Provide for Double Buffering
86 typedef volatile struct CommonBufferDescriptor
{
87 cbd_t rxbd
[PKTBUFSRX
]; /* Rx BD */
88 cbd_t txbd
[TX_BUF_CNT
]; /* Tx BD */
91 static RTXBD
*rtx
= NULL
;
93 int eth_send (volatile void *packet
, int length
)
96 volatile fec_t
*fecp
= (fec_t
*) (FEC_ADDR
);
102 while ((rtx
->txbd
[txIdx
].cbd_sc
& BD_ENET_TX_READY
)
103 && (j
< TOUT_LOOP
)) {
107 if (j
>= TOUT_LOOP
) {
108 printf ("TX not ready\n");
111 rtx
->txbd
[txIdx
].cbd_bufaddr
= (uint
) packet
;
112 rtx
->txbd
[txIdx
].cbd_datlen
= length
;
113 rtx
->txbd
[txIdx
].cbd_sc
|= BD_ENET_TX_READY
| BD_ENET_TX_LAST
;
115 /* Activate transmit Buffer Descriptor polling */
116 fecp
->fec_x_des_active
= 0x01000000; /* Descriptor polling active */
119 while ((rtx
->txbd
[txIdx
].cbd_sc
& BD_ENET_TX_READY
)
120 && (j
< TOUT_LOOP
)) {
124 if (j
>= TOUT_LOOP
) {
125 printf ("TX timeout\n");
128 printf ("%s[%d] %s: cycles: %d status: %x retry cnt: %d\n",
129 __FILE__
, __LINE__
, __FUNCTION__
, j
, rtx
->txbd
[txIdx
].cbd_sc
,
130 (rtx
->txbd
[txIdx
].cbd_sc
& 0x003C) >> 2);
133 /* return only status bits */ ;
134 rc
= (rtx
->txbd
[txIdx
].cbd_sc
& BD_ENET_TX_STATS
);
136 txIdx
= (txIdx
+ 1) % TX_BUF_CNT
;
144 volatile fec_t
*fecp
= (fec_t
*) FEC_ADDR
;
147 /* section 16.9.23.2 */
148 if (rtx
->rxbd
[rxIdx
].cbd_sc
& BD_ENET_RX_EMPTY
) {
150 break; /* nothing received - leave for() loop */
153 length
= rtx
->rxbd
[rxIdx
].cbd_datlen
;
155 if (rtx
->rxbd
[rxIdx
].cbd_sc
& 0x003f) {
157 printf ("%s[%d] err: %x\n",
158 __FUNCTION__
, __LINE__
,
159 rtx
->rxbd
[rxIdx
].cbd_sc
);
162 /* Pass the packet up to the protocol layers. */
163 NetReceive (NetRxPackets
[rxIdx
], length
- 4);
166 /* Give the buffer back to the FEC. */
167 rtx
->rxbd
[rxIdx
].cbd_datlen
= 0;
169 /* wrap around buffer index when necessary */
170 if ((rxIdx
+ 1) >= PKTBUFSRX
) {
171 rtx
->rxbd
[PKTBUFSRX
- 1].cbd_sc
=
172 (BD_ENET_RX_WRAP
| BD_ENET_RX_EMPTY
);
175 rtx
->rxbd
[rxIdx
].cbd_sc
= BD_ENET_RX_EMPTY
;
179 /* Try to fill Buffer Descriptors */
180 fecp
->fec_r_des_active
= 0x01000000; /* Descriptor polling active */
186 /**************************************************************
188 * FEC Ethernet Initialization Routine
190 *************************************************************/
191 #define FEC_ECNTRL_ETHER_EN 0x00000002
192 #define FEC_ECNTRL_RESET 0x00000001
194 #define FEC_RCNTRL_BC_REJ 0x00000010
195 #define FEC_RCNTRL_PROM 0x00000008
196 #define FEC_RCNTRL_MII_MODE 0x00000004
197 #define FEC_RCNTRL_DRT 0x00000002
198 #define FEC_RCNTRL_LOOP 0x00000001
200 #define FEC_TCNTRL_FDEN 0x00000004
201 #define FEC_TCNTRL_HBC 0x00000002
202 #define FEC_TCNTRL_GTS 0x00000001
204 #define FEC_RESET_DELAY 50000
206 int eth_init (bd_t
* bd
)
208 #ifndef CFG_ENET_BD_BASE
209 DECLARE_GLOBAL_DATA_PTR
;
212 volatile fec_t
*fecp
= (fec_t
*) (FEC_ADDR
);
215 * A delay is required between a reset of the FEC block and
216 * initialization of other FEC registers because the reset takes
217 * some time to complete. If you don't delay, subsequent writes
218 * to FEC registers might get killed by the reset routine which is
221 fecp
->fec_ecntrl
= FEC_ECNTRL_RESET
;
223 (fecp
->fec_ecntrl
& FEC_ECNTRL_RESET
) && (i
< FEC_RESET_DELAY
);
227 if (i
== FEC_RESET_DELAY
) {
228 printf ("FEC_RESET_DELAY timeout\n");
232 /* We use strictly polling mode only
236 /* Clear any pending interrupt */
237 fecp
->fec_ievent
= 0xffffffff;
239 /* Set station address */
240 #define ea bd->bi_enetaddr
241 fecp
->fec_addr_low
= (ea
[0] << 24) | (ea
[1] << 16) |
242 (ea
[2] << 8) | (ea
[3]);
243 fecp
->fec_addr_high
= (ea
[4] << 24) | (ea
[5] << 16);
245 printf ("Eth Addrs: %02x:%02x:%02x:%02x:%02x:%02x\n",
246 ea
[0], ea
[1], ea
[2], ea
[3], ea
[4], ea
[5]);
251 /* Clear multicast address hash table
253 fecp
->fec_ghash_table_high
= 0;
254 fecp
->fec_ghash_table_low
= 0;
256 /* Clear individual address hash table
258 fecp
->fec_ihash_table_high
= 0;
259 fecp
->fec_ihash_table_low
= 0;
261 /* Clear multicast address hash table
264 fecp
->fec_ihash_table_high
= 0;
265 fecp
->fec_ihash_table_low
= 0;
267 fecp
->fec_hash_table_high
= 0;
268 fecp
->fec_hash_table_low
= 0;
272 /* Set maximum receive buffer size.
274 fecp
->fec_r_buff_size
= PKT_MAXBLR_SIZE
;
277 * Setup Buffers and Buffer Desriptors
283 #ifdef CFG_ENET_BD_BASE
284 rtx
= (RTXBD
*) CFG_ENET_BD_BASE
;
286 rtx
= (RTXBD
*) (CFG_MONITOR_BASE
+gd
->reloc_off
-
287 (((PKTBUFSRX
+TX_BUF_CNT
)*+sizeof(cbd_t
)
291 debug("set ENET_DB_BASE to %lX\n",(long) rtx
);
296 * Setup Receiver Buffer Descriptors (13.14.24.18)
300 for (i
= 0; i
< PKTBUFSRX
; i
++) {
301 rtx
->rxbd
[i
].cbd_sc
= BD_ENET_RX_EMPTY
;
302 rtx
->rxbd
[i
].cbd_datlen
= 0; /* Reset */
303 rtx
->rxbd
[i
].cbd_bufaddr
= (uint
) NetRxPackets
[i
];
305 rtx
->rxbd
[PKTBUFSRX
- 1].cbd_sc
|= BD_ENET_RX_WRAP
;
308 * Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19)
312 for (i
= 0; i
< TX_BUF_CNT
; i
++) {
313 rtx
->txbd
[i
].cbd_sc
= BD_ENET_TX_LAST
| BD_ENET_TX_TC
;
314 rtx
->txbd
[i
].cbd_datlen
= 0; /* Reset */
315 rtx
->txbd
[i
].cbd_bufaddr
= (uint
) (&txbuf
[0]);
317 rtx
->txbd
[TX_BUF_CNT
- 1].cbd_sc
|= BD_ENET_TX_WRAP
;
319 /* Set receive and transmit descriptor base
321 fecp
->fec_r_des_start
= (unsigned int) (&rtx
->rxbd
[0]);
322 fecp
->fec_x_des_start
= (unsigned int) (&rtx
->txbd
[0]);
327 #if 0 /* Full duplex mode */
328 fecp
->fec_r_cntrl
= FEC_RCNTRL_MII_MODE
;
329 fecp
->fec_x_cntrl
= FEC_TCNTRL_FDEN
;
330 #else /* Half duplex mode */
331 fecp
->fec_r_cntrl
= (PKT_MAXBUF_SIZE
<< 16); /* set max frame length */
332 fecp
->fec_r_cntrl
|= FEC_RCNTRL_MII_MODE
| FEC_RCNTRL_DRT
;
333 fecp
->fec_x_cntrl
= 0;
336 fecp
->fec_mii_speed
= (((CFG_CLK
/ 2) / (2500000 / 10)) + 5) / 10;
337 fecp
->fec_mii_speed
*= 2;
339 /* Configure port B for MII.
341 /* port initialization was already made in cpu_init_f() */
343 /* Now enable the transmit and receive processing
345 fecp
->fec_ecntrl
= FEC_ECNTRL_ETHER_EN
;
347 #ifdef CFG_DISCOVER_PHY
348 /* wait for the PHY to wake up after reset */
352 /* And last, try to fill Rx Buffer Descriptors */
353 fecp
->fec_r_des_active
= 0x01000000; /* Descriptor polling active */
360 volatile fec_t
*fecp
= (fec_t
*) FEC_ADDR
;
362 fecp
->fec_ecntrl
= 0;
366 #if defined(CFG_DISCOVER_PHY) || (CONFIG_COMMANDS & CFG_CMD_MII)
368 static int phyaddr
= -1; /* didn't find a PHY yet */
371 /* Make MII read/write commands for the FEC.
374 #define mk_mii_read(ADDR, REG) (0x60020000 | ((ADDR << 23) | \
377 #define mk_mii_write(ADDR, REG, VAL) (0x50020000 | ((ADDR << 23) | \
378 (REG & 0x1f) << 18) | \
381 /* Interrupt events/masks.
383 #define FEC_ENET_HBERR ((uint)0x80000000) /* Heartbeat error */
384 #define FEC_ENET_BABR ((uint)0x40000000) /* Babbling receiver */
385 #define FEC_ENET_BABT ((uint)0x20000000) /* Babbling transmitter */
386 #define FEC_ENET_GRA ((uint)0x10000000) /* Graceful stop complete */
387 #define FEC_ENET_TXF ((uint)0x08000000) /* Full frame transmitted */
388 #define FEC_ENET_TXB ((uint)0x04000000) /* A buffer was transmitted */
389 #define FEC_ENET_RXF ((uint)0x02000000) /* Full frame received */
390 #define FEC_ENET_RXB ((uint)0x01000000) /* A buffer was received */
391 #define FEC_ENET_MII ((uint)0x00800000) /* MII interrupt */
392 #define FEC_ENET_EBERR ((uint)0x00400000) /* SDMA bus error */
394 /* PHY identification
396 #define PHY_ID_LXT970 0x78100000 /* LXT970 */
397 #define PHY_ID_LXT971 0x001378e0 /* LXT971 and 972 */
398 #define PHY_ID_82555 0x02a80150 /* Intel 82555 */
399 #define PHY_ID_QS6612 0x01814400 /* QS6612 */
400 #define PHY_ID_AMD79C784 0x00225610 /* AMD 79C784 */
401 #define PHY_ID_LSI80225 0x0016f870 /* LSI 80225 */
402 #define PHY_ID_LSI80225B 0x0016f880 /* LSI 80225/B */
404 /* send command to phy using mii, wait for result */
405 static uint
mii_send (uint mii_cmd
)
408 volatile fec_t
*ep
= (fec_t
*) (FEC_ADDR
);
410 ep
->fec_mii_data
= mii_cmd
; /* command to phy */
412 /* wait for mii complete */
413 while (!(ep
->fec_ievent
& FEC_ENET_MII
)); /* spin until done */
414 mii_reply
= ep
->fec_mii_data
; /* result from phy */
415 ep
->fec_ievent
= FEC_ENET_MII
; /* clear MII complete */
417 printf ("%s[%d] %s: sent=0x%8.8x, reply=0x%8.8x\n",
418 __FILE__
, __LINE__
, __FUNCTION__
, mii_cmd
, mii_reply
);
420 return (mii_reply
& 0xffff); /* data read from phy */
422 #endif /* CFG_DISCOVER_PHY || (CONFIG_COMMANDS & CFG_CMD_MII) */
424 #if defined(CFG_DISCOVER_PHY)
425 static void mii_discover_phy (void)
427 #define MAX_PHY_PASSES 11
431 phyaddr
= -1; /* didn't find a PHY yet */
432 for (pass
= 1; pass
<= MAX_PHY_PASSES
&& phyaddr
< 0; ++pass
) {
434 /* PHY may need more time to recover from reset.
435 * The LXT970 needs 50ms typical, no maximum is
436 * specified, so wait 10ms before try again.
437 * With 11 passes this gives it 100ms to wake up.
439 udelay (10000); /* wait 10ms */
441 for (phyno
= 1; phyno
< 32 && phyaddr
< 0; ++phyno
) {
442 phytype
= mii_send (mk_mii_read (phyno
, PHY_PHYIDR1
));
444 printf ("PHY type 0x%x pass %d type ", phytype
, pass
);
446 if (phytype
!= 0xffff) {
449 phytype
|= mii_send (mk_mii_read (phyno
,
453 printf ("PHY @ 0x%x pass %d type ", phyno
,
455 switch (phytype
& 0xfffffff0) {
468 case PHY_ID_AMD79C784
:
469 printf ("AMD79C784\n");
471 case PHY_ID_LSI80225B
:
472 printf ("LSI L80225/B\n");
475 printf ("0x%08x\n", phytype
);
483 printf ("No PHY device found.\n");
486 #endif /* CFG_DISCOVER_PHY */
488 #if (CONFIG_COMMANDS & CFG_CMD_MII) && !defined(CONFIG_BITBANGMII)
490 static int mii_init_done
= 0;
492 /****************************************************************************
493 * mii_init -- Initialize the MII for MII command without ethernet
494 * This function is a subset of eth_init
495 ****************************************************************************
499 volatile fec_t
*fecp
= (fec_t
*) (FEC_ADDR
);
503 if (mii_init_done
!= 0) {
508 * A delay is required between a reset of the FEC block and
509 * initialization of other FEC registers because the reset takes
510 * some time to complete. If you don't delay, subsequent writes
511 * to FEC registers might get killed by the reset routine which is
515 fecp
->fec_ecntrl
= FEC_ECNTRL_RESET
;
517 (fecp
->fec_ecntrl
& FEC_ECNTRL_RESET
) && (i
< FEC_RESET_DELAY
);
521 if (i
== FEC_RESET_DELAY
) {
522 printf ("FEC_RESET_DELAY timeout\n");
526 /* We use strictly polling mode only
530 /* Clear any pending interrupt
532 fecp
->fec_ievent
= 0xffffffff;
535 fecp
->fec_mii_speed
= 0x0e;
537 /* Configure port B for MII.
539 /* port initialization was already made in cpu_init_f() */
541 /* Now enable the transmit and receive processing */
542 fecp
->fec_ecntrl
= FEC_ECNTRL_ETHER_EN
;
547 /*****************************************************************************
548 * Read and write a MII PHY register, routines used by MII Utilities
550 * FIXME: These routines are expected to return 0 on success, but mii_send
551 * does _not_ return an error code. Maybe 0xFFFF means error, i.e.
552 * no PHY connected...
553 * For now always return 0.
554 * FIXME: These routines only work after calling eth_init() at least once!
555 * Otherwise they hang in mii_send() !!! Sorry!
556 *****************************************************************************/
558 int mcf52x2_miiphy_read (char *devname
, unsigned char addr
,
559 unsigned char reg
, unsigned short *value
)
561 short rdreg
; /* register working value */
564 printf ("miiphy_read(0x%x) @ 0x%x = ", reg
, addr
);
566 rdreg
= mii_send (mk_mii_read (addr
, reg
));
571 printf ("0x%04x\n", *value
);
577 int mcf52x2_miiphy_write (char *devname
, unsigned char addr
,
578 unsigned char reg
, unsigned short value
)
580 short rdreg
; /* register working value */
583 printf ("miiphy_write(0x%x) @ 0x%x = ", reg
, addr
);
586 rdreg
= mii_send (mk_mii_write (addr
, reg
, value
));
589 printf ("0x%04x\n", value
);
594 #endif /* (CONFIG_COMMANDS & CFG_CMD_MII) && !defined(CONFIG_BITBANGMII) */
595 #endif /* CFG_CMD_NET, FEC_ENET */
597 int mcf52x2_miiphy_initialize(bd_t
*bis
)
599 #if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(FEC_ENET)
600 #if (CONFIG_COMMANDS & CFG_CMD_MII) && !defined(CONFIG_BITBANGMII)
601 miiphy_register("mcf52x2phy", mcf52x2_miiphy_read
, mcf52x2_miiphy_write
);