Merge branch 'u-boot-imx/master' into 'u-boot-arm/master'
[platform/kernel/u-boot.git] / drivers / net / greth.c
1 /* Gaisler.com GRETH 10/100/1000 Ethernet MAC driver
2  *
3  * Driver use polling mode (no Interrupt)
4  *
5  * (C) Copyright 2007
6  * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
7  *
8  * See file CREDITS for list of people who contributed to this
9  * project.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License as
13  * published by the Free Software Foundation; either version 2 of
14  * the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24  * MA 02111-1307 USA
25  */
26
27 /* #define DEBUG */
28
29 #include <common.h>
30 #include <command.h>
31 #include <net.h>
32 #include <netdev.h>
33 #include <malloc.h>
34 #include <asm/processor.h>
35 #include <ambapp.h>
36 #include <asm/leon.h>
37
38 #include "greth.h"
39
40 /* Default to 3s timeout on autonegotiation */
41 #ifndef GRETH_PHY_TIMEOUT_MS
42 #define GRETH_PHY_TIMEOUT_MS 3000
43 #endif
44
45 /* Default to PHY adrress 0 not not specified */
46 #ifdef CONFIG_SYS_GRLIB_GRETH_PHYADDR
47 #define GRETH_PHY_ADR_DEFAULT CONFIG_SYS_GRLIB_GRETH_PHYADDR
48 #else
49 #define GRETH_PHY_ADR_DEFAULT 0
50 #endif
51
52 /* ByPass Cache when reading regs */
53 #define GRETH_REGLOAD(addr)             SPARC_NOCACHE_READ(addr)
54 /* Write-through cache ==> no bypassing needed on writes */
55 #define GRETH_REGSAVE(addr,data) (*(volatile unsigned int *)(addr) = (data))
56 #define GRETH_REGORIN(addr,data) GRETH_REGSAVE(addr,GRETH_REGLOAD(addr)|data)
57 #define GRETH_REGANDIN(addr,data) GRETH_REGSAVE(addr,GRETH_REGLOAD(addr)&data)
58
59 #define GRETH_RXBD_CNT 4
60 #define GRETH_TXBD_CNT 1
61
62 #define GRETH_RXBUF_SIZE 1540
63 #define GRETH_BUF_ALIGN 4
64 #define GRETH_RXBUF_EFF_SIZE \
65         ( (GRETH_RXBUF_SIZE&~(GRETH_BUF_ALIGN-1))+GRETH_BUF_ALIGN )
66
67 typedef struct {
68         greth_regs *regs;
69         int irq;
70         struct eth_device *dev;
71
72         /* Hardware info */
73         unsigned char phyaddr;
74         int gbit_mac;
75
76         /* Current operating Mode */
77         int gb;                 /* GigaBit */
78         int fd;                 /* Full Duplex */
79         int sp;                 /* 10/100Mbps speed (1=100,0=10) */
80         int auto_neg;           /* Auto negotiate done */
81
82         unsigned char hwaddr[6];        /* MAC Address */
83
84         /* Descriptors */
85         greth_bd *rxbd_base, *rxbd_max;
86         greth_bd *txbd_base, *txbd_max;
87
88         greth_bd *rxbd_curr;
89
90         /* rx buffers in rx descriptors */
91         void *rxbuf_base;       /* (GRETH_RXBUF_SIZE+ALIGNBYTES) * GRETH_RXBD_CNT */
92
93         /* unused for gbit_mac, temp buffer for sending packets with unligned
94          * start.
95          * Pointer to packet allocated with malloc.
96          */
97         void *txbuf;
98
99         struct {
100                 /* rx status */
101                 unsigned int rx_packets,
102                     rx_crc_errors, rx_frame_errors, rx_length_errors, rx_errors;
103
104                 /* tx stats */
105                 unsigned int tx_packets,
106                     tx_latecol_errors,
107                     tx_underrun_errors, tx_limit_errors, tx_errors;
108         } stats;
109 } greth_priv;
110
111 /* Read MII register 'addr' from core 'regs' */
112 static int read_mii(int phyaddr, int regaddr, volatile greth_regs * regs)
113 {
114         while (GRETH_REGLOAD(&regs->mdio) & GRETH_MII_BUSY) {
115         }
116
117         GRETH_REGSAVE(&regs->mdio, ((phyaddr & 0x1F) << 11) | ((regaddr & 0x1F) << 6) | 2);
118
119         while (GRETH_REGLOAD(&regs->mdio) & GRETH_MII_BUSY) {
120         }
121
122         if (!(GRETH_REGLOAD(&regs->mdio) & GRETH_MII_NVALID)) {
123                 return (GRETH_REGLOAD(&regs->mdio) >> 16) & 0xFFFF;
124         } else {
125                 return -1;
126         }
127 }
128
129 static void write_mii(int phyaddr, int regaddr, int data, volatile greth_regs * regs)
130 {
131         while (GRETH_REGLOAD(&regs->mdio) & GRETH_MII_BUSY) {
132         }
133
134         GRETH_REGSAVE(&regs->mdio,
135                       ((data & 0xFFFF) << 16) | ((phyaddr & 0x1F) << 11) |
136                       ((regaddr & 0x1F) << 6) | 1);
137
138         while (GRETH_REGLOAD(&regs->mdio) & GRETH_MII_BUSY) {
139         }
140
141 }
142
143 /* init/start hardware and allocate descriptor buffers for rx side
144  *
145  */
146 int greth_init(struct eth_device *dev, bd_t * bis)
147 {
148         int i;
149
150         greth_priv *greth = dev->priv;
151         greth_regs *regs = greth->regs;
152
153         debug("greth_init\n");
154
155         /* Reset core */
156         GRETH_REGSAVE(&regs->control, (GRETH_RESET | (greth->gb << 8) |
157                 (greth->sp << 7) | (greth->fd << 4)));
158
159         /* Wait for Reset to complete */
160         while ( GRETH_REGLOAD(&regs->control) & GRETH_RESET) ;
161
162         GRETH_REGSAVE(&regs->control,
163                 ((greth->gb << 8) | (greth->sp << 7) | (greth->fd << 4)));
164
165         if (!greth->rxbd_base) {
166
167                 /* allocate descriptors */
168                 greth->rxbd_base = (greth_bd *)
169                     memalign(0x1000, GRETH_RXBD_CNT * sizeof(greth_bd));
170                 greth->txbd_base = (greth_bd *)
171                     memalign(0x1000, GRETH_TXBD_CNT * sizeof(greth_bd));
172
173                 /* allocate buffers to all descriptors  */
174                 greth->rxbuf_base =
175                     malloc(GRETH_RXBUF_EFF_SIZE * GRETH_RXBD_CNT);
176         }
177
178         /* initate rx decriptors */
179         for (i = 0; i < GRETH_RXBD_CNT; i++) {
180                 greth->rxbd_base[i].addr = (unsigned int)
181                     greth->rxbuf_base + (GRETH_RXBUF_EFF_SIZE * i);
182                 /* enable desciptor & set wrap bit if last descriptor */
183                 if (i >= (GRETH_RXBD_CNT - 1)) {
184                         greth->rxbd_base[i].stat = GRETH_BD_EN | GRETH_BD_WR;
185                 } else {
186                         greth->rxbd_base[i].stat = GRETH_BD_EN;
187                 }
188         }
189
190         /* initiate indexes */
191         greth->rxbd_curr = greth->rxbd_base;
192         greth->rxbd_max = greth->rxbd_base + (GRETH_RXBD_CNT - 1);
193         greth->txbd_max = greth->txbd_base + (GRETH_TXBD_CNT - 1);
194         /*
195          * greth->txbd_base->addr = 0;
196          * greth->txbd_base->stat = GRETH_BD_WR;
197          */
198
199         /* initate tx decriptors */
200         for (i = 0; i < GRETH_TXBD_CNT; i++) {
201                 greth->txbd_base[i].addr = 0;
202                 /* enable desciptor & set wrap bit if last descriptor */
203                 if (i >= (GRETH_TXBD_CNT - 1)) {
204                         greth->txbd_base[i].stat = GRETH_BD_WR;
205                 } else {
206                         greth->txbd_base[i].stat = 0;
207                 }
208         }
209
210         /**** SET HARDWARE REGS ****/
211
212         /* Set pointer to tx/rx descriptor areas */
213         GRETH_REGSAVE(&regs->rx_desc_p, (unsigned int)&greth->rxbd_base[0]);
214         GRETH_REGSAVE(&regs->tx_desc_p, (unsigned int)&greth->txbd_base[0]);
215
216         /* Enable Transmitter, GRETH will now scan descriptors for packets
217          * to transmitt */
218         debug("greth_init: enabling receiver\n");
219         GRETH_REGORIN(&regs->control, GRETH_RXEN);
220
221         return 0;
222 }
223
224 /* Initiate PHY to a relevant speed
225  * return:
226  *  - 0 = success
227  *  - 1 = timeout/fail
228  */
229 int greth_init_phy(greth_priv * dev, bd_t * bis)
230 {
231         greth_regs *regs = dev->regs;
232         int tmp, tmp1, tmp2, i;
233         unsigned int start, timeout;
234         int phyaddr = GRETH_PHY_ADR_DEFAULT;
235
236 #ifndef CONFIG_SYS_GRLIB_GRETH_PHYADDR
237         /* If BSP doesn't provide a hardcoded PHY address the driver will
238          * try to autodetect PHY address by stopping the search on the first
239          * PHY address which has REG0 implemented.
240          */
241         for (i=0; i<32; i++) {
242                 tmp = read_mii(i, 0, regs);
243                 if ( (tmp != 0) && (tmp != 0xffff) ) {
244                         phyaddr = i;
245                         break;
246                 }
247         }
248 #endif
249
250         /* Save PHY Address */
251         dev->phyaddr = phyaddr;
252
253         debug("GRETH PHY ADDRESS: %d\n", phyaddr);
254
255         /* X msecs to ticks */
256         timeout = usec2ticks(GRETH_PHY_TIMEOUT_MS * 1000);
257
258         /* Get system timer0 current value
259          * Total timeout is 5s
260          */
261         start = get_timer(0);
262
263         /* get phy control register default values */
264
265         while ((tmp = read_mii(phyaddr, 0, regs)) & 0x8000) {
266                 if (get_timer(start) > timeout) {
267                         debug("greth_init_phy: PHY read 1 failed\n");
268                         return 1;       /* Fail */
269                 }
270         }
271
272         /* reset PHY and wait for completion */
273         write_mii(phyaddr, 0, 0x8000 | tmp, regs);
274
275         while (((tmp = read_mii(phyaddr, 0, regs))) & 0x8000) {
276                 if (get_timer(start) > timeout) {
277                         debug("greth_init_phy: PHY read 2 failed\n");
278                         return 1;       /* Fail */
279                 }
280         }
281
282         /* Check if PHY is autoneg capable and then determine operating
283          * mode, otherwise force it to 10 Mbit halfduplex
284          */
285         dev->gb = 0;
286         dev->fd = 0;
287         dev->sp = 0;
288         dev->auto_neg = 0;
289         if (!((tmp >> 12) & 1)) {
290                 write_mii(phyaddr, 0, 0, regs);
291         } else {
292                 /* wait for auto negotiation to complete and then check operating mode */
293                 dev->auto_neg = 1;
294                 i = 0;
295                 while (!(((tmp = read_mii(phyaddr, 1, regs)) >> 5) & 1)) {
296                         if (get_timer(start) > timeout) {
297                                 printf("Auto negotiation timed out. "
298                                        "Selecting default config\n");
299                                 tmp = read_mii(phyaddr, 0, regs);
300                                 dev->gb = ((tmp >> 6) & 1)
301                                     && !((tmp >> 13) & 1);
302                                 dev->sp = !((tmp >> 6) & 1)
303                                     && ((tmp >> 13) & 1);
304                                 dev->fd = (tmp >> 8) & 1;
305                                 goto auto_neg_done;
306                         }
307                 }
308                 if ((tmp >> 8) & 1) {
309                         tmp1 = read_mii(phyaddr, 9, regs);
310                         tmp2 = read_mii(phyaddr, 10, regs);
311                         if ((tmp1 & GRETH_MII_EXTADV_1000FD) &&
312                             (tmp2 & GRETH_MII_EXTPRT_1000FD)) {
313                                 dev->gb = 1;
314                                 dev->fd = 1;
315                         }
316                         if ((tmp1 & GRETH_MII_EXTADV_1000HD) &&
317                             (tmp2 & GRETH_MII_EXTPRT_1000HD)) {
318                                 dev->gb = 1;
319                                 dev->fd = 0;
320                         }
321                 }
322                 if ((dev->gb == 0) || ((dev->gb == 1) && (dev->gbit_mac == 0))) {
323                         tmp1 = read_mii(phyaddr, 4, regs);
324                         tmp2 = read_mii(phyaddr, 5, regs);
325                         if ((tmp1 & GRETH_MII_100TXFD) &&
326                             (tmp2 & GRETH_MII_100TXFD)) {
327                                 dev->sp = 1;
328                                 dev->fd = 1;
329                         }
330                         if ((tmp1 & GRETH_MII_100TXHD) &&
331                             (tmp2 & GRETH_MII_100TXHD)) {
332                                 dev->sp = 1;
333                                 dev->fd = 0;
334                         }
335                         if ((tmp1 & GRETH_MII_10FD) && (tmp2 & GRETH_MII_10FD)) {
336                                 dev->fd = 1;
337                         }
338                         if ((dev->gb == 1) && (dev->gbit_mac == 0)) {
339                                 dev->gb = 0;
340                                 dev->fd = 0;
341                                 write_mii(phyaddr, 0, dev->sp << 13, regs);
342                         }
343                 }
344
345         }
346       auto_neg_done:
347         debug("%s GRETH Ethermac at [0x%x] irq %d. Running \
348                 %d Mbps %s duplex\n", dev->gbit_mac ? "10/100/1000" : "10/100", (unsigned int)(regs), (unsigned int)(dev->irq), dev->gb ? 1000 : (dev->sp ? 100 : 10), dev->fd ? "full" : "half");
349         /* Read out PHY info if extended registers are available */
350         if (tmp & 1) {
351                 tmp1 = read_mii(phyaddr, 2, regs);
352                 tmp2 = read_mii(phyaddr, 3, regs);
353                 tmp1 = (tmp1 << 6) | ((tmp2 >> 10) & 0x3F);
354                 tmp = tmp2 & 0xF;
355
356                 tmp2 = (tmp2 >> 4) & 0x3F;
357                 debug("PHY: Vendor %x   Device %x    Revision %d\n", tmp1,
358                        tmp2, tmp);
359         } else {
360                 printf("PHY info not available\n");
361         }
362
363         /* set speed and duplex bits in control register */
364         GRETH_REGORIN(&regs->control,
365                       (dev->gb << 8) | (dev->sp << 7) | (dev->fd << 4));
366
367         return 0;
368 }
369
370 void greth_halt(struct eth_device *dev)
371 {
372         greth_priv *greth;
373         greth_regs *regs;
374         int i;
375
376         debug("greth_halt\n");
377
378         if (!dev || !dev->priv)
379                 return;
380
381         greth = dev->priv;
382         regs = greth->regs;
383
384         if (!regs)
385                 return;
386
387         /* disable receiver/transmitter by clearing the enable bits */
388         GRETH_REGANDIN(&regs->control, ~(GRETH_RXEN | GRETH_TXEN));
389
390         /* reset rx/tx descriptors */
391         if (greth->rxbd_base) {
392                 for (i = 0; i < GRETH_RXBD_CNT; i++) {
393                         greth->rxbd_base[i].stat =
394                             (i >= (GRETH_RXBD_CNT - 1)) ? GRETH_BD_WR : 0;
395                 }
396         }
397
398         if (greth->txbd_base) {
399                 for (i = 0; i < GRETH_TXBD_CNT; i++) {
400                         greth->txbd_base[i].stat =
401                             (i >= (GRETH_TXBD_CNT - 1)) ? GRETH_BD_WR : 0;
402                 }
403         }
404 }
405
406 int greth_send(struct eth_device *dev, void *eth_data, int data_length)
407 {
408         greth_priv *greth = dev->priv;
409         greth_regs *regs = greth->regs;
410         greth_bd *txbd;
411         void *txbuf;
412         unsigned int status;
413
414         debug("greth_send\n");
415
416         /* send data, wait for data to be sent, then return */
417         if (((unsigned int)eth_data & (GRETH_BUF_ALIGN - 1))
418             && !greth->gbit_mac) {
419                 /* data not aligned as needed by GRETH 10/100, solve this by allocating 4 byte aligned buffer
420                  * and copy data to before giving it to GRETH.
421                  */
422                 if (!greth->txbuf) {
423                         greth->txbuf = malloc(GRETH_RXBUF_SIZE);
424                 }
425
426                 txbuf = greth->txbuf;
427
428                 /* copy data info buffer */
429                 memcpy((char *)txbuf, (char *)eth_data, data_length);
430
431                 /* keep buffer to next time */
432         } else {
433                 txbuf = (void *)eth_data;
434         }
435         /* get descriptor to use, only 1 supported... hehe easy */
436         txbd = greth->txbd_base;
437
438         /* setup descriptor to wrap around to it self */
439         txbd->addr = (unsigned int)txbuf;
440         txbd->stat = GRETH_BD_EN | GRETH_BD_WR | data_length;
441
442         /* Remind Core which descriptor to use when sending */
443         GRETH_REGSAVE(&regs->tx_desc_p, (unsigned int)txbd);
444
445         /* initate send by enabling transmitter */
446         GRETH_REGORIN(&regs->control, GRETH_TXEN);
447
448         /* Wait for data to be sent */
449         while ((status = GRETH_REGLOAD(&txbd->stat)) & GRETH_BD_EN) {
450                 ;
451         }
452
453         /* was the packet transmitted succesfully? */
454         if (status & GRETH_TXBD_ERR_AL) {
455                 greth->stats.tx_limit_errors++;
456         }
457
458         if (status & GRETH_TXBD_ERR_UE) {
459                 greth->stats.tx_underrun_errors++;
460         }
461
462         if (status & GRETH_TXBD_ERR_LC) {
463                 greth->stats.tx_latecol_errors++;
464         }
465
466         if (status &
467             (GRETH_TXBD_ERR_LC | GRETH_TXBD_ERR_UE | GRETH_TXBD_ERR_AL)) {
468                 /* any error */
469                 greth->stats.tx_errors++;
470                 return -1;
471         }
472
473         /* bump tx packet counter */
474         greth->stats.tx_packets++;
475
476         /* return succefully */
477         return 0;
478 }
479
480 int greth_recv(struct eth_device *dev)
481 {
482         greth_priv *greth = dev->priv;
483         greth_regs *regs = greth->regs;
484         greth_bd *rxbd;
485         unsigned int status, len = 0, bad;
486         char *d;
487         int enable = 0;
488         int i;
489
490         /* Receive One packet only, but clear as many error packets as there are
491          * available.
492          */
493         {
494                 /* current receive descriptor */
495                 rxbd = greth->rxbd_curr;
496
497                 /* get status of next received packet */
498                 status = GRETH_REGLOAD(&rxbd->stat);
499
500                 bad = 0;
501
502                 /* stop if no more packets received */
503                 if (status & GRETH_BD_EN) {
504                         goto done;
505                 }
506
507                 debug("greth_recv: packet 0x%x, 0x%x, len: %d\n",
508                        (unsigned int)rxbd, status, status & GRETH_BD_LEN);
509
510                 /* Check status for errors.
511                  */
512                 if (status & GRETH_RXBD_ERR_FT) {
513                         greth->stats.rx_length_errors++;
514                         bad = 1;
515                 }
516                 if (status & (GRETH_RXBD_ERR_AE | GRETH_RXBD_ERR_OE)) {
517                         greth->stats.rx_frame_errors++;
518                         bad = 1;
519                 }
520                 if (status & GRETH_RXBD_ERR_CRC) {
521                         greth->stats.rx_crc_errors++;
522                         bad = 1;
523                 }
524                 if (bad) {
525                         greth->stats.rx_errors++;
526                         printf
527                             ("greth_recv: Bad packet (%d, %d, %d, 0x%08x, %d)\n",
528                              greth->stats.rx_length_errors,
529                              greth->stats.rx_frame_errors,
530                              greth->stats.rx_crc_errors, status,
531                              greth->stats.rx_packets);
532                         /* print all rx descriptors */
533                         for (i = 0; i < GRETH_RXBD_CNT; i++) {
534                                 printf("[%d]: Stat=0x%lx, Addr=0x%lx\n", i,
535                                        GRETH_REGLOAD(&greth->rxbd_base[i].stat),
536                                        GRETH_REGLOAD(&greth->rxbd_base[i].addr));
537                         }
538                 } else {
539                         /* Process the incoming packet. */
540                         len = status & GRETH_BD_LEN;
541                         d = (char *)rxbd->addr;
542
543                         debug
544                             ("greth_recv: new packet, length: %d. data: %x %x %x %x %x %x %x %x\n",
545                              len, d[0], d[1], d[2], d[3], d[4], d[5], d[6],
546                              d[7]);
547
548                         /* flush all data cache to make sure we're not reading old packet data */
549                         sparc_dcache_flush_all();
550
551                         /* pass packet on to network subsystem */
552                         NetReceive((void *)d, len);
553
554                         /* bump stats counters */
555                         greth->stats.rx_packets++;
556
557                         /* bad is now 0 ==> will stop loop */
558                 }
559
560                 /* reenable descriptor to receive more packet with this descriptor, wrap around if needed */
561                 rxbd->stat =
562                     GRETH_BD_EN |
563                     (((unsigned int)greth->rxbd_curr >=
564                       (unsigned int)greth->rxbd_max) ? GRETH_BD_WR : 0);
565                 enable = 1;
566
567                 /* increase index */
568                 greth->rxbd_curr =
569                     ((unsigned int)greth->rxbd_curr >=
570                      (unsigned int)greth->rxbd_max) ? greth->
571                     rxbd_base : (greth->rxbd_curr + 1);
572
573         }
574
575         if (enable) {
576                 GRETH_REGORIN(&regs->control, GRETH_RXEN);
577         }
578       done:
579         /* return positive length of packet or 0 if non received */
580         return len;
581 }
582
583 void greth_set_hwaddr(greth_priv * greth, unsigned char *mac)
584 {
585         /* save new MAC address */
586         greth->dev->enetaddr[0] = greth->hwaddr[0] = mac[0];
587         greth->dev->enetaddr[1] = greth->hwaddr[1] = mac[1];
588         greth->dev->enetaddr[2] = greth->hwaddr[2] = mac[2];
589         greth->dev->enetaddr[3] = greth->hwaddr[3] = mac[3];
590         greth->dev->enetaddr[4] = greth->hwaddr[4] = mac[4];
591         greth->dev->enetaddr[5] = greth->hwaddr[5] = mac[5];
592         greth->regs->esa_msb = (mac[0] << 8) | mac[1];
593         greth->regs->esa_lsb =
594             (mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5];
595
596         debug("GRETH: New MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
597                mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
598 }
599
600 int greth_initialize(bd_t * bis)
601 {
602         greth_priv *greth;
603         ambapp_apbdev apbdev;
604         struct eth_device *dev;
605         int i;
606         char *addr_str, *end;
607         unsigned char addr[6];
608
609         debug("Scanning for GRETH\n");
610
611         /* Find Device & IRQ via AMBA Plug&Play information */
612         if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_ETHMAC, &apbdev) != 1) {
613                 return -1;      /* GRETH not found */
614         }
615
616         greth = (greth_priv *) malloc(sizeof(greth_priv));
617         dev = (struct eth_device *)malloc(sizeof(struct eth_device));
618         memset(dev, 0, sizeof(struct eth_device));
619         memset(greth, 0, sizeof(greth_priv));
620
621         greth->regs = (greth_regs *) apbdev.address;
622         greth->irq = apbdev.irq;
623         debug("Found GRETH at %p, irq %d\n", greth->regs, greth->irq);
624         dev->priv = (void *)greth;
625         dev->iobase = (unsigned int)greth->regs;
626         dev->init = greth_init;
627         dev->halt = greth_halt;
628         dev->send = greth_send;
629         dev->recv = greth_recv;
630         greth->dev = dev;
631
632         /* Reset Core */
633         GRETH_REGSAVE(&greth->regs->control, GRETH_RESET);
634
635         /* Wait for core to finish reset cycle */
636         while (GRETH_REGLOAD(&greth->regs->control) & GRETH_RESET) ;
637
638         /* Get the phy address which assumed to have been set
639            correctly with the reset value in hardware */
640         greth->phyaddr = (GRETH_REGLOAD(&greth->regs->mdio) >> 11) & 0x1F;
641
642         /* Check if mac is gigabit capable */
643         greth->gbit_mac = (GRETH_REGLOAD(&greth->regs->control) >> 27) & 1;
644
645         /* Make descriptor string */
646         if (greth->gbit_mac) {
647                 sprintf(dev->name, "GRETH_10/100/GB");
648         } else {
649                 sprintf(dev->name, "GRETH_10/100");
650         }
651
652         /* initiate PHY, select speed/duplex depending on connected PHY */
653         if (greth_init_phy(greth, bis)) {
654                 /* Failed to init PHY (timedout) */
655                 debug("GRETH[%p]: Failed to init PHY\n", greth->regs);
656                 return -1;
657         }
658
659         /* Register Device to EtherNet subsystem  */
660         eth_register(dev);
661
662         /* Get MAC address */
663         if ((addr_str = getenv("ethaddr")) != NULL) {
664                 for (i = 0; i < 6; i++) {
665                         addr[i] =
666                             addr_str ? simple_strtoul(addr_str, &end, 16) : 0;
667                         if (addr_str) {
668                                 addr_str = (*end) ? end + 1 : end;
669                         }
670                 }
671         } else {
672                 /* HW Address not found in environment, Set default HW address */
673                 addr[0] = GRETH_HWADDR_0;       /* MSB */
674                 addr[1] = GRETH_HWADDR_1;
675                 addr[2] = GRETH_HWADDR_2;
676                 addr[3] = GRETH_HWADDR_3;
677                 addr[4] = GRETH_HWADDR_4;
678                 addr[5] = GRETH_HWADDR_5;       /* LSB */
679         }
680
681         /* set and remember MAC address */
682         greth_set_hwaddr(greth, addr);
683
684         debug("GRETH[%p]: Initialized successfully\n", greth->regs);
685         return 0;
686 }