]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
KM/IVM: split the IVM reading and parsing in 2 parts
authorValentin Longchamp <valentin.longchamp@keymile.com>
Tue, 10 Feb 2015 16:10:13 +0000 (17:10 +0100)
committerLothar Waßmann <LW@KARO-electronics.de>
Tue, 1 Sep 2015 11:52:21 +0000 (13:52 +0200)
This allows to first read the IVM content (earlier in the boot sequence)
and define the ethaddr env variable thanks to the ivm_read_eepromi().
Later, the IVM content can be parsed and used to define some hush
variables, when the hush subsystem is available thanks to
ivm_analyze_eeprom().

To avoid the HW read to happen twice, the buffer passed to
ivm_read_eeprom() has to be reused by ivm_analyze_eeprom (and thus
allocated before calling ivm_read_eeprom()).

Signed-off-by: Valentin Longchamp <valentin.longchamp@keymile.com>
board/keymile/common/common.h
board/keymile/common/ivm.c

index e075f4687bac7f01ce51dc2f31dd20ac55afdc28..7e16d2570b56cfb6e976fd0cd944369e12384010 100644 (file)
@@ -127,6 +127,8 @@ struct bfticu_iomap {
 
 int ethernet_present(void);
 int ivm_read_eeprom(void);
+int ivm_simple_read_eeprom(unsigned char *buf, int len);
+int ivm_analyze_eeprom(unsigned char *buf, int len);
 
 int trigger_fpga_config(void);
 int wait_for_fpga_config(void);
index b6b19ccb8ea1379b2e0fbed5b86df26e40aa1a1e..9abc09abc6be55b0874fb6f273ca6e9e50cb9812 100644 (file)
@@ -10,6 +10,8 @@
 #include <i2c.h>
 #include "common.h"
 
+#define MAC_STR_SZ     20
+
 static int ivm_calc_crc(unsigned char *buf, int len)
 {
        const unsigned short crc_tab[16] = {
@@ -185,45 +187,37 @@ static int ivm_check_crc(unsigned char *buf, int block)
        return 0;
 }
 
-static int calculate_mac_offset(unsigned char *valbuf, unsigned char *buf,
+/* take care of the possible MAC address offset and the IVM content offset */
+static int process_mac(unsigned char *valbuf, unsigned char *buf,
                                int offset)
 {
+       unsigned char mac[6];
        unsigned long val = (buf[4] << 16) + (buf[5] << 8) + buf[6];
 
-       if (offset == 0)
-               return 0;
+       /* use an intermediate buffer, to not change IVM content
+        * MAC address is at offset 1
+        */
+       memcpy(mac, buf+1, 6);
 
-       val += offset;
-       buf[4] = (val >> 16) & 0xff;
-       buf[5] = (val >> 8) & 0xff;
-       buf[6] = val & 0xff;
-       sprintf((char *)valbuf, "%pM", buf + 1);
+       if (offset) {
+               val += offset;
+               mac[3] = (val >> 16) & 0xff;
+               mac[4] = (val >> 8) & 0xff;
+               mac[5] = val & 0xff;
+       }
+
+       sprintf((char *)valbuf, "%pM", mac);
        return 0;
 }
 
 static int ivm_analyze_block2(unsigned char *buf, int len)
 {
-       unsigned char   valbuf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN];
+       unsigned char   valbuf[MAC_STR_SZ];
        unsigned long   count;
 
        /* IVM_MAC Adress begins at offset 1 */
        sprintf((char *)valbuf, "%pM", buf + 1);
        ivm_set_value("IVM_MacAddress", (char *)valbuf);
-       /* if an offset is defined, add it */
-       calculate_mac_offset(buf, valbuf, CONFIG_PIGGY_MAC_ADRESS_OFFSET);
-#ifdef MACH_TYPE_KM_KIRKWOOD
-       setenv((char *)"ethaddr", (char *)valbuf);
-#else
-       if (getenv("ethaddr") == NULL)
-               setenv((char *)"ethaddr", (char *)valbuf);
-#endif
-#ifdef CONFIG_KMVECT1
-/* KMVECT1 has two ethernet interfaces */
-       if (getenv("eth1addr") == NULL) {
-               calculate_mac_offset(buf, valbuf, 1);
-               setenv((char *)"eth1addr", (char *)valbuf);
-       }
-#endif
        /* IVM_MacCount */
        count = (buf[10] << 24) +
                   (buf[11] << 16) +
@@ -236,7 +230,7 @@ static int ivm_analyze_block2(unsigned char *buf, int len)
        return 0;
 }
 
-static int ivm_analyze_eeprom(unsigned char *buf, int len)
+int ivm_analyze_eeprom(unsigned char *buf, int len)
 {
        unsigned short  val;
        unsigned char   valbuf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN];
@@ -296,6 +290,48 @@ static int ivm_analyze_eeprom(unsigned char *buf, int len)
        return 0;
 }
 
+static int ivm_populate_env(unsigned char *buf, int len)
+{
+       unsigned char   *page2;
+       unsigned char   valbuf[MAC_STR_SZ];
+
+       /* do we have the page 2 filled ? if not return */
+       if (ivm_check_crc(buf, 2))
+               return 0;
+       page2 = &buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN*2];
+
+       /* if an offset is defined, add it */
+       process_mac(valbuf, page2, CONFIG_PIGGY_MAC_ADRESS_OFFSET);
+       if (getenv("ethaddr") == NULL)
+               setenv((char *)"ethaddr", (char *)valbuf);
+#ifdef CONFIG_KMVECT1
+/* KMVECT1 has two ethernet interfaces */
+       if (getenv("eth1addr") == NULL) {
+               process_mac(valbuf, page2, 1);
+               setenv((char *)"eth1addr", (char *)valbuf);
+       }
+#endif
+
+       return 0;
+}
+
+int ivm_simple_read_eeprom(unsigned char *buf, int len)
+{
+       int ret;
+
+       i2c_set_bus_num(CONFIG_KM_IVM_BUS);
+       /* add deblocking here */
+       i2c_make_abort();
+
+       ret = i2c_read(CONFIG_SYS_IVM_EEPROM_ADR, 0, 1, buf, len);
+       if (ret != 0) {
+               printf("Error reading EEprom\n");
+               return -2;
+       }
+
+       return ivm_populate_env(buf, len);
+}
+
 int ivm_read_eeprom(void)
 {
        uchar i2c_buffer[CONFIG_SYS_IVM_EEPROM_MAX_LEN];