Commit 16ac90c7ee6fe973ee86fa9b08f876e5c33751bc
Committed by
Tom Rini
1 parent
b9ea0c3a20
Exists in
v2017.01-smarct4x
and in
37 other branches
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 Side-by-side Diff
board/keymile/common/common.h
... | ... | @@ -127,6 +127,8 @@ |
127 | 127 | |
128 | 128 | int ethernet_present(void); |
129 | 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 | 133 | int trigger_fpga_config(void); |
132 | 134 | int wait_for_fpga_config(void); |
board/keymile/common/ivm.c
... | ... | @@ -10,6 +10,8 @@ |
10 | 10 | #include <i2c.h> |
11 | 11 | #include "common.h" |
12 | 12 | |
13 | +#define MAC_STR_SZ 20 | |
14 | + | |
13 | 15 | static int ivm_calc_crc(unsigned char *buf, int len) |
14 | 16 | { |
15 | 17 | const unsigned short crc_tab[16] = { |
16 | 18 | |
17 | 19 | |
18 | 20 | |
19 | 21 | |
20 | 22 | |
... | ... | @@ -185,45 +187,37 @@ |
185 | 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 | 192 | int offset) |
190 | 193 | { |
194 | + unsigned char mac[6]; | |
191 | 195 | unsigned long val = (buf[4] << 16) + (buf[5] << 8) + buf[6]; |
192 | 196 | |
193 | - if (offset == 0) | |
194 | - return 0; | |
197 | + /* use an intermediate buffer, to not change IVM content | |
198 | + * MAC address is at offset 1 | |
199 | + */ | |
200 | + memcpy(mac, buf+1, 6); | |
195 | 201 | |
196 | - val += offset; | |
197 | - buf[4] = (val >> 16) & 0xff; | |
198 | - buf[5] = (val >> 8) & 0xff; | |
199 | - buf[6] = val & 0xff; | |
200 | - sprintf((char *)valbuf, "%pM", buf + 1); | |
202 | + if (offset) { | |
203 | + val += offset; | |
204 | + mac[3] = (val >> 16) & 0xff; | |
205 | + mac[4] = (val >> 8) & 0xff; | |
206 | + mac[5] = val & 0xff; | |
207 | + } | |
208 | + | |
209 | + sprintf((char *)valbuf, "%pM", mac); | |
201 | 210 | return 0; |
202 | 211 | } |
203 | 212 | |
204 | 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 | 216 | unsigned long count; |
208 | 217 | |
209 | 218 | /* IVM_MAC Adress begins at offset 1 */ |
210 | 219 | sprintf((char *)valbuf, "%pM", buf + 1); |
211 | 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 | 221 | /* IVM_MacCount */ |
228 | 222 | count = (buf[10] << 24) + |
229 | 223 | (buf[11] << 16) + |
... | ... | @@ -236,7 +230,7 @@ |
236 | 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 | 235 | unsigned short val; |
242 | 236 | unsigned char valbuf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN]; |
... | ... | @@ -294,6 +288,48 @@ |
294 | 288 | CONFIG_SYS_IVM_EEPROM_PAGE_LEN); |
295 | 289 | |
296 | 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 | 335 | int ivm_read_eeprom(void) |