~ubuntu-branches/ubuntu/maverick/u-boot-omap3/maverick

« back to all changes in this revision

Viewing changes to cpu/mpc8xx/fec.c

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Grawert
  • Date: 2010-03-22 15:06:23 UTC
  • Revision ID: james.westby@ubuntu.com-20100322150623-i21g8rgiyl5dohag
Tags: upstream-2010.3git20100315
ImportĀ upstreamĀ versionĀ 2010.3git20100315

Show diffs side-by-side

added added

removed removed

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