diff options
author | Yizhou Jiang <yizhou.jiang@amlogic.com> | 2016-11-17 10:31:37 +0800 |
---|---|---|
committer | Haixiang Bao <haixiang.bao@amlogic.com> | 2016-11-16 21:28:41 -0800 |
commit | 47b7420dbcdb78afccd7216711bd2c5d62bc0b05 (patch) | |
tree | 47d8550491592a3f5b57ae8182fb38d697dd288e /net | |
parent | 10c0bfd34b84b76a210b57f1c62bf00b2a821b2d (diff) | |
download | u-boot-odroid-c1-47b7420dbcdb78afccd7216711bd2c5d62bc0b05.tar.gz |
PD#119623: eth: use random mac if not burn
avoid mac address conflict
avoid unnecessary testing failures
avoid wasting time to solve the unnecessary testing failures
Change-Id: I6b2f53abf35a9487f7ea8a0288012f6b1f0a289c
Diffstat (limited to 'net')
-rw-r--r-- | net/eth.c | 121 |
1 files changed, 101 insertions, 20 deletions
@@ -11,6 +11,11 @@ #include <miiphy.h> #include <phy.h> #include <asm/errno.h> +#include <amlogic/keyunify.h> +#ifdef CONFIG_RANDOM_ETHADDR +#include <asm/arch/io.h> +#include <asm/arch/secure_apb.h> +#endif void eth_parse_enetaddr(const char *addr, uchar *enetaddr) { @@ -158,35 +163,111 @@ static int eth_address_set(unsigned char *addr) return memcmp(addr, "\0\0\0\0\0\0", 6); } +#ifdef CONFIG_RANDOM_ETHADDR +static inline void eth_hw_addr_random(struct eth_device *dev) +{ + unsigned int tmp = readl(P_RNG_DATA); + + dev->enetaddr[0] = tmp&0xFF; + dev->enetaddr[1] = (tmp>>8)&0xFF; + dev->enetaddr[2] = (tmp>>16)&0xFF; + dev->enetaddr[3] = (tmp>>24)&0xFF; + + tmp = readl(P_RNG_DATA); + + dev->enetaddr[4] = tmp&0xFF; + dev->enetaddr[5] = (tmp>>8)&0xFF; + + dev->enetaddr[0] &= 0xFE; + dev->enetaddr[0] |= 0x02; +} +#endif +#ifdef CONFIG_RANDOM_ETHADDR + +static int eth_get_efuse_mac(struct eth_device *dev) +{ +#define MAC_MAX_LEN 17 + int i = 0; + int err = 0, exist = 0; + ssize_t keysize = 0; + const char* seedNum = "0x1234"; + unsigned char buf[MAC_MAX_LEN+1] = {0}; + + err = key_unify_init(seedNum, NULL); + if (err) + return err; + + err = key_unify_query_exist("mac", &exist); + if (err || (!exist)) + return -EEXIST; + + err = key_unify_query_size("mac", &keysize); + if (err) + return err; + + if (keysize != MAC_MAX_LEN) { + return -EINVAL; + } + + err = key_unify_read("mac", buf, keysize); + if (err) + return err; + + for (i=0; i<6; i++) { + buf[i*3 + 2] = '\0'; + dev->enetaddr[i] = simple_strtoul((char *)&buf[i*3], NULL, 16); + } + + return key_unify_uninit(); +} +#endif int eth_write_hwaddr(struct eth_device *dev, const char *base_name, int eth_number) { unsigned char env_enetaddr[6]; int ret = 0; +#ifdef CONFIG_RANDOM_ETHADDR + eth_get_efuse_mac(dev); +#endif - eth_getenv_enetaddr_by_index(base_name, eth_number, env_enetaddr); - - if (eth_address_set(env_enetaddr)) { - if (eth_address_set(dev->enetaddr) && - memcmp(dev->enetaddr, env_enetaddr, 6)) { - printf("\nWarning: %s MAC addresses don't match:\n", - dev->name); - printf("Address in SROM is %pM\n", + if (is_valid_ether_addr(dev->enetaddr)) { + eth_setenv_enetaddr_by_index(base_name, eth_number, + dev->enetaddr); + } else { + eth_getenv_enetaddr_by_index(base_name, eth_number, env_enetaddr); + if(env_enetaddr[0] == 0x0 && env_enetaddr[1] == 0x15 && env_enetaddr[2] == 0x18 + && env_enetaddr[3] == 0x01 && env_enetaddr[4] == 0x81 && env_enetaddr[5] == 0x31) + { +#ifdef CONFIG_RANDOM_ETHADDR + eth_hw_addr_random(dev); + eth_setenv_enetaddr_by_index(base_name, eth_number, dev->enetaddr); - printf("Address in environment is %pM\n", - env_enetaddr); +#endif } + eth_getenv_enetaddr_by_index(base_name, eth_number, env_enetaddr); + + if (eth_address_set(env_enetaddr)) { + if (eth_address_set(dev->enetaddr) && + memcmp(dev->enetaddr, env_enetaddr, 6)) { + printf("\nWarning: %s MAC addresses don't match:\n", + dev->name); + printf("Address in SROM is %pM\n", + dev->enetaddr); + printf("Address in environment is %pM\n", + env_enetaddr); + } - memcpy(dev->enetaddr, env_enetaddr, 6); - } else if (is_valid_ether_addr(dev->enetaddr)) { - eth_setenv_enetaddr_by_index(base_name, eth_number, - dev->enetaddr); - printf("\nWarning: %s using MAC address from net device\n", - dev->name); - } else if (!(eth_address_set(dev->enetaddr))) { - printf("\nError: %s address not set.\n", - dev->name); - return -EINVAL; + memcpy(dev->enetaddr, env_enetaddr, 6); + } else if (is_valid_ether_addr(dev->enetaddr)) { + eth_setenv_enetaddr_by_index(base_name, eth_number, + dev->enetaddr); + printf("\nWarning: %s using MAC address from net device\n", + dev->name); + } else if (!(eth_address_set(dev->enetaddr))) { + printf("\nError: %s address not set.\n", + dev->name); + return -EINVAL; + } } if (dev->write_hwaddr && !eth_mac_skip(eth_number)) { |