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>
This commit is contained in:
Joe Hershberger 2015-03-24 02:41:49 -05:00
parent 3d6af748eb
commit f566c9949f
4 changed files with 48 additions and 47 deletions

View File

@ -154,12 +154,6 @@ static int bcm_sf2_eth_open(struct eth_device *dev, bd_t *bt)
debug("Enabling BCM SF2 Ethernet.\n");
/* Set MAC address from env */
if (bcm_sf2_eth_write_hwaddr(dev) != 0) {
error("%s: MAC set error when opening !\n", __func__);
return -1;
}
eth->enable_mac();
/* enable tx and rx DMA */

View File

@ -243,10 +243,6 @@ static int _dw_eth_init(struct dw_eth_dev *priv, u8 *enetaddr)
mdelay(100);
};
/* Soft reset above clears HW address registers.
* So we have to set it here once again */
_dw_write_hwaddr(priv, enetaddr);
rx_descs_init(priv);
tx_descs_init(priv);

View File

@ -525,7 +525,6 @@ static int macb_phy_init(struct macb_device *macb)
return 1;
}
static int macb_write_hwaddr(struct eth_device *dev);
static int macb_init(struct eth_device *netdev, bd_t *bd)
{
struct macb_device *macb = to_macb(netdev);
@ -594,14 +593,6 @@ static int macb_init(struct eth_device *netdev, bd_t *bd)
#endif /* CONFIG_RMII */
}
/* update the ethaddr */
if (is_valid_ethaddr(netdev->enetaddr)) {
macb_write_hwaddr(netdev);
} else {
printf("%s: mac address is not valid\n", netdev->name);
return -1;
}
if (!macb_phy_init(macb))
return -1;

View File

@ -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);