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 defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI)
31 #if defined(CONFIG_ATHEROS)
32 extern int ath_gmac_enet_initialize(bd_t * bis);
34 extern int ag7240_enet_initialize(bd_t * bis);
38 static struct eth_device *eth_devices, *eth_current;
40 struct eth_device *eth_get_dev(void){
45 static struct eth_device *eth_devices;
46 struct eth_device *eth_current;
49 struct eth_device *eth_get_dev_by_name(char *devname){
50 struct eth_device *dev, *target_dev;
60 if(strcmp(devname, dev->name) == 0){
65 } while(dev != eth_devices);
70 int eth_get_dev_index(void){
71 struct eth_device *dev;
78 for(dev = eth_devices; dev; dev = dev->next){
79 if(dev == eth_current){
92 int eth_register(struct eth_device* dev){
96 eth_current = eth_devices = dev;
97 #ifdef CONFIG_NET_MULTI
98 /* update current ethernet name */
99 char *act = getenv("ethact");
100 if(act == NULL || strcmp(act, eth_current->name) != 0){
101 setenv("ethact", eth_current->name);
105 for (d = eth_devices; d->next != eth_devices; d = d->next);
109 dev->state = ETH_STATE_INIT;
110 dev->next = eth_devices;
115 int eth_initialize(bd_t *bis){
117 int i, eth_number = 0;
118 char *tmp = NULL, *end = NULL;
123 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
127 // ag7240 initialization
128 #if defined(CONFIG_ATHEROS)
129 ath_gmac_enet_initialize(bis);
131 ag7240_enet_initialize(bis);
135 printf_err("no ethernet found\n");
137 struct eth_device *dev = eth_devices;
138 char *ethprime = getenv("ethprime");
146 printf("%s", dev->name);
149 if(ethprime && strcmp(dev->name, ethprime) == 0){
154 sprintf(enetvar, eth_number ? "eth%daddr" : "ethaddr", eth_number);
155 tmp = getenv(enetvar);
157 for(i = 0; i < 6; i++){
159 tmp = (*end) ? end + 1 : end;
166 } while(dev != eth_devices);
168 #ifdef CONFIG_NET_MULTI
169 /* update current ethernet name */
171 char *act = getenv("ethact");
172 if(act == NULL || strcmp(act, eth_current->name) != 0){
173 setenv("ethact", eth_current->name);
176 setenv("ethact", NULL);
186 void eth_set_enetaddr(int num, char *addr){
187 struct eth_device *dev;
188 unsigned char enetaddr[6];
192 //debug("eth_set_enetaddr(num=%d, addr=%s)\n", num, addr);
198 for(i = 0; i < 6; i++){
199 enetaddr[i] = addr ? simple_strtoul(addr, &end, 16) : 0;
201 addr = (*end) ? end + 1 : end;
209 if(dev == eth_devices){
214 //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]);
215 memcpy(dev->enetaddr, enetaddr, 6);
218 int eth_init(bd_t *bis){
219 struct eth_device* old_current;
225 old_current = eth_current;
228 #if !defined(CFG_ATHRS26_PHY) && !defined(CFG_ATHRHDR_EN)
229 //debug("Trying %s\n", eth_current->name);
231 if(eth_current->init(eth_current, bis)){
232 eth_current->state = ETH_STATE_ACTIVE;
239 } while(old_current != eth_current);
249 eth_current->halt(eth_current);
250 eth_current->state = ETH_STATE_PASSIVE;
253 int eth_send(volatile void *packet, int length){
258 return(eth_current->send(eth_current, packet, length));
266 return(eth_current->recv(eth_current));
269 void eth_try_another(int first_restart){
270 static struct eth_device *first_failed = NULL;
277 first_failed = eth_current;
280 eth_current = eth_current->next;
282 #ifdef CONFIG_NET_MULTI
283 /* update current ethernet name */
284 char *act = getenv("ethact");
285 if(act == NULL || strcmp(act, eth_current->name) != 0){
286 setenv("ethact", eth_current->name);
290 if (first_failed == eth_current){
295 #ifdef CONFIG_NET_MULTI
296 void eth_set_current(void){
299 struct eth_device* old_current;
305 act = getenv("ethact");
308 old_current = eth_current;
310 if(strcmp(eth_current->name, act) == 0){
313 eth_current = eth_current->next;
314 } while(old_current != eth_current);
317 setenv("ethact", eth_current->name);
321 char *eth_get_name(void){
322 return(eth_current ? eth_current->name : "unknown");
324 #elif defined(CONFIG_CMD_NET) && !defined(CONFIG_NET_MULTI)
326 int eth_initialize(bd_t *bis){
327 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)