mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 15:14:43 +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
|
||||
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:
|
||||
==============
|
||||
|
|
|
@ -70,6 +70,7 @@ int ape_register(bd_t *bis, int iobase)
|
|||
dev->halt = ape_halt;
|
||||
dev->send = ape_send;
|
||||
dev->recv = ape_recv;
|
||||
dev->write_hwaddr = ape_write_hwaddr;
|
||||
|
||||
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
|
||||
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_send(struct eth_device *dev, volatile void *packet, int length);
|
||||
int ape_recv(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
|
||||
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
|
||||
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:
|
||||
some net operation (ping / tftp / whatever...)
|
||||
eth_init()
|
||||
|
|
|
@ -33,11 +33,13 @@ Correct flow of setting up the MAC address (summarized):
|
|||
1. Read from hardware in initialize() function
|
||||
2. Read from environment in net/eth.c after initialize()
|
||||
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
|
||||
in the board-specific board_eth_init() function by calling eth_init()
|
||||
after all the NICs have been registered.
|
||||
Previous behavior had the MAC address always being programmed into hardware
|
||||
in the device's init() function.
|
||||
|
||||
-------
|
||||
Usage
|
||||
|
|
|
@ -105,6 +105,7 @@ struct eth_device {
|
|||
#ifdef CONFIG_MCAST_TFTP
|
||||
int (*mcast) (struct eth_device*, u32 ip, u8 set);
|
||||
#endif
|
||||
int (*write_hwaddr) (struct eth_device*);
|
||||
struct eth_device *next;
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
/*
|
||||
|
@ -242,6 +250,11 @@ int eth_initialize(bd_t *bis)
|
|||
|
||||
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++;
|
||||
dev = dev->next;
|
||||
|
|
Loading…
Reference in a new issue