diff options
author | Michael Brown <mcb30@ipxe.org> | 2011-10-28 22:32:33 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2011-10-28 22:32:33 +0100 |
commit | 4f4369064b8ab1adee411f61f3cc24bd18c0d9a2 (patch) | |
tree | ee5d9542a49f07c3adc6b0a4b846440506568a03 /src/net/netdevice.c | |
parent | b0d65b5f0c93e276895e94d81362e63d3432521e (diff) | |
download | ipxe-4f4369064b8ab1adee411f61f3cc24bd18c0d9a2.tar.gz |
[netdevice] Allow driver to preinitialise the link-layer address
Drivers are currently expected to initialise only the hardware
address, with the link-layer protocol code taking care of converting
this into a valid link-layer address. Some drivers (e.g. undinet) can
legitimately determine both the hardware and link-layer addresses,
which may differ.
Allow for this situation by checking to see if the link-layer address
is empty before initialising it from the hardware address.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/net/netdevice.c')
-rw-r--r-- | src/net/netdevice.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/src/net/netdevice.c b/src/net/netdevice.c index d1ae8af3..b9b1337a 100644 --- a/src/net/netdevice.c +++ b/src/net/netdevice.c @@ -63,6 +63,23 @@ struct errortab netdev_errors[] __errortab = { }; /** + * Check whether or not network device has a link-layer address + * + * @v netdev Network device + * @ret has_ll_addr Network device has a link-layer address + */ +static int netdev_has_ll_addr ( struct net_device *netdev ) { + uint8_t *ll_addr = netdev->ll_addr; + size_t remaining = sizeof ( netdev->ll_addr ); + + while ( remaining-- ) { + if ( *(ll_addr++) != 0 ) + return 1; + } + return 0; +} + +/** * Notify drivers of network device or link state change * * @v netdev Network device @@ -432,8 +449,11 @@ int register_netdev ( struct net_device *netdev ) { ifindex++ ); } - /* Set initial link-layer address */ - netdev->ll_protocol->init_addr ( netdev->hw_addr, netdev->ll_addr ); + /* Set initial link-layer address, if not already set */ + if ( ! netdev_has_ll_addr ( netdev ) ) { + netdev->ll_protocol->init_addr ( netdev->hw_addr, + netdev->ll_addr ); + } /* Add to device list */ netdev_get ( netdev ); |