km/common: remove hdlc_enet implementation
[pandora-u-boot.git] / board / keymile / common / common.c
1 /*
2  * (C) Copyright 2008
3  * Heiko Schocher, DENX Software Engineering, hs@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 #if defined(CONFIG_MGCOGE) || defined(CONFIG_MGCOGE2NE)
26 #include <mpc8260.h>
27 #endif
28 #include <ioports.h>
29 #include <malloc.h>
30 #include <hush.h>
31 #include <net.h>
32 #include <netdev.h>
33 #include <asm/io.h>
34
35 #if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT)
36 #include <libfdt.h>
37 #endif
38
39 #include "../common/common.h"
40 #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
41 #include <i2c.h>
42
43 static void i2c_write_start_seq(void);
44 static int i2c_make_abort(void);
45 DECLARE_GLOBAL_DATA_PTR;
46
47 int ivm_calc_crc(unsigned char *buf, int len)
48 {
49         const unsigned short crc_tab[16] = {
50                 0x0000, 0xCC01, 0xD801, 0x1400,
51                 0xF001, 0x3C00, 0x2800, 0xE401,
52                 0xA001, 0x6C00, 0x7800, 0xB401,
53                 0x5000, 0x9C01, 0x8801, 0x4400};
54
55         unsigned short crc     = 0;   /* final result */
56         unsigned short r1      = 0;   /* temp */
57         unsigned char  byte    = 0;   /* input buffer */
58         int     i;
59
60         /* calculate CRC from array data */
61         for (i = 0; i < len; i++) {
62                 byte = buf[i];
63
64                 /* lower 4 bits */
65                 r1 = crc_tab[crc & 0xF];
66                 crc = ((crc) >> 4) & 0x0FFF;
67                 crc = crc ^ r1 ^ crc_tab[byte & 0xF];
68
69                 /* upper 4 bits */
70                 r1 = crc_tab[crc & 0xF];
71                 crc = (crc >> 4) & 0x0FFF;
72                 crc = crc ^ r1 ^ crc_tab[(byte >> 4) & 0xF];
73         }
74         return crc;
75 }
76
77 /*
78  * Set Keymile specific environment variables
79  * Currently only some memory layout variables are calculated here
80  * ... ------------------------------------------------
81  * ... |@rootfsaddr |@pnvramaddr |@varaddr |@reserved |@END_OF_RAM
82  * ... |<------------------- pram ------------------->|
83  * ... ------------------------------------------------
84  * @END_OF_RAM: denotes the RAM size
85  * @pnvramaddr: Startadress of pseudo non volatile RAM in hex
86  * @pram      : preserved ram size in k
87  * @varaddr   : startadress for /var mounted into RAM
88  */
89 int set_km_env(void)
90 {
91         uchar buf[32];
92         unsigned int pnvramaddr;
93         unsigned int pram;
94         unsigned int varaddr;
95
96         pnvramaddr = gd->ram_size - CONFIG_KM_RESERVED_PRAM - CONFIG_KM_PHRAM
97                         - CONFIG_KM_PNVRAM;
98         sprintf((char *)buf, "0x%x", pnvramaddr);
99         setenv("pnvramaddr", (char *)buf);
100
101         pram = (CONFIG_KM_RESERVED_PRAM + CONFIG_KM_PHRAM + CONFIG_KM_PNVRAM) /
102                 0x400;
103         sprintf((char *)buf, "0x%x", pram);
104         setenv("pram", (char *)buf);
105
106         varaddr = gd->ram_size - CONFIG_KM_RESERVED_PRAM - CONFIG_KM_PHRAM;
107         sprintf((char *)buf, "0x%x", varaddr);
108         setenv("varaddr", (char *)buf);
109         return 0;
110 }
111
112 static int ivm_set_value(char *name, char *value)
113 {
114         char tempbuf[256];
115
116         if (value != NULL) {
117                 sprintf(tempbuf, "%s=%s", name, value);
118                 return set_local_var(tempbuf, 0);
119         } else {
120                 unset_local_var(name);
121         }
122         return 0;
123 }
124
125 static int ivm_get_value(unsigned char *buf, int len, char *name, int off,
126                                 int check)
127 {
128         unsigned short  val;
129         unsigned char   valbuf[30];
130
131         if ((buf[off + 0] != buf[off + 2]) &&
132             (buf[off + 2] != buf[off + 4])) {
133                 printf("%s Error corrupted %s\n", __func__, name);
134                 val = -1;
135         } else {
136                 val = buf[off + 0] + (buf[off + 1] << 8);
137                 if ((val == 0) && (check == 1))
138                         val = -1;
139         }
140         sprintf((char *)valbuf, "%x", val);
141         ivm_set_value(name, (char *)valbuf);
142         return val;
143 }
144
145 #define INV_BLOCKSIZE           0x100
146 #define INV_DATAADDRESS         0x21
147 #define INVENTORYDATASIZE       (INV_BLOCKSIZE - INV_DATAADDRESS - 3)
148
149 #define IVM_POS_SHORT_TEXT              0
150 #define IVM_POS_MANU_ID                 1
151 #define IVM_POS_MANU_SERIAL             2
152 #define IVM_POS_PART_NUMBER             3
153 #define IVM_POS_BUILD_STATE             4
154 #define IVM_POS_SUPPLIER_PART_NUMBER    5
155 #define IVM_POS_DELIVERY_DATE           6
156 #define IVM_POS_SUPPLIER_BUILD_STATE    7
157 #define IVM_POS_CUSTOMER_ID             8
158 #define IVM_POS_CUSTOMER_PROD_ID        9
159 #define IVM_POS_HISTORY                 10
160 #define IVM_POS_SYMBOL_ONLY             11
161
162 static char convert_char(char c)
163 {
164         return (c < ' ' || c > '~') ? '.' : c;
165 }
166
167 static int ivm_findinventorystring(int type,
168                                         unsigned char* const string,
169                                         unsigned long maxlen,
170                                         unsigned char *buf)
171 {
172         int xcode = 0;
173         unsigned long cr = 0;
174         unsigned long addr = INV_DATAADDRESS;
175         unsigned long size = 0;
176         unsigned long nr = type;
177         int stop = 0;   /* stop on semicolon */
178
179         memset(string, '\0', maxlen);
180         switch (type) {
181                 case IVM_POS_SYMBOL_ONLY:
182                         nr = 0;
183                         stop= 1;
184                 break;
185                 default:
186                         nr = type;
187                         stop = 0;
188         }
189
190         /* Look for the requested number of CR. */
191         while ((cr != nr) && (addr < INVENTORYDATASIZE)) {
192                 if ((buf[addr] == '\r')) {
193                         cr++;
194                 }
195                 addr++;
196         }
197
198         /*
199          * the expected number of CR was found until the end of the IVM
200          *  content --> fill string
201          */
202         if (addr < INVENTORYDATASIZE) {
203                 /* Copy the IVM string in the corresponding string */
204                 for (; (buf[addr] != '\r')                      &&
205                         ((buf[addr] != ';') ||  (!stop))        &&
206                         (size < (maxlen - 1)                    &&
207                         (addr < INVENTORYDATASIZE)); addr++)
208                 {
209                         size += sprintf((char *)string + size, "%c",
210                                                 convert_char (buf[addr]));
211                 }
212
213                 /*
214                  * copy phase is done: check if everything is ok. If not,
215                  * the inventory data is most probably corrupted: tell
216                  * the world there is a problem!
217                  */
218                 if (addr == INVENTORYDATASIZE) {
219                         xcode = -1;
220                         printf("Error end of string not found\n");
221                 } else if ((size >= (maxlen - 1)) &&
222                            (buf[addr] != '\r')) {
223                         xcode = -1;
224                         printf("string too long till next CR\n");
225                 }
226         } else {
227                 /*
228                  * some CR are missing...
229                  * the inventory data is most probably corrupted
230                  */
231                 xcode = -1;
232                 printf("not enough cr found\n");
233         }
234         return xcode;
235 }
236
237 #define GET_STRING(name, which, len) \
238         if (ivm_findinventorystring(which, valbuf, len, buf) == 0) { \
239                 ivm_set_value(name, (char *)valbuf); \
240         }
241
242 static int ivm_check_crc(unsigned char *buf, int block)
243 {
244         unsigned long   crc;
245         unsigned long   crceeprom;
246
247         crc = ivm_calc_crc(buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN - 2);
248         crceeprom = (buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN - 1] + \
249                         buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN - 2] * 256);
250         if (crc != crceeprom) {
251                 if (block == 0)
252                         printf("Error CRC Block: %d EEprom: calculated: \
253                         %lx EEprom: %lx\n", block, crc, crceeprom);
254                 return -1;
255         }
256         return 0;
257 }
258
259 static int ivm_analyze_block2(unsigned char *buf, int len)
260 {
261         unsigned char   valbuf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN];
262         unsigned long   count;
263
264         /* IVM_MacAddress */
265         sprintf((char *)valbuf, "%pM", buf);
266         ivm_set_value("IVM_MacAddress", (char *)valbuf);
267         /* if an offset is defined, add it */
268 #if defined(CONFIG_PIGGY_MAC_ADRESS_OFFSET)
269         if (CONFIG_PIGGY_MAC_ADRESS_OFFSET > 0) {
270                 unsigned long val = (buf[4] << 16) + (buf[5] << 8) + buf[6];
271
272                 val += CONFIG_PIGGY_MAC_ADRESS_OFFSET;
273                 buf[4] = (val >> 16) & 0xff;
274                 buf[5] = (val >> 8) & 0xff;
275                 buf[6] = val & 0xff;
276                 sprintf((char *)valbuf, "%pM", buf);
277         }
278 #endif
279         if (getenv("ethaddr") == NULL)
280                 setenv((char *)"ethaddr", (char *)valbuf);
281
282         /* IVM_MacCount */
283         count = (buf[10] << 24) +
284                    (buf[11] << 16) +
285                    (buf[12] << 8)  +
286                     buf[13];
287         if (count == 0xffffffff)
288                 count = 1;
289         sprintf((char *)valbuf, "%lx", count);
290         ivm_set_value("IVM_MacCount", (char *)valbuf);
291         return 0;
292 }
293
294 int ivm_analyze_eeprom(unsigned char *buf, int len)
295 {
296         unsigned short  val;
297         unsigned char   valbuf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN];
298         unsigned char   *tmp;
299
300         if (ivm_check_crc(buf, 0) != 0)
301                 return -1;
302
303         ivm_get_value(buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN,
304                         "IVM_BoardId", 0, 1);
305         val = ivm_get_value(buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN,
306                         "IVM_HWKey", 6, 1);
307         if (val != 0xffff) {
308                 sprintf((char *)valbuf, "%x", ((val / 100) % 10));
309                 ivm_set_value("IVM_HWVariant", (char *)valbuf);
310                 sprintf((char *)valbuf, "%x", (val % 100));
311                 ivm_set_value("IVM_HWVersion", (char *)valbuf);
312         }
313         ivm_get_value(buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN,
314                 "IVM_Functions", 12, 0);
315
316         GET_STRING("IVM_Symbol", IVM_POS_SYMBOL_ONLY, 8)
317         GET_STRING("IVM_DeviceName", IVM_POS_SHORT_TEXT, 64)
318         tmp = (unsigned char *) getenv("IVM_DeviceName");
319         if (tmp) {
320                 int     len = strlen((char *)tmp);
321                 int     i = 0;
322
323                 while (i < len) {
324                         if (tmp[i] == ';') {
325                                 ivm_set_value("IVM_ShortText",
326                                         (char *)&tmp[i + 1]);
327                                 break;
328                         }
329                         i++;
330                 }
331                 if (i >= len)
332                         ivm_set_value("IVM_ShortText", NULL);
333         } else {
334                 ivm_set_value("IVM_ShortText", NULL);
335         }
336         GET_STRING("IVM_ManufacturerID", IVM_POS_MANU_ID, 32)
337         GET_STRING("IVM_ManufacturerSerialNumber", IVM_POS_MANU_SERIAL, 20)
338         GET_STRING("IVM_ManufacturerPartNumber", IVM_POS_PART_NUMBER, 32)
339         GET_STRING("IVM_ManufacturerBuildState", IVM_POS_BUILD_STATE, 32)
340         GET_STRING("IVM_SupplierPartNumber", IVM_POS_SUPPLIER_PART_NUMBER, 32)
341         GET_STRING("IVM_DelieveryDate", IVM_POS_DELIVERY_DATE, 32)
342         GET_STRING("IVM_SupplierBuildState", IVM_POS_SUPPLIER_BUILD_STATE, 32)
343         GET_STRING("IVM_CustomerID", IVM_POS_CUSTOMER_ID, 32)
344         GET_STRING("IVM_CustomerProductID", IVM_POS_CUSTOMER_PROD_ID, 32)
345
346         if (ivm_check_crc(&buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN * 2], 2) != 0)
347                 return 0;
348         ivm_analyze_block2(&buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN * 2],
349                 CONFIG_SYS_IVM_EEPROM_PAGE_LEN);
350
351         return 0;
352 }
353
354 int ivm_read_eeprom(void)
355 {
356 #if defined(CONFIG_I2C_MUX)
357         I2C_MUX_DEVICE *dev = NULL;
358 #endif
359         uchar i2c_buffer[CONFIG_SYS_IVM_EEPROM_MAX_LEN];
360         uchar   *buf;
361         unsigned dev_addr = CONFIG_SYS_IVM_EEPROM_ADR;
362         int ret;
363
364 #if defined(CONFIG_I2C_MUX)
365         /* First init the Bus, select the Bus */
366 #if defined(CONFIG_SYS_I2C_IVM_BUS)
367         dev = i2c_mux_ident_muxstring((uchar *)CONFIG_SYS_I2C_IVM_BUS);
368 #else
369         buf = (unsigned char *) getenv("EEprom_ivm");
370         if (buf != NULL)
371                 dev = i2c_mux_ident_muxstring(buf);
372 #endif
373         if (dev == NULL) {
374                 printf("Error couldnt add Bus for IVM\n");
375                 return -1;
376         }
377         i2c_set_bus_num(dev->busid);
378 #endif
379
380         buf = (unsigned char *) getenv("EEprom_ivm_addr");
381         if (buf != NULL)
382                 dev_addr = simple_strtoul((char *)buf, NULL, 16);
383
384         /* add deblocking here */
385         i2c_make_abort();
386
387         ret = i2c_read(dev_addr, 0, 1, i2c_buffer,
388                 CONFIG_SYS_IVM_EEPROM_MAX_LEN);
389         if (ret != 0) {
390                 printf ("Error reading EEprom\n");
391                 return -2;
392         }
393
394         return ivm_analyze_eeprom(i2c_buffer, CONFIG_SYS_IVM_EEPROM_MAX_LEN);
395 }
396
397 #if defined(CONFIG_SYS_I2C_INIT_BOARD)
398 #define DELAY_ABORT_SEQ         62  /* @200kHz 9 clocks = 44us, 62us is ok */
399 #define DELAY_HALF_PERIOD       (500 / (CONFIG_SYS_I2C_SPEED / 1000))
400
401 #if defined(CONFIG_MGCOGE) || defined(CONFIG_MGCOGE2NE)
402 #define SDA_MASK        0x00010000
403 #define SCL_MASK        0x00020000
404 static void set_pin(int state, unsigned long mask)
405 {
406         ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, 3);
407
408         if (state)
409                 setbits_be32(&iop->pdat, mask);
410         else
411                 clrbits_be32(&iop->pdat, mask);
412
413         setbits_be32(&iop->pdir, mask);
414 }
415
416 static int get_pin(unsigned long mask)
417 {
418         ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, 3);
419
420         clrbits_be32(&iop->pdir, mask);
421         return 0 != (in_be32(&iop->pdat) & mask);
422 }
423
424 static void set_sda(int state)
425 {
426         set_pin(state, SDA_MASK);
427 }
428
429 static void set_scl(int state)
430 {
431         set_pin(state, SCL_MASK);
432 }
433
434 static int get_sda(void)
435 {
436         return get_pin(SDA_MASK);
437 }
438
439 static int get_scl(void)
440 {
441         return get_pin(SCL_MASK);
442 }
443
444 #if defined(CONFIG_HARD_I2C)
445 static void setports(int gpio)
446 {
447         ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, 3);
448
449         if (gpio) {
450                 clrbits_be32(&iop->ppar, (SDA_MASK | SCL_MASK));
451                 clrbits_be32(&iop->podr, (SDA_MASK | SCL_MASK));
452         } else {
453                 setbits_be32(&iop->ppar, (SDA_MASK | SCL_MASK));
454                 clrbits_be32(&iop->pdir, (SDA_MASK | SCL_MASK));
455                 setbits_be32(&iop->podr, (SDA_MASK | SCL_MASK));
456         }
457 }
458 #endif
459 #endif
460
461 #if !defined(CONFIG_MPC83xx)
462 static void i2c_write_start_seq(void)
463 {
464         set_sda(1);
465         udelay(DELAY_HALF_PERIOD);
466         set_scl(1);
467         udelay(DELAY_HALF_PERIOD);
468         set_sda(0);
469         udelay(DELAY_HALF_PERIOD);
470         set_scl(0);
471         udelay(DELAY_HALF_PERIOD);
472 }
473
474 /*
475  * I2C is a synchronous protocol and resets of the processor in the middle
476  * of an access can block the I2C Bus until a powerdown of the full unit is
477  * done. This function toggles the SCL until the SCL and SCA line are
478  * released, but max. 16 times, after this a I2C start-sequence is sent.
479  * This I2C Deblocking mechanism was developed by Keymile in association
480  * with Anatech and Atmel in 1998.
481  */
482 static int i2c_make_abort(void)
483 {
484
485 #if defined(CONFIG_HARD_I2C) && !defined(MACH_TYPE_KM_KIRKWOOD)
486         immap_t *immap = (immap_t *)CONFIG_SYS_IMMR ;
487         i2c8260_t *i2c  = (i2c8260_t *)&immap->im_i2c;
488
489         /*
490          * disable I2C controller first, otherwhise it thinks we want to
491          * talk to the slave port...
492          */
493         clrbits_8(&i2c->i2c_i2mod, 0x01);
494
495         /* Set the PortPins to GPIO */
496         setports(1);
497 #endif
498
499         int     scl_state = 0;
500         int     sda_state = 0;
501         int     i = 0;
502         int     ret = 0;
503
504         if (!get_sda()) {
505                 ret = -1;
506                 while (i < 16) {
507                         i++;
508                         set_scl(0);
509                         udelay(DELAY_ABORT_SEQ);
510                         set_scl(1);
511                         udelay(DELAY_ABORT_SEQ);
512                         scl_state = get_scl();
513                         sda_state = get_sda();
514                         if (scl_state && sda_state) {
515                                 ret = 0;
516                                 break;
517                         }
518                 }
519         }
520         if (ret == 0)
521                 for (i = 0; i < 5; i++)
522                         i2c_write_start_seq();
523
524         /* respect stop setup time */
525         udelay(DELAY_ABORT_SEQ);
526         set_scl(1);
527         udelay(DELAY_ABORT_SEQ);
528         set_sda(1);
529         get_sda();
530
531 #if defined(CONFIG_HARD_I2C)
532         /* Set the PortPins back to use for I2C */
533         setports(0);
534 #endif
535         return ret;
536 }
537 #endif
538
539 #if defined(CONFIG_MPC83xx)
540 static void i2c_write_start_seq(void)
541 {
542         struct fsl_i2c *dev;
543         dev = (struct fsl_i2c *) (CONFIG_SYS_IMMR + CONFIG_SYS_I2C_OFFSET);
544         udelay(DELAY_ABORT_SEQ);
545         out_8(&dev->cr, (I2C_CR_MEN | I2C_CR_MSTA));
546         udelay(DELAY_ABORT_SEQ);
547         out_8(&dev->cr, (I2C_CR_MEN));
548 }
549
550 static int i2c_make_abort(void)
551 {
552         struct fsl_i2c *dev;
553         dev = (struct fsl_i2c *) (CONFIG_SYS_IMMR + CONFIG_SYS_I2C_OFFSET);
554         uchar   dummy;
555         uchar   last;
556         int     nbr_read = 0;
557         int     i = 0;
558         int         ret = 0;
559
560         /* wait after each operation to finsh with a delay */
561         out_8(&dev->cr, (I2C_CR_MSTA));
562         udelay(DELAY_ABORT_SEQ);
563         out_8(&dev->cr, (I2C_CR_MEN | I2C_CR_MSTA));
564         udelay(DELAY_ABORT_SEQ);
565         dummy = in_8(&dev->dr);
566         udelay(DELAY_ABORT_SEQ);
567         last = in_8(&dev->dr);
568         nbr_read++;
569
570         /*
571          * do read until the last bit is 1, but stop if the full eeprom is
572          * read.
573          */
574         while (((last & 0x01) != 0x01) &&
575                 (nbr_read < CONFIG_SYS_IVM_EEPROM_MAX_LEN)) {
576                 udelay(DELAY_ABORT_SEQ);
577                 last = in_8(&dev->dr);
578                 nbr_read++;
579         }
580         if ((last & 0x01) != 0x01)
581                 ret = -2;
582         if ((last != 0xff) || (nbr_read > 1))
583                 printf("[INFO] i2c abort after %d bytes (0x%02x)\n",
584                         nbr_read, last);
585         udelay(DELAY_ABORT_SEQ);
586         out_8(&dev->cr, (I2C_CR_MEN));
587         udelay(DELAY_ABORT_SEQ);
588         /* clear status reg */
589         out_8(&dev->sr, 0);
590
591         for (i = 0; i < 5; i++)
592                 i2c_write_start_seq();
593         if (ret != 0)
594                 printf("[ERROR] i2c abort failed after %d bytes (0x%02x)\n",
595                         nbr_read, last);
596
597         return ret;
598 }
599 #endif
600
601 /**
602  * i2c_init_board - reset i2c bus. When the board is powercycled during a
603  * bus transfer it might hang; for details see doc/I2C_Edge_Conditions.
604  */
605 void i2c_init_board(void)
606 {
607         /* Now run the AbortSequence() */
608         i2c_make_abort();
609 }
610 #endif
611 #endif
612
613 #if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT)
614 int fdt_set_node_and_value(void *blob,
615                                 char *nodename,
616                                 char *regname,
617                                 void *var,
618                                 int size)
619 {
620         int ret = 0;
621         int nodeoffset = 0;
622
623         nodeoffset = fdt_path_offset(blob, nodename);
624         if (nodeoffset >= 0) {
625                 ret = fdt_setprop(blob, nodeoffset, regname, var,
626                                         size);
627                 if (ret < 0)
628                         printf("ft_blob_update(): cannot set %s/%s "
629                                 "property err:%s\n", nodename, regname,
630                                 fdt_strerror(ret));
631         } else {
632                 printf("ft_blob_update(): cannot find %s node "
633                         "err:%s\n", nodename, fdt_strerror(nodeoffset));
634         }
635         return ret;
636 }
637
638 int fdt_get_node_and_value(void *blob,
639                                 char *nodename,
640                                 char *propname,
641                                 void **var)
642 {
643         int len;
644         int nodeoffset = 0;
645
646         nodeoffset = fdt_path_offset(blob, nodename);
647         if (nodeoffset >= 0) {
648                 *var = (void *)fdt_getprop(blob, nodeoffset, propname, &len);
649                 if (len == 0) {
650                         /* no value */
651                         printf("%s no value\n", __func__);
652                         return -1;
653                 } else if (len > 0) {
654                         return len;
655                 } else {
656                         printf("libfdt fdt_getprop(): %s\n",
657                                 fdt_strerror(len));
658                         return -2;
659                 }
660         } else {
661                 printf("%s: cannot find %s node err:%s\n", __func__,
662                         nodename, fdt_strerror(nodeoffset));
663                 return -3;
664         }
665 }
666 #endif
667
668 #if !defined(MACH_TYPE_KM_KIRKWOOD)
669 int ethernet_present(void)
670 {
671         struct km_bec_fpga *base =
672                 (struct km_bec_fpga *)CONFIG_SYS_KMBEC_FPGA_BASE;
673
674         return in_8(&base->bprth) & PIGGY_PRESENT;
675 }
676 #endif
677
678 int board_eth_init(bd_t *bis)
679 {
680         if (ethernet_present())
681                 return cpu_eth_init(bis);
682
683         return -1;
684 }