Commit ecee9324d73555e744593f3e0d387bec4c566f55
1 parent
c960b13ed2
Exists in
master
and in
54 other branches
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>
Showing 5 changed files with 31 additions and 5 deletions Side-by-side Diff
README
... | ... | @@ -3303,6 +3303,11 @@ |
3303 | 3303 | o If neither SROM nor the environment contain a MAC address, an error |
3304 | 3304 | is raised. |
3305 | 3305 | |
3306 | +If Ethernet drivers implement the 'write_hwaddr' function, valid MAC addresses | |
3307 | +will be programmed into hardware as part of the initialization process. This | |
3308 | +may be skipped by setting the appropriate 'ethmacskip' environment variable. | |
3309 | +The naming convention is as follows: | |
3310 | +"ethmacskip" (=>eth0), "eth1macskip" (=>eth1) etc. | |
3306 | 3311 | |
3307 | 3312 | Image Formats: |
3308 | 3313 | ============== |
doc/README.drivers.eth
... | ... | @@ -70,6 +70,7 @@ |
70 | 70 | dev->halt = ape_halt; |
71 | 71 | dev->send = ape_send; |
72 | 72 | dev->recv = ape_recv; |
73 | + dev->write_hwaddr = ape_write_hwaddr; | |
73 | 74 | |
74 | 75 | eth_register(dev); |
75 | 76 | |
76 | 77 | |
... | ... | @@ -102,11 +103,12 @@ |
102 | 103 | ----------- |
103 | 104 | |
104 | 105 | Now that we've registered with the ethernet layer, we can start getting some |
105 | -real work done. You will need four functions: | |
106 | +real work done. You will need five functions: | |
106 | 107 | int ape_init(struct eth_device *dev, bd_t *bis); |
107 | 108 | int ape_send(struct eth_device *dev, volatile void *packet, int length); |
108 | 109 | int ape_recv(struct eth_device *dev); |
109 | 110 | int ape_halt(struct eth_device *dev); |
111 | + int ape_write_hwaddr(struct eth_device *dev); | |
110 | 112 | |
111 | 113 | The init function checks the hardware (probing/identifying) and gets it ready |
112 | 114 | for send/recv operations. You often do things here such as resetting the MAC |
... | ... | @@ -149,6 +151,9 @@ |
149 | 151 | The halt function should turn off / disable the hardware and place it back in |
150 | 152 | its reset state. It can be called at any time (before any call to the related |
151 | 153 | init function), so make sure it can handle this sort of thing. |
154 | + | |
155 | +The write_hwaddr function should program the MAC address stored in dev->enetaddr | |
156 | +into the Ethernet controller. | |
152 | 157 | |
153 | 158 | So the call graph at this stage would look something like: |
154 | 159 | some net operation (ping / tftp / whatever...) |
doc/README.enetaddr
... | ... | @@ -33,11 +33,13 @@ |
33 | 33 | 1. Read from hardware in initialize() function |
34 | 34 | 2. Read from environment in net/eth.c after initialize() |
35 | 35 | 3. Give priority to the value in the environment if a conflict |
36 | -4. Program hardware in the device's init() function. | |
36 | +4. Program the address into hardware if the following conditions are met: | |
37 | + a) The relevant driver has a 'write_addr' function | |
38 | + b) The user hasn't set an 'ethmacskip' environment variable | |
39 | + c) The address is valid (unicast, not all-zeros) | |
37 | 40 | |
38 | -If somebody wants to subvert the design philosophy, this can be done | |
39 | -in the board-specific board_eth_init() function by calling eth_init() | |
40 | -after all the NICs have been registered. | |
41 | +Previous behavior had the MAC address always being programmed into hardware | |
42 | +in the device's init() function. | |
41 | 43 | |
42 | 44 | ------- |
43 | 45 | Usage |
include/net.h
net/eth.c
... | ... | @@ -60,6 +60,14 @@ |
60 | 60 | return eth_getenv_enetaddr(enetvar, enetaddr); |
61 | 61 | } |
62 | 62 | |
63 | +static int eth_mac_skip(int index) | |
64 | +{ | |
65 | + char enetvar[15]; | |
66 | + char *skip_state; | |
67 | + sprintf(enetvar, index ? "eth%dmacskip" : "ethmacskip", index); | |
68 | + return ((skip_state = getenv(enetvar)) != NULL); | |
69 | +} | |
70 | + | |
63 | 71 | #ifdef CONFIG_NET_MULTI |
64 | 72 | |
65 | 73 | /* |
... | ... | @@ -241,6 +249,11 @@ |
241 | 249 | } |
242 | 250 | |
243 | 251 | memcpy(dev->enetaddr, env_enetaddr, 6); |
252 | + } | |
253 | + if (dev->write_hwaddr && | |
254 | + !eth_mac_skip(eth_number) && | |
255 | + is_valid_ether_addr(dev->enetaddr)) { | |
256 | + dev->write_hwaddr(dev); | |
244 | 257 | } |
245 | 258 | |
246 | 259 | eth_number++; |