]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/powerpc/cpu/mpc8xx/fec.c
454e77af992cf9e5083e3e5f773a82419346e3aa
[karo-tx-uboot.git] / arch / powerpc / cpu / mpc8xx / fec.c
1 /*
2  * (C) Copyright 2000
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <common.h>
9 #include <malloc.h>
10 #include <commproc.h>
11 #include <net.h>
12 #include <command.h>
13
14 DECLARE_GLOBAL_DATA_PTR;
15
16 #undef  ET_DEBUG
17
18 #if defined(CONFIG_CMD_NET) && \
19         (defined(FEC_ENET) || defined(CONFIG_ETHER_ON_FEC1) || defined(CONFIG_ETHER_ON_FEC2))
20
21 /* compatibility test, if only FEC_ENET defined assume ETHER on FEC1 */
22 #if defined(FEC_ENET) && !defined(CONFIG_ETHER_ON_FEC1) && !defined(CONFIG_ETHER_ON_FEC2)
23 #define CONFIG_ETHER_ON_FEC1 1
24 #endif
25
26 /* define WANT_MII when MII support is required */
27 #if defined(CONFIG_SYS_DISCOVER_PHY) || defined(CONFIG_FEC1_PHY) || defined(CONFIG_FEC2_PHY)
28 #define WANT_MII
29 #else
30 #undef WANT_MII
31 #endif
32
33 #if defined(WANT_MII)
34 #include <miiphy.h>
35
36 #if !(defined(CONFIG_MII) || defined(CONFIG_CMD_MII))
37 #error "CONFIG_MII has to be defined!"
38 #endif
39
40 #endif
41
42 #if defined(CONFIG_RMII) && !defined(WANT_MII)
43 #error RMII support is unusable without a working PHY.
44 #endif
45
46 #ifdef CONFIG_SYS_DISCOVER_PHY
47 static int mii_discover_phy(struct eth_device *dev);
48 #endif
49
50 int fec8xx_miiphy_read(const char *devname, unsigned char addr,
51                 unsigned char  reg, unsigned short *value);
52 int fec8xx_miiphy_write(const char *devname, unsigned char  addr,
53                 unsigned char  reg, unsigned short value);
54
55 static struct ether_fcc_info_s
56 {
57         int ether_index;
58         int fecp_offset;
59         int phy_addr;
60         int actual_phy_addr;
61         int initialized;
62 }
63         ether_fcc_info[] = {
64 #if defined(CONFIG_ETHER_ON_FEC1)
65         {
66                 0,
67                 offsetof(immap_t, im_cpm.cp_fec1),
68 #if defined(CONFIG_FEC1_PHY)
69                 CONFIG_FEC1_PHY,
70 #else
71                 -1,     /* discover */
72 #endif
73                 -1,
74                 0,
75
76         },
77 #endif
78 #if defined(CONFIG_ETHER_ON_FEC2)
79         {
80                 1,
81                 offsetof(immap_t, im_cpm.cp_fec2),
82 #if defined(CONFIG_FEC2_PHY)
83                 CONFIG_FEC2_PHY,
84 #else
85                 -1,
86 #endif
87                 -1,
88                 0,
89         },
90 #endif
91 };
92
93 /* Ethernet Transmit and Receive Buffers */
94 #define DBUF_LENGTH  1520
95
96 #define TX_BUF_CNT 2
97
98 #define TOUT_LOOP 100
99
100 #define PKT_MAXBUF_SIZE         1518
101 #define PKT_MINBUF_SIZE         64
102 #define PKT_MAXBLR_SIZE         1520
103
104 #ifdef __GNUC__
105 static char txbuf[DBUF_LENGTH] __attribute__ ((aligned(8)));
106 #else
107 #error txbuf must be aligned.
108 #endif
109
110 static uint rxIdx;      /* index of the current RX buffer */
111 static uint txIdx;      /* index of the current TX buffer */
112
113 /*
114   * FEC Ethernet Tx and Rx buffer descriptors allocated at the
115   *  immr->udata_bd address on Dual-Port RAM
116   * Provide for Double Buffering
117   */
118
119 typedef volatile struct CommonBufferDescriptor {
120     cbd_t rxbd[PKTBUFSRX];              /* Rx BD */
121     cbd_t txbd[TX_BUF_CNT];             /* Tx BD */
122 } RTXBD;
123
124 static RTXBD *rtx = NULL;
125
126 static int fec_send(struct eth_device *dev, void *packet, int length);
127 static int fec_recv(struct eth_device* dev);
128 static int fec_init(struct eth_device* dev, bd_t * bd);
129 static void fec_halt(struct eth_device* dev);
130 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
131 static void __mii_init(void);
132 #endif
133
134 int fec_initialize(bd_t *bis)
135 {
136         struct eth_device* dev;
137         struct ether_fcc_info_s *efis;
138         int             i;
139
140         for (i = 0; i < sizeof(ether_fcc_info) / sizeof(ether_fcc_info[0]); i++) {
141
142                 dev = malloc(sizeof(*dev));
143                 if (dev == NULL)
144                         hang();
145
146                 memset(dev, 0, sizeof(*dev));
147
148                 /* for FEC1 make sure that the name of the interface is the same
149                    as the old one for compatibility reasons */
150                 if (i == 0) {
151                         sprintf (dev->name, "FEC");
152                 } else {
153                         sprintf (dev->name, "FEC%d",
154                                 ether_fcc_info[i].ether_index + 1);
155                 }
156
157                 efis = &ether_fcc_info[i];
158
159                 /*
160                  * reset actual phy addr
161                  */
162                 efis->actual_phy_addr = -1;
163
164                 dev->priv = efis;
165                 dev->init = fec_init;
166                 dev->halt = fec_halt;
167                 dev->send = fec_send;
168                 dev->recv = fec_recv;
169
170                 eth_register(dev);
171
172 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
173                 miiphy_register(dev->name,
174                         fec8xx_miiphy_read, fec8xx_miiphy_write);
175 #endif
176         }
177         return 1;
178 }
179
180 static int fec_send(struct eth_device *dev, void *packet, int length)
181 {
182         int j, rc;
183         struct ether_fcc_info_s *efis = dev->priv;
184         volatile fec_t *fecp = (volatile fec_t *)(CONFIG_SYS_IMMR + efis->fecp_offset);
185
186         /* section 16.9.23.3
187          * Wait for ready
188          */
189         j = 0;
190         while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j<TOUT_LOOP)) {
191                 udelay(1);
192                 j++;
193         }
194         if (j>=TOUT_LOOP) {
195                 printf("TX not ready\n");
196         }
197
198         rtx->txbd[txIdx].cbd_bufaddr = (uint)packet;
199         rtx->txbd[txIdx].cbd_datlen  = length;
200         rtx->txbd[txIdx].cbd_sc |= BD_ENET_TX_READY | BD_ENET_TX_LAST;
201         __asm__ ("eieio");
202
203         /* Activate transmit Buffer Descriptor polling */
204         fecp->fec_x_des_active = 0x01000000;    /* Descriptor polling active    */
205
206         j = 0;
207         while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j<TOUT_LOOP)) {
208                 udelay(1);
209                 j++;
210         }
211         if (j>=TOUT_LOOP) {
212                 printf("TX timeout\n");
213         }
214 #ifdef ET_DEBUG
215         printf("%s[%d] %s: cycles: %d    status: %x  retry cnt: %d\n",
216         __FILE__,__LINE__,__FUNCTION__,j,rtx->txbd[txIdx].cbd_sc,
217         (rtx->txbd[txIdx].cbd_sc & 0x003C)>>2);
218 #endif
219         /* return only status bits */;
220         rc = (rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_STATS);
221
222         txIdx = (txIdx + 1) % TX_BUF_CNT;
223
224         return rc;
225 }
226
227 static int fec_recv (struct eth_device *dev)
228 {
229         struct ether_fcc_info_s *efis = dev->priv;
230         volatile fec_t *fecp =
231                 (volatile fec_t *) (CONFIG_SYS_IMMR + efis->fecp_offset);
232         int length;
233
234         for (;;) {
235                 /* section 16.9.23.2 */
236                 if (rtx->rxbd[rxIdx].cbd_sc & BD_ENET_RX_EMPTY) {
237                         length = -1;
238                         break;  /* nothing received - leave for() loop */
239                 }
240
241                 length = rtx->rxbd[rxIdx].cbd_datlen;
242
243                 if (rtx->rxbd[rxIdx].cbd_sc & 0x003f) {
244 #ifdef ET_DEBUG
245                         printf ("%s[%d] err: %x\n",
246                                 __FUNCTION__, __LINE__,
247                                 rtx->rxbd[rxIdx].cbd_sc);
248 #endif
249                 } else {
250                         uchar *rx = NetRxPackets[rxIdx];
251
252                         length -= 4;
253
254 #if defined(CONFIG_CMD_CDP)
255                         if ((rx[0] & 1) != 0 &&
256                             memcmp((uchar *)rx, net_bcast_ethaddr, 6) != 0 &&
257                             !is_cdp_packet((uchar *)rx))
258                                 rx = NULL;
259 #endif
260                         /*
261                          * Pass the packet up to the protocol layers.
262                          */
263                         if (rx != NULL)
264                                 NetReceive (rx, length);
265                 }
266
267                 /* Give the buffer back to the FEC. */
268                 rtx->rxbd[rxIdx].cbd_datlen = 0;
269
270                 /* wrap around buffer index when necessary */
271                 if ((rxIdx + 1) >= PKTBUFSRX) {
272                         rtx->rxbd[PKTBUFSRX - 1].cbd_sc =
273                                 (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);
274                         rxIdx = 0;
275                 } else {
276                         rtx->rxbd[rxIdx].cbd_sc = BD_ENET_RX_EMPTY;
277                         rxIdx++;
278                 }
279
280                 __asm__ ("eieio");
281
282                 /* Try to fill Buffer Descriptors */
283                 fecp->fec_r_des_active = 0x01000000;    /* Descriptor polling active    */
284         }
285
286         return length;
287 }
288
289 /**************************************************************
290  *
291  * FEC Ethernet Initialization Routine
292  *
293  *************************************************************/
294
295 #define FEC_ECNTRL_PINMUX       0x00000004
296 #define FEC_ECNTRL_ETHER_EN     0x00000002
297 #define FEC_ECNTRL_RESET        0x00000001
298
299 #define FEC_RCNTRL_BC_REJ       0x00000010
300 #define FEC_RCNTRL_PROM         0x00000008
301 #define FEC_RCNTRL_MII_MODE     0x00000004
302 #define FEC_RCNTRL_DRT          0x00000002
303 #define FEC_RCNTRL_LOOP         0x00000001
304
305 #define FEC_TCNTRL_FDEN         0x00000004
306 #define FEC_TCNTRL_HBC          0x00000002
307 #define FEC_TCNTRL_GTS          0x00000001
308
309 #define FEC_RESET_DELAY         50
310
311 #if defined(CONFIG_RMII)
312
313 static inline void fec_10Mbps(struct eth_device *dev)
314 {
315         struct ether_fcc_info_s *efis = dev->priv;
316         int fecidx = efis->ether_index;
317         uint mask = (fecidx == 0) ? 0x0000010 : 0x0000008;
318
319         if ((unsigned int)fecidx >= 2)
320                 hang();
321
322         ((volatile immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_cptr |=  mask;
323 }
324
325 static inline void fec_100Mbps(struct eth_device *dev)
326 {
327         struct ether_fcc_info_s *efis = dev->priv;
328         int fecidx = efis->ether_index;
329         uint mask = (fecidx == 0) ? 0x0000010 : 0x0000008;
330
331         if ((unsigned int)fecidx >= 2)
332                 hang();
333
334         ((volatile immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_cptr &= ~mask;
335 }
336
337 #endif
338
339 static inline void fec_full_duplex(struct eth_device *dev)
340 {
341         struct ether_fcc_info_s *efis = dev->priv;
342         volatile fec_t *fecp = (volatile fec_t *)(CONFIG_SYS_IMMR + efis->fecp_offset);
343
344         fecp->fec_r_cntrl &= ~FEC_RCNTRL_DRT;
345         fecp->fec_x_cntrl |=  FEC_TCNTRL_FDEN;  /* FD enable */
346 }
347
348 static inline void fec_half_duplex(struct eth_device *dev)
349 {
350         struct ether_fcc_info_s *efis = dev->priv;
351         volatile fec_t *fecp = (volatile fec_t *)(CONFIG_SYS_IMMR + efis->fecp_offset);
352
353         fecp->fec_r_cntrl |=  FEC_RCNTRL_DRT;
354         fecp->fec_x_cntrl &= ~FEC_TCNTRL_FDEN;  /* FD disable */
355 }
356
357 static void fec_pin_init(int fecidx)
358 {
359         bd_t           *bd = gd->bd;
360         volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
361
362         /*
363          * Set MII speed to 2.5 MHz or slightly below.
364          *
365          * According to the MPC860T (Rev. D) Fast ethernet controller user
366          * manual (6.2.14),
367          * the MII management interface clock must be less than or equal
368          * to 2.5 MHz.
369          * This MDC frequency is equal to system clock / (2 * MII_SPEED).
370          * Then MII_SPEED = system_clock / 2 * 2,5 MHz.
371          *
372          * All MII configuration is done via FEC1 registers:
373          */
374         immr->im_cpm.cp_fec1.fec_mii_speed = ((bd->bi_intfreq + 4999999) / 5000000) << 1;
375
376 #if defined(CONFIG_MPC885_FAMILY) && defined(WANT_MII)
377         /* use MDC for MII */
378         immr->im_ioport.iop_pdpar |=  0x0080;
379         immr->im_ioport.iop_pddir &= ~0x0080;
380 #endif
381
382         if (fecidx == 0) {
383 #if defined(CONFIG_ETHER_ON_FEC1)
384
385 #if defined(CONFIG_MPC885_FAMILY) /* MPC87x/88x have got 2 FECs and different pinout */
386
387 #if !defined(CONFIG_RMII)
388
389                 immr->im_ioport.iop_papar |=  0xf830;
390                 immr->im_ioport.iop_padir |=  0x0830;
391                 immr->im_ioport.iop_padir &= ~0xf000;
392
393                 immr->im_cpm.cp_pbpar     |=  0x00001001;
394                 immr->im_cpm.cp_pbdir     &= ~0x00001001;
395
396                 immr->im_ioport.iop_pcpar |=  0x000c;
397                 immr->im_ioport.iop_pcdir &= ~0x000c;
398
399                 immr->im_cpm.cp_pepar     |=  0x00000003;
400                 immr->im_cpm.cp_pedir     |=  0x00000003;
401                 immr->im_cpm.cp_peso      &= ~0x00000003;
402
403                 immr->im_cpm.cp_cptr      &= ~0x00000100;
404
405 #else
406
407 #if !defined(CONFIG_FEC1_PHY_NORXERR)
408                 immr->im_ioport.iop_papar |=  0x1000;
409                 immr->im_ioport.iop_padir &= ~0x1000;
410 #endif
411                 immr->im_ioport.iop_papar |=  0xe810;
412                 immr->im_ioport.iop_padir |=  0x0810;
413                 immr->im_ioport.iop_padir &= ~0xe000;
414
415                 immr->im_cpm.cp_pbpar     |=  0x00000001;
416                 immr->im_cpm.cp_pbdir     &= ~0x00000001;
417
418                 immr->im_cpm.cp_cptr      |=  0x00000100;
419                 immr->im_cpm.cp_cptr      &= ~0x00000050;
420
421 #endif /* !CONFIG_RMII */
422
423 #else
424                 /*
425                  * Configure all of port D for MII.
426                  */
427                 immr->im_ioport.iop_pdpar = 0x1fff;
428
429                 /*
430                  * Bits moved from Rev. D onward
431                  */
432                 if ((get_immr(0) & 0xffff) < 0x0501)
433                         immr->im_ioport.iop_pddir = 0x1c58;     /* Pre rev. D */
434                 else
435                         immr->im_ioport.iop_pddir = 0x1fff;     /* Rev. D and later */
436 #endif
437
438 #endif  /* CONFIG_ETHER_ON_FEC1 */
439         } else if (fecidx == 1) {
440
441 #if defined(CONFIG_ETHER_ON_FEC2)
442
443 #if defined(CONFIG_MPC885_FAMILY) /* MPC87x/88x have got 2 FECs and different pinout */
444
445 #if !defined(CONFIG_RMII)
446                 immr->im_cpm.cp_pepar     |=  0x0003fffc;
447                 immr->im_cpm.cp_pedir     |=  0x0003fffc;
448                 immr->im_cpm.cp_peso      &= ~0x000087fc;
449                 immr->im_cpm.cp_peso      |=  0x00037800;
450
451                 immr->im_cpm.cp_cptr      &= ~0x00000080;
452 #else
453
454 #if !defined(CONFIG_FEC2_PHY_NORXERR)
455                 immr->im_cpm.cp_pepar     |=  0x00000010;
456                 immr->im_cpm.cp_pedir     |=  0x00000010;
457                 immr->im_cpm.cp_peso      &= ~0x00000010;
458 #endif
459                 immr->im_cpm.cp_pepar     |=  0x00039620;
460                 immr->im_cpm.cp_pedir     |=  0x00039620;
461                 immr->im_cpm.cp_peso      |=  0x00031000;
462                 immr->im_cpm.cp_peso      &= ~0x00008620;
463
464                 immr->im_cpm.cp_cptr      |=  0x00000080;
465                 immr->im_cpm.cp_cptr      &= ~0x00000028;
466 #endif /* CONFIG_RMII */
467
468 #endif /* CONFIG_MPC885_FAMILY */
469
470 #endif /* CONFIG_ETHER_ON_FEC2 */
471
472         }
473 }
474
475 static int fec_reset(volatile fec_t *fecp)
476 {
477         int i;
478
479         /* Whack a reset.
480          * A delay is required between a reset of the FEC block and
481          * initialization of other FEC registers because the reset takes
482          * some time to complete. If you don't delay, subsequent writes
483          * to FEC registers might get killed by the reset routine which is
484          * still in progress.
485          */
486
487         fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET;
488         for (i = 0;
489              (fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY);
490              ++i) {
491                 udelay (1);
492         }
493         if (i == FEC_RESET_DELAY)
494                 return -1;
495
496         return 0;
497 }
498
499 static int fec_init (struct eth_device *dev, bd_t * bd)
500 {
501         struct ether_fcc_info_s *efis = dev->priv;
502         volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
503         volatile fec_t *fecp =
504                 (volatile fec_t *) (CONFIG_SYS_IMMR + efis->fecp_offset);
505         int i;
506
507 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
508         /* the MII interface is connected to FEC1
509          * so for the miiphy_xxx function to work we must
510          * call mii_init since fec_halt messes the thing up
511          */
512         if (efis->ether_index != 0)
513                 __mii_init();
514 #endif
515
516         if (fec_reset(fecp) < 0)
517                 printf ("FEC_RESET_DELAY timeout\n");
518
519         /* We use strictly polling mode only
520          */
521         fecp->fec_imask = 0;
522
523         /* Clear any pending interrupt
524          */
525         fecp->fec_ievent = 0xffc0;
526
527         /* No need to set the IVEC register */
528
529         /* Set station address
530          */
531 #define ea dev->enetaddr
532         fecp->fec_addr_low = (ea[0] << 24) | (ea[1] << 16) | (ea[2] << 8) | (ea[3]);
533         fecp->fec_addr_high = (ea[4] << 8) | (ea[5]);
534 #undef ea
535
536 #if defined(CONFIG_CMD_CDP)
537         /*
538          * Turn on multicast address hash table
539          */
540         fecp->fec_hash_table_high = 0xffffffff;
541         fecp->fec_hash_table_low = 0xffffffff;
542 #else
543         /* Clear multicast address hash table
544          */
545         fecp->fec_hash_table_high = 0;
546         fecp->fec_hash_table_low = 0;
547 #endif
548
549         /* Set maximum receive buffer size.
550          */
551         fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
552
553         /* Set maximum frame length
554          */
555         fecp->fec_r_hash = PKT_MAXBUF_SIZE;
556
557         /*
558          * Setup Buffers and Buffer Desriptors
559          */
560         rxIdx = 0;
561         txIdx = 0;
562
563         if (!rtx) {
564 #ifdef CONFIG_SYS_ALLOC_DPRAM
565                 rtx = (RTXBD *) (immr->im_cpm.cp_dpmem +
566                                  dpram_alloc_align (sizeof (RTXBD), 8));
567 #else
568                 rtx = (RTXBD *) (immr->im_cpm.cp_dpmem + CPM_FEC_BASE);
569 #endif
570         }
571         /*
572          * Setup Receiver Buffer Descriptors (13.14.24.18)
573          * Settings:
574          *     Empty, Wrap
575          */
576         for (i = 0; i < PKTBUFSRX; i++) {
577                 rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
578                 rtx->rxbd[i].cbd_datlen = 0;    /* Reset */
579                 rtx->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i];
580         }
581         rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
582
583         /*
584          * Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19)
585          * Settings:
586          *    Last, Tx CRC
587          */
588         for (i = 0; i < TX_BUF_CNT; i++) {
589                 rtx->txbd[i].cbd_sc = BD_ENET_TX_LAST | BD_ENET_TX_TC;
590                 rtx->txbd[i].cbd_datlen = 0;    /* Reset */
591                 rtx->txbd[i].cbd_bufaddr = (uint) (&txbuf[0]);
592         }
593         rtx->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;
594
595         /* Set receive and transmit descriptor base
596          */
597         fecp->fec_r_des_start = (unsigned int) (&rtx->rxbd[0]);
598         fecp->fec_x_des_start = (unsigned int) (&rtx->txbd[0]);
599
600         /* Enable MII mode
601          */
602 #if 0                           /* Full duplex mode */
603         fecp->fec_r_cntrl = FEC_RCNTRL_MII_MODE;
604         fecp->fec_x_cntrl = FEC_TCNTRL_FDEN;
605 #else  /* Half duplex mode */
606         fecp->fec_r_cntrl = FEC_RCNTRL_MII_MODE | FEC_RCNTRL_DRT;
607         fecp->fec_x_cntrl = 0;
608 #endif
609
610         /* Enable big endian and don't care about SDMA FC.
611          */
612         fecp->fec_fun_code = 0x78000000;
613
614         /*
615          * Setup the pin configuration of the FEC
616          */
617         fec_pin_init (efis->ether_index);
618
619         rxIdx = 0;
620         txIdx = 0;
621
622         /*
623          * Now enable the transmit and receive processing
624          */
625         fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN;
626
627         if (efis->phy_addr == -1) {
628 #ifdef CONFIG_SYS_DISCOVER_PHY
629                 /*
630                  * wait for the PHY to wake up after reset
631                  */
632                 efis->actual_phy_addr = mii_discover_phy (dev);
633
634                 if (efis->actual_phy_addr == -1) {
635                         printf ("Unable to discover phy!\n");
636                         return -1;
637                 }
638 #else
639                 efis->actual_phy_addr = -1;
640 #endif
641         } else {
642                 efis->actual_phy_addr = efis->phy_addr;
643         }
644
645 #if defined(CONFIG_MII) && defined(CONFIG_RMII)
646         /*
647          * adapt the RMII speed to the speed of the phy
648          */
649         if (miiphy_speed (dev->name, efis->actual_phy_addr) == _100BASET) {
650                 fec_100Mbps (dev);
651         } else {
652                 fec_10Mbps (dev);
653         }
654 #endif
655
656 #if defined(CONFIG_MII)
657         /*
658          * adapt to the half/full speed settings
659          */
660         if (miiphy_duplex (dev->name, efis->actual_phy_addr) == FULL) {
661                 fec_full_duplex (dev);
662         } else {
663                 fec_half_duplex (dev);
664         }
665 #endif
666
667         /* And last, try to fill Rx Buffer Descriptors */
668         fecp->fec_r_des_active = 0x01000000;    /* Descriptor polling active    */
669
670         efis->initialized = 1;
671
672         return 0;
673 }
674
675
676 static void fec_halt(struct eth_device* dev)
677 {
678         struct ether_fcc_info_s *efis = dev->priv;
679         volatile fec_t *fecp = (volatile fec_t *)(CONFIG_SYS_IMMR + efis->fecp_offset);
680         int i;
681
682         /* avoid halt if initialized; mii gets stuck otherwise */
683         if (!efis->initialized)
684                 return;
685
686         /* Whack a reset.
687          * A delay is required between a reset of the FEC block and
688          * initialization of other FEC registers because the reset takes
689          * some time to complete. If you don't delay, subsequent writes
690          * to FEC registers might get killed by the reset routine which is
691          * still in progress.
692          */
693
694         fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_RESET;
695         for (i = 0;
696              (fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY);
697              ++i) {
698                 udelay (1);
699         }
700         if (i == FEC_RESET_DELAY) {
701                 printf ("FEC_RESET_DELAY timeout\n");
702                 return;
703         }
704
705         efis->initialized = 0;
706 }
707
708 #if defined(CONFIG_SYS_DISCOVER_PHY) || defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
709
710 /* Make MII read/write commands for the FEC.
711 */
712
713 #define mk_mii_read(ADDR, REG)  (0x60020000 | ((ADDR << 23) | \
714                                                 (REG & 0x1f) << 18))
715
716 #define mk_mii_write(ADDR, REG, VAL)    (0x50020000 | ((ADDR << 23) | \
717                                                 (REG & 0x1f) << 18) | \
718                                                 (VAL & 0xffff))
719
720 /* Interrupt events/masks.
721 */
722 #define FEC_ENET_HBERR  ((uint)0x80000000)      /* Heartbeat error */
723 #define FEC_ENET_BABR   ((uint)0x40000000)      /* Babbling receiver */
724 #define FEC_ENET_BABT   ((uint)0x20000000)      /* Babbling transmitter */
725 #define FEC_ENET_GRA    ((uint)0x10000000)      /* Graceful stop complete */
726 #define FEC_ENET_TXF    ((uint)0x08000000)      /* Full frame transmitted */
727 #define FEC_ENET_TXB    ((uint)0x04000000)      /* A buffer was transmitted */
728 #define FEC_ENET_RXF    ((uint)0x02000000)      /* Full frame received */
729 #define FEC_ENET_RXB    ((uint)0x01000000)      /* A buffer was received */
730 #define FEC_ENET_MII    ((uint)0x00800000)      /* MII interrupt */
731 #define FEC_ENET_EBERR  ((uint)0x00400000)      /* SDMA bus error */
732
733 /* PHY identification
734  */
735 #define PHY_ID_LXT970           0x78100000      /* LXT970 */
736 #define PHY_ID_LXT971           0x001378e0      /* LXT971 and 972 */
737 #define PHY_ID_82555            0x02a80150      /* Intel 82555 */
738 #define PHY_ID_QS6612           0x01814400      /* QS6612 */
739 #define PHY_ID_AMD79C784        0x00225610      /* AMD 79C784 */
740 #define PHY_ID_LSI80225         0x0016f870      /* LSI 80225 */
741 #define PHY_ID_LSI80225B        0x0016f880      /* LSI 80225/B */
742 #define PHY_ID_DM9161           0x0181B880      /* Davicom DM9161 */
743 #define PHY_ID_KSM8995M         0x00221450      /* MICREL KS8995MA */
744
745 /* send command to phy using mii, wait for result */
746 static uint
747 mii_send(uint mii_cmd)
748 {
749         uint mii_reply;
750         volatile fec_t  *ep;
751         int cnt;
752
753         ep = &(((immap_t *)CONFIG_SYS_IMMR)->im_cpm.cp_fec);
754
755         ep->fec_mii_data = mii_cmd;     /* command to phy */
756
757         /* wait for mii complete */
758         cnt = 0;
759         while (!(ep->fec_ievent & FEC_ENET_MII)) {
760                 if (++cnt > 1000) {
761                         printf("mii_send STUCK!\n");
762                         break;
763                 }
764         }
765         mii_reply = ep->fec_mii_data;           /* result from phy */
766         ep->fec_ievent = FEC_ENET_MII;          /* clear MII complete */
767 #if 0
768         printf("%s[%d] %s: sent=0x%8.8x, reply=0x%8.8x\n",
769                 __FILE__,__LINE__,__FUNCTION__,mii_cmd,mii_reply);
770 #endif
771         return (mii_reply & 0xffff);            /* data read from phy */
772 }
773 #endif
774
775 #if defined(CONFIG_SYS_DISCOVER_PHY)
776 static int mii_discover_phy(struct eth_device *dev)
777 {
778 #define MAX_PHY_PASSES 11
779         uint phyno;
780         int  pass;
781         uint phytype;
782         int phyaddr;
783
784         phyaddr = -1;   /* didn't find a PHY yet */
785         for (pass = 1; pass <= MAX_PHY_PASSES && phyaddr < 0; ++pass) {
786                 if (pass > 1) {
787                         /* PHY may need more time to recover from reset.
788                          * The LXT970 needs 50ms typical, no maximum is
789                          * specified, so wait 10ms before try again.
790                          * With 11 passes this gives it 100ms to wake up.
791                          */
792                         udelay(10000);  /* wait 10ms */
793                 }
794                 for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) {
795                         phytype = mii_send(mk_mii_read(phyno, MII_PHYSID2));
796 #ifdef ET_DEBUG
797                         printf("PHY type 0x%x pass %d type ", phytype, pass);
798 #endif
799                         if (phytype != 0xffff) {
800                                 phyaddr = phyno;
801                                 phytype |= mii_send(mk_mii_read(phyno,
802                                                                 MII_PHYSID1)) << 16;
803
804 #ifdef ET_DEBUG
805                                 printf("PHY @ 0x%x pass %d type ",phyno,pass);
806                                 switch (phytype & 0xfffffff0) {
807                                 case PHY_ID_LXT970:
808                                         printf("LXT970\n");
809                                         break;
810                                 case PHY_ID_LXT971:
811                                         printf("LXT971\n");
812                                         break;
813                                 case PHY_ID_82555:
814                                         printf("82555\n");
815                                         break;
816                                 case PHY_ID_QS6612:
817                                         printf("QS6612\n");
818                                         break;
819                                 case PHY_ID_AMD79C784:
820                                         printf("AMD79C784\n");
821                                         break;
822                                 case PHY_ID_LSI80225B:
823                                         printf("LSI L80225/B\n");
824                                         break;
825                                 case PHY_ID_DM9161:
826                                         printf("Davicom DM9161\n");
827                                         break;
828                                 case PHY_ID_KSM8995M:
829                                         printf("MICREL KS8995M\n");
830                                         break;
831                                 default:
832                                         printf("0x%08x\n", phytype);
833                                         break;
834                                 }
835 #endif
836                         }
837                 }
838         }
839         if (phyaddr < 0) {
840                 printf("No PHY device found.\n");
841         }
842         return phyaddr;
843 }
844 #endif  /* CONFIG_SYS_DISCOVER_PHY */
845
846 #if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && !defined(CONFIG_BITBANGMII)
847
848 /****************************************************************************
849  * mii_init -- Initialize the MII via FEC 1 for MII command without ethernet
850  * This function is a subset of eth_init
851  ****************************************************************************
852  */
853 static void __mii_init(void)
854 {
855         volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
856         volatile fec_t *fecp = &(immr->im_cpm.cp_fec);
857
858         if (fec_reset(fecp) < 0)
859                 printf ("FEC_RESET_DELAY timeout\n");
860
861         /* We use strictly polling mode only
862          */
863         fecp->fec_imask = 0;
864
865         /* Clear any pending interrupt
866          */
867         fecp->fec_ievent = 0xffc0;
868
869         /* Now enable the transmit and receive processing
870          */
871         fecp->fec_ecntrl = FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN;
872 }
873
874 void mii_init (void)
875 {
876         int i;
877
878         __mii_init();
879
880         /* Setup the pin configuration of the FEC(s)
881         */
882         for (i = 0; i < sizeof(ether_fcc_info) / sizeof(ether_fcc_info[0]); i++)
883                 fec_pin_init(ether_fcc_info[i].ether_index);
884 }
885
886 /*****************************************************************************
887  * Read and write a MII PHY register, routines used by MII Utilities
888  *
889  * FIXME: These routines are expected to return 0 on success, but mii_send
890  *        does _not_ return an error code. Maybe 0xFFFF means error, i.e.
891  *        no PHY connected...
892  *        For now always return 0.
893  * FIXME: These routines only work after calling eth_init() at least once!
894  *        Otherwise they hang in mii_send() !!! Sorry!
895  *****************************************************************************/
896
897 int fec8xx_miiphy_read(const char *devname, unsigned char addr,
898                 unsigned char  reg, unsigned short *value)
899 {
900         short rdreg;    /* register working value */
901
902 #ifdef MII_DEBUG
903         printf ("miiphy_read(0x%x) @ 0x%x = ", reg, addr);
904 #endif
905         rdreg = mii_send(mk_mii_read(addr, reg));
906
907         *value = rdreg;
908 #ifdef MII_DEBUG
909         printf ("0x%04x\n", *value);
910 #endif
911         return 0;
912 }
913
914 int fec8xx_miiphy_write(const char *devname, unsigned char  addr,
915                 unsigned char  reg, unsigned short value)
916 {
917 #ifdef MII_DEBUG
918         printf ("miiphy_write(0x%x) @ 0x%x = ", reg, addr);
919 #endif
920         (void)mii_send(mk_mii_write(addr, reg, value));
921
922 #ifdef MII_DEBUG
923         printf ("0x%04x\n", value);
924 #endif
925         return 0;
926 }
927 #endif
928
929 #endif