From 4f4369064b8ab1adee411f61f3cc24bd18c0d9a2 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 28 Oct 2011 22:32:33 +0100 Subject: [PATCH] [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 --- src/net/netdevice.c | 24 ++++++++++++++++++++++-- 1 file 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 @@ -62,6 +62,23 @@ struct errortab netdev_errors[] __errortab = { __einfo_errortab ( EINFO_ENOTCONN_LINK_DOWN ), }; +/** + * 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 * @@ -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 );