mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-24 21:54:01 +00:00
Program net device MAC addresses after initializing
Add a new function to the eth_device struct for programming a network controller's hardware address. After all network devices have been initialized and the proper MAC address for each has been determined, make a device driver call to program the address into the device. Only device instances with valid unicast addresses will be programmed. Signed-off-by: Ben Warren <biggerbadderben@gmail.com> Acked-by: Detlev Zundel <dzu@denx.de> Tested-by: Prafulla Wadaskar <prafulla@marvell.com> Tested-by: Heiko Schocher <hs@denx.de> Tested-by: Thomas Chou <thomas@wytron.com.tw>
This commit is contained in:
parent
c960b13ed2
commit
ecee9324d7
5 changed files with 31 additions and 5 deletions
5
README
5
README
|
@ -3303,6 +3303,11 @@ o If both the SROM and the environment contain a MAC address, and the
|
||||||
o If neither SROM nor the environment contain a MAC address, an error
|
o If neither SROM nor the environment contain a MAC address, an error
|
||||||
is raised.
|
is raised.
|
||||||
|
|
||||||
|
If Ethernet drivers implement the 'write_hwaddr' function, valid MAC addresses
|
||||||
|
will be programmed into hardware as part of the initialization process. This
|
||||||
|
may be skipped by setting the appropriate 'ethmacskip' environment variable.
|
||||||
|
The naming convention is as follows:
|
||||||
|
"ethmacskip" (=>eth0), "eth1macskip" (=>eth1) etc.
|
||||||
|
|
||||||
Image Formats:
|
Image Formats:
|
||||||
==============
|
==============
|
||||||
|
|
|
@ -70,6 +70,7 @@ int ape_register(bd_t *bis, int iobase)
|
||||||
dev->halt = ape_halt;
|
dev->halt = ape_halt;
|
||||||
dev->send = ape_send;
|
dev->send = ape_send;
|
||||||
dev->recv = ape_recv;
|
dev->recv = ape_recv;
|
||||||
|
dev->write_hwaddr = ape_write_hwaddr;
|
||||||
|
|
||||||
eth_register(dev);
|
eth_register(dev);
|
||||||
|
|
||||||
|
@ -102,11 +103,12 @@ not checking its state or doing random probing.
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
Now that we've registered with the ethernet layer, we can start getting some
|
Now that we've registered with the ethernet layer, we can start getting some
|
||||||
real work done. You will need four functions:
|
real work done. You will need five functions:
|
||||||
int ape_init(struct eth_device *dev, bd_t *bis);
|
int ape_init(struct eth_device *dev, bd_t *bis);
|
||||||
int ape_send(struct eth_device *dev, volatile void *packet, int length);
|
int ape_send(struct eth_device *dev, volatile void *packet, int length);
|
||||||
int ape_recv(struct eth_device *dev);
|
int ape_recv(struct eth_device *dev);
|
||||||
int ape_halt(struct eth_device *dev);
|
int ape_halt(struct eth_device *dev);
|
||||||
|
int ape_write_hwaddr(struct eth_device *dev);
|
||||||
|
|
||||||
The init function checks the hardware (probing/identifying) and gets it ready
|
The init function checks the hardware (probing/identifying) and gets it ready
|
||||||
for send/recv operations. You often do things here such as resetting the MAC
|
for send/recv operations. You often do things here such as resetting the MAC
|
||||||
|
@ -150,6 +152,9 @@ The halt function should turn off / disable the hardware and place it back in
|
||||||
its reset state. It can be called at any time (before any call to the related
|
its reset state. It can be called at any time (before any call to the related
|
||||||
init function), so make sure it can handle this sort of thing.
|
init function), so make sure it can handle this sort of thing.
|
||||||
|
|
||||||
|
The write_hwaddr function should program the MAC address stored in dev->enetaddr
|
||||||
|
into the Ethernet controller.
|
||||||
|
|
||||||
So the call graph at this stage would look something like:
|
So the call graph at this stage would look something like:
|
||||||
some net operation (ping / tftp / whatever...)
|
some net operation (ping / tftp / whatever...)
|
||||||
eth_init()
|
eth_init()
|
||||||
|
|
|
@ -33,11 +33,13 @@ Correct flow of setting up the MAC address (summarized):
|
||||||
1. Read from hardware in initialize() function
|
1. Read from hardware in initialize() function
|
||||||
2. Read from environment in net/eth.c after initialize()
|
2. Read from environment in net/eth.c after initialize()
|
||||||
3. Give priority to the value in the environment if a conflict
|
3. Give priority to the value in the environment if a conflict
|
||||||
4. Program hardware in the device's init() function.
|
4. Program the address into hardware if the following conditions are met:
|
||||||
|
a) The relevant driver has a 'write_addr' function
|
||||||
|
b) The user hasn't set an 'ethmacskip' environment variable
|
||||||
|
c) The address is valid (unicast, not all-zeros)
|
||||||
|
|
||||||
If somebody wants to subvert the design philosophy, this can be done
|
Previous behavior had the MAC address always being programmed into hardware
|
||||||
in the board-specific board_eth_init() function by calling eth_init()
|
in the device's init() function.
|
||||||
after all the NICs have been registered.
|
|
||||||
|
|
||||||
-------
|
-------
|
||||||
Usage
|
Usage
|
||||||
|
|
|
@ -105,6 +105,7 @@ struct eth_device {
|
||||||
#ifdef CONFIG_MCAST_TFTP
|
#ifdef CONFIG_MCAST_TFTP
|
||||||
int (*mcast) (struct eth_device*, u32 ip, u8 set);
|
int (*mcast) (struct eth_device*, u32 ip, u8 set);
|
||||||
#endif
|
#endif
|
||||||
|
int (*write_hwaddr) (struct eth_device*);
|
||||||
struct eth_device *next;
|
struct eth_device *next;
|
||||||
void *priv;
|
void *priv;
|
||||||
};
|
};
|
||||||
|
|
13
net/eth.c
13
net/eth.c
|
@ -60,6 +60,14 @@ int eth_getenv_enetaddr_by_index(int index, uchar *enetaddr)
|
||||||
return eth_getenv_enetaddr(enetvar, enetaddr);
|
return eth_getenv_enetaddr(enetvar, enetaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int eth_mac_skip(int index)
|
||||||
|
{
|
||||||
|
char enetvar[15];
|
||||||
|
char *skip_state;
|
||||||
|
sprintf(enetvar, index ? "eth%dmacskip" : "ethmacskip", index);
|
||||||
|
return ((skip_state = getenv(enetvar)) != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_NET_MULTI
|
#ifdef CONFIG_NET_MULTI
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -242,6 +250,11 @@ int eth_initialize(bd_t *bis)
|
||||||
|
|
||||||
memcpy(dev->enetaddr, env_enetaddr, 6);
|
memcpy(dev->enetaddr, env_enetaddr, 6);
|
||||||
}
|
}
|
||||||
|
if (dev->write_hwaddr &&
|
||||||
|
!eth_mac_skip(eth_number) &&
|
||||||
|
is_valid_ether_addr(dev->enetaddr)) {
|
||||||
|
dev->write_hwaddr(dev);
|
||||||
|
}
|
||||||
|
|
||||||
eth_number++;
|
eth_number++;
|
||||||
dev = dev->next;
|
dev = dev->next;
|
||||||
|
|
Loading…
Reference in a new issue