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 186ff4137fSMike Frysinger - environment ("ethaddr", "eth1addr", ...) (see CONFIG_ETHADDR) 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 31*8e64d6efSHeiko SchocherCorrect flow of setting up the MAC address (summarized): 32*8e64d6efSHeiko Schocher 33*8e64d6efSHeiko Schocher1. Read from hardware in initialize() function 34*8e64d6efSHeiko Schocher2. Read from environment in net/eth.c after initialize() 35*8e64d6efSHeiko Schocher3. Give priority to the value in the environment if a conflict 36*8e64d6efSHeiko Schocher4. Program hardware in the device's init() function. 37*8e64d6efSHeiko Schocher 38*8e64d6efSHeiko SchocherIf somebody wants to subvert the design philosophy, this can be done 39*8e64d6efSHeiko Schocherin the board-specific board_eth_init() function by calling eth_init() 40*8e64d6efSHeiko Schocherafter all the NICs have been registered. 41*8e64d6efSHeiko Schocher 426ff4137fSMike Frysinger------- 436ff4137fSMike Frysinger Usage 446ff4137fSMike Frysinger------- 456ff4137fSMike Frysinger 466ff4137fSMike FrysingerIf the hardware design mandates that the MAC address is stored in some special 476ff4137fSMike Frysingerplace (like EEPROM etc...), then the board specific init code (such as the 486ff4137fSMike Frysingerboard-specific misc_init_r() function) is responsible for locating the MAC 496ff4137fSMike Frysingeraddress(es) and initializing the respective environment variable(s) from it. 506ff4137fSMike FrysingerNote that this shall be done if, and only if, the environment does not already 516ff4137fSMike Frysingercontain these environment variables, i.e. existing variable definitions must 526ff4137fSMike Frysingernot be overwritten. 536ff4137fSMike Frysinger 546ff4137fSMike FrysingerDuring runtime, the ethernet layer will use the environment variables to sync 556ff4137fSMike Frysingerthe MAC addresses to the ethernet structures. All ethernet driver code should 566ff4137fSMike Frysingerthen only use the enetaddr member of the eth_device structure. This is done 576ff4137fSMike Frysingeron every network command, so the ethernet copies will stay in sync. 586ff4137fSMike Frysinger 596ff4137fSMike FrysingerAny other code that wishes to access the MAC address should query the 606ff4137fSMike Frysingerenvironment directly. The helper functions documented below should make 616ff4137fSMike Frysingerworking with this storage much smoother. 626ff4137fSMike Frysinger 636ff4137fSMike Frysinger--------- 646ff4137fSMike Frysinger Helpers 656ff4137fSMike Frysinger--------- 666ff4137fSMike Frysinger 676ff4137fSMike FrysingerTo assist in the management of these layers, a few helper functions exist. You 686ff4137fSMike Frysingershould use these rather than attempt to do any kind of parsing/manipulation 696ff4137fSMike Frysingeryourself as many common errors have arisen in the past. 706ff4137fSMike Frysinger 716ff4137fSMike Frysinger * void eth_parse_enetaddr(const char *addr, uchar *enetaddr); 726ff4137fSMike Frysinger 736ff4137fSMike FrysingerConvert a string representation of a MAC address to the binary version. 746ff4137fSMike Frysingerchar *addr = "00:11:22:33:44:55"; 756ff4137fSMike Frysingeruchar enetaddr[6]; 766ff4137fSMike Frysingereth_parse_enetaddr(addr, enetaddr); 776ff4137fSMike Frysinger/* enetaddr now equals { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 } */ 786ff4137fSMike Frysinger 796ff4137fSMike Frysinger * int eth_getenv_enetaddr(char *name, uchar *enetaddr); 806ff4137fSMike Frysinger 816ff4137fSMike FrysingerLook up an environment variable and convert the stored address. If the address 826ff4137fSMike Frysingeris valid, then the function returns 1. Otherwise, the function returns 0. In 836ff4137fSMike Frysingerall cases, the enetaddr memory is initialized. If the env var is not found, 846ff4137fSMike Frysingerthen it is set to all zeros. The common function is_valid_ether_addr() is used 856ff4137fSMike Frysingerto determine address validity. 866ff4137fSMike Frysingeruchar enetaddr[6]; 876ff4137fSMike Frysingerif (!eth_getenv_enetaddr("ethaddr", enetaddr)) { 886ff4137fSMike Frysinger /* "ethaddr" is not set in the environment */ 896ff4137fSMike Frysinger ... try and setup "ethaddr" in the env ... 906ff4137fSMike Frysinger} 916ff4137fSMike Frysinger/* enetaddr is now set to the value stored in the ethaddr env var */ 926ff4137fSMike Frysinger 936ff4137fSMike Frysinger * int eth_setenv_enetaddr(char *name, const uchar *enetaddr); 946ff4137fSMike Frysinger 956ff4137fSMike FrysingerStore the MAC address into the named environment variable. The return value is 966ff4137fSMike Frysingerthe same as the setenv() function. 976ff4137fSMike Frysingeruchar enetaddr[6] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }; 986ff4137fSMike Frysingereth_setenv_enetaddr("ethaddr", enetaddr); 996ff4137fSMike Frysinger/* the "ethaddr" env var should now be set to "00:11:22:33:44:55" */ 1006ff4137fSMike Frysinger 1016ff4137fSMike Frysinger * the %pM format modifier 1026ff4137fSMike Frysinger 1036ff4137fSMike FrysingerThe %pM format modifier can be used with any standard printf function to format 1046ff4137fSMike Frysingerthe binary 6 byte array representation of a MAC address. 1056ff4137fSMike Frysingeruchar enetaddr[6] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }; 1066ff4137fSMike Frysingerprintf("The MAC is %pM\n", enetaddr); 1076ff4137fSMike Frysinger 1086ff4137fSMike Frysingerchar buf[20]; 1096ff4137fSMike Frysingersprintf(buf, "%pM", enetaddr); 1106ff4137fSMike Frysinger/* the buf variable is now set to "00:11:22:33:44:55" */ 111