00d905c299de4d6e3d451ec886067b88c7f9d523
[oweals/u-boot.git] / drivers / net / fsl_mcdmafec.c
1 /*
2  * (C) Copyright 2000-2004
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * (C) Copyright 2007 Freescale Semiconductor, Inc.
6  * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
7  *
8  * SPDX-License-Identifier:     GPL-2.0+
9  */
10
11 #include <common.h>
12 #include <environment.h>
13 #include <malloc.h>
14 #include <command.h>
15 #include <config.h>
16 #include <net.h>
17 #include <miiphy.h>
18
19 #undef  ET_DEBUG
20 #undef  MII_DEBUG
21
22 /* Ethernet Transmit and Receive Buffers */
23 #define DBUF_LENGTH             1520
24 #define PKT_MAXBUF_SIZE         1518
25 #define PKT_MINBUF_SIZE         64
26 #define PKT_MAXBLR_SIZE         1536
27 #define LAST_PKTBUFSRX          PKTBUFSRX - 1
28 #define BD_ENET_RX_W_E          (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY)
29 #define BD_ENET_TX_RDY_LST      (BD_ENET_TX_READY | BD_ENET_TX_LAST)
30 #define FIFO_ERRSTAT            (FIFO_STAT_RXW | FIFO_STAT_UF | FIFO_STAT_OF)
31
32 /* RxBD bits definitions */
33 #define BD_ENET_RX_ERR  (BD_ENET_RX_LG | BD_ENET_RX_NO | BD_ENET_RX_CR | \
34                          BD_ENET_RX_OV | BD_ENET_RX_TR)
35
36 #include <asm/immap.h>
37 #include <asm/fsl_mcdmafec.h>
38
39 #include "MCD_dma.h"
40
41 DECLARE_GLOBAL_DATA_PTR;
42
43 struct fec_info_dma fec_info[] = {
44 #ifdef CONFIG_SYS_FEC0_IOBASE
45         {
46          0,                     /* index */
47          CONFIG_SYS_FEC0_IOBASE,        /* io base */
48          CONFIG_SYS_FEC0_PINMUX,        /* gpio pin muxing */
49          CONFIG_SYS_FEC0_MIIBASE,       /* mii base */
50          -1,                    /* phy_addr */
51          0,                     /* duplex and speed */
52          0,                     /* phy name */
53          0,                     /* phyname init */
54          0,                     /* RX BD */
55          0,                     /* TX BD */
56          0,                     /* rx Index */
57          0,                     /* tx Index */
58          0,                     /* tx buffer */
59          0,                     /* initialized flag */
60          (struct fec_info_dma *)-1,     /* next */
61          FEC0_RX_TASK,          /* rxTask */
62          FEC0_TX_TASK,          /* txTask */
63          FEC0_RX_PRIORITY,      /* rxPri */
64          FEC0_TX_PRIORITY,      /* txPri */
65          FEC0_RX_INIT,          /* rxInit */
66          FEC0_TX_INIT,          /* txInit */
67          0,                     /* usedTbdIndex */
68          0,                     /* cleanTbdNum */
69          },
70 #endif
71 #ifdef CONFIG_SYS_FEC1_IOBASE
72         {
73          1,                     /* index */
74          CONFIG_SYS_FEC1_IOBASE,        /* io base */
75          CONFIG_SYS_FEC1_PINMUX,        /* gpio pin muxing */
76          CONFIG_SYS_FEC1_MIIBASE,       /* mii base */
77          -1,                    /* phy_addr */
78          0,                     /* duplex and speed */
79          0,                     /* phy name */
80          0,                     /* phy name init */
81 #ifdef CONFIG_SYS_DMA_USE_INTSRAM
82          (cbd_t *)DBUF_LENGTH,  /* RX BD */
83 #else
84          0,                     /* RX BD */
85 #endif
86          0,                     /* TX BD */
87          0,                     /* rx Index */
88          0,                     /* tx Index */
89          0,                     /* tx buffer */
90          0,                     /* initialized flag */
91          (struct fec_info_dma *)-1,     /* next */
92          FEC1_RX_TASK,          /* rxTask */
93          FEC1_TX_TASK,          /* txTask */
94          FEC1_RX_PRIORITY,      /* rxPri */
95          FEC1_TX_PRIORITY,      /* txPri */
96          FEC1_RX_INIT,          /* rxInit */
97          FEC1_TX_INIT,          /* txInit */
98          0,                     /* usedTbdIndex */
99          0,                     /* cleanTbdNum */
100          }
101 #endif
102 };
103
104 static int fec_send(struct eth_device *dev, void *packet, int length);
105 static int fec_recv(struct eth_device *dev);
106 static int fec_init(struct eth_device *dev, bd_t * bd);
107 static void fec_halt(struct eth_device *dev);
108
109 #ifdef ET_DEBUG
110 static void dbg_fec_regs(struct eth_device *dev)
111 {
112         struct fec_info_dma *info = dev->priv;
113         volatile fecdma_t *fecp = (fecdma_t *) (info->iobase);
114
115         printf("=====\n");
116         printf("ievent       %x - %x\n", (int)&fecp->eir, fecp->eir);
117         printf("imask        %x - %x\n", (int)&fecp->eimr, fecp->eimr);
118         printf("ecntrl       %x - %x\n", (int)&fecp->ecr, fecp->ecr);
119         printf("mii_mframe   %x - %x\n", (int)&fecp->mmfr, fecp->mmfr);
120         printf("mii_speed    %x - %x\n", (int)&fecp->mscr, fecp->mscr);
121         printf("mii_ctrlstat %x - %x\n", (int)&fecp->mibc, fecp->mibc);
122         printf("r_cntrl      %x - %x\n", (int)&fecp->rcr, fecp->rcr);
123         printf("r hash       %x - %x\n", (int)&fecp->rhr, fecp->rhr);
124         printf("x_cntrl      %x - %x\n", (int)&fecp->tcr, fecp->tcr);
125         printf("padr_l       %x - %x\n", (int)&fecp->palr, fecp->palr);
126         printf("padr_u       %x - %x\n", (int)&fecp->paur, fecp->paur);
127         printf("op_pause     %x - %x\n", (int)&fecp->opd, fecp->opd);
128         printf("iadr_u       %x - %x\n", (int)&fecp->iaur, fecp->iaur);
129         printf("iadr_l       %x - %x\n", (int)&fecp->ialr, fecp->ialr);
130         printf("gadr_u       %x - %x\n", (int)&fecp->gaur, fecp->gaur);
131         printf("gadr_l       %x - %x\n", (int)&fecp->galr, fecp->galr);
132         printf("x_wmrk       %x - %x\n", (int)&fecp->tfwr, fecp->tfwr);
133         printf("r_fdata      %x - %x\n", (int)&fecp->rfdr, fecp->rfdr);
134         printf("r_fstat      %x - %x\n", (int)&fecp->rfsr, fecp->rfsr);
135         printf("r_fctrl      %x - %x\n", (int)&fecp->rfcr, fecp->rfcr);
136         printf("r_flrfp      %x - %x\n", (int)&fecp->rlrfp, fecp->rlrfp);
137         printf("r_flwfp      %x - %x\n", (int)&fecp->rlwfp, fecp->rlwfp);
138         printf("r_frfar      %x - %x\n", (int)&fecp->rfar, fecp->rfar);
139         printf("r_frfrp      %x - %x\n", (int)&fecp->rfrp, fecp->rfrp);
140         printf("r_frfwp      %x - %x\n", (int)&fecp->rfwp, fecp->rfwp);
141         printf("t_fdata      %x - %x\n", (int)&fecp->tfdr, fecp->tfdr);
142         printf("t_fstat      %x - %x\n", (int)&fecp->tfsr, fecp->tfsr);
143         printf("t_fctrl      %x - %x\n", (int)&fecp->tfcr, fecp->tfcr);
144         printf("t_flrfp      %x - %x\n", (int)&fecp->tlrfp, fecp->tlrfp);
145         printf("t_flwfp      %x - %x\n", (int)&fecp->tlwfp, fecp->tlwfp);
146         printf("t_ftfar      %x - %x\n", (int)&fecp->tfar, fecp->tfar);
147         printf("t_ftfrp      %x - %x\n", (int)&fecp->tfrp, fecp->tfrp);
148         printf("t_ftfwp      %x - %x\n", (int)&fecp->tfwp, fecp->tfwp);
149         printf("frst         %x - %x\n", (int)&fecp->frst, fecp->frst);
150         printf("ctcwr        %x - %x\n", (int)&fecp->ctcwr, fecp->ctcwr);
151 }
152 #endif
153
154 static void set_fec_duplex_speed(volatile fecdma_t * fecp, bd_t * bd,
155                                  int dup_spd)
156 {
157         if ((dup_spd >> 16) == FULL) {
158                 /* Set maximum frame length */
159                 fecp->rcr = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) | FEC_RCR_MII_MODE |
160                     FEC_RCR_PROM | 0x100;
161                 fecp->tcr = FEC_TCR_FDEN;
162         } else {
163                 /* Half duplex mode */
164                 fecp->rcr = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) |
165                     FEC_RCR_MII_MODE | FEC_RCR_DRT;
166                 fecp->tcr &= ~FEC_TCR_FDEN;
167         }
168
169         if ((dup_spd & 0xFFFF) == _100BASET) {
170 #ifdef MII_DEBUG
171                 printf("100Mbps\n");
172 #endif
173                 bd->bi_ethspeed = 100;
174         } else {
175 #ifdef MII_DEBUG
176                 printf("10Mbps\n");
177 #endif
178                 bd->bi_ethspeed = 10;
179         }
180 }
181
182 static int fec_send(struct eth_device *dev, void *packet, int length)
183 {
184         struct fec_info_dma *info = dev->priv;
185         cbd_t *pTbd, *pUsedTbd;
186         u16 phyStatus;
187
188         miiphy_read(dev->name, info->phy_addr, MII_BMSR, &phyStatus);
189
190         /* process all the consumed TBDs */
191         while (info->cleanTbdNum < CONFIG_SYS_TX_ETH_BUFFER) {
192                 pUsedTbd = &info->txbd[info->usedTbdIdx];
193                 if (pUsedTbd->cbd_sc & BD_ENET_TX_READY) {
194 #ifdef ET_DEBUG
195                         printf("Cannot clean TBD %d, in use\n",
196                                info->cleanTbdNum);
197 #endif
198                         return 0;
199                 }
200
201                 /* clean this buffer descriptor */
202                 if (info->usedTbdIdx == (CONFIG_SYS_TX_ETH_BUFFER - 1))
203                         pUsedTbd->cbd_sc = BD_ENET_TX_WRAP;
204                 else
205                         pUsedTbd->cbd_sc = 0;
206
207                 /* update some indeces for a correct handling of the TBD ring */
208                 info->cleanTbdNum++;
209                 info->usedTbdIdx = (info->usedTbdIdx + 1) % CONFIG_SYS_TX_ETH_BUFFER;
210         }
211
212         /* Check for valid length of data. */
213         if ((length > 1500) || (length <= 0)) {
214                 return -1;
215         }
216
217         /* Check the number of vacant TxBDs. */
218         if (info->cleanTbdNum < 1) {
219                 printf("No available TxBDs ...\n");
220                 return -1;
221         }
222
223         /* Get the first TxBD to send the mac header */
224         pTbd = &info->txbd[info->txIdx];
225         pTbd->cbd_datlen = length;
226         pTbd->cbd_bufaddr = (u32) packet;
227         pTbd->cbd_sc |= BD_ENET_TX_LAST | BD_ENET_TX_TC | BD_ENET_TX_READY;
228         info->txIdx = (info->txIdx + 1) % CONFIG_SYS_TX_ETH_BUFFER;
229
230         /* Enable DMA transmit task */
231         MCD_continDma(info->txTask);
232
233         info->cleanTbdNum -= 1;
234
235         /* wait until frame is sent . */
236         while (pTbd->cbd_sc & BD_ENET_TX_READY) {
237                 udelay(10);
238         }
239
240         return (int)(info->txbd[info->txIdx].cbd_sc & BD_ENET_TX_STATS);
241 }
242
243 static int fec_recv(struct eth_device *dev)
244 {
245         struct fec_info_dma *info = dev->priv;
246         volatile fecdma_t *fecp = (fecdma_t *) (info->iobase);
247
248         cbd_t *prbd = &info->rxbd[info->rxIdx];
249         u32 ievent;
250         int frame_length, len = 0;
251
252         /* Check if any critical events have happened */
253         ievent = fecp->eir;
254         if (ievent != 0) {
255                 fecp->eir = ievent;
256
257                 if (ievent & (FEC_EIR_BABT | FEC_EIR_TXERR | FEC_EIR_RXERR)) {
258                         printf("fec_recv: error\n");
259                         fec_halt(dev);
260                         fec_init(dev, NULL);
261                         return 0;
262                 }
263
264                 if (ievent & FEC_EIR_HBERR) {
265                         /* Heartbeat error */
266                         fecp->tcr |= FEC_TCR_GTS;
267                 }
268
269                 if (ievent & FEC_EIR_GRA) {
270                         /* Graceful stop complete */
271                         if (fecp->tcr & FEC_TCR_GTS) {
272                                 printf("fec_recv: tcr_gts\n");
273                                 fec_halt(dev);
274                                 fecp->tcr &= ~FEC_TCR_GTS;
275                                 fec_init(dev, NULL);
276                         }
277                 }
278         }
279
280         if (!(prbd->cbd_sc & BD_ENET_RX_EMPTY)) {
281                 if ((prbd->cbd_sc & BD_ENET_RX_LAST) &&
282                     !(prbd->cbd_sc & BD_ENET_RX_ERR) &&
283                     ((prbd->cbd_datlen - 4) > 14)) {
284
285                         /* Get buffer address and size */
286                         frame_length = prbd->cbd_datlen - 4;
287
288                         /* Fill the buffer and pass it to upper layers */
289                         net_process_received_packet((uchar *)prbd->cbd_bufaddr,
290                                                     frame_length);
291                         len = frame_length;
292                 }
293
294                 /* Reset buffer descriptor as empty */
295                 if ((info->rxIdx) == (PKTBUFSRX - 1))
296                         prbd->cbd_sc = (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);
297                 else
298                         prbd->cbd_sc = BD_ENET_RX_EMPTY;
299
300                 prbd->cbd_datlen = PKTSIZE_ALIGN;
301
302                 /* Now, we have an empty RxBD, restart the DMA receive task */
303                 MCD_continDma(info->rxTask);
304
305                 /* Increment BD count */
306                 info->rxIdx = (info->rxIdx + 1) % PKTBUFSRX;
307         }
308
309         return len;
310 }
311
312 static void fec_set_hwaddr(volatile fecdma_t * fecp, u8 * mac)
313 {
314         u8 currByte;            /* byte for which to compute the CRC */
315         int byte;               /* loop - counter */
316         int bit;                /* loop - counter */
317         u32 crc = 0xffffffff;   /* initial value */
318
319         for (byte = 0; byte < 6; byte++) {
320                 currByte = mac[byte];
321                 for (bit = 0; bit < 8; bit++) {
322                         if ((currByte & 0x01) ^ (crc & 0x01)) {
323                                 crc >>= 1;
324                                 crc = crc ^ 0xedb88320;
325                         } else {
326                                 crc >>= 1;
327                         }
328                         currByte >>= 1;
329                 }
330         }
331
332         crc = crc >> 26;
333
334         /* Set individual hash table register */
335         if (crc >= 32) {
336                 fecp->ialr = (1 << (crc - 32));
337                 fecp->iaur = 0;
338         } else {
339                 fecp->ialr = 0;
340                 fecp->iaur = (1 << crc);
341         }
342
343         /* Set physical address */
344         fecp->palr = (mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3];
345         fecp->paur = (mac[4] << 24) + (mac[5] << 16) + 0x8808;
346
347         /* Clear multicast address hash table */
348         fecp->gaur = 0;
349         fecp->galr = 0;
350 }
351
352 static int fec_init(struct eth_device *dev, bd_t * bd)
353 {
354         struct fec_info_dma *info = dev->priv;
355         volatile fecdma_t *fecp = (fecdma_t *) (info->iobase);
356         int i;
357         uchar enetaddr[6];
358
359 #ifdef ET_DEBUG
360         printf("fec_init: iobase 0x%08x ...\n", info->iobase);
361 #endif
362
363         fecpin_setclear(dev, 1);
364
365         fec_halt(dev);
366
367 #if defined(CONFIG_CMD_MII) || defined (CONFIG_MII) || \
368         defined (CONFIG_SYS_DISCOVER_PHY)
369
370         mii_init();
371
372         set_fec_duplex_speed(fecp, bd, info->dup_spd);
373 #else
374 #ifndef CONFIG_SYS_DISCOVER_PHY
375         set_fec_duplex_speed(fecp, bd, (FECDUPLEX << 16) | FECSPEED);
376 #endif                          /* ifndef CONFIG_SYS_DISCOVER_PHY */
377 #endif                          /* CONFIG_CMD_MII || CONFIG_MII */
378
379         /* We use strictly polling mode only */
380         fecp->eimr = 0;
381
382         /* Clear any pending interrupt */
383         fecp->eir = 0xffffffff;
384
385         /* Set station address   */
386         if ((u32) fecp == CONFIG_SYS_FEC0_IOBASE)
387                 eth_env_get_enetaddr("ethaddr", enetaddr);
388         else
389                 eth_env_get_enetaddr("eth1addr", enetaddr);
390         fec_set_hwaddr(fecp, enetaddr);
391
392         /* Set Opcode/Pause Duration Register */
393         fecp->opd = 0x00010020;
394
395         /* Setup Buffers and Buffer Descriptors */
396         info->rxIdx = 0;
397         info->txIdx = 0;
398
399         /* Setup Receiver Buffer Descriptors (13.14.24.18)
400          * Settings:     Empty, Wrap */
401         for (i = 0; i < PKTBUFSRX; i++) {
402                 info->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
403                 info->rxbd[i].cbd_datlen = PKTSIZE_ALIGN;
404                 info->rxbd[i].cbd_bufaddr = (uint) net_rx_packets[i];
405         }
406         info->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
407
408         /* Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19)
409          * Settings:    Last, Tx CRC */
410         for (i = 0; i < CONFIG_SYS_TX_ETH_BUFFER; i++) {
411                 info->txbd[i].cbd_sc = 0;
412                 info->txbd[i].cbd_datlen = 0;
413                 info->txbd[i].cbd_bufaddr = (uint) (&info->txbuf[0]);
414         }
415         info->txbd[CONFIG_SYS_TX_ETH_BUFFER - 1].cbd_sc |= BD_ENET_TX_WRAP;
416
417         info->usedTbdIdx = 0;
418         info->cleanTbdNum = CONFIG_SYS_TX_ETH_BUFFER;
419
420         /* Set Rx FIFO alarm and granularity value */
421         fecp->rfcr = 0x0c000000;
422         fecp->rfar = 0x0000030c;
423
424         /* Set Tx FIFO granularity value */
425         fecp->tfcr = FIFO_CTRL_FRAME | FIFO_CTRL_GR(6) | 0x00040000;
426         fecp->tfar = 0x00000080;
427
428         fecp->tfwr = 0x2;
429         fecp->ctcwr = 0x03000000;
430
431         /* Enable DMA receive task */
432         MCD_startDma(info->rxTask,      /* Dma channel */
433                      (s8 *) info->rxbd, /*Source Address */
434                      0,         /* Source increment */
435                      (s8 *) (&fecp->rfdr),      /* dest */
436                      4,         /* dest increment */
437                      0,         /* DMA size */
438                      4,         /* xfer size */
439                      info->rxInit,      /* initiator */
440                      info->rxPri,       /* priority */
441                      (MCD_FECRX_DMA | MCD_TT_FLAGS_DEF),        /* Flags */
442                      (MCD_NO_CSUM | MCD_NO_BYTE_SWAP)   /* Function description */
443             );
444
445         /* Enable DMA tx task with no ready buffer descriptors */
446         MCD_startDma(info->txTask,      /* Dma channel */
447                      (s8 *) info->txbd, /*Source Address */
448                      0,         /* Source increment */
449                      (s8 *) (&fecp->tfdr),      /* dest */
450                      4,         /* dest incr */
451                      0,         /* DMA size */
452                      4,         /* xfer size */
453                      info->txInit,      /* initiator */
454                      info->txPri,       /* priority */
455                      (MCD_FECTX_DMA | MCD_TT_FLAGS_DEF),        /* Flags */
456                      (MCD_NO_CSUM | MCD_NO_BYTE_SWAP)   /* Function description */
457             );
458
459         /* Now enable the transmit and receive processing */
460         fecp->ecr |= FEC_ECR_ETHER_EN;
461
462         return 1;
463 }
464
465 static void fec_halt(struct eth_device *dev)
466 {
467         struct fec_info_dma *info = dev->priv;
468         volatile fecdma_t *fecp = (fecdma_t *) (info->iobase);
469         int counter = 0xffff;
470
471         /* issue graceful stop command to the FEC transmitter if necessary */
472         fecp->tcr |= FEC_TCR_GTS;
473
474         /* wait for graceful stop to register */
475         while ((counter--) && (!(fecp->eir & FEC_EIR_GRA))) ;
476
477         /* Disable DMA tasks */
478         MCD_killDma(info->txTask);
479         MCD_killDma(info->rxTask);
480
481         /* Disable the Ethernet Controller */
482         fecp->ecr &= ~FEC_ECR_ETHER_EN;
483
484         /* Clear FIFO status registers */
485         fecp->rfsr &= FIFO_ERRSTAT;
486         fecp->tfsr &= FIFO_ERRSTAT;
487
488         fecp->frst = 0x01000000;
489
490         /* Issue a reset command to the FEC chip */
491         fecp->ecr |= FEC_ECR_RESET;
492
493         /* wait at least 20 clock cycles */
494         udelay(10000);
495
496 #ifdef ET_DEBUG
497         printf("Ethernet task stopped\n");
498 #endif
499 }
500
501 int mcdmafec_initialize(bd_t * bis)
502 {
503         struct eth_device *dev;
504         int i;
505 #ifdef CONFIG_SYS_DMA_USE_INTSRAM
506         u32 tmp = CONFIG_SYS_INTSRAM + 0x2000;
507 #endif
508
509         for (i = 0; i < ARRAY_SIZE(fec_info); i++) {
510
511                 dev =
512                     (struct eth_device *)memalign(CONFIG_SYS_CACHELINE_SIZE,
513                                                   sizeof *dev);
514                 if (dev == NULL)
515                         hang();
516
517                 memset(dev, 0, sizeof(*dev));
518
519                 sprintf(dev->name, "FEC%d", fec_info[i].index);
520
521                 dev->priv = &fec_info[i];
522                 dev->init = fec_init;
523                 dev->halt = fec_halt;
524                 dev->send = fec_send;
525                 dev->recv = fec_recv;
526
527                 /* setup Receive and Transmit buffer descriptor */
528 #ifdef CONFIG_SYS_DMA_USE_INTSRAM
529                 fec_info[i].rxbd = (cbd_t *)((u32)fec_info[i].rxbd + tmp);
530                 tmp = (u32)fec_info[i].rxbd;
531                 fec_info[i].txbd =
532                     (cbd_t *)((u32)fec_info[i].txbd + tmp +
533                     (PKTBUFSRX * sizeof(cbd_t)));
534                 tmp = (u32)fec_info[i].txbd;
535                 fec_info[i].txbuf =
536                     (char *)((u32)fec_info[i].txbuf + tmp +
537                     (CONFIG_SYS_TX_ETH_BUFFER * sizeof(cbd_t)));
538                 tmp = (u32)fec_info[i].txbuf;
539 #else
540                 fec_info[i].rxbd =
541                     (cbd_t *) memalign(CONFIG_SYS_CACHELINE_SIZE,
542                                        (PKTBUFSRX * sizeof(cbd_t)));
543                 fec_info[i].txbd =
544                     (cbd_t *) memalign(CONFIG_SYS_CACHELINE_SIZE,
545                                        (CONFIG_SYS_TX_ETH_BUFFER * sizeof(cbd_t)));
546                 fec_info[i].txbuf =
547                     (char *)memalign(CONFIG_SYS_CACHELINE_SIZE, DBUF_LENGTH);
548 #endif
549
550 #ifdef ET_DEBUG
551                 printf("rxbd %x txbd %x\n",
552                        (int)fec_info[i].rxbd, (int)fec_info[i].txbd);
553 #endif
554
555                 fec_info[i].phy_name = (char *)memalign(CONFIG_SYS_CACHELINE_SIZE, 32);
556
557                 eth_register(dev);
558
559 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
560                 int retval;
561                 struct mii_dev *mdiodev = mdio_alloc();
562                 if (!mdiodev)
563                         return -ENOMEM;
564                 strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
565                 mdiodev->read = mcffec_miiphy_read;
566                 mdiodev->write = mcffec_miiphy_write;
567
568                 retval = mdio_register(mdiodev);
569                 if (retval < 0)
570                         return retval;
571 #endif
572
573                 if (i > 0)
574                         fec_info[i - 1].next = &fec_info[i];
575         }
576         fec_info[i - 1].next = &fec_info[0];
577
578         /* default speed */
579         bis->bi_ethspeed = 10;
580
581         return 0;
582 }