xref: /openbmc/u-boot/doc/README.enetaddr (revision 6ff4137f2ad640e4fc8ea1b0455161ddff1f6730)
1*6ff4137fSMike Frysinger---------------------------------
2*6ff4137fSMike Frysinger Ethernet Address (MAC) Handling
3*6ff4137fSMike Frysinger---------------------------------
4*6ff4137fSMike Frysinger
5*6ff4137fSMike FrysingerThere are a variety of places in U-Boot where the MAC address is used, parsed,
6*6ff4137fSMike Frysingerand stored.  This document covers proper usage of each location and the moving
7*6ff4137fSMike Frysingerof data between them.
8*6ff4137fSMike Frysinger
9*6ff4137fSMike Frysinger-----------
10*6ff4137fSMike Frysinger Locations
11*6ff4137fSMike Frysinger-----------
12*6ff4137fSMike Frysinger
13*6ff4137fSMike FrysingerHere are the places where MAC addresses might be stored:
14*6ff4137fSMike Frysinger
15*6ff4137fSMike Frysinger - board-specific location (eeprom, dedicated flash, ...)
16*6ff4137fSMike Frysinger	Note: only used when mandatory due to hardware design etc...
17*6ff4137fSMike Frysinger
18*6ff4137fSMike Frysinger - environment ("ethaddr", "eth1addr", ...) (see CONFIG_ETHADDR)
19*6ff4137fSMike Frysinger	Note: this is the preferred way to permanently store MAC addresses
20*6ff4137fSMike Frysinger
21*6ff4137fSMike Frysinger - ethernet data (struct eth_device -> enetaddr)
22*6ff4137fSMike Frysinger	Note: these are temporary copies of the MAC address which exist only
23*6ff4137fSMike Frysinger	      after the respective init steps have run and only to make usage
24*6ff4137fSMike Frysinger	      in other places easier (to avoid constant env lookup/parsing)
25*6ff4137fSMike Frysinger
26*6ff4137fSMike Frysinger - struct bd_info and/or device tree
27*6ff4137fSMike Frysinger	Note: these are temporary copies of the MAC address only for the
28*6ff4137fSMike Frysinger	      purpose of passing this information to an OS kernel we are about
29*6ff4137fSMike Frysinger	      to boot
30*6ff4137fSMike Frysinger
31*6ff4137fSMike Frysinger-------
32*6ff4137fSMike Frysinger Usage
33*6ff4137fSMike Frysinger-------
34*6ff4137fSMike Frysinger
35*6ff4137fSMike FrysingerIf the hardware design mandates that the MAC address is stored in some special
36*6ff4137fSMike Frysingerplace (like EEPROM etc...), then the board specific init code (such as the
37*6ff4137fSMike Frysingerboard-specific misc_init_r() function) is responsible for locating the MAC
38*6ff4137fSMike Frysingeraddress(es) and initializing the respective environment variable(s) from it.
39*6ff4137fSMike FrysingerNote that this shall be done if, and only if, the environment does not already
40*6ff4137fSMike Frysingercontain these environment variables, i.e. existing variable definitions must
41*6ff4137fSMike Frysingernot be overwritten.
42*6ff4137fSMike Frysinger
43*6ff4137fSMike FrysingerDuring runtime, the ethernet layer will use the environment variables to sync
44*6ff4137fSMike Frysingerthe MAC addresses to the ethernet structures.  All ethernet driver code should
45*6ff4137fSMike Frysingerthen only use the enetaddr member of the eth_device structure.  This is done
46*6ff4137fSMike Frysingeron every network command, so the ethernet copies will stay in sync.
47*6ff4137fSMike Frysinger
48*6ff4137fSMike FrysingerAny other code that wishes to access the MAC address should query the
49*6ff4137fSMike Frysingerenvironment directly.  The helper functions documented below should make
50*6ff4137fSMike Frysingerworking with this storage much smoother.
51*6ff4137fSMike Frysinger
52*6ff4137fSMike Frysinger---------
53*6ff4137fSMike Frysinger Helpers
54*6ff4137fSMike Frysinger---------
55*6ff4137fSMike Frysinger
56*6ff4137fSMike FrysingerTo assist in the management of these layers, a few helper functions exist.  You
57*6ff4137fSMike Frysingershould use these rather than attempt to do any kind of parsing/manipulation
58*6ff4137fSMike Frysingeryourself as many common errors have arisen in the past.
59*6ff4137fSMike Frysinger
60*6ff4137fSMike Frysinger	* void eth_parse_enetaddr(const char *addr, uchar *enetaddr);
61*6ff4137fSMike Frysinger
62*6ff4137fSMike FrysingerConvert a string representation of a MAC address to the binary version.
63*6ff4137fSMike Frysingerchar *addr = "00:11:22:33:44:55";
64*6ff4137fSMike Frysingeruchar enetaddr[6];
65*6ff4137fSMike Frysingereth_parse_enetaddr(addr, enetaddr);
66*6ff4137fSMike Frysinger/* enetaddr now equals { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 } */
67*6ff4137fSMike Frysinger
68*6ff4137fSMike Frysinger	* int eth_getenv_enetaddr(char *name, uchar *enetaddr);
69*6ff4137fSMike Frysinger
70*6ff4137fSMike FrysingerLook up an environment variable and convert the stored address.  If the address
71*6ff4137fSMike Frysingeris valid, then the function returns 1.  Otherwise, the function returns 0.  In
72*6ff4137fSMike Frysingerall cases, the enetaddr memory is initialized.  If the env var is not found,
73*6ff4137fSMike Frysingerthen it is set to all zeros.  The common function is_valid_ether_addr() is used
74*6ff4137fSMike Frysingerto determine address validity.
75*6ff4137fSMike Frysingeruchar enetaddr[6];
76*6ff4137fSMike Frysingerif (!eth_getenv_enetaddr("ethaddr", enetaddr)) {
77*6ff4137fSMike Frysinger	/* "ethaddr" is not set in the environment */
78*6ff4137fSMike Frysinger	... try and setup "ethaddr" in the env ...
79*6ff4137fSMike Frysinger}
80*6ff4137fSMike Frysinger/* enetaddr is now set to the value stored in the ethaddr env var */
81*6ff4137fSMike Frysinger
82*6ff4137fSMike Frysinger	* int eth_setenv_enetaddr(char *name, const uchar *enetaddr);
83*6ff4137fSMike Frysinger
84*6ff4137fSMike FrysingerStore the MAC address into the named environment variable.  The return value is
85*6ff4137fSMike Frysingerthe same as the setenv() function.
86*6ff4137fSMike Frysingeruchar enetaddr[6] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 };
87*6ff4137fSMike Frysingereth_setenv_enetaddr("ethaddr", enetaddr);
88*6ff4137fSMike Frysinger/* the "ethaddr" env var should now be set to "00:11:22:33:44:55" */
89*6ff4137fSMike Frysinger
90*6ff4137fSMike Frysinger	* the %pM format modifier
91*6ff4137fSMike Frysinger
92*6ff4137fSMike FrysingerThe %pM format modifier can be used with any standard printf function to format
93*6ff4137fSMike Frysingerthe binary 6 byte array representation of a MAC address.
94*6ff4137fSMike Frysingeruchar enetaddr[6] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 };
95*6ff4137fSMike Frysingerprintf("The MAC is %pM\n", enetaddr);
96*6ff4137fSMike Frysinger
97*6ff4137fSMike Frysingerchar buf[20];
98*6ff4137fSMike Frysingersprintf(buf, "%pM", enetaddr);
99*6ff4137fSMike Frysinger/* the buf variable is now set to "00:11:22:33:44:55" */
100