xref: /openbmc/u-boot/board/micronas/vct/smc_eeprom.c (revision 54841ab5)
1ae691e57SStefan Roese /*
2ae691e57SStefan Roese  * (C) Copyright 2008 Stefan Roese <sr@denx.de>, DENX Software Engineering
3ae691e57SStefan Roese  *
4ae691e57SStefan Roese  * Copyright 2005, Seagate Technology LLC
5ae691e57SStefan Roese  *
6ae691e57SStefan Roese  * See file CREDITS for list of people who contributed to this
7ae691e57SStefan Roese  * project.
8ae691e57SStefan Roese  *
9ae691e57SStefan Roese  * This program is free software; you can redistribute it and/or modify
10ae691e57SStefan Roese  * it under the terms of the GNU General Public License version 2 as
11ae691e57SStefan Roese  * published by the Free Software Foundation.
12ae691e57SStefan Roese  *
13ae691e57SStefan Roese  * This program is distributed in the hope that it will be useful,
14ae691e57SStefan Roese  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15ae691e57SStefan Roese  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16ae691e57SStefan Roese  * GNU General Public License for more details.
17ae691e57SStefan Roese  *
18ae691e57SStefan Roese  * You should have received a copy of the GNU General Public License
19ae691e57SStefan Roese  * along with this program; if not, write to the Free Software
20ae691e57SStefan Roese  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21ae691e57SStefan Roese  * MA 02111-1307 USA
22ae691e57SStefan Roese  *
23ae691e57SStefan Roese  */
24ae691e57SStefan Roese 
25ae691e57SStefan Roese #undef DEBUG
26ae691e57SStefan Roese 
27ae691e57SStefan Roese #include <common.h>
28ae691e57SStefan Roese #include <command.h>
29ae691e57SStefan Roese #include <config.h>
30ae691e57SStefan Roese #include <net.h>
31ae691e57SStefan Roese 
32ae691e57SStefan Roese #include "vct.h"
33ae691e57SStefan Roese 
34ae691e57SStefan Roese #define SMSC9118_BASE		CONFIG_DRIVER_SMC911X_BASE
35ae691e57SStefan Roese #define BYTE_TEST		(SMSC9118_BASE + 0x64)
36ae691e57SStefan Roese #define GPIO_CFG		(SMSC9118_BASE + 0x88)
37ae691e57SStefan Roese #define MAC_CSR_CMD		(SMSC9118_BASE + 0xA4)
38ae691e57SStefan Roese #define  MAC_CSR_CMD_CSR_BUSY	(0x80000000)
39ae691e57SStefan Roese #define  MAC_CSR_CMD_RNW	(0x40000000)
40ae691e57SStefan Roese #define  MAC_RD_CMD(reg)	((reg & 0x000000FF) |			\
41ae691e57SStefan Roese 				 (MAC_CSR_CMD_CSR_BUSY | MAC_CSR_CMD_RNW))
42ae691e57SStefan Roese #define  MAC_WR_CMD(reg)	((reg & 0x000000FF) |		\
43ae691e57SStefan Roese 				 (MAC_CSR_CMD_CSR_BUSY))
44ae691e57SStefan Roese #define MAC_CSR_DATA		(SMSC9118_BASE + 0xA8)
45ae691e57SStefan Roese #define E2P_CMD			(SMSC9118_BASE + 0xB0)
46ae691e57SStefan Roese #define  E2P_CMD_EPC_BUSY_	(0x80000000UL)	/* Self Clearing */
47ae691e57SStefan Roese #define  E2P_CMD_EPC_CMD_	(0x70000000UL)	/* R/W */
48ae691e57SStefan Roese #define  E2P_CMD_EPC_CMD_READ_	(0x00000000UL)	/* R/W */
49ae691e57SStefan Roese #define  E2P_CMD_EPC_CMD_EWDS_	(0x10000000UL)	/* R/W */
50ae691e57SStefan Roese #define  E2P_CMD_EPC_CMD_EWEN_	(0x20000000UL)	/* R/W */
51ae691e57SStefan Roese #define  E2P_CMD_EPC_CMD_WRITE_	(0x30000000UL)	/* R/W */
52ae691e57SStefan Roese #define  E2P_CMD_EPC_CMD_WRAL_	(0x40000000UL)	/* R/W */
53ae691e57SStefan Roese #define  E2P_CMD_EPC_CMD_ERASE_	(0x50000000UL)	/* R/W */
54ae691e57SStefan Roese #define  E2P_CMD_EPC_CMD_ERAL_	(0x60000000UL)	/* R/W */
55ae691e57SStefan Roese #define  E2P_CMD_EPC_CMD_RELOAD_ (0x70000000UL)	/* R/W */
56ae691e57SStefan Roese #define  E2P_CMD_EPC_TIMEOUT_	(0x00000200UL)	/* R */
57ae691e57SStefan Roese #define  E2P_CMD_MAC_ADDR_LOADED_ (0x00000100UL) /* RO */
58ae691e57SStefan Roese #define  E2P_CMD_EPC_ADDR_	(0x000000FFUL)	/* R/W */
59ae691e57SStefan Roese #define E2P_DATA		(SMSC9118_BASE + 0xB4)
60ae691e57SStefan Roese 
61ae691e57SStefan Roese #define MAC_ADDRH		(0x2)
62ae691e57SStefan Roese #define MAC_ADDRL		(0x3)
63ae691e57SStefan Roese 
64ae691e57SStefan Roese #define MAC_TIMEOUT		200
65ae691e57SStefan Roese 
66ae691e57SStefan Roese #define HIBYTE(word)		((u8)(((u16)(word)) >> 8))
67ae691e57SStefan Roese #define LOBYTE(word)		((u8)(((u16)(word)) & 0x00FFU))
68ae691e57SStefan Roese #define HIWORD(dword)		((u16)(((u32)(dword)) >> 16))
69ae691e57SStefan Roese #define LOWORD(dword)		((u16)(((u32)(dword)) & 0x0000FFFFUL))
70ae691e57SStefan Roese 
mac_busy(int req_to)71ae691e57SStefan Roese static int mac_busy(int req_to)
72ae691e57SStefan Roese {
73ae691e57SStefan Roese 	int timeout = req_to;
74ae691e57SStefan Roese 
75ae691e57SStefan Roese 	while (timeout--) {
76ae691e57SStefan Roese 		if (!(smc911x_reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY))
77ae691e57SStefan Roese 			goto done;
78ae691e57SStefan Roese 	}
79ae691e57SStefan Roese 	return 1;		/* Timeout */
80ae691e57SStefan Roese 
81ae691e57SStefan Roese done:
82ae691e57SStefan Roese 	return 0;		/* No timeout */
83ae691e57SStefan Roese }
84ae691e57SStefan Roese 
get_mac_reg(int reg)85ae691e57SStefan Roese static ulong get_mac_reg(int reg)
86ae691e57SStefan Roese {
87ae691e57SStefan Roese 	ulong reg_val = 0xffffffff;
88ae691e57SStefan Roese 
89ae691e57SStefan Roese 	if (smc911x_reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) {
90ae691e57SStefan Roese 		printf("get_mac_reg: previous command not complete\n");
91ae691e57SStefan Roese 		goto done;
92ae691e57SStefan Roese 	}
93ae691e57SStefan Roese 
94ae691e57SStefan Roese 	smc911x_reg_write(MAC_CSR_CMD, MAC_RD_CMD(reg));
95ae691e57SStefan Roese 	udelay(10000);
96ae691e57SStefan Roese 
97ae691e57SStefan Roese 	if (mac_busy(MAC_TIMEOUT) == 1) {
98ae691e57SStefan Roese 		printf("get_mac_reg: timeout waiting for response from MAC\n");
99ae691e57SStefan Roese 		goto done;
100ae691e57SStefan Roese 	}
101ae691e57SStefan Roese 
102ae691e57SStefan Roese 	reg_val = smc911x_reg_read(MAC_CSR_DATA);
103ae691e57SStefan Roese 
104ae691e57SStefan Roese done:
105ae691e57SStefan Roese 	return (reg_val);
106ae691e57SStefan Roese }
107ae691e57SStefan Roese 
eeprom_enable_access(void)108ae691e57SStefan Roese static ulong eeprom_enable_access(void)
109ae691e57SStefan Roese {
110ae691e57SStefan Roese 	ulong gpio;
111ae691e57SStefan Roese 
112ae691e57SStefan Roese 	gpio = smc911x_reg_read(GPIO_CFG);
113ae691e57SStefan Roese 	debug("%s: gpio= 0x%08lx ---> 0x%08lx\n", __func__, gpio,
114ae691e57SStefan Roese 	      (gpio & 0xFF0FFFFFUL));
115ae691e57SStefan Roese 
116ae691e57SStefan Roese 	smc911x_reg_write(GPIO_CFG, (gpio & 0xFF0FFFFFUL));
117ae691e57SStefan Roese 	return gpio;
118ae691e57SStefan Roese }
119ae691e57SStefan Roese 
eeprom_disable_access(ulong gpio)120ae691e57SStefan Roese static void eeprom_disable_access(ulong gpio)
121ae691e57SStefan Roese {
122ae691e57SStefan Roese 	debug("%s: gpio= 0x%08lx\n", __func__, gpio);
123ae691e57SStefan Roese 	smc911x_reg_write(GPIO_CFG, gpio);
124ae691e57SStefan Roese }
125ae691e57SStefan Roese 
eeprom_is_mac_address_loaded(void)126ae691e57SStefan Roese static int eeprom_is_mac_address_loaded(void)
127ae691e57SStefan Roese {
128ae691e57SStefan Roese 	int ret;
129ae691e57SStefan Roese 
130ae691e57SStefan Roese 	ret = smc911x_reg_read(MAC_CSR_CMD) & E2P_CMD_MAC_ADDR_LOADED_;
131ae691e57SStefan Roese 	debug("%s: ret = %x\n", __func__, ret);
132ae691e57SStefan Roese 
133ae691e57SStefan Roese 	return ret;
134ae691e57SStefan Roese }
135ae691e57SStefan Roese 
eeprom_read_location(unchar address,u8 * data)136ae691e57SStefan Roese static int eeprom_read_location(unchar address, u8 *data)
137ae691e57SStefan Roese {
138ae691e57SStefan Roese 	ulong timeout = 100000;
139ae691e57SStefan Roese 	ulong temp = 0;
140ae691e57SStefan Roese 
141ae691e57SStefan Roese 	if ((temp = smc911x_reg_read(E2P_CMD)) & E2P_CMD_EPC_BUSY_) {
142ae691e57SStefan Roese 		printf("%s: Busy at start, E2P_CMD=0x%08lX\n", __func__, temp);
143ae691e57SStefan Roese 		return 0;
144ae691e57SStefan Roese 	}
145ae691e57SStefan Roese 
146ae691e57SStefan Roese 	smc911x_reg_write(E2P_CMD,
147ae691e57SStefan Roese 			  (E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_READ_ |
148ae691e57SStefan Roese 			   ((ulong) address)));
149ae691e57SStefan Roese 
150ae691e57SStefan Roese 	while ((timeout > 0) && (smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY_)) {
151ae691e57SStefan Roese 		udelay(10);
152ae691e57SStefan Roese 		timeout--;
153ae691e57SStefan Roese 	}
154ae691e57SStefan Roese 
155ae691e57SStefan Roese 	if (timeout == 0) {
156ae691e57SStefan Roese 		printf("Timeout\n");
157ae691e57SStefan Roese 		return 0;
158ae691e57SStefan Roese 	}
159ae691e57SStefan Roese 	(*data) = (unchar) (smc911x_reg_read(E2P_DATA));
160ae691e57SStefan Roese 	debug("%s: ret = %x\n", __func__, (*data));
161ae691e57SStefan Roese 
162ae691e57SStefan Roese 	return 1;
163ae691e57SStefan Roese }
164ae691e57SStefan Roese 
eeprom_enable_erase_and_write(void)165ae691e57SStefan Roese static int eeprom_enable_erase_and_write(void)
166ae691e57SStefan Roese {
167ae691e57SStefan Roese 	ulong timeout = 100000;
168ae691e57SStefan Roese 
169ae691e57SStefan Roese 	if (smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY_) {
170ae691e57SStefan Roese 		printf("%s: Busy at start\n", __func__);
171ae691e57SStefan Roese 		return 0;
172ae691e57SStefan Roese 	}
173ae691e57SStefan Roese 	smc911x_reg_write(E2P_CMD, (E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_EWEN_));
174ae691e57SStefan Roese 
175ae691e57SStefan Roese 	while ((timeout > 0) && (smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY_)) {
176ae691e57SStefan Roese 		udelay(10);
177ae691e57SStefan Roese 		timeout--;
178ae691e57SStefan Roese 	}
179ae691e57SStefan Roese 
180ae691e57SStefan Roese 	if (timeout == 0) {
181ae691e57SStefan Roese 		printf("Timeout[1]\n");
182ae691e57SStefan Roese 		return 0;
183ae691e57SStefan Roese 	}
184ae691e57SStefan Roese 
185ae691e57SStefan Roese 	return 1;
186ae691e57SStefan Roese }
187ae691e57SStefan Roese 
eeprom_disable_erase_and_write(void)188ae691e57SStefan Roese static int eeprom_disable_erase_and_write(void)
189ae691e57SStefan Roese {
190ae691e57SStefan Roese 	ulong timeout = 100000;
191ae691e57SStefan Roese 
192ae691e57SStefan Roese 	if (smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY_) {
193ae691e57SStefan Roese 		printf("%s: Busy at start\n", __func__);
194ae691e57SStefan Roese 		return 0;
195ae691e57SStefan Roese 	}
196ae691e57SStefan Roese 	smc911x_reg_write(E2P_CMD, (E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_EWDS_));
197ae691e57SStefan Roese 
198ae691e57SStefan Roese 	while ((timeout > 0) && (smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY_)) {
199ae691e57SStefan Roese 		udelay(10);
200ae691e57SStefan Roese 		timeout--;
201ae691e57SStefan Roese 	}
202ae691e57SStefan Roese 
203ae691e57SStefan Roese 	if (timeout == 0) {
204ae691e57SStefan Roese 		printf("Timeout[2]\n");
205ae691e57SStefan Roese 		return 0;
206ae691e57SStefan Roese 	}
207ae691e57SStefan Roese 
208ae691e57SStefan Roese 	return 1;
209ae691e57SStefan Roese }
210ae691e57SStefan Roese 
eeprom_write_location(unchar address,unchar data)211ae691e57SStefan Roese static int eeprom_write_location(unchar address, unchar data)
212ae691e57SStefan Roese {
213ae691e57SStefan Roese 	ulong timeout = 100000;
214ae691e57SStefan Roese 
215ae691e57SStefan Roese 	debug("%s: address: %x data = %x\n", __func__, address, data);
216ae691e57SStefan Roese 
217ae691e57SStefan Roese 	if (smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY_) {
218ae691e57SStefan Roese 		printf("%s: Busy at start\n", __func__);
219ae691e57SStefan Roese 		return 0;
220ae691e57SStefan Roese 	}
221ae691e57SStefan Roese 
222ae691e57SStefan Roese 	smc911x_reg_write(E2P_DATA, ((ulong) data));
223ae691e57SStefan Roese 	smc911x_reg_write(E2P_CMD,
224ae691e57SStefan Roese 			  (E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_WRITE_ |
225ae691e57SStefan Roese 			   ((ulong) address)));
226ae691e57SStefan Roese 
227ae691e57SStefan Roese 	while ((timeout > 0) && (smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY_)) {
228ae691e57SStefan Roese 		udelay(10);
229ae691e57SStefan Roese 		timeout--;
230ae691e57SStefan Roese 	}
231ae691e57SStefan Roese 
232ae691e57SStefan Roese 	if (timeout == 0) {
233ae691e57SStefan Roese 		printf("Timeout[3]\n");
234ae691e57SStefan Roese 		return 0;
235ae691e57SStefan Roese 	}
236ae691e57SStefan Roese 
237ae691e57SStefan Roese 	return 1;
238ae691e57SStefan Roese }
239ae691e57SStefan Roese 
eeprom_erase_all(void)240ae691e57SStefan Roese static int eeprom_erase_all(void)
241ae691e57SStefan Roese {
242ae691e57SStefan Roese 	ulong timeout = 100000;
243ae691e57SStefan Roese 
244ae691e57SStefan Roese 	if (smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY_) {
245ae691e57SStefan Roese 		printf("%s: Busy at start\n", __func__);
246ae691e57SStefan Roese 		return 0;
247ae691e57SStefan Roese 	}
248ae691e57SStefan Roese 
249ae691e57SStefan Roese 	smc911x_reg_write(E2P_CMD, (E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_ERAL_));
250ae691e57SStefan Roese 
251ae691e57SStefan Roese 	while ((timeout > 0) && (smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY_)) {
252ae691e57SStefan Roese 		udelay(10);
253ae691e57SStefan Roese 		timeout--;
254ae691e57SStefan Roese 	}
255ae691e57SStefan Roese 
256ae691e57SStefan Roese 	if (timeout == 0) {
257ae691e57SStefan Roese 		printf("Timeout[4]\n");
258ae691e57SStefan Roese 		return 0;
259ae691e57SStefan Roese 	}
260ae691e57SStefan Roese 
261ae691e57SStefan Roese 	return 1;
262ae691e57SStefan Roese }
263ae691e57SStefan Roese 
eeprom_reload(void)264ae691e57SStefan Roese static int eeprom_reload(void)
265ae691e57SStefan Roese {
266ae691e57SStefan Roese 	ulong timeout = 100000;
267ae691e57SStefan Roese 
268ae691e57SStefan Roese 	if (smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY_) {
269ae691e57SStefan Roese 		printf("%s: Busy at start\n", __func__);
270ae691e57SStefan Roese 		return -1;
271ae691e57SStefan Roese 	}
272ae691e57SStefan Roese 	smc911x_reg_write(E2P_CMD,
273ae691e57SStefan Roese 			  (E2P_CMD_EPC_BUSY_ | E2P_CMD_EPC_CMD_RELOAD_));
274ae691e57SStefan Roese 
275ae691e57SStefan Roese 	while ((timeout > 0) && (smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY_)) {
276ae691e57SStefan Roese 		udelay(10);
277ae691e57SStefan Roese 		timeout--;
278ae691e57SStefan Roese 	}
279ae691e57SStefan Roese 
280ae691e57SStefan Roese 	if (timeout == 0)
281ae691e57SStefan Roese 		return 0;
282ae691e57SStefan Roese 
283ae691e57SStefan Roese 	return 1;
284ae691e57SStefan Roese }
285ae691e57SStefan Roese 
eeprom_save_mac_address(ulong dwHi16,ulong dwLo32)286ae691e57SStefan Roese static int eeprom_save_mac_address(ulong dwHi16, ulong dwLo32)
287ae691e57SStefan Roese {
288ae691e57SStefan Roese 	int result = 0;
289ae691e57SStefan Roese 
290ae691e57SStefan Roese 	debug("%s: dwHI: 0x%08lx dwLO: %08lx, \n", __func__, dwHi16, dwLo32);
291ae691e57SStefan Roese 
292ae691e57SStefan Roese 	if (!eeprom_enable_erase_and_write())
293ae691e57SStefan Roese 		goto DONE;
294ae691e57SStefan Roese 	if (!eeprom_erase_all())
295ae691e57SStefan Roese 		goto DONE;
296ae691e57SStefan Roese 	if (!eeprom_write_location(0, 0xA5))
297ae691e57SStefan Roese 		goto DONE;
298ae691e57SStefan Roese 	if (!eeprom_write_location(1, LOBYTE(LOWORD(dwLo32))))
299ae691e57SStefan Roese 		goto DONE;
300ae691e57SStefan Roese 	if (!eeprom_write_location(2, HIBYTE(LOWORD(dwLo32))))
301ae691e57SStefan Roese 		goto DONE;
302ae691e57SStefan Roese 	if (!eeprom_write_location(3, LOBYTE(HIWORD(dwLo32))))
303ae691e57SStefan Roese 		goto DONE;
304ae691e57SStefan Roese 	if (!eeprom_write_location(4, HIBYTE(HIWORD(dwLo32))))
305ae691e57SStefan Roese 		goto DONE;
306ae691e57SStefan Roese 	if (!eeprom_write_location(5, LOBYTE(LOWORD(dwHi16))))
307ae691e57SStefan Roese 		goto DONE;
308ae691e57SStefan Roese 	if (!eeprom_write_location(6, HIBYTE(LOWORD(dwHi16))))
309ae691e57SStefan Roese 		goto DONE;
310ae691e57SStefan Roese 	if (!eeprom_disable_erase_and_write())
311ae691e57SStefan Roese 		goto DONE;
312ae691e57SStefan Roese 
313ae691e57SStefan Roese 	result = 1;
314ae691e57SStefan Roese 
315ae691e57SStefan Roese DONE:
316ae691e57SStefan Roese 	return result;
317ae691e57SStefan Roese }
318ae691e57SStefan Roese 
do_eeprom_dump(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])319*54841ab5SWolfgang Denk static int do_eeprom_dump(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
320ae691e57SStefan Roese {
321ae691e57SStefan Roese 	unchar data = 0, index = 0;
322ae691e57SStefan Roese 	ulong gpio_old_val;
323ae691e57SStefan Roese 
324ae691e57SStefan Roese 	gpio_old_val = eeprom_enable_access();
325ae691e57SStefan Roese 
326ae691e57SStefan Roese 	printf("EEPROM content: \n");
327ae691e57SStefan Roese 	for (index = 0; index < 8; index++) {
328ae691e57SStefan Roese 		if (eeprom_read_location(index, &data))
329ae691e57SStefan Roese 			printf("%02x ", data);
330ae691e57SStefan Roese 		else
331ae691e57SStefan Roese 			printf("FAILED");
332ae691e57SStefan Roese 	}
333ae691e57SStefan Roese 
334ae691e57SStefan Roese 	eeprom_disable_access(gpio_old_val);
335ae691e57SStefan Roese 	printf("\n");
336ae691e57SStefan Roese 
337ae691e57SStefan Roese 	return 0;
338ae691e57SStefan Roese }
339ae691e57SStefan Roese 
do_eeprom_erase_all(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])340*54841ab5SWolfgang Denk static int do_eeprom_erase_all(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
341ae691e57SStefan Roese {
342ae691e57SStefan Roese 	eeprom_erase_all();
343ae691e57SStefan Roese 
344ae691e57SStefan Roese 	return 0;
345ae691e57SStefan Roese }
346ae691e57SStefan Roese 
do_eeprom_save_mac(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])347*54841ab5SWolfgang Denk static int do_eeprom_save_mac(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
348ae691e57SStefan Roese {
349ae691e57SStefan Roese 	ulong hi16, lo32;
350ae691e57SStefan Roese 	unchar ethaddr[6], i;
351ae691e57SStefan Roese 	ulong gpio;
352ae691e57SStefan Roese 	char *tmp, *end;
353ae691e57SStefan Roese 
354ae691e57SStefan Roese 	tmp = argv[1];
355ae691e57SStefan Roese 	for (i = 0; i < 6; i++) {
356ae691e57SStefan Roese 		ethaddr[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0;
357ae691e57SStefan Roese 		if (tmp)
358ae691e57SStefan Roese 			tmp = (*end) ? end + 1 : end;
359ae691e57SStefan Roese 	}
360ae691e57SStefan Roese 
361ae691e57SStefan Roese 	hi16 = (ethaddr[5] << 8) | (ethaddr[4]);
362ae691e57SStefan Roese 	lo32 = (ethaddr[3] << 24) | (ethaddr[2] << 16) |
363ae691e57SStefan Roese 		(ethaddr[1] << 8) | (ethaddr[0]);
364ae691e57SStefan Roese 
365ae691e57SStefan Roese 	gpio = eeprom_enable_access();
366ae691e57SStefan Roese 
367ae691e57SStefan Roese 	eeprom_save_mac_address(hi16, lo32);
368ae691e57SStefan Roese 
369ae691e57SStefan Roese 	eeprom_reload();
370ae691e57SStefan Roese 
371ae691e57SStefan Roese 	/* Check new values */
372ae691e57SStefan Roese 	if (eeprom_is_mac_address_loaded()) {
373ae691e57SStefan Roese 		ulong mac_hi16, mac_lo32;
374ae691e57SStefan Roese 
375ae691e57SStefan Roese 		mac_hi16 = get_mac_reg(MAC_ADDRH);
376ae691e57SStefan Roese 		mac_lo32 = get_mac_reg(MAC_ADDRL);
377ae691e57SStefan Roese 		printf("New MAC address: %lx, %lx\n", mac_hi16, mac_lo32);
378ae691e57SStefan Roese 	} else {
379ae691e57SStefan Roese 		printf("Address is not reloaded \n");
380ae691e57SStefan Roese 	}
381ae691e57SStefan Roese 	eeprom_disable_access(gpio);
382ae691e57SStefan Roese 
383ae691e57SStefan Roese 	return 0;
384ae691e57SStefan Roese }
385ae691e57SStefan Roese 
386ae691e57SStefan Roese U_BOOT_CMD(smcee, 1, 0, do_eeprom_erase_all,
387a89c33dbSWolfgang Denk 	   "smcee   - Erase content of SMC EEPROM",);
388ae691e57SStefan Roese 
389ae691e57SStefan Roese U_BOOT_CMD(smced, 1, 0, do_eeprom_dump,
390a89c33dbSWolfgang Denk 	   "smced   - Dump content of SMC EEPROM",);
391ae691e57SStefan Roese 
392ae691e57SStefan Roese U_BOOT_CMD(smcew, 2, 0, do_eeprom_save_mac,
393ae691e57SStefan Roese 	   "smcew   - Write MAC address to SMC EEPROM\n",
394a89c33dbSWolfgang Denk 	   "aa:bb:cc:dd:ee:ff  new mac address");
395