diff options
author | Joe Hershberger <joe.hershberger@ni.com> | 2015-03-24 02:41:49 -0500 |
---|---|---|
committer | Joe Hershberger <joe.hershberger@ni.com> | 2015-05-19 13:33:21 -0500 |
commit | f566c9949fbdce2e09a900c5343ca9986e5ba360 (patch) | |
tree | cb7bb4f188ff373695d36c02aa7b3d850b23c65b /net/eth.c | |
parent | 3d6af748ebd831524cb22a29433e9092af469ec7 (diff) | |
download | u-boot-f566c9949fbdce2e09a900c5343ca9986e5ba360.tar.gz |
net: Update hardware MAC address if it changes in env
When the ethaddr changes in the env, the hardware should also be updated
so that MAC filtering will work properly without resetting U-Boot.
Also remove the manual calls to set the hwaddr that was included in a
few drivers as a result of the framework not doing it.
Reported-by: Michal Simek <michal.simek@xilinx.com>
Signed-off-by: Joe Hershberger <joe.hershberger@ni.com>
Tested-by: Michal Simek <michal.simek@xilinx.com>
Diffstat (limited to 'net/eth.c')
-rw-r--r-- | net/eth.c | 76 |
1 files changed, 48 insertions, 28 deletions
@@ -281,6 +281,31 @@ int eth_get_dev_index(void) return -1; } +static int eth_write_hwaddr(struct udevice *dev) +{ + struct eth_pdata *pdata = dev->platdata; + int ret = 0; + + if (!dev || !device_active(dev)) + return -EINVAL; + + /* seq is valid since the device is active */ + if (eth_get_ops(dev)->write_hwaddr && !eth_mac_skip(dev->seq)) { + if (!is_valid_ethaddr(pdata->enetaddr)) { + printf("\nError: %s address %pM illegal value\n", + dev->name, pdata->enetaddr); + return -EINVAL; + } + + ret = eth_get_ops(dev)->write_hwaddr(dev); + if (ret) + printf("\nWarning: %s failed to set MAC address\n", + dev->name); + } + + return ret; +} + int eth_init(void) { struct udevice *current; @@ -300,13 +325,22 @@ int eth_init(void) if (device_active(current)) { uchar env_enetaddr[6]; struct eth_pdata *pdata = current->platdata; + int enetaddr_changed = 0; /* Sync environment with network device */ if (eth_getenv_enetaddr_by_index("eth", current->seq, - env_enetaddr)) + env_enetaddr)) { + enetaddr_changed = memcmp(pdata->enetaddr, + env_enetaddr, 6); memcpy(pdata->enetaddr, env_enetaddr, 6); - else + } else { + memset(env_enetaddr, 0, 6); + enetaddr_changed = memcmp(pdata->enetaddr, + env_enetaddr, 6); memset(pdata->enetaddr, 0, 6); + } + if (enetaddr_changed) + eth_write_hwaddr(current); ret = eth_get_ops(current)->start(current); if (ret >= 0) { @@ -401,31 +435,6 @@ int eth_rx(void) return ret; } -static int eth_write_hwaddr(struct udevice *dev) -{ - struct eth_pdata *pdata = dev->platdata; - int ret = 0; - - if (!dev || !device_active(dev)) - return -EINVAL; - - /* seq is valid since the device is active */ - if (eth_get_ops(dev)->write_hwaddr && !eth_mac_skip(dev->seq)) { - if (!is_valid_ethaddr(pdata->enetaddr)) { - printf("\nError: %s address %pM illegal value\n", - dev->name, pdata->enetaddr); - return -EINVAL; - } - - ret = eth_get_ops(dev)->write_hwaddr(dev); - if (ret) - printf("\nWarning: %s failed to set MAC address\n", - dev->name); - } - - return ret; -} - int eth_initialize(void) { int num_devices = 0; @@ -834,10 +843,21 @@ int eth_init(void) dev = eth_devices; do { uchar env_enetaddr[6]; + int enetaddr_changed = 0; if (eth_getenv_enetaddr_by_index("eth", dev->index, - env_enetaddr)) + env_enetaddr)) { + enetaddr_changed = memcmp(dev->enetaddr, + env_enetaddr, 6); memcpy(dev->enetaddr, env_enetaddr, 6); + } else { + memset(env_enetaddr, 0, 6); + enetaddr_changed = memcmp(dev->enetaddr, + env_enetaddr, 6); + memset(dev->enetaddr, 0, 6); + } + if (enetaddr_changed) + eth_write_hwaddr(dev, "eth", dev->index); dev = dev->next; } while (dev != eth_devices); |