X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=board%2Fkeymile%2Fcommon%2Fivm.c;h=da0634f01bfa00fa92a78235f0f07a7b2e4e83b4;hb=9fb625ce05539fe6876a59ce1dcadb76b33c6f6e;hp=eaa924f0e6a6aae6dc5706db1f38e4cf7c058848;hpb=9fe2cfb43aab2225a8c970a69341534b2488da8c;p=oweals%2Fu-boot.git diff --git a/board/keymile/common/ivm.c b/board/keymile/common/ivm.c index eaa924f0e6..da0634f01b 100644 --- a/board/keymile/common/ivm.c +++ b/board/keymile/common/ivm.c @@ -1,32 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * (C) Copyright 2011 * Holger Brunck, Keymile GmbH Hannover, holger.brunck@keymile.com - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA */ #include -#include +#include +#include #include #include "common.h" -int ivm_calc_crc(unsigned char *buf, int len) +#define MAC_STR_SZ 20 + +static int ivm_calc_crc(unsigned char *buf, int len) { const unsigned short crc_tab[16] = { 0x0000, 0xCC01, 0xD801, 0x1400, @@ -136,7 +122,7 @@ static int ivm_findinventorystring(int type, /* Look for the requested number of CR. */ while ((cr != nr) && (addr < INVENTORYDATASIZE)) { - if ((buf[addr] == '\r')) + if (buf[addr] == '\r') cr++; addr++; } @@ -201,33 +187,44 @@ static int ivm_check_crc(unsigned char *buf, int block) return 0; } +/* 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, bool unique) +{ + unsigned char mac[6]; + unsigned long val = (buf[4] << 16) + (buf[5] << 8) + buf[6]; + + /* use an intermediate buffer, to not change IVM content + * MAC address is at offset 1 + */ + memcpy(mac, buf+1, 6); + + /* MAC adress can be set to locally administred, this is only allowed + * for interfaces which have now connection to the outside. For these + * addresses we need to set the second bit in the first byte. + */ + if (!unique) + mac[0] |= 0x2; + + 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 */ -#if defined(CONFIG_PIGGY_MAC_ADRESS_OFFSET) - if (CONFIG_PIGGY_MAC_ADRESS_OFFSET > 0) { - unsigned long val = (buf[4] << 16) + (buf[5] << 8) + buf[6]; - - val += CONFIG_PIGGY_MAC_ADRESS_OFFSET; - buf[4] = (val >> 16) & 0xff; - buf[5] = (val >> 8) & 0xff; - buf[6] = val & 0xff; - sprintf((char *)valbuf, "%pM", buf + 1); - } -#endif -#ifdef MACH_TYPE_KM_KIRKWOOD - setenv((char *)"ethaddr", (char *)valbuf); -#else - if (getenv("ethaddr") == NULL) - setenv((char *)"ethaddr", (char *)valbuf); -#endif - /* IVM_MacCount */ count = (buf[10] << 24) + (buf[11] << 16) + @@ -264,7 +261,7 @@ int ivm_analyze_eeprom(unsigned char *buf, int len) GET_STRING("IVM_Symbol", IVM_POS_SYMBOL_ONLY, 8) GET_STRING("IVM_DeviceName", IVM_POS_SHORT_TEXT, 64) - tmp = (unsigned char *) getenv("IVM_DeviceName"); + tmp = (unsigned char *)env_get("IVM_DeviceName"); if (tmp) { int len = strlen((char *)tmp); int i = 0; @@ -300,48 +297,52 @@ int ivm_analyze_eeprom(unsigned char *buf, int len) return 0; } -int ivm_read_eeprom(void) +static int ivm_populate_env(unsigned char *buf, int len) { -#if defined(CONFIG_I2C_MUX) - I2C_MUX_DEVICE *dev = NULL; -#endif - uchar i2c_buffer[CONFIG_SYS_IVM_EEPROM_MAX_LEN]; - uchar *buf; - unsigned long dev_addr = CONFIG_SYS_IVM_EEPROM_ADR; - int ret; + unsigned char *page2; + unsigned char valbuf[MAC_STR_SZ]; -#if defined(CONFIG_I2C_MUX) - /* First init the Bus, select the Bus */ -#if defined(CONFIG_SYS_I2C_IVM_BUS) - dev = i2c_mux_ident_muxstring((uchar *)CONFIG_SYS_I2C_IVM_BUS); -#else - buf = (unsigned char *) getenv("EEprom_ivm"); - if (buf != NULL) - dev = i2c_mux_ident_muxstring(buf); + /* 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]; + +#ifndef CONFIG_KMTEGR1 + /* if an offset is defined, add it */ + process_mac(valbuf, page2, CONFIG_PIGGY_MAC_ADRESS_OFFSET, true); + env_set((char *)"ethaddr", (char *)valbuf); +#ifdef CONFIG_KMVECT1 +/* KMVECT1 has two ethernet interfaces */ + process_mac(valbuf, page2, 1, true); + env_set((char *)"eth1addr", (char *)valbuf); #endif - if (dev == NULL) { - printf("Error couldnt add Bus for IVM\n"); - return -1; - } - i2c_set_bus_num(dev->busid); +#else +/* KMTEGR1 has a special setup. eth0 has no connection to the outside and + * gets an locally administred MAC address, eth1 is the debug interface and + * gets the official MAC address from the IVM + */ + process_mac(valbuf, page2, CONFIG_PIGGY_MAC_ADRESS_OFFSET, false); + env_set((char *)"ethaddr", (char *)valbuf); + process_mac(valbuf, page2, CONFIG_PIGGY_MAC_ADRESS_OFFSET, true); + env_set((char *)"eth1addr", (char *)valbuf); #endif - buf = (unsigned char *) getenv("EEprom_ivm_addr"); - if (buf != NULL) { - ret = strict_strtoul((char *)buf, 16, &dev_addr); - if (ret != 0) - return -3; - } + return 0; +} + +int ivm_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(dev_addr, 0, 1, i2c_buffer, - CONFIG_SYS_IVM_EEPROM_MAX_LEN); + ret = i2c_read(CONFIG_SYS_IVM_EEPROM_ADR, 0, 1, buf, len); if (ret != 0) { printf("Error reading EEprom\n"); return -2; } - return ivm_analyze_eeprom(i2c_buffer, CONFIG_SYS_IVM_EEPROM_MAX_LEN); + return ivm_populate_env(buf, len); }