[U-Boot] [PATCH v2 0/6] keymile: enhance IVM reading

All Keymile boards have an EEPROM that is called IVM that contain information about the board that is progammed at production time. One piece of information is the MAC addresses assigned to the board.
u-boot requires the MAC address of the ethernet interfaces it uses to be defined when the interface is intialized. This is most of the time read from the environment but in the case where only the default environment is available, this must be read from somewhere else, in our case the IVM.
This patch series splits the reading and analysis of the IVM content in 2, so that the IVM content and MAC addresses can be read prior to ethernet initialization. The analysis of the rest of the IVM content still happens at a later second stage.
Changes in v2: - Include the first patch, which was forgotten in the first submission
Valentin Longchamp (6): KM/IVM: split the IVM reading and parsing in 2 parts kirkwood/km_arm: read the IVM eeprom earlier 85xx/kmp204x: read the IVM eeprom earlier 83xx/km83xx: read the IVM eeprom earlier 82xx/km82xx: read the IVM eeprom earlier KM/IVM: remove ivm_read_eeprom(void)
board/keymile/common/common.h | 3 +- board/keymile/common/ivm.c | 77 +++++++++++++++++++++++++---------------- board/keymile/km82xx/km82xx.c | 10 +++++- board/keymile/km83xx/km83xx.c | 5 ++- board/keymile/km_arm/km_arm.c | 6 +++- board/keymile/kmp204x/kmp204x.c | 5 ++- include/configs/km82xx.h | 2 ++ 7 files changed, 73 insertions(+), 35 deletions(-)

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
---
Changes in v2: - Include the first patch, which was forgotten in the first submission
board/keymile/common/common.h | 2 + board/keymile/common/ivm.c | 88 ++++++++++++++++++++++++++++++------------- 2 files changed, 64 insertions(+), 26 deletions(-)
diff --git a/board/keymile/common/common.h b/board/keymile/common/common.h index e075f46..7e16d25 100644 --- a/board/keymile/common/common.h +++ b/board/keymile/common/common.h @@ -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); diff --git a/board/keymile/common/ivm.c b/board/keymile/common/ivm.c index b6b19cc..4cb0b9a 100644 --- a/board/keymile/common/ivm.c +++ b/board/keymile/common/ivm.c @@ -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]; @@ -305,7 +341,7 @@ int ivm_read_eeprom(void) /* add deblocking here */ i2c_make_abort();
- ret = i2c_read(CONFIG_SYS_IVM_EEPROM_ADR, 0, 1, i2c_buffer, + ret = i2c_read(CONFIG_SYS_IVM_EEPROM_ADR, 0, 1, i2c_bufer, CONFIG_SYS_IVM_EEPROM_MAX_LEN); if (ret != 0) { printf("Error reading EEprom\n");

This allows to define the ethaddr env variable according to the the IVM content by reading the IVM in misc_init_r.
Later, when HUSH is available the content read earlier is analyzed to populate some non env variables.
Signed-off-by: Valentin Longchamp valentin.longchamp@keymile.com ---
Changes in v2: None
board/keymile/km_arm/km_arm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/board/keymile/km_arm/km_arm.c b/board/keymile/km_arm/km_arm.c index 1c7c108..6eb6712 100644 --- a/board/keymile/km_arm/km_arm.c +++ b/board/keymile/km_arm/km_arm.c @@ -102,6 +102,8 @@ static const u32 kwmpp_config[] = { 0 };
+static uchar ivm_content[CONFIG_SYS_IVM_EEPROM_MAX_LEN]; + #if defined(CONFIG_KM_MGCOGE3UN) /* * Wait for startup OK from mgcoge3ne @@ -210,6 +212,8 @@ int misc_init_r(void) } #endif
+ ivm_simple_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); + initialize_unit_leds(); set_km_env(); set_bootcount_addr(); @@ -419,7 +423,7 @@ void reset_phy(void) #if defined(CONFIG_HUSH_INIT_VAR) int hush_init_var(void) { - ivm_read_eeprom(); + ivm_analyze_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); return 0; } #endif

This allows to define the ethaddr env variable according to the the IVM content by reading the IVM in misc_init_r.
Later, when HUSH is available the content read earlier is analyzed to populate some non env variables.
Signed-off-by: Valentin Longchamp valentin.longchamp@keymile.com ---
Changes in v2: None
board/keymile/kmp204x/kmp204x.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/board/keymile/kmp204x/kmp204x.c b/board/keymile/kmp204x/kmp204x.c index a74f75b..0f544fb 100644 --- a/board/keymile/kmp204x/kmp204x.c +++ b/board/keymile/kmp204x/kmp204x.c @@ -26,6 +26,8 @@
DECLARE_GLOBAL_DATA_PTR;
+static uchar ivm_content[CONFIG_SYS_IVM_EEPROM_MAX_LEN]; + int checkboard(void) { printf("Board: Keymile %s\n", CONFIG_KM_BOARD_NAME); @@ -195,13 +197,14 @@ int misc_init_r(void) } }
+ ivm_simple_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); return 0; }
#if defined(CONFIG_HUSH_INIT_VAR) int hush_init_var(void) { - ivm_read_eeprom(); + ivm_analyze_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); return 0; } #endif

This allows to define the ethaddr env variable according to the the IVM content by reading the IVM in misc_init_r.
Later, when HUSH is available the content read earlier is analyzed to populate some non env variables.
Signed-off-by: Valentin Longchamp valentin.longchamp@keymile.com ---
Changes in v2: None
board/keymile/km83xx/km83xx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/board/keymile/km83xx/km83xx.c b/board/keymile/km83xx/km83xx.c index 1da0dcb..fc68a2f 100644 --- a/board/keymile/km83xx/km83xx.c +++ b/board/keymile/km83xx/km83xx.c @@ -28,6 +28,8 @@
#include "../common/common.h"
+static uchar ivm_content[CONFIG_SYS_IVM_EEPROM_MAX_LEN]; + const qe_iop_conf_t qe_iop_conf_tab[] = { /* port pin dir open_drain assign */ #if defined(CONFIG_MPC8360) @@ -190,6 +192,7 @@ int board_early_init_r(void)
int misc_init_r(void) { + ivm_simple_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); return 0; }
@@ -370,7 +373,7 @@ int ft_board_setup(void *blob, bd_t *bd) #if defined(CONFIG_HUSH_INIT_VAR) int hush_init_var(void) { - ivm_read_eeprom(); + ivm_analyze_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); return 0; } #endif

This allows to define the ethaddr env variable according to the the IVM content by reading the IVM in misc_init_r.
Later, when HUSH is available the content read earlier is analyzed to populate some non env variables.
Signed-off-by: Valentin Longchamp valentin.longchamp@keymile.com ---
Changes in v2: None
board/keymile/km82xx/km82xx.c | 10 +++++++++- include/configs/km82xx.h | 2 ++ 2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/board/keymile/km82xx/km82xx.c b/board/keymile/km82xx/km82xx.c index bf84676..c3a1131 100644 --- a/board/keymile/km82xx/km82xx.c +++ b/board/keymile/km82xx/km82xx.c @@ -18,6 +18,8 @@ #include <i2c.h> #include "../common/common.h"
+static uchar ivm_content[CONFIG_SYS_IVM_EEPROM_MAX_LEN]; + /* * I/O Port configuration table * @@ -393,9 +395,15 @@ int board_early_init_r(void) return 0; }
+int misc_init_r(void) +{ + ivm_simple_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); + return 0; +} + int hush_init_var(void) { - ivm_read_eeprom(); + ivm_analyze_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); return 0; }
diff --git a/include/configs/km82xx.h b/include/configs/km82xx.h index 14fd290..12f9d42 100644 --- a/include/configs/km82xx.h +++ b/include/configs/km82xx.h @@ -34,6 +34,8 @@
#define CONFIG_SYS_TEXT_BASE 0xFE000000
+#define CONFIG_MISC_INIT_R + /* include common defines/options for all Keymile boards */ #include "km/keymile-common.h" #include "km/km-powerpc.h"

This is not used anymore since the procedure was split into a simple read function and a later alaysis.
The ivm_read_eeprom name is now used for the previous ivm_simple_read_eeprom function.
Signed-off-by: Valentin Longchamp valentin.longchamp@keymile.com
---
Changes in v2: None
board/keymile/common/common.h | 3 +-- board/keymile/common/ivm.c | 21 +-------------------- board/keymile/km82xx/km82xx.c | 2 +- board/keymile/km83xx/km83xx.c | 2 +- board/keymile/km_arm/km_arm.c | 2 +- board/keymile/kmp204x/kmp204x.c | 2 +- 6 files changed, 6 insertions(+), 26 deletions(-)
diff --git a/board/keymile/common/common.h b/board/keymile/common/common.h index 7e16d25..dcfefc4 100644 --- a/board/keymile/common/common.h +++ b/board/keymile/common/common.h @@ -126,8 +126,7 @@ struct bfticu_iomap { #endif
int ethernet_present(void); -int ivm_read_eeprom(void); -int ivm_simple_read_eeprom(unsigned char *buf, int len); +int ivm_read_eeprom(unsigned char *buf, int len); int ivm_analyze_eeprom(unsigned char *buf, int len);
int trigger_fpga_config(void); diff --git a/board/keymile/common/ivm.c b/board/keymile/common/ivm.c index 4cb0b9a..42db542 100644 --- a/board/keymile/common/ivm.c +++ b/board/keymile/common/ivm.c @@ -315,7 +315,7 @@ static int ivm_populate_env(unsigned char *buf, int len) return 0; }
-int ivm_simple_read_eeprom(unsigned char *buf, int len) +int ivm_read_eeprom(unsigned char *buf, int len) { int ret;
@@ -331,22 +331,3 @@ int ivm_simple_read_eeprom(unsigned char *buf, int len)
return ivm_populate_env(buf, len); } - -int ivm_read_eeprom(void) -{ - uchar i2c_buffer[CONFIG_SYS_IVM_EEPROM_MAX_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, i2c_bufer, - CONFIG_SYS_IVM_EEPROM_MAX_LEN); - if (ret != 0) { - printf("Error reading EEprom\n"); - return -2; - } - - return ivm_analyze_eeprom(i2c_buffer, CONFIG_SYS_IVM_EEPROM_MAX_LEN); -} diff --git a/board/keymile/km82xx/km82xx.c b/board/keymile/km82xx/km82xx.c index c3a1131..c599b40 100644 --- a/board/keymile/km82xx/km82xx.c +++ b/board/keymile/km82xx/km82xx.c @@ -397,7 +397,7 @@ int board_early_init_r(void)
int misc_init_r(void) { - ivm_simple_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); + ivm_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); return 0; }
diff --git a/board/keymile/km83xx/km83xx.c b/board/keymile/km83xx/km83xx.c index fc68a2f..89e9e1e 100644 --- a/board/keymile/km83xx/km83xx.c +++ b/board/keymile/km83xx/km83xx.c @@ -192,7 +192,7 @@ int board_early_init_r(void)
int misc_init_r(void) { - ivm_simple_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); + ivm_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); return 0; }
diff --git a/board/keymile/km_arm/km_arm.c b/board/keymile/km_arm/km_arm.c index 6eb6712..2938861 100644 --- a/board/keymile/km_arm/km_arm.c +++ b/board/keymile/km_arm/km_arm.c @@ -212,7 +212,7 @@ int misc_init_r(void) } #endif
- ivm_simple_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); + ivm_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN);
initialize_unit_leds(); set_km_env(); diff --git a/board/keymile/kmp204x/kmp204x.c b/board/keymile/kmp204x/kmp204x.c index 0f544fb..eebb47f 100644 --- a/board/keymile/kmp204x/kmp204x.c +++ b/board/keymile/kmp204x/kmp204x.c @@ -197,7 +197,7 @@ int misc_init_r(void) } }
- ivm_simple_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); + ivm_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN); return 0; }
participants (1)
-
Valentin Longchamp