2 * (C) Copyright 2001-2004
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 * See file CREDITS for list of people who contributed to this
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 #if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI)
30 extern int ag7240_enet_initialize(bd_t * bis);
33 static struct eth_device *eth_devices, *eth_current;
35 struct eth_device *eth_get_dev(void){
40 static struct eth_device *eth_devices;
41 struct eth_device *eth_current;
44 struct eth_device *eth_get_dev_by_name(char *devname){
45 struct eth_device *dev, *target_dev;
55 if(strcmp(devname, dev->name) == 0){
60 } while(dev != eth_devices);
65 int eth_get_dev_index(void){
66 struct eth_device *dev;
73 for(dev = eth_devices; dev; dev = dev->next){
74 if(dev == eth_current){
87 int eth_register(struct eth_device* dev){
91 eth_current = eth_devices = dev;
92 #ifdef CONFIG_NET_MULTI
93 /* update current ethernet name */
94 char *act = getenv("ethact");
95 if(act == NULL || strcmp(act, eth_current->name) != 0){
96 setenv("ethact", eth_current->name);
100 for (d = eth_devices; d->next != eth_devices; d = d->next);
104 dev->state = ETH_STATE_INIT;
105 dev->next = eth_devices;
110 int eth_initialize(bd_t *bis){
112 int i, eth_number = 0;
113 char *tmp = NULL, *end = NULL;
118 #if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)
122 // ag7240 initialization
123 ag7240_enet_initialize(bis);
126 puts("## Error: no ethernet found\n");
128 struct eth_device *dev = eth_devices;
129 char *ethprime = getenv("ethprime");
137 printf("%s", dev->name);
140 if(ethprime && strcmp(dev->name, ethprime) == 0){
145 sprintf(enetvar, eth_number ? "eth%daddr" : "ethaddr", eth_number);
146 tmp = getenv(enetvar);
148 for(i = 0; i < 6; i++){
150 tmp = (*end) ? end + 1 : end;
157 } while(dev != eth_devices);
159 #ifdef CONFIG_NET_MULTI
160 /* update current ethernet name */
162 char *act = getenv("ethact");
163 if(act == NULL || strcmp(act, eth_current->name) != 0){
164 setenv("ethact", eth_current->name);
167 setenv("ethact", NULL);
177 void eth_set_enetaddr(int num, char *addr){
178 struct eth_device *dev;
179 unsigned char enetaddr[6];
183 //debug("eth_set_enetaddr(num=%d, addr=%s)\n", num, addr);
189 for(i = 0; i < 6; i++){
190 enetaddr[i] = addr ? simple_strtoul(addr, &end, 16) : 0;
192 addr = (*end) ? end + 1 : end;
200 if(dev == eth_devices){
205 //debug("Setting new HW address on %s\nNew Address is %02X:%02X:%02X:%02X:%02X:%02X\n", dev->name, enetaddr[0], enetaddr[1], enetaddr[2], enetaddr[3], enetaddr[4], enetaddr[5]);
206 memcpy(dev->enetaddr, enetaddr, 6);
209 int eth_init(bd_t *bis){
210 struct eth_device* old_current;
216 old_current = eth_current;
219 #if !defined(CFG_ATHRS26_PHY) && !defined(CFG_ATHRHDR_EN)
220 //debug("Trying %s\n", eth_current->name);
222 if(eth_current->init(eth_current, bis)){
223 eth_current->state = ETH_STATE_ACTIVE;
230 } while(old_current != eth_current);
240 eth_current->halt(eth_current);
241 eth_current->state = ETH_STATE_PASSIVE;
244 int eth_send(volatile void *packet, int length){
249 return(eth_current->send(eth_current, packet, length));
257 return(eth_current->recv(eth_current));
260 void eth_try_another(int first_restart){
261 static struct eth_device *first_failed = NULL;
268 first_failed = eth_current;
271 eth_current = eth_current->next;
273 #ifdef CONFIG_NET_MULTI
274 /* update current ethernet name */
275 char *act = getenv("ethact");
276 if(act == NULL || strcmp(act, eth_current->name) != 0){
277 setenv("ethact", eth_current->name);
281 if (first_failed == eth_current){
286 #ifdef CONFIG_NET_MULTI
287 void eth_set_current(void){
290 struct eth_device* old_current;
296 act = getenv("ethact");
299 old_current = eth_current;
301 if(strcmp(eth_current->name, act) == 0){
304 eth_current = eth_current->next;
305 } while(old_current != eth_current);
308 setenv("ethact", eth_current->name);
312 char *eth_get_name(void){
313 return(eth_current ? eth_current->name : "unknown");
315 #elif (CONFIG_COMMANDS & CFG_CMD_NET) && !defined(CONFIG_NET_MULTI)
317 int eth_initialize(bd_t *bis){
318 #if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)