diff options
| author | Bartlomiej Sieka <tur@semihalf.com> | 2006-02-24 09:37:22 +0100 | 
|---|---|---|
| committer | Bartlomiej Sieka <tur@pollux.(none)> | 2006-02-24 09:37:22 +0100 | 
| commit | 038ccac511214b062c56f22b9413f784b86bcd87 (patch) | |
| tree | 9925a8bb04e791550c76e864c5821b12fc478e2e /board/netstar/eeprom.c | |
| parent | 84e106c09d324e345f335d2edef246d0b4c9131a (diff) | |
| parent | 8e9655f863246db60c51140153186acc2afdc855 (diff) | |
| download | olio-uboot-2014.01-038ccac511214b062c56f22b9413f784b86bcd87.tar.xz olio-uboot-2014.01-038ccac511214b062c56f22b9413f784b86bcd87.zip | |
Merge with /home/wd/git/u-boot/testing-NAND/ to add new NAND handling.
Diffstat (limited to 'board/netstar/eeprom.c')
| -rw-r--r-- | board/netstar/eeprom.c | 215 | 
1 files changed, 215 insertions, 0 deletions
| diff --git a/board/netstar/eeprom.c b/board/netstar/eeprom.c new file mode 100644 index 000000000..fef3822aa --- /dev/null +++ b/board/netstar/eeprom.c @@ -0,0 +1,215 @@ +/* + * (C) Copyright 2005 + * Ladislav Michl, 2N Telekomunikace, michl@2n.cz + * + * 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 version 2 as + * published by the Free Software Foundation. + * + * 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 + * + * Some code shamelessly stolen back from Robin Getz. + */ + +#define DEBUG + +#include <common.h> +#include <exports.h> +#include "../drivers/smc91111.h" + +#define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE + +static u16 read_eeprom_reg(u16 reg) +{ +	int timeout; + +	SMC_SELECT_BANK(2); +	SMC_outw(reg, PTR_REG); + +	SMC_SELECT_BANK(1); +	SMC_outw(SMC_inw (CTL_REG) | CTL_EEPROM_SELECT | CTL_RELOAD, +		 CTL_REG); +	timeout = 100; +	while((SMC_inw (CTL_REG) & CTL_RELOAD) && --timeout) +		udelay(100); +	if (timeout == 0) { +		printf("Timeout Reading EEPROM register %02x\n", reg); +		return 0; +	} + +	return SMC_inw (GP_REG); +} + +static int write_eeprom_reg(u16 value, u16 reg) +{ +	int timeout; + +	SMC_SELECT_BANK(2); +	SMC_outw(reg, PTR_REG); + +	SMC_SELECT_BANK(1); +	SMC_outw(value, GP_REG); +	SMC_outw(SMC_inw (CTL_REG) | CTL_EEPROM_SELECT | CTL_STORE, CTL_REG); +	timeout = 100; +	while ((SMC_inw(CTL_REG) & CTL_STORE) && --timeout) +		udelay (100); +	if (timeout == 0) { +		printf("Timeout Writing EEPROM register %02x\n", reg); +		return 0; +	} + +	return 1; +} + +static int write_data(u16 *buf, int len) +{ +	u16 reg = 0x23; + +	while (len--) +		write_eeprom_reg(*buf++, reg++); + +	return 0; +} + +static int verify_macaddr(char *s) +{ +	u16 reg; +	int i, err = 0; + +	printf("MAC Address: "); +	err = i = 0; +	for (i = 0; i < 3; i++) { +		reg = read_eeprom_reg(0x20 + i); +		printf("%02x:%02x%c", reg & 0xff, reg >> 8, i != 2 ? ':' : '\n'); +		if (s) +			err |= reg != ((u16 *)s)[i]; +	} + +	return err ? 0 : 1; +} + +static int set_mac(char *s) +{ +	int i; +	char *e, eaddr[6]; + +	/* turn string into mac value */ +	for (i = 0; i < 6; i++) { +		eaddr[i] = simple_strtoul(s, &e, 16); +		s = (*e) ? e+1 : e; +	} + +	for (i = 0; i < 3; i++) +		write_eeprom_reg(*(((u16 *)eaddr) + i), 0x20 + i); + +	return 0; +} + +static int parse_element(char *s, unsigned char *buf, int len) +{ +	int cnt; +	char *p, num[3]; +	unsigned char id; + +	id = simple_strtoul(s, &p, 16); +	if (*p++ != ':') +		return -1; +	cnt = 2; +	num[2] = 0; +	for (; *p; p += 2) { +		if (p[1] == 0) +			return -2; +		if (cnt + 3 > len) +			return -3; +		num[0] = p[0]; +		num[1] = p[1]; +		buf[cnt++] = simple_strtoul(num, NULL, 16); +	} +	buf[0] = id; +	buf[1] = cnt - 2; + +	return cnt; +} + +extern int crcek(void); + +int eeprom(int argc, char *argv[]) +{ +	int i, len, ret; +	unsigned char buf[58], *p; + +	app_startup(argv); +	if (get_version() != XF_VERSION) { +		printf("Wrong XF_VERSION.\n"); +		printf("Application expects ABI version %d\n", XF_VERSION); +		printf("Actual U-Boot ABI version %d\n", (int)get_version()); +		return 1; +	} + +	return crcek(); + +	if ((SMC_inw (BANK_SELECT) & 0xFF00) != 0x3300) { +		printf("SMSC91111 not found.\n"); +		return 2; +	} + +	/* Called without parameters - print MAC address */ +	if (argc < 2) { +		verify_macaddr(NULL); +		return 0; +	} + +	/* Print help message */ +	if (argv[1][1] == 'h') { +		printf("VoiceBlue EEPROM writer\n"); +		printf("Built: %s at %s\n", __DATE__ , __TIME__ ); +		printf("Usage:\n\t<mac_address> [<element_1>] [<...>]\n"); +		return 0; +	} + +	/* Try to parse information elements */ +	len = sizeof(buf); +	p = buf; +	for (i = 2; i < argc; i++) { +		ret = parse_element(argv[i], p, len); +		switch (ret) { +		case -1: +			printf("Element %d: malformed\n", i - 1); +			return 3; +		case -2: +			printf("Element %d: odd character count\n", i - 1); +			return 3; +		case -3: +			printf("Out of EEPROM memory\n"); +			return 3; +		default: +			p += ret; +			len -= ret; +		} +	} + +	/* First argument (MAC) is mandatory */ +	set_mac(argv[1]); +	if (verify_macaddr(argv[1])) { +		printf("*** MAC address does not match! ***\n"); +		return 4; +	} + +	while (len--) +		*p++ = 0; + +	write_data((u16 *)buf, sizeof(buf) >> 1); + +	return 0; +} |