]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/net/mpc5xxx_fec.c
Merge branch 'master' of git://git.denx.de/u-boot-mips
[karo-tx-uboot.git] / drivers / net / mpc5xxx_fec.c
1 /*
2  * (C) Copyright 2003-2005
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * This file is based on mpc4200fec.c,
6  * (C) Copyright Motorola, Inc., 2000
7  */
8
9 #include <common.h>
10 #include <mpc5xxx.h>
11 #include <mpc5xxx_sdma.h>
12 #include <malloc.h>
13 #include <net.h>
14 #include <netdev.h>
15 #include <miiphy.h>
16 #include "mpc5xxx_fec.h"
17
18 DECLARE_GLOBAL_DATA_PTR;
19
20 /* #define DEBUG        0x28 */
21
22 #if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
23         defined(CONFIG_MPC5xxx_FEC)
24
25 #if !(defined(CONFIG_MII) || defined(CONFIG_CMD_MII))
26 #error "CONFIG_MII has to be defined!"
27 #endif
28
29 #if (DEBUG & 0x60)
30 static void tfifo_print(char *devname, mpc5xxx_fec_priv *fec);
31 static void rfifo_print(char *devname, mpc5xxx_fec_priv *fec);
32 #endif /* DEBUG */
33
34 #if (DEBUG & 0x40)
35 static uint32 local_crc32(char *string, unsigned int crc_value, int len);
36 #endif
37
38 typedef struct {
39     uint8 data[1500];           /* actual data */
40     int length;                 /* actual length */
41     int used;                   /* buffer in use or not */
42     uint8 head[16];             /* MAC header(6 + 6 + 2) + 2(aligned) */
43 } NBUF;
44
45 int fec5xxx_miiphy_read(char *devname, uint8 phyAddr, uint8 regAddr, uint16 * retVal);
46 int fec5xxx_miiphy_write(char *devname, uint8 phyAddr, uint8 regAddr, uint16 data);
47
48 /********************************************************************/
49 #if (DEBUG & 0x2)
50 static void mpc5xxx_fec_phydump (char *devname)
51 {
52         uint16 phyStatus, i;
53         uint8 phyAddr = CONFIG_PHY_ADDR;
54         uint8 reg_mask[] = {
55 #if CONFIG_PHY_TYPE == 0x79c874 /* AMD Am79C874 */
56                 /* regs to print: 0...7, 16...19, 21, 23, 24 */
57                 1, 1, 1, 1,  1, 1, 1, 1,     0, 0, 0, 0,  0, 0, 0, 0,
58                 1, 1, 1, 1,  0, 1, 0, 1,     1, 0, 0, 0,  0, 0, 0, 0,
59 #else
60                 /* regs to print: 0...8, 16...20 */
61                 1, 1, 1, 1,  1, 1, 1, 1,     1, 0, 0, 0,  0, 0, 0, 0,
62                 1, 1, 1, 1,  1, 0, 0, 0,     0, 0, 0, 0,  0, 0, 0, 0,
63 #endif
64         };
65
66         for (i = 0; i < 32; i++) {
67                 if (reg_mask[i]) {
68                         miiphy_read(devname, phyAddr, i, &phyStatus);
69                         printf("Mii reg %d: 0x%04x\n", i, phyStatus);
70                 }
71         }
72 }
73 #endif
74
75 /********************************************************************/
76 static int mpc5xxx_fec_rbd_init(mpc5xxx_fec_priv *fec)
77 {
78         int ix;
79         char *data;
80         static int once = 0;
81
82         for (ix = 0; ix < FEC_RBD_NUM; ix++) {
83                 if (!once) {
84                         data = (char *)malloc(FEC_MAX_PKT_SIZE);
85                         if (data == NULL) {
86                                 printf ("RBD INIT FAILED\n");
87                                 return -1;
88                         }
89                         fec->rbdBase[ix].dataPointer = (uint32)data;
90                 }
91                 fec->rbdBase[ix].status = FEC_RBD_EMPTY;
92                 fec->rbdBase[ix].dataLength = 0;
93         }
94         once ++;
95
96         /*
97          * have the last RBD to close the ring
98          */
99         fec->rbdBase[ix - 1].status |= FEC_RBD_WRAP;
100         fec->rbdIndex = 0;
101
102         return 0;
103 }
104
105 /********************************************************************/
106 static void mpc5xxx_fec_tbd_init(mpc5xxx_fec_priv *fec)
107 {
108         int ix;
109
110         for (ix = 0; ix < FEC_TBD_NUM; ix++) {
111                 fec->tbdBase[ix].status = 0;
112         }
113
114         /*
115          * Have the last TBD to close the ring
116          */
117         fec->tbdBase[ix - 1].status |= FEC_TBD_WRAP;
118
119         /*
120          * Initialize some indices
121          */
122         fec->tbdIndex = 0;
123         fec->usedTbdIndex = 0;
124         fec->cleanTbdNum = FEC_TBD_NUM;
125 }
126
127 /********************************************************************/
128 static void mpc5xxx_fec_rbd_clean(mpc5xxx_fec_priv *fec, volatile FEC_RBD * pRbd)
129 {
130         /*
131          * Reset buffer descriptor as empty
132          */
133         if ((fec->rbdIndex) == (FEC_RBD_NUM - 1))
134                 pRbd->status = (FEC_RBD_WRAP | FEC_RBD_EMPTY);
135         else
136                 pRbd->status = FEC_RBD_EMPTY;
137
138         pRbd->dataLength = 0;
139
140         /*
141          * Now, we have an empty RxBD, restart the SmartDMA receive task
142          */
143         SDMA_TASK_ENABLE(FEC_RECV_TASK_NO);
144
145         /*
146          * Increment BD count
147          */
148         fec->rbdIndex = (fec->rbdIndex + 1) % FEC_RBD_NUM;
149 }
150
151 /********************************************************************/
152 static void mpc5xxx_fec_tbd_scrub(mpc5xxx_fec_priv *fec)
153 {
154         volatile FEC_TBD *pUsedTbd;
155
156 #if (DEBUG & 0x1)
157         printf ("tbd_scrub: fec->cleanTbdNum = %d, fec->usedTbdIndex = %d\n",
158                 fec->cleanTbdNum, fec->usedTbdIndex);
159 #endif
160
161         /*
162          * process all the consumed TBDs
163          */
164         while (fec->cleanTbdNum < FEC_TBD_NUM) {
165                 pUsedTbd = &fec->tbdBase[fec->usedTbdIndex];
166                 if (pUsedTbd->status & FEC_TBD_READY) {
167 #if (DEBUG & 0x20)
168                         printf("Cannot clean TBD %d, in use\n", fec->cleanTbdNum);
169 #endif
170                         return;
171                 }
172
173                 /*
174                  * clean this buffer descriptor
175                  */
176                 if (fec->usedTbdIndex == (FEC_TBD_NUM - 1))
177                         pUsedTbd->status = FEC_TBD_WRAP;
178                 else
179                         pUsedTbd->status = 0;
180
181                 /*
182                  * update some indeces for a correct handling of the TBD ring
183                  */
184                 fec->cleanTbdNum++;
185                 fec->usedTbdIndex = (fec->usedTbdIndex + 1) % FEC_TBD_NUM;
186         }
187 }
188
189 /********************************************************************/
190 static void mpc5xxx_fec_set_hwaddr(mpc5xxx_fec_priv *fec, char *mac)
191 {
192         uint8 currByte;                 /* byte for which to compute the CRC */
193         int byte;                       /* loop - counter */
194         int bit;                        /* loop - counter */
195         uint32 crc = 0xffffffff;        /* initial value */
196
197         /*
198          * The algorithm used is the following:
199          * we loop on each of the six bytes of the provided address,
200          * and we compute the CRC by left-shifting the previous
201          * value by one position, so that each bit in the current
202          * byte of the address may contribute the calculation. If
203          * the latter and the MSB in the CRC are different, then
204          * the CRC value so computed is also ex-ored with the
205          * "polynomium generator". The current byte of the address
206          * is also shifted right by one bit at each iteration.
207          * This is because the CRC generatore in hardware is implemented
208          * as a shift-register with as many ex-ores as the radixes
209          * in the polynomium. This suggests that we represent the
210          * polynomiumm itself as a 32-bit constant.
211          */
212         for (byte = 0; byte < 6; byte++) {
213                 currByte = mac[byte];
214                 for (bit = 0; bit < 8; bit++) {
215                         if ((currByte & 0x01) ^ (crc & 0x01)) {
216                                 crc >>= 1;
217                                 crc = crc ^ 0xedb88320;
218                         } else {
219                                 crc >>= 1;
220                         }
221                         currByte >>= 1;
222                 }
223         }
224
225         crc = crc >> 26;
226
227         /*
228          * Set individual hash table register
229          */
230         if (crc >= 32) {
231                 fec->eth->iaddr1 = (1 << (crc - 32));
232                 fec->eth->iaddr2 = 0;
233         } else {
234                 fec->eth->iaddr1 = 0;
235                 fec->eth->iaddr2 = (1 << crc);
236         }
237
238         /*
239          * Set physical address
240          */
241         fec->eth->paddr1 = (mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3];
242         fec->eth->paddr2 = (mac[4] << 24) + (mac[5] << 16) + 0x8808;
243 }
244
245 /********************************************************************/
246 static int mpc5xxx_fec_init(struct eth_device *dev, bd_t * bis)
247 {
248         mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
249         struct mpc5xxx_sdma *sdma = (struct mpc5xxx_sdma *)MPC5XXX_SDMA;
250
251 #if (DEBUG & 0x1)
252         printf ("mpc5xxx_fec_init... Begin\n");
253 #endif
254
255         /*
256          * Initialize RxBD/TxBD rings
257          */
258         mpc5xxx_fec_rbd_init(fec);
259         mpc5xxx_fec_tbd_init(fec);
260
261         /*
262          * Clear FEC-Lite interrupt event register(IEVENT)
263          */
264         fec->eth->ievent = 0xffffffff;
265
266         /*
267          * Set interrupt mask register
268          */
269         fec->eth->imask = 0x00000000;
270
271         /*
272          * Set FEC-Lite receive control register(R_CNTRL):
273          */
274         if (fec->xcv_type == SEVENWIRE) {
275                 /*
276                  * Frame length=1518; 7-wire mode
277                  */
278                 fec->eth->r_cntrl = 0x05ee0020; /*0x05ee0000;FIXME */
279         } else {
280                 /*
281                  * Frame length=1518; MII mode;
282                  */
283                 fec->eth->r_cntrl = 0x05ee0024; /*0x05ee0004;FIXME */
284         }
285
286         fec->eth->x_cntrl = 0x00000000; /* half-duplex, heartbeat disabled */
287         if (fec->xcv_type != SEVENWIRE) {
288                 /*
289                  * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
290                  * and do not drop the Preamble.
291                  */
292                 fec->eth->mii_speed = (((gd->ipb_clk >> 20) / 5) << 1); /* No MII for 7-wire mode */
293         }
294
295         /*
296          * Set Opcode/Pause Duration Register
297          */
298         fec->eth->op_pause = 0x00010020;        /*FIXME 0xffff0020; */
299
300         /*
301          * Set Rx FIFO alarm and granularity value
302          */
303         fec->eth->rfifo_cntrl = 0x0c000000
304                                 | (fec->eth->rfifo_cntrl & ~0x0f000000);
305         fec->eth->rfifo_alarm = 0x0000030c;
306 #if (DEBUG & 0x22)
307         if (fec->eth->rfifo_status & 0x00700000 ) {
308                 printf("mpc5xxx_fec_init() RFIFO error\n");
309         }
310 #endif
311
312         /*
313          * Set Tx FIFO granularity value
314          */
315         fec->eth->tfifo_cntrl = 0x0c000000
316                                 | (fec->eth->tfifo_cntrl & ~0x0f000000);
317 #if (DEBUG & 0x2)
318         printf("tfifo_status: 0x%08x\n", fec->eth->tfifo_status);
319         printf("tfifo_alarm: 0x%08x\n", fec->eth->tfifo_alarm);
320 #endif
321
322         /*
323          * Set transmit fifo watermark register(X_WMRK), default = 64
324          */
325         fec->eth->tfifo_alarm = 0x00000080;
326         fec->eth->x_wmrk = 0x2;
327
328         /*
329          * Set individual address filter for unicast address
330          * and set physical address registers.
331          */
332         mpc5xxx_fec_set_hwaddr(fec, (char *)dev->enetaddr);
333
334         /*
335          * Set multicast address filter
336          */
337         fec->eth->gaddr1 = 0x00000000;
338         fec->eth->gaddr2 = 0x00000000;
339
340         /*
341          * Turn ON cheater FSM: ????
342          */
343         fec->eth->xmit_fsm = 0x03000000;
344
345 #if defined(CONFIG_MPC5200)
346         /*
347          * Turn off COMM bus prefetch in the MGT5200 BestComm. It doesn't
348          * work w/ the current receive task.
349          */
350          sdma->PtdCntrl |= 0x00000001;
351 #endif
352
353         /*
354          * Set priority of different initiators
355          */
356         sdma->IPR0 = 7;         /* always */
357         sdma->IPR3 = 6;         /* Eth RX */
358         sdma->IPR4 = 5;         /* Eth Tx */
359
360         /*
361          * Clear SmartDMA task interrupt pending bits
362          */
363         SDMA_CLEAR_IEVENT(FEC_RECV_TASK_NO);
364
365         /*
366          * Initialize SmartDMA parameters stored in SRAM
367          */
368         *(volatile int *)FEC_TBD_BASE = (int)fec->tbdBase;
369         *(volatile int *)FEC_RBD_BASE = (int)fec->rbdBase;
370         *(volatile int *)FEC_TBD_NEXT = (int)fec->tbdBase;
371         *(volatile int *)FEC_RBD_NEXT = (int)fec->rbdBase;
372
373         /*
374          * Enable FEC-Lite controller
375          */
376         fec->eth->ecntrl |= 0x00000006;
377
378 #if (DEBUG & 0x2)
379         if (fec->xcv_type != SEVENWIRE)
380                 mpc5xxx_fec_phydump (dev->name);
381 #endif
382
383         /*
384          * Enable SmartDMA receive task
385          */
386         SDMA_TASK_ENABLE(FEC_RECV_TASK_NO);
387
388 #if (DEBUG & 0x1)
389         printf("mpc5xxx_fec_init... Done \n");
390 #endif
391
392         return 1;
393 }
394
395 /********************************************************************/
396 static int mpc5xxx_fec_init_phy(struct eth_device *dev, bd_t * bis)
397 {
398         mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
399         const uint8 phyAddr = CONFIG_PHY_ADDR;  /* Only one PHY */
400
401 #if (DEBUG & 0x1)
402         printf ("mpc5xxx_fec_init_phy... Begin\n");
403 #endif
404
405         /*
406          * Initialize GPIO pins
407          */
408         if (fec->xcv_type == SEVENWIRE) {
409                 /*  10MBit with 7-wire operation */
410 #if defined(CONFIG_TOTAL5200)
411                 /* 7-wire and USB2 on Ethernet */
412                 *(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= 0x00030000;
413 #else   /* !CONFIG_TOTAL5200 */
414                 /* 7-wire only */
415                 *(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= 0x00020000;
416 #endif  /* CONFIG_TOTAL5200 */
417         } else {
418                 /* 100MBit with MD operation */
419                 *(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= 0x00050000;
420         }
421
422         /*
423          * Clear FEC-Lite interrupt event register(IEVENT)
424          */
425         fec->eth->ievent = 0xffffffff;
426
427         /*
428          * Set interrupt mask register
429          */
430         fec->eth->imask = 0x00000000;
431
432 /*
433  * In original Promess-provided code PHY initialization is disabled with the
434  * following comment: "Phy initialization is DISABLED for now.  There was a
435  * problem with running 100 Mbps on PRO board". Thus we temporarily disable
436  * PHY initialization for the Motion-PRO board, until a proper fix is found.
437  */
438
439         if (fec->xcv_type != SEVENWIRE) {
440                 /*
441                  * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
442                  * and do not drop the Preamble.
443                  */
444                 fec->eth->mii_speed = (((gd->ipb_clk >> 20) / 5) << 1); /* No MII for 7-wire mode */
445         }
446
447         if (fec->xcv_type != SEVENWIRE) {
448                 /*
449                  * Initialize PHY(LXT971A):
450                  *
451                  *   Generally, on power up, the LXT971A reads its configuration
452                  *   pins to check for forced operation, If not cofigured for
453                  *   forced operation, it uses auto-negotiation/parallel detection
454                  *   to automatically determine line operating conditions.
455                  *   If the PHY device on the other side of the link supports
456                  *   auto-negotiation, the LXT971A auto-negotiates with it
457                  *   using Fast Link Pulse(FLP) Bursts. If the PHY partner does not
458                  *   support auto-negotiation, the LXT971A automatically detects
459                  *   the presence of either link pulses(10Mbps PHY) or Idle
460                  *   symbols(100Mbps) and sets its operating conditions accordingly.
461                  *
462                  *   When auto-negotiation is controlled by software, the following
463                  *   steps are recommended.
464                  *
465                  * Note:
466                  *   The physical address is dependent on hardware configuration.
467                  *
468                  */
469                 int timeout = 1;
470                 uint16 phyStatus;
471
472                 /*
473                  * Reset PHY, then delay 300ns
474                  */
475                 miiphy_write(dev->name, phyAddr, 0x0, 0x8000);
476                 udelay(1000);
477
478 #if defined(CONFIG_UC101) || defined(CONFIG_MUCMC52)
479                 /* Set the LED configuration Register for the UC101
480                    and MUCMC52 Board */
481                 miiphy_write(dev->name, phyAddr, 0x14, 0x4122);
482 #endif
483                 if (fec->xcv_type == MII10) {
484                         /*
485                          * Force 10Base-T, FDX operation
486                          */
487 #if (DEBUG & 0x2)
488                         printf("Forcing 10 Mbps ethernet link... ");
489 #endif
490                         miiphy_read(dev->name, phyAddr, 0x1, &phyStatus);
491                         /*
492                         miiphy_write(dev->name, fec, phyAddr, 0x0, 0x0100);
493                         */
494                         miiphy_write(dev->name, phyAddr, 0x0, 0x0180);
495
496                         timeout = 20;
497                         do {    /* wait for link status to go down */
498                                 udelay(10000);
499                                 if ((timeout--) == 0) {
500 #if (DEBUG & 0x2)
501                                         printf("hmmm, should not have waited...");
502 #endif
503                                         break;
504                                 }
505                                 miiphy_read(dev->name, phyAddr, 0x1, &phyStatus);
506 #if (DEBUG & 0x2)
507                                 printf("=");
508 #endif
509                         } while ((phyStatus & 0x0004)); /* !link up */
510
511                         timeout = 1000;
512                         do {    /* wait for link status to come back up */
513                                 udelay(10000);
514                                 if ((timeout--) == 0) {
515                                         printf("failed. Link is down.\n");
516                                         break;
517                                 }
518                                 miiphy_read(dev->name, phyAddr, 0x1, &phyStatus);
519 #if (DEBUG & 0x2)
520                                 printf("+");
521 #endif
522                         } while (!(phyStatus & 0x0004));        /* !link up */
523
524 #if (DEBUG & 0x2)
525                         printf ("done.\n");
526 #endif
527                 } else {        /* MII100 */
528                         /*
529                          * Set the auto-negotiation advertisement register bits
530                          */
531                         miiphy_write(dev->name, phyAddr, 0x4, 0x01e1);
532
533                         /*
534                          * Set MDIO bit 0.12 = 1(&& bit 0.9=1?) to enable auto-negotiation
535                          */
536                         miiphy_write(dev->name, phyAddr, 0x0, 0x1200);
537
538                         /*
539                          * Wait for AN completion
540                          */
541                         timeout = 5000;
542                         do {
543                                 udelay(1000);
544
545                                 if ((timeout--) == 0) {
546 #if (DEBUG & 0x2)
547                                         printf("PHY auto neg 0 failed...\n");
548 #endif
549                                         return -1;
550                                 }
551
552                                 if (miiphy_read(dev->name, phyAddr, 0x1, &phyStatus) != 0) {
553 #if (DEBUG & 0x2)
554                                         printf("PHY auto neg 1 failed 0x%04x...\n", phyStatus);
555 #endif
556                                         return -1;
557                                 }
558                         } while (!(phyStatus & 0x0004));
559
560 #if (DEBUG & 0x2)
561                         printf("PHY auto neg complete! \n");
562 #endif
563                 }
564
565         }
566
567 #if (DEBUG & 0x2)
568         if (fec->xcv_type != SEVENWIRE)
569                 mpc5xxx_fec_phydump (dev->name);
570 #endif
571
572
573 #if (DEBUG & 0x1)
574         printf("mpc5xxx_fec_init_phy... Done \n");
575 #endif
576
577         return 1;
578 }
579
580 /********************************************************************/
581 static void mpc5xxx_fec_halt(struct eth_device *dev)
582 {
583 #if defined(CONFIG_MPC5200)
584         struct mpc5xxx_sdma *sdma = (struct mpc5xxx_sdma *)MPC5XXX_SDMA;
585 #endif
586         mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
587         int counter = 0xffff;
588
589 #if (DEBUG & 0x2)
590         if (fec->xcv_type != SEVENWIRE)
591                 mpc5xxx_fec_phydump (dev->name);
592 #endif
593
594         /*
595          * mask FEC chip interrupts
596          */
597         fec->eth->imask = 0;
598
599         /*
600          * issue graceful stop command to the FEC transmitter if necessary
601          */
602         fec->eth->x_cntrl |= 0x00000001;
603
604         /*
605          * wait for graceful stop to register
606          */
607         while ((counter--) && (!(fec->eth->ievent & 0x10000000))) ;
608
609         /*
610          * Disable SmartDMA tasks
611          */
612         SDMA_TASK_DISABLE (FEC_XMIT_TASK_NO);
613         SDMA_TASK_DISABLE (FEC_RECV_TASK_NO);
614
615 #if defined(CONFIG_MPC5200)
616         /*
617          * Turn on COMM bus prefetch in the MGT5200 BestComm after we're
618          * done. It doesn't work w/ the current receive task.
619          */
620          sdma->PtdCntrl &= ~0x00000001;
621 #endif
622
623         /*
624          * Disable the Ethernet Controller
625          */
626         fec->eth->ecntrl &= 0xfffffffd;
627
628         /*
629          * Clear FIFO status registers
630          */
631         fec->eth->rfifo_status &= 0x00700000;
632         fec->eth->tfifo_status &= 0x00700000;
633
634         fec->eth->reset_cntrl = 0x01000000;
635
636         /*
637          * Issue a reset command to the FEC chip
638          */
639         fec->eth->ecntrl |= 0x1;
640
641         /*
642          * wait at least 16 clock cycles
643          */
644         udelay(10);
645
646 #if (DEBUG & 0x3)
647         printf("Ethernet task stopped\n");
648 #endif
649 }
650
651 #if (DEBUG & 0x60)
652 /********************************************************************/
653
654 static void tfifo_print(char *devname, mpc5xxx_fec_priv *fec)
655 {
656         uint16 phyAddr = CONFIG_PHY_ADDR;
657         uint16 phyStatus;
658
659         if ((fec->eth->tfifo_lrf_ptr != fec->eth->tfifo_lwf_ptr)
660                 || (fec->eth->tfifo_rdptr != fec->eth->tfifo_wrptr)) {
661
662                 miiphy_read(devname, phyAddr, 0x1, &phyStatus);
663                 printf("\nphyStatus: 0x%04x\n", phyStatus);
664                 printf("ecntrl:   0x%08x\n", fec->eth->ecntrl);
665                 printf("ievent:   0x%08x\n", fec->eth->ievent);
666                 printf("x_status: 0x%08x\n", fec->eth->x_status);
667                 printf("tfifo: status  0x%08x\n", fec->eth->tfifo_status);
668
669                 printf("       control 0x%08x\n", fec->eth->tfifo_cntrl);
670                 printf("       lrfp    0x%08x\n", fec->eth->tfifo_lrf_ptr);
671                 printf("       lwfp    0x%08x\n", fec->eth->tfifo_lwf_ptr);
672                 printf("       alarm   0x%08x\n", fec->eth->tfifo_alarm);
673                 printf("       readptr 0x%08x\n", fec->eth->tfifo_rdptr);
674                 printf("       writptr 0x%08x\n", fec->eth->tfifo_wrptr);
675         }
676 }
677
678 static void rfifo_print(char *devname, mpc5xxx_fec_priv *fec)
679 {
680         uint16 phyAddr = CONFIG_PHY_ADDR;
681         uint16 phyStatus;
682
683         if ((fec->eth->rfifo_lrf_ptr != fec->eth->rfifo_lwf_ptr)
684                 || (fec->eth->rfifo_rdptr != fec->eth->rfifo_wrptr)) {
685
686                 miiphy_read(devname, phyAddr, 0x1, &phyStatus);
687                 printf("\nphyStatus: 0x%04x\n", phyStatus);
688                 printf("ecntrl:   0x%08x\n", fec->eth->ecntrl);
689                 printf("ievent:   0x%08x\n", fec->eth->ievent);
690                 printf("x_status: 0x%08x\n", fec->eth->x_status);
691                 printf("rfifo: status  0x%08x\n", fec->eth->rfifo_status);
692
693                 printf("       control 0x%08x\n", fec->eth->rfifo_cntrl);
694                 printf("       lrfp    0x%08x\n", fec->eth->rfifo_lrf_ptr);
695                 printf("       lwfp    0x%08x\n", fec->eth->rfifo_lwf_ptr);
696                 printf("       alarm   0x%08x\n", fec->eth->rfifo_alarm);
697                 printf("       readptr 0x%08x\n", fec->eth->rfifo_rdptr);
698                 printf("       writptr 0x%08x\n", fec->eth->rfifo_wrptr);
699         }
700 }
701 #endif /* DEBUG */
702
703 /********************************************************************/
704
705 static int mpc5xxx_fec_send(struct eth_device *dev, volatile void *eth_data,
706                 int data_length)
707 {
708         /*
709          * This routine transmits one frame.  This routine only accepts
710          * 6-byte Ethernet addresses.
711          */
712         mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
713         volatile FEC_TBD *pTbd;
714
715 #if (DEBUG & 0x20)
716         printf("tbd status: 0x%04x\n", fec->tbdBase[0].status);
717         tfifo_print(dev->name, fec);
718 #endif
719
720         /*
721          * Clear Tx BD ring at first
722          */
723         mpc5xxx_fec_tbd_scrub(fec);
724
725         /*
726          * Check for valid length of data.
727          */
728         if ((data_length > 1500) || (data_length <= 0)) {
729                 return -1;
730         }
731
732         /*
733          * Check the number of vacant TxBDs.
734          */
735         if (fec->cleanTbdNum < 1) {
736 #if (DEBUG & 0x20)
737                 printf("No available TxBDs ...\n");
738 #endif
739                 return -1;
740         }
741
742         /*
743          * Get the first TxBD to send the mac header
744          */
745         pTbd = &fec->tbdBase[fec->tbdIndex];
746         pTbd->dataLength = data_length;
747         pTbd->dataPointer = (uint32)eth_data;
748         pTbd->status |= FEC_TBD_LAST | FEC_TBD_TC | FEC_TBD_READY;
749         fec->tbdIndex = (fec->tbdIndex + 1) % FEC_TBD_NUM;
750
751 #if (DEBUG & 0x100)
752         printf("SDMA_TASK_ENABLE, fec->tbdIndex = %d \n", fec->tbdIndex);
753 #endif
754
755         /*
756          * Kick the MII i/f
757          */
758         if (fec->xcv_type != SEVENWIRE) {
759                 uint16 phyStatus;
760                 miiphy_read(dev->name, 0, 0x1, &phyStatus);
761         }
762
763         /*
764          * Enable SmartDMA transmit task
765          */
766
767 #if (DEBUG & 0x20)
768         tfifo_print(dev->name, fec);
769 #endif
770         SDMA_TASK_ENABLE (FEC_XMIT_TASK_NO);
771 #if (DEBUG & 0x20)
772         tfifo_print(dev->name, fec);
773 #endif
774 #if (DEBUG & 0x8)
775         printf( "+" );
776 #endif
777
778         fec->cleanTbdNum -= 1;
779
780 #if (DEBUG & 0x129) && (DEBUG & 0x80000000)
781         printf ("smartDMA ethernet Tx task enabled\n");
782 #endif
783         /*
784          * wait until frame is sent .
785          */
786         while (pTbd->status & FEC_TBD_READY) {
787                 udelay(10);
788 #if (DEBUG & 0x8)
789                 printf ("TDB status = %04x\n", pTbd->status);
790 #endif
791         }
792
793         return 0;
794 }
795
796
797 /********************************************************************/
798 static int mpc5xxx_fec_recv(struct eth_device *dev)
799 {
800         /*
801          * This command pulls one frame from the card
802          */
803         mpc5xxx_fec_priv *fec = (mpc5xxx_fec_priv *)dev->priv;
804         volatile FEC_RBD *pRbd = &fec->rbdBase[fec->rbdIndex];
805         unsigned long ievent;
806         int frame_length, len = 0;
807         NBUF *frame;
808         uchar buff[FEC_MAX_PKT_SIZE];
809
810 #if (DEBUG & 0x1)
811         printf ("mpc5xxx_fec_recv %d Start...\n", fec->rbdIndex);
812 #endif
813 #if (DEBUG & 0x8)
814         printf( "-" );
815 #endif
816
817         /*
818          * Check if any critical events have happened
819          */
820         ievent = fec->eth->ievent;
821         fec->eth->ievent = ievent;
822         if (ievent & 0x20060000) {
823                 /* BABT, Rx/Tx FIFO errors */
824                 mpc5xxx_fec_halt(dev);
825                 mpc5xxx_fec_init(dev, NULL);
826                 return 0;
827         }
828         if (ievent & 0x80000000) {
829                 /* Heartbeat error */
830                 fec->eth->x_cntrl |= 0x00000001;
831         }
832         if (ievent & 0x10000000) {
833                 /* Graceful stop complete */
834                 if (fec->eth->x_cntrl & 0x00000001) {
835                         mpc5xxx_fec_halt(dev);
836                         fec->eth->x_cntrl &= ~0x00000001;
837                         mpc5xxx_fec_init(dev, NULL);
838                 }
839         }
840
841         if (!(pRbd->status & FEC_RBD_EMPTY)) {
842                 if ((pRbd->status & FEC_RBD_LAST) && !(pRbd->status & FEC_RBD_ERR) &&
843                         ((pRbd->dataLength - 4) > 14)) {
844
845                         /*
846                          * Get buffer address and size
847                          */
848                         frame = (NBUF *)pRbd->dataPointer;
849                         frame_length = pRbd->dataLength - 4;
850
851 #if (DEBUG & 0x20)
852                         {
853                                 int i;
854                                 printf("recv data hdr:");
855                                 for (i = 0; i < 14; i++)
856                                         printf("%x ", *(frame->head + i));
857                                 printf("\n");
858                         }
859 #endif
860                         /*
861                          *  Fill the buffer and pass it to upper layers
862                          */
863                         memcpy(buff, frame->head, 14);
864                         memcpy(buff + 14, frame->data, frame_length);
865                         NetReceive(buff, frame_length);
866                         len = frame_length;
867                 }
868                 /*
869                  * Reset buffer descriptor as empty
870                  */
871                 mpc5xxx_fec_rbd_clean(fec, pRbd);
872         }
873         SDMA_CLEAR_IEVENT (FEC_RECV_TASK_NO);
874         return len;
875 }
876
877
878 /********************************************************************/
879 int mpc5xxx_fec_initialize(bd_t * bis)
880 {
881         mpc5xxx_fec_priv *fec;
882         struct eth_device *dev;
883         char *tmp, *end;
884         char env_enetaddr[6];
885         int i;
886
887         fec = (mpc5xxx_fec_priv *)malloc(sizeof(*fec));
888         dev = (struct eth_device *)malloc(sizeof(*dev));
889         memset(dev, 0, sizeof *dev);
890
891         fec->eth = (ethernet_regs *)MPC5XXX_FEC;
892         fec->tbdBase = (FEC_TBD *)FEC_BD_BASE;
893         fec->rbdBase = (FEC_RBD *)(FEC_BD_BASE + FEC_TBD_NUM * sizeof(FEC_TBD));
894 #if defined(CONFIG_CANMB)               || \
895         defined(CONFIG_CM5200)          || \
896         defined(CONFIG_HMI1001)         || \
897         defined(CONFIG_ICECUBE)         || \
898         defined(CONFIG_INKA4X0)         || \
899         defined(CONFIG_JUPITER)         || \
900         defined(CONFIG_MCC200)          || \
901         defined(CONFIG_MOTIONPRO)       || \
902         defined(CONFIG_MUCMC52)         || \
903         defined(CONFIG_O2DNT)           || \
904         defined(CONFIG_PM520)           || \
905         defined(CONFIG_TOP5200)         || \
906         defined(CONFIG_TQM5200)         || \
907         defined(CONFIG_UC101)           || \
908         defined(CONFIG_V38B)            || \
909         defined(CONFIG_MUNICES)
910 # ifndef CONFIG_FEC_10MBIT
911         fec->xcv_type = MII100;
912 # else
913         fec->xcv_type = MII10;
914 # endif
915 #elif defined(CONFIG_TOTAL5200)
916         fec->xcv_type = SEVENWIRE;
917 #else
918 #error fec->xcv_type not initialized.
919 #endif
920
921         dev->priv = (void *)fec;
922         dev->iobase = MPC5XXX_FEC;
923         dev->init = mpc5xxx_fec_init;
924         dev->halt = mpc5xxx_fec_halt;
925         dev->send = mpc5xxx_fec_send;
926         dev->recv = mpc5xxx_fec_recv;
927
928         sprintf(dev->name, "FEC ETHERNET");
929         eth_register(dev);
930
931 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
932         miiphy_register (dev->name,
933                         fec5xxx_miiphy_read, fec5xxx_miiphy_write);
934 #endif
935
936         /*
937          * Try to set the mac address now. The fec mac address is
938          * a garbage after reset. When not using fec for booting
939          * the Linux fec driver will try to work with this garbage.
940          */
941         tmp = getenv("ethaddr");
942         if (tmp) {
943                 for (i=0; i<6; i++) {
944                         env_enetaddr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0;
945                         if (tmp)
946                                 tmp = (*end) ? end+1 : end;
947                 }
948                 mpc5xxx_fec_set_hwaddr(fec, env_enetaddr);
949         }
950
951         mpc5xxx_fec_init_phy(dev, bis);
952
953         return 1;
954 }
955
956 /* MII-interface related functions */
957 /********************************************************************/
958 int fec5xxx_miiphy_read(char *devname, uint8 phyAddr, uint8 regAddr, uint16 * retVal)
959 {
960         ethernet_regs *eth = (ethernet_regs *)MPC5XXX_FEC;
961         uint32 reg;             /* convenient holder for the PHY register */
962         uint32 phy;             /* convenient holder for the PHY */
963         int timeout = 0xffff;
964
965         /*
966          * reading from any PHY's register is done by properly
967          * programming the FEC's MII data register.
968          */
969         reg = regAddr << FEC_MII_DATA_RA_SHIFT;
970         phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
971
972         eth->mii_data = (FEC_MII_DATA_ST | FEC_MII_DATA_OP_RD | FEC_MII_DATA_TA | phy | reg);
973
974         /*
975          * wait for the related interrupt
976          */
977         while ((timeout--) && (!(eth->ievent & 0x00800000))) ;
978
979         if (timeout == 0) {
980 #if (DEBUG & 0x2)
981                 printf ("Read MDIO failed...\n");
982 #endif
983                 return -1;
984         }
985
986         /*
987          * clear mii interrupt bit
988          */
989         eth->ievent = 0x00800000;
990
991         /*
992          * it's now safe to read the PHY's register
993          */
994         *retVal = (uint16) eth->mii_data;
995
996         return 0;
997 }
998
999 /********************************************************************/
1000 int fec5xxx_miiphy_write(char *devname, uint8 phyAddr, uint8 regAddr, uint16 data)
1001 {
1002         ethernet_regs *eth = (ethernet_regs *)MPC5XXX_FEC;
1003         uint32 reg;             /* convenient holder for the PHY register */
1004         uint32 phy;             /* convenient holder for the PHY */
1005         int timeout = 0xffff;
1006
1007         reg = regAddr << FEC_MII_DATA_RA_SHIFT;
1008         phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
1009
1010         eth->mii_data = (FEC_MII_DATA_ST | FEC_MII_DATA_OP_WR |
1011                         FEC_MII_DATA_TA | phy | reg | data);
1012
1013         /*
1014          * wait for the MII interrupt
1015          */
1016         while ((timeout--) && (!(eth->ievent & 0x00800000))) ;
1017
1018         if (timeout == 0) {
1019 #if (DEBUG & 0x2)
1020                 printf ("Write MDIO failed...\n");
1021 #endif
1022                 return -1;
1023         }
1024
1025         /*
1026          * clear MII interrupt bit
1027          */
1028         eth->ievent = 0x00800000;
1029
1030         return 0;
1031 }
1032
1033 #if (DEBUG & 0x40)
1034 static uint32 local_crc32(char *string, unsigned int crc_value, int len)
1035 {
1036         int i;
1037         char c;
1038         unsigned int crc, count;
1039
1040         /*
1041          * crc32 algorithm
1042          */
1043         /*
1044          * crc = 0xffffffff; * The initialized value should be 0xffffffff
1045          */
1046         crc = crc_value;
1047
1048         for (i = len; --i >= 0;) {
1049                 c = *string++;
1050                 for (count = 0; count < 8; count++) {
1051                         if ((c & 0x01) ^ (crc & 0x01)) {
1052                                 crc >>= 1;
1053                                 crc = crc ^ 0xedb88320;
1054                         } else {
1055                                 crc >>= 1;
1056                         }
1057                         c >>= 1;
1058                 }
1059         }
1060
1061         /*
1062          * In big endian system, do byte swaping for crc value
1063          */
1064          /**/ return crc;
1065 }
1066 #endif  /* DEBUG */
1067
1068 #endif /* CONFIG_MPC5xxx_FEC */