Commit 16ac90c7ee6fe973ee86fa9b08f876e5c33751bc

Authored by Valentin Longchamp
Committed by Tom Rini
1 parent b9ea0c3a20

KM/IVM: split the IVM reading and parsing in 2 parts

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>

Showing 2 changed files with 63 additions and 25 deletions Inline Diff

board/keymile/common/common.h
1 /* 1 /*
2 * (C) Copyright 2008 2 * (C) Copyright 2008
3 * Heiko Schocher, DENX Software Engineering, hs@denx.de. 3 * Heiko Schocher, DENX Software Engineering, hs@denx.de.
4 * 4 *
5 * SPDX-License-Identifier: GPL-2.0+ 5 * SPDX-License-Identifier: GPL-2.0+
6 */ 6 */
7 7
8 #ifndef __KEYMILE_COMMON_H 8 #ifndef __KEYMILE_COMMON_H
9 #define __KEYMILE_COMMON_H 9 #define __KEYMILE_COMMON_H
10 10
11 #define WRG_RESET 0x80 11 #define WRG_RESET 0x80
12 #define H_OPORTS_14 0x40 12 #define H_OPORTS_14 0x40
13 #define WRG_LED 0x02 13 #define WRG_LED 0x02
14 #define WRL_BOOT 0x01 14 #define WRL_BOOT 0x01
15 15
16 #define OPRTL_XBUFENA 0x20 16 #define OPRTL_XBUFENA 0x20
17 17
18 #define H_OPORTS_SCC4_ENA 0x10 18 #define H_OPORTS_SCC4_ENA 0x10
19 #define H_OPORTS_SCC4_FD_ENA 0x04 19 #define H_OPORTS_SCC4_FD_ENA 0x04
20 #define H_OPORTS_FCC1_PW_DWN 0x01 20 #define H_OPORTS_FCC1_PW_DWN 0x01
21 21
22 #define PIGGY_PRESENT 0x80 22 #define PIGGY_PRESENT 0x80
23 23
24 struct km_bec_fpga { 24 struct km_bec_fpga {
25 unsigned char id; 25 unsigned char id;
26 unsigned char rev; 26 unsigned char rev;
27 unsigned char oprth; 27 unsigned char oprth;
28 unsigned char oprtl; 28 unsigned char oprtl;
29 unsigned char res1[3]; 29 unsigned char res1[3];
30 unsigned char bprth; 30 unsigned char bprth;
31 unsigned char bprtl; 31 unsigned char bprtl;
32 unsigned char gprt3; 32 unsigned char gprt3;
33 unsigned char gprt2; 33 unsigned char gprt2;
34 unsigned char gprt1; 34 unsigned char gprt1;
35 unsigned char gprt0; 35 unsigned char gprt0;
36 unsigned char res2[2]; 36 unsigned char res2[2];
37 unsigned char prst; 37 unsigned char prst;
38 unsigned char res3[0xfff0]; 38 unsigned char res3[0xfff0];
39 unsigned char pgy_id; 39 unsigned char pgy_id;
40 unsigned char pgy_rev; 40 unsigned char pgy_rev;
41 unsigned char pgy_outputs; 41 unsigned char pgy_outputs;
42 unsigned char pgy_eth; 42 unsigned char pgy_eth;
43 }; 43 };
44 44
45 #define BFTICU_DIPSWITCH_MASK 0x0f 45 #define BFTICU_DIPSWITCH_MASK 0x0f
46 46
47 /* 47 /*
48 * BFTICU FPGA iomap 48 * BFTICU FPGA iomap
49 * BFTICU is used on mgcoge and mgocge3ne 49 * BFTICU is used on mgcoge and mgocge3ne
50 */ 50 */
51 struct bfticu_iomap { 51 struct bfticu_iomap {
52 u8 xi_ena; /* General defect enable */ 52 u8 xi_ena; /* General defect enable */
53 u8 pack1[3]; 53 u8 pack1[3];
54 u8 en_csn; 54 u8 en_csn;
55 u8 pack2; 55 u8 pack2;
56 u8 safe_mem; 56 u8 safe_mem;
57 u8 pack3; 57 u8 pack3;
58 u8 id; 58 u8 id;
59 u8 pack4; 59 u8 pack4;
60 u8 rev; 60 u8 rev;
61 u8 build; 61 u8 build;
62 u8 p_frc; 62 u8 p_frc;
63 u8 p_msk; 63 u8 p_msk;
64 u8 pack5[2]; 64 u8 pack5[2];
65 u8 xg_int; 65 u8 xg_int;
66 u8 pack6[15]; 66 u8 pack6[15];
67 u8 s_conf; 67 u8 s_conf;
68 u8 pack7; 68 u8 pack7;
69 u8 dmx_conf12; 69 u8 dmx_conf12;
70 u8 pack8; 70 u8 pack8;
71 u8 s_clkslv; 71 u8 s_clkslv;
72 u8 pack9[11]; 72 u8 pack9[11];
73 u8 d_conf; 73 u8 d_conf;
74 u8 d_mask_ca; 74 u8 d_mask_ca;
75 u8 d_pll_del; 75 u8 d_pll_del;
76 u8 pack10[16]; 76 u8 pack10[16];
77 u8 t_conf_ca; 77 u8 t_conf_ca;
78 u8 t_mask_ca; 78 u8 t_mask_ca;
79 u8 pack11[13]; 79 u8 pack11[13];
80 u8 m_def0; 80 u8 m_def0;
81 u8 m_def1; 81 u8 m_def1;
82 u8 m_def2; 82 u8 m_def2;
83 u8 m_def3; 83 u8 m_def3;
84 u8 m_def4; 84 u8 m_def4;
85 u8 m_def5; 85 u8 m_def5;
86 u8 m_def_trap0; 86 u8 m_def_trap0;
87 u8 m_def_trap1; 87 u8 m_def_trap1;
88 u8 m_def_trap2; 88 u8 m_def_trap2;
89 u8 m_def_trap3; 89 u8 m_def_trap3;
90 u8 m_def_trap4; 90 u8 m_def_trap4;
91 u8 m_def_trap5; 91 u8 m_def_trap5;
92 u8 m_mask_def0; 92 u8 m_mask_def0;
93 u8 m_mask_def1; 93 u8 m_mask_def1;
94 u8 m_mask_def2; 94 u8 m_mask_def2;
95 u8 m_mask_def3; 95 u8 m_mask_def3;
96 u8 m_mask_def4; 96 u8 m_mask_def4;
97 u8 m_mask_def5; 97 u8 m_mask_def5;
98 u8 m_def_mask0; 98 u8 m_def_mask0;
99 u8 m_def_mask1; 99 u8 m_def_mask1;
100 u8 m_def_mask2; 100 u8 m_def_mask2;
101 u8 m_def_mask3; 101 u8 m_def_mask3;
102 u8 m_def_mask4; 102 u8 m_def_mask4;
103 u8 m_def_mask5; 103 u8 m_def_mask5;
104 u8 m_def_pri; 104 u8 m_def_pri;
105 u8 pack12[11]; 105 u8 pack12[11];
106 u8 hw_status; 106 u8 hw_status;
107 u8 pack13; 107 u8 pack13;
108 u8 hw_control1; 108 u8 hw_control1;
109 u8 hw_control2; 109 u8 hw_control2;
110 u8 hw_control3; 110 u8 hw_control3;
111 u8 pack14[7]; 111 u8 pack14[7];
112 u8 led_on; /* Leds */ 112 u8 led_on; /* Leds */
113 u8 pack15; 113 u8 pack15;
114 u8 sfp_control; /* SFP modules */ 114 u8 sfp_control; /* SFP modules */
115 u8 pack16; 115 u8 pack16;
116 u8 alarm_control; /* Alarm output */ 116 u8 alarm_control; /* Alarm output */
117 u8 pack17; 117 u8 pack17;
118 u8 icps; /* ICN clock pulse shaping */ 118 u8 icps; /* ICN clock pulse shaping */
119 u8 mswitch; /* Read mode switch */ 119 u8 mswitch; /* Read mode switch */
120 u8 pack18[6]; 120 u8 pack18[6];
121 u8 pb_dbug; 121 u8 pb_dbug;
122 }; 122 };
123 123
124 #if !defined(CONFIG_PIGGY_MAC_ADRESS_OFFSET) 124 #if !defined(CONFIG_PIGGY_MAC_ADRESS_OFFSET)
125 #define CONFIG_PIGGY_MAC_ADRESS_OFFSET 0 125 #define CONFIG_PIGGY_MAC_ADRESS_OFFSET 0
126 #endif 126 #endif
127 127
128 int ethernet_present(void); 128 int ethernet_present(void);
129 int ivm_read_eeprom(void); 129 int ivm_read_eeprom(void);
130 int ivm_simple_read_eeprom(unsigned char *buf, int len);
131 int ivm_analyze_eeprom(unsigned char *buf, int len);
130 132
131 int trigger_fpga_config(void); 133 int trigger_fpga_config(void);
132 int wait_for_fpga_config(void); 134 int wait_for_fpga_config(void);
133 int fpga_reset(void); 135 int fpga_reset(void);
134 int toggle_eeprom_spi_bus(void); 136 int toggle_eeprom_spi_bus(void);
135 137
136 int set_km_env(void); 138 int set_km_env(void);
137 int fdt_set_node_and_value(void *blob, 139 int fdt_set_node_and_value(void *blob,
138 char *nodename, 140 char *nodename,
139 char *regname, 141 char *regname,
140 void *var, 142 void *var,
141 int size); 143 int size);
142 int fdt_get_node_and_value(void *blob, 144 int fdt_get_node_and_value(void *blob,
143 char *nodename, 145 char *nodename,
144 char *propname, 146 char *propname,
145 void **var); 147 void **var);
146 148
147 #define DELAY_ABORT_SEQ 62 /* @200kHz 9 clocks = 44us, 62us is ok */ 149 #define DELAY_ABORT_SEQ 62 /* @200kHz 9 clocks = 44us, 62us is ok */
148 #define DELAY_HALF_PERIOD (500 / (CONFIG_SYS_I2C_SPEED / 1000)) 150 #define DELAY_HALF_PERIOD (500 / (CONFIG_SYS_I2C_SPEED / 1000))
149 151
150 int i2c_soft_read_pin(void); 152 int i2c_soft_read_pin(void);
151 int i2c_make_abort(void); 153 int i2c_make_abort(void);
152 #endif /* __KEYMILE_COMMON_H */ 154 #endif /* __KEYMILE_COMMON_H */
153 155
board/keymile/common/ivm.c
1 /* 1 /*
2 * (C) Copyright 2011 2 * (C) Copyright 2011
3 * Holger Brunck, Keymile GmbH Hannover, holger.brunck@keymile.com 3 * Holger Brunck, Keymile GmbH Hannover, holger.brunck@keymile.com
4 * 4 *
5 * SPDX-License-Identifier: GPL-2.0+ 5 * SPDX-License-Identifier: GPL-2.0+
6 */ 6 */
7 7
8 #include <common.h> 8 #include <common.h>
9 #include <cli_hush.h> 9 #include <cli_hush.h>
10 #include <i2c.h> 10 #include <i2c.h>
11 #include "common.h" 11 #include "common.h"
12 12
13 #define MAC_STR_SZ 20
14
13 static int ivm_calc_crc(unsigned char *buf, int len) 15 static int ivm_calc_crc(unsigned char *buf, int len)
14 { 16 {
15 const unsigned short crc_tab[16] = { 17 const unsigned short crc_tab[16] = {
16 0x0000, 0xCC01, 0xD801, 0x1400, 18 0x0000, 0xCC01, 0xD801, 0x1400,
17 0xF001, 0x3C00, 0x2800, 0xE401, 19 0xF001, 0x3C00, 0x2800, 0xE401,
18 0xA001, 0x6C00, 0x7800, 0xB401, 20 0xA001, 0x6C00, 0x7800, 0xB401,
19 0x5000, 0x9C01, 0x8801, 0x4400}; 21 0x5000, 0x9C01, 0x8801, 0x4400};
20 22
21 unsigned short crc = 0; /* final result */ 23 unsigned short crc = 0; /* final result */
22 unsigned short r1 = 0; /* temp */ 24 unsigned short r1 = 0; /* temp */
23 unsigned char byte = 0; /* input buffer */ 25 unsigned char byte = 0; /* input buffer */
24 int i; 26 int i;
25 27
26 /* calculate CRC from array data */ 28 /* calculate CRC from array data */
27 for (i = 0; i < len; i++) { 29 for (i = 0; i < len; i++) {
28 byte = buf[i]; 30 byte = buf[i];
29 31
30 /* lower 4 bits */ 32 /* lower 4 bits */
31 r1 = crc_tab[crc & 0xF]; 33 r1 = crc_tab[crc & 0xF];
32 crc = ((crc) >> 4) & 0x0FFF; 34 crc = ((crc) >> 4) & 0x0FFF;
33 crc = crc ^ r1 ^ crc_tab[byte & 0xF]; 35 crc = crc ^ r1 ^ crc_tab[byte & 0xF];
34 36
35 /* upper 4 bits */ 37 /* upper 4 bits */
36 r1 = crc_tab[crc & 0xF]; 38 r1 = crc_tab[crc & 0xF];
37 crc = (crc >> 4) & 0x0FFF; 39 crc = (crc >> 4) & 0x0FFF;
38 crc = crc ^ r1 ^ crc_tab[(byte >> 4) & 0xF]; 40 crc = crc ^ r1 ^ crc_tab[(byte >> 4) & 0xF];
39 } 41 }
40 return crc; 42 return crc;
41 } 43 }
42 44
43 static int ivm_set_value(char *name, char *value) 45 static int ivm_set_value(char *name, char *value)
44 { 46 {
45 char tempbuf[256]; 47 char tempbuf[256];
46 48
47 if (value != NULL) { 49 if (value != NULL) {
48 sprintf(tempbuf, "%s=%s", name, value); 50 sprintf(tempbuf, "%s=%s", name, value);
49 return set_local_var(tempbuf, 0); 51 return set_local_var(tempbuf, 0);
50 } else { 52 } else {
51 unset_local_var(name); 53 unset_local_var(name);
52 } 54 }
53 return 0; 55 return 0;
54 } 56 }
55 57
56 static int ivm_get_value(unsigned char *buf, int len, char *name, int off, 58 static int ivm_get_value(unsigned char *buf, int len, char *name, int off,
57 int check) 59 int check)
58 { 60 {
59 unsigned short val; 61 unsigned short val;
60 unsigned char valbuf[30]; 62 unsigned char valbuf[30];
61 63
62 if ((buf[off + 0] != buf[off + 2]) && 64 if ((buf[off + 0] != buf[off + 2]) &&
63 (buf[off + 2] != buf[off + 4])) { 65 (buf[off + 2] != buf[off + 4])) {
64 printf("%s Error corrupted %s\n", __func__, name); 66 printf("%s Error corrupted %s\n", __func__, name);
65 val = -1; 67 val = -1;
66 } else { 68 } else {
67 val = buf[off + 0] + (buf[off + 1] << 8); 69 val = buf[off + 0] + (buf[off + 1] << 8);
68 if ((val == 0) && (check == 1)) 70 if ((val == 0) && (check == 1))
69 val = -1; 71 val = -1;
70 } 72 }
71 sprintf((char *)valbuf, "%x", val); 73 sprintf((char *)valbuf, "%x", val);
72 ivm_set_value(name, (char *)valbuf); 74 ivm_set_value(name, (char *)valbuf);
73 return val; 75 return val;
74 } 76 }
75 77
76 #define INV_BLOCKSIZE 0x100 78 #define INV_BLOCKSIZE 0x100
77 #define INV_DATAADDRESS 0x21 79 #define INV_DATAADDRESS 0x21
78 #define INVENTORYDATASIZE (INV_BLOCKSIZE - INV_DATAADDRESS - 3) 80 #define INVENTORYDATASIZE (INV_BLOCKSIZE - INV_DATAADDRESS - 3)
79 81
80 #define IVM_POS_SHORT_TEXT 0 82 #define IVM_POS_SHORT_TEXT 0
81 #define IVM_POS_MANU_ID 1 83 #define IVM_POS_MANU_ID 1
82 #define IVM_POS_MANU_SERIAL 2 84 #define IVM_POS_MANU_SERIAL 2
83 #define IVM_POS_PART_NUMBER 3 85 #define IVM_POS_PART_NUMBER 3
84 #define IVM_POS_BUILD_STATE 4 86 #define IVM_POS_BUILD_STATE 4
85 #define IVM_POS_SUPPLIER_PART_NUMBER 5 87 #define IVM_POS_SUPPLIER_PART_NUMBER 5
86 #define IVM_POS_DELIVERY_DATE 6 88 #define IVM_POS_DELIVERY_DATE 6
87 #define IVM_POS_SUPPLIER_BUILD_STATE 7 89 #define IVM_POS_SUPPLIER_BUILD_STATE 7
88 #define IVM_POS_CUSTOMER_ID 8 90 #define IVM_POS_CUSTOMER_ID 8
89 #define IVM_POS_CUSTOMER_PROD_ID 9 91 #define IVM_POS_CUSTOMER_PROD_ID 9
90 #define IVM_POS_HISTORY 10 92 #define IVM_POS_HISTORY 10
91 #define IVM_POS_SYMBOL_ONLY 11 93 #define IVM_POS_SYMBOL_ONLY 11
92 94
93 static char convert_char(char c) 95 static char convert_char(char c)
94 { 96 {
95 return (c < ' ' || c > '~') ? '.' : c; 97 return (c < ' ' || c > '~') ? '.' : c;
96 } 98 }
97 99
98 static int ivm_findinventorystring(int type, 100 static int ivm_findinventorystring(int type,
99 unsigned char *const string, 101 unsigned char *const string,
100 unsigned long maxlen, 102 unsigned long maxlen,
101 unsigned char *buf) 103 unsigned char *buf)
102 { 104 {
103 int xcode = 0; 105 int xcode = 0;
104 unsigned long cr = 0; 106 unsigned long cr = 0;
105 unsigned long addr = INV_DATAADDRESS; 107 unsigned long addr = INV_DATAADDRESS;
106 unsigned long size = 0; 108 unsigned long size = 0;
107 unsigned long nr = type; 109 unsigned long nr = type;
108 int stop = 0; /* stop on semicolon */ 110 int stop = 0; /* stop on semicolon */
109 111
110 memset(string, '\0', maxlen); 112 memset(string, '\0', maxlen);
111 switch (type) { 113 switch (type) {
112 case IVM_POS_SYMBOL_ONLY: 114 case IVM_POS_SYMBOL_ONLY:
113 nr = 0; 115 nr = 0;
114 stop = 1; 116 stop = 1;
115 break; 117 break;
116 default: 118 default:
117 nr = type; 119 nr = type;
118 stop = 0; 120 stop = 0;
119 } 121 }
120 122
121 /* Look for the requested number of CR. */ 123 /* Look for the requested number of CR. */
122 while ((cr != nr) && (addr < INVENTORYDATASIZE)) { 124 while ((cr != nr) && (addr < INVENTORYDATASIZE)) {
123 if (buf[addr] == '\r') 125 if (buf[addr] == '\r')
124 cr++; 126 cr++;
125 addr++; 127 addr++;
126 } 128 }
127 129
128 /* 130 /*
129 * the expected number of CR was found until the end of the IVM 131 * the expected number of CR was found until the end of the IVM
130 * content --> fill string 132 * content --> fill string
131 */ 133 */
132 if (addr < INVENTORYDATASIZE) { 134 if (addr < INVENTORYDATASIZE) {
133 /* Copy the IVM string in the corresponding string */ 135 /* Copy the IVM string in the corresponding string */
134 for (; (buf[addr] != '\r') && 136 for (; (buf[addr] != '\r') &&
135 ((buf[addr] != ';') || (!stop)) && 137 ((buf[addr] != ';') || (!stop)) &&
136 (size < (maxlen - 1) && 138 (size < (maxlen - 1) &&
137 (addr < INVENTORYDATASIZE)); addr++) { 139 (addr < INVENTORYDATASIZE)); addr++) {
138 size += sprintf((char *)string + size, "%c", 140 size += sprintf((char *)string + size, "%c",
139 convert_char (buf[addr])); 141 convert_char (buf[addr]));
140 } 142 }
141 143
142 /* 144 /*
143 * copy phase is done: check if everything is ok. If not, 145 * copy phase is done: check if everything is ok. If not,
144 * the inventory data is most probably corrupted: tell 146 * the inventory data is most probably corrupted: tell
145 * the world there is a problem! 147 * the world there is a problem!
146 */ 148 */
147 if (addr == INVENTORYDATASIZE) { 149 if (addr == INVENTORYDATASIZE) {
148 xcode = -1; 150 xcode = -1;
149 printf("Error end of string not found\n"); 151 printf("Error end of string not found\n");
150 } else if ((size > (maxlen - 1)) && 152 } else if ((size > (maxlen - 1)) &&
151 (buf[addr] != '\r')) { 153 (buf[addr] != '\r')) {
152 xcode = -1; 154 xcode = -1;
153 printf("string too long till next CR\n"); 155 printf("string too long till next CR\n");
154 } 156 }
155 } else { 157 } else {
156 /* 158 /*
157 * some CR are missing... 159 * some CR are missing...
158 * the inventory data is most probably corrupted 160 * the inventory data is most probably corrupted
159 */ 161 */
160 xcode = -1; 162 xcode = -1;
161 printf("not enough cr found\n"); 163 printf("not enough cr found\n");
162 } 164 }
163 return xcode; 165 return xcode;
164 } 166 }
165 167
166 #define GET_STRING(name, which, len) \ 168 #define GET_STRING(name, which, len) \
167 if (ivm_findinventorystring(which, valbuf, len, buf) == 0) { \ 169 if (ivm_findinventorystring(which, valbuf, len, buf) == 0) { \
168 ivm_set_value(name, (char *)valbuf); \ 170 ivm_set_value(name, (char *)valbuf); \
169 } 171 }
170 172
171 static int ivm_check_crc(unsigned char *buf, int block) 173 static int ivm_check_crc(unsigned char *buf, int block)
172 { 174 {
173 unsigned long crc; 175 unsigned long crc;
174 unsigned long crceeprom; 176 unsigned long crceeprom;
175 177
176 crc = ivm_calc_crc(buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN - 2); 178 crc = ivm_calc_crc(buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN - 2);
177 crceeprom = (buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN - 1] + \ 179 crceeprom = (buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN - 1] + \
178 buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN - 2] * 256); 180 buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN - 2] * 256);
179 if (crc != crceeprom) { 181 if (crc != crceeprom) {
180 if (block == 0) 182 if (block == 0)
181 printf("Error CRC Block: %d EEprom: calculated: \ 183 printf("Error CRC Block: %d EEprom: calculated: \
182 %lx EEprom: %lx\n", block, crc, crceeprom); 184 %lx EEprom: %lx\n", block, crc, crceeprom);
183 return -1; 185 return -1;
184 } 186 }
185 return 0; 187 return 0;
186 } 188 }
187 189
188 static int calculate_mac_offset(unsigned char *valbuf, unsigned char *buf, 190 /* take care of the possible MAC address offset and the IVM content offset */
191 static int process_mac(unsigned char *valbuf, unsigned char *buf,
189 int offset) 192 int offset)
190 { 193 {
194 unsigned char mac[6];
191 unsigned long val = (buf[4] << 16) + (buf[5] << 8) + buf[6]; 195 unsigned long val = (buf[4] << 16) + (buf[5] << 8) + buf[6];
192 196
193 if (offset == 0) 197 /* use an intermediate buffer, to not change IVM content
194 return 0; 198 * MAC address is at offset 1
199 */
200 memcpy(mac, buf+1, 6);
195 201
196 val += offset; 202 if (offset) {
197 buf[4] = (val >> 16) & 0xff; 203 val += offset;
198 buf[5] = (val >> 8) & 0xff; 204 mac[3] = (val >> 16) & 0xff;
199 buf[6] = val & 0xff; 205 mac[4] = (val >> 8) & 0xff;
200 sprintf((char *)valbuf, "%pM", buf + 1); 206 mac[5] = val & 0xff;
207 }
208
209 sprintf((char *)valbuf, "%pM", mac);
201 return 0; 210 return 0;
202 } 211 }
203 212
204 static int ivm_analyze_block2(unsigned char *buf, int len) 213 static int ivm_analyze_block2(unsigned char *buf, int len)
205 { 214 {
206 unsigned char valbuf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN]; 215 unsigned char valbuf[MAC_STR_SZ];
207 unsigned long count; 216 unsigned long count;
208 217
209 /* IVM_MAC Adress begins at offset 1 */ 218 /* IVM_MAC Adress begins at offset 1 */
210 sprintf((char *)valbuf, "%pM", buf + 1); 219 sprintf((char *)valbuf, "%pM", buf + 1);
211 ivm_set_value("IVM_MacAddress", (char *)valbuf); 220 ivm_set_value("IVM_MacAddress", (char *)valbuf);
212 /* if an offset is defined, add it */
213 calculate_mac_offset(buf, valbuf, CONFIG_PIGGY_MAC_ADRESS_OFFSET);
214 #ifdef MACH_TYPE_KM_KIRKWOOD
215 setenv((char *)"ethaddr", (char *)valbuf);
216 #else
217 if (getenv("ethaddr") == NULL)
218 setenv((char *)"ethaddr", (char *)valbuf);
219 #endif
220 #ifdef CONFIG_KMVECT1
221 /* KMVECT1 has two ethernet interfaces */
222 if (getenv("eth1addr") == NULL) {
223 calculate_mac_offset(buf, valbuf, 1);
224 setenv((char *)"eth1addr", (char *)valbuf);
225 }
226 #endif
227 /* IVM_MacCount */ 221 /* IVM_MacCount */
228 count = (buf[10] << 24) + 222 count = (buf[10] << 24) +
229 (buf[11] << 16) + 223 (buf[11] << 16) +
230 (buf[12] << 8) + 224 (buf[12] << 8) +
231 buf[13]; 225 buf[13];
232 if (count == 0xffffffff) 226 if (count == 0xffffffff)
233 count = 1; 227 count = 1;
234 sprintf((char *)valbuf, "%lx", count); 228 sprintf((char *)valbuf, "%lx", count);
235 ivm_set_value("IVM_MacCount", (char *)valbuf); 229 ivm_set_value("IVM_MacCount", (char *)valbuf);
236 return 0; 230 return 0;
237 } 231 }
238 232
239 static int ivm_analyze_eeprom(unsigned char *buf, int len) 233 int ivm_analyze_eeprom(unsigned char *buf, int len)
240 { 234 {
241 unsigned short val; 235 unsigned short val;
242 unsigned char valbuf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN]; 236 unsigned char valbuf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN];
243 unsigned char *tmp; 237 unsigned char *tmp;
244 238
245 if (ivm_check_crc(buf, 0) != 0) 239 if (ivm_check_crc(buf, 0) != 0)
246 return -1; 240 return -1;
247 241
248 ivm_get_value(buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN, 242 ivm_get_value(buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN,
249 "IVM_BoardId", 0, 1); 243 "IVM_BoardId", 0, 1);
250 val = ivm_get_value(buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN, 244 val = ivm_get_value(buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN,
251 "IVM_HWKey", 6, 1); 245 "IVM_HWKey", 6, 1);
252 if (val != 0xffff) { 246 if (val != 0xffff) {
253 sprintf((char *)valbuf, "%x", ((val / 100) % 10)); 247 sprintf((char *)valbuf, "%x", ((val / 100) % 10));
254 ivm_set_value("IVM_HWVariant", (char *)valbuf); 248 ivm_set_value("IVM_HWVariant", (char *)valbuf);
255 sprintf((char *)valbuf, "%x", (val % 100)); 249 sprintf((char *)valbuf, "%x", (val % 100));
256 ivm_set_value("IVM_HWVersion", (char *)valbuf); 250 ivm_set_value("IVM_HWVersion", (char *)valbuf);
257 } 251 }
258 ivm_get_value(buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN, 252 ivm_get_value(buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN,
259 "IVM_Functions", 12, 0); 253 "IVM_Functions", 12, 0);
260 254
261 GET_STRING("IVM_Symbol", IVM_POS_SYMBOL_ONLY, 8) 255 GET_STRING("IVM_Symbol", IVM_POS_SYMBOL_ONLY, 8)
262 GET_STRING("IVM_DeviceName", IVM_POS_SHORT_TEXT, 64) 256 GET_STRING("IVM_DeviceName", IVM_POS_SHORT_TEXT, 64)
263 tmp = (unsigned char *) getenv("IVM_DeviceName"); 257 tmp = (unsigned char *) getenv("IVM_DeviceName");
264 if (tmp) { 258 if (tmp) {
265 int len = strlen((char *)tmp); 259 int len = strlen((char *)tmp);
266 int i = 0; 260 int i = 0;
267 261
268 while (i < len) { 262 while (i < len) {
269 if (tmp[i] == ';') { 263 if (tmp[i] == ';') {
270 ivm_set_value("IVM_ShortText", 264 ivm_set_value("IVM_ShortText",
271 (char *)&tmp[i + 1]); 265 (char *)&tmp[i + 1]);
272 break; 266 break;
273 } 267 }
274 i++; 268 i++;
275 } 269 }
276 if (i >= len) 270 if (i >= len)
277 ivm_set_value("IVM_ShortText", NULL); 271 ivm_set_value("IVM_ShortText", NULL);
278 } else { 272 } else {
279 ivm_set_value("IVM_ShortText", NULL); 273 ivm_set_value("IVM_ShortText", NULL);
280 } 274 }
281 GET_STRING("IVM_ManufacturerID", IVM_POS_MANU_ID, 32) 275 GET_STRING("IVM_ManufacturerID", IVM_POS_MANU_ID, 32)
282 GET_STRING("IVM_ManufacturerSerialNumber", IVM_POS_MANU_SERIAL, 20) 276 GET_STRING("IVM_ManufacturerSerialNumber", IVM_POS_MANU_SERIAL, 20)
283 GET_STRING("IVM_ManufacturerPartNumber", IVM_POS_PART_NUMBER, 32) 277 GET_STRING("IVM_ManufacturerPartNumber", IVM_POS_PART_NUMBER, 32)
284 GET_STRING("IVM_ManufacturerBuildState", IVM_POS_BUILD_STATE, 32) 278 GET_STRING("IVM_ManufacturerBuildState", IVM_POS_BUILD_STATE, 32)
285 GET_STRING("IVM_SupplierPartNumber", IVM_POS_SUPPLIER_PART_NUMBER, 32) 279 GET_STRING("IVM_SupplierPartNumber", IVM_POS_SUPPLIER_PART_NUMBER, 32)
286 GET_STRING("IVM_DelieveryDate", IVM_POS_DELIVERY_DATE, 32) 280 GET_STRING("IVM_DelieveryDate", IVM_POS_DELIVERY_DATE, 32)
287 GET_STRING("IVM_SupplierBuildState", IVM_POS_SUPPLIER_BUILD_STATE, 32) 281 GET_STRING("IVM_SupplierBuildState", IVM_POS_SUPPLIER_BUILD_STATE, 32)
288 GET_STRING("IVM_CustomerID", IVM_POS_CUSTOMER_ID, 32) 282 GET_STRING("IVM_CustomerID", IVM_POS_CUSTOMER_ID, 32)
289 GET_STRING("IVM_CustomerProductID", IVM_POS_CUSTOMER_PROD_ID, 32) 283 GET_STRING("IVM_CustomerProductID", IVM_POS_CUSTOMER_PROD_ID, 32)
290 284
291 if (ivm_check_crc(&buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN * 2], 2) != 0) 285 if (ivm_check_crc(&buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN * 2], 2) != 0)
292 return 0; 286 return 0;
293 ivm_analyze_block2(&buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN * 2], 287 ivm_analyze_block2(&buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN * 2],
294 CONFIG_SYS_IVM_EEPROM_PAGE_LEN); 288 CONFIG_SYS_IVM_EEPROM_PAGE_LEN);
295 289
296 return 0; 290 return 0;
291 }
292
293 static int ivm_populate_env(unsigned char *buf, int len)
294 {
295 unsigned char *page2;
296 unsigned char valbuf[MAC_STR_SZ];
297
298 /* do we have the page 2 filled ? if not return */
299 if (ivm_check_crc(buf, 2))
300 return 0;
301 page2 = &buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN*2];
302
303 /* if an offset is defined, add it */
304 process_mac(valbuf, page2, CONFIG_PIGGY_MAC_ADRESS_OFFSET);
305 if (getenv("ethaddr") == NULL)
306 setenv((char *)"ethaddr", (char *)valbuf);
307 #ifdef CONFIG_KMVECT1
308 /* KMVECT1 has two ethernet interfaces */
309 if (getenv("eth1addr") == NULL) {
310 process_mac(valbuf, page2, 1);
311 setenv((char *)"eth1addr", (char *)valbuf);
312 }
313 #endif
314
315 return 0;
316 }
317
318 int ivm_simple_read_eeprom(unsigned char *buf, int len)
319 {
320 int ret;
321
322 i2c_set_bus_num(CONFIG_KM_IVM_BUS);
323 /* add deblocking here */
324 i2c_make_abort();
325
326 ret = i2c_read(CONFIG_SYS_IVM_EEPROM_ADR, 0, 1, buf, len);
327 if (ret != 0) {
328 printf("Error reading EEprom\n");
329 return -2;
330 }
331
332 return ivm_populate_env(buf, len);
297 } 333 }
298 334
299 int ivm_read_eeprom(void) 335 int ivm_read_eeprom(void)
300 { 336 {
301 uchar i2c_buffer[CONFIG_SYS_IVM_EEPROM_MAX_LEN]; 337 uchar i2c_buffer[CONFIG_SYS_IVM_EEPROM_MAX_LEN];
302 int ret; 338 int ret;