xref: /openbmc/u-boot/doc/README.enetaddr (revision 35affd7a2ff9a77b9946bf93b616228fcf218d60)
16ff4137fSMike Frysinger---------------------------------
26ff4137fSMike Frysinger Ethernet Address (MAC) Handling
36ff4137fSMike Frysinger---------------------------------
46ff4137fSMike Frysinger
56ff4137fSMike FrysingerThere are a variety of places in U-Boot where the MAC address is used, parsed,
66ff4137fSMike Frysingerand stored.  This document covers proper usage of each location and the moving
76ff4137fSMike Frysingerof data between them.
86ff4137fSMike Frysinger
96ff4137fSMike Frysinger-----------
106ff4137fSMike Frysinger Locations
116ff4137fSMike Frysinger-----------
126ff4137fSMike Frysinger
136ff4137fSMike FrysingerHere are the places where MAC addresses might be stored:
146ff4137fSMike Frysinger
156ff4137fSMike Frysinger - board-specific location (eeprom, dedicated flash, ...)
166ff4137fSMike Frysinger	Note: only used when mandatory due to hardware design etc...
176ff4137fSMike Frysinger
1892ac5208SJoe Hershberger - environment ("ethaddr", "eth1addr", ...)
196ff4137fSMike Frysinger	Note: this is the preferred way to permanently store MAC addresses
206ff4137fSMike Frysinger
216ff4137fSMike Frysinger - ethernet data (struct eth_device -> enetaddr)
226ff4137fSMike Frysinger	Note: these are temporary copies of the MAC address which exist only
236ff4137fSMike Frysinger	      after the respective init steps have run and only to make usage
246ff4137fSMike Frysinger	      in other places easier (to avoid constant env lookup/parsing)
256ff4137fSMike Frysinger
266ff4137fSMike Frysinger - struct bd_info and/or device tree
276ff4137fSMike Frysinger	Note: these are temporary copies of the MAC address only for the
286ff4137fSMike Frysinger	      purpose of passing this information to an OS kernel we are about
296ff4137fSMike Frysinger	      to boot
306ff4137fSMike Frysinger
318e64d6efSHeiko SchocherCorrect flow of setting up the MAC address (summarized):
328e64d6efSHeiko Schocher
338e64d6efSHeiko Schocher1. Read from hardware in initialize() function
348e64d6efSHeiko Schocher2. Read from environment in net/eth.c after initialize()
35c88ef3c1SRob Herring3. The environment variable will be compared to the driver initialized
36c88ef3c1SRob Herring   struct eth_device->enetaddr. If they differ, a warning is printed, and the
37c88ef3c1SRob Herring   environment variable will be used unchanged.
38c88ef3c1SRob Herring   If the environment variable is not set, it will be initialized from
39c88ef3c1SRob Herring   eth_device->enetaddr, and a warning will be printed.
40bef1014bSJoe Hershberger   If both are invalid and CONFIG_NET_RANDOM_ETHADDR is defined, a random,
41bef1014bSJoe Hershberger   locally-assigned MAC is written to eth_device->enetaddr.
42ecee9324SBen Warren4. Program the address into hardware if the following conditions are met:
43ecee9324SBen Warren	a) The relevant driver has a 'write_addr' function
44ecee9324SBen Warren	b) The user hasn't set an 'ethmacskip' environment variable
45ecee9324SBen Warren	c) The address is valid (unicast, not all-zeros)
468e64d6efSHeiko Schocher
47ecee9324SBen WarrenPrevious behavior had the MAC address always being programmed into hardware
48ecee9324SBen Warrenin the device's init() function.
498e64d6efSHeiko Schocher
506ff4137fSMike Frysinger-------
516ff4137fSMike Frysinger Usage
526ff4137fSMike Frysinger-------
536ff4137fSMike Frysinger
546ff4137fSMike FrysingerIf the hardware design mandates that the MAC address is stored in some special
556ff4137fSMike Frysingerplace (like EEPROM etc...), then the board specific init code (such as the
566ff4137fSMike Frysingerboard-specific misc_init_r() function) is responsible for locating the MAC
576ff4137fSMike Frysingeraddress(es) and initializing the respective environment variable(s) from it.
586ff4137fSMike FrysingerNote that this shall be done if, and only if, the environment does not already
596ff4137fSMike Frysingercontain these environment variables, i.e. existing variable definitions must
606ff4137fSMike Frysingernot be overwritten.
616ff4137fSMike Frysinger
626ff4137fSMike FrysingerDuring runtime, the ethernet layer will use the environment variables to sync
636ff4137fSMike Frysingerthe MAC addresses to the ethernet structures.  All ethernet driver code should
646ff4137fSMike Frysingerthen only use the enetaddr member of the eth_device structure.  This is done
656ff4137fSMike Frysingeron every network command, so the ethernet copies will stay in sync.
666ff4137fSMike Frysinger
676ff4137fSMike FrysingerAny other code that wishes to access the MAC address should query the
686ff4137fSMike Frysingerenvironment directly.  The helper functions documented below should make
696ff4137fSMike Frysingerworking with this storage much smoother.
706ff4137fSMike Frysinger
716ff4137fSMike Frysinger---------
726ff4137fSMike Frysinger Helpers
736ff4137fSMike Frysinger---------
746ff4137fSMike Frysinger
756ff4137fSMike FrysingerTo assist in the management of these layers, a few helper functions exist.  You
766ff4137fSMike Frysingershould use these rather than attempt to do any kind of parsing/manipulation
776ff4137fSMike Frysingeryourself as many common errors have arisen in the past.
786ff4137fSMike Frysinger
796ff4137fSMike Frysinger	* void eth_parse_enetaddr(const char *addr, uchar *enetaddr);
806ff4137fSMike Frysinger
816ff4137fSMike FrysingerConvert a string representation of a MAC address to the binary version.
826ff4137fSMike Frysingerchar *addr = "00:11:22:33:44:55";
836ff4137fSMike Frysingeruchar enetaddr[6];
846ff4137fSMike Frysingereth_parse_enetaddr(addr, enetaddr);
856ff4137fSMike Frysinger/* enetaddr now equals { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 } */
866ff4137fSMike Frysinger
87*35affd7aSSimon Glass	* int eth_env_get_enetaddr(char *name, uchar *enetaddr);
886ff4137fSMike Frysinger
896ff4137fSMike FrysingerLook up an environment variable and convert the stored address.  If the address
906ff4137fSMike Frysingeris valid, then the function returns 1.  Otherwise, the function returns 0.  In
916ff4137fSMike Frysingerall cases, the enetaddr memory is initialized.  If the env var is not found,
920adb5b76SJoe Hershbergerthen it is set to all zeros.  The common function is_valid_ethaddr() is used
936ff4137fSMike Frysingerto determine address validity.
946ff4137fSMike Frysingeruchar enetaddr[6];
95*35affd7aSSimon Glassif (!eth_env_get_enetaddr("ethaddr", enetaddr)) {
966ff4137fSMike Frysinger	/* "ethaddr" is not set in the environment */
976ff4137fSMike Frysinger	... try and setup "ethaddr" in the env ...
986ff4137fSMike Frysinger}
996ff4137fSMike Frysinger/* enetaddr is now set to the value stored in the ethaddr env var */
1006ff4137fSMike Frysinger
101fd1e959eSSimon Glass	* int eth_env_set_enetaddr(char *name, const uchar *enetaddr);
1026ff4137fSMike Frysinger
1036ff4137fSMike FrysingerStore the MAC address into the named environment variable.  The return value is
104382bee57SSimon Glassthe same as the env_set() function.
1056ff4137fSMike Frysingeruchar enetaddr[6] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 };
106fd1e959eSSimon Glasseth_env_set_enetaddr("ethaddr", enetaddr);
1076ff4137fSMike Frysinger/* the "ethaddr" env var should now be set to "00:11:22:33:44:55" */
1086ff4137fSMike Frysinger
1096ff4137fSMike Frysinger	* the %pM format modifier
1106ff4137fSMike Frysinger
1116ff4137fSMike FrysingerThe %pM format modifier can be used with any standard printf function to format
1126ff4137fSMike Frysingerthe binary 6 byte array representation of a MAC address.
1136ff4137fSMike Frysingeruchar enetaddr[6] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 };
1146ff4137fSMike Frysingerprintf("The MAC is %pM\n", enetaddr);
1156ff4137fSMike Frysinger
1166ff4137fSMike Frysingerchar buf[20];
1176ff4137fSMike Frysingersprintf(buf, "%pM", enetaddr);
1186ff4137fSMike Frysinger/* the buf variable is now set to "00:11:22:33:44:55" */
119