summaryrefslogtreecommitdiffstats
path: root/src/net/netdevice.c
diff options
context:
space:
mode:
authorMichael Brown2011-10-28 23:32:33 +0200
committerMichael Brown2011-10-28 23:32:33 +0200
commit4f4369064b8ab1adee411f61f3cc24bd18c0d9a2 (patch)
treeee5d9542a49f07c3adc6b0a4b846440506568a03 /src/net/netdevice.c
parent[cmdline] Make "reboot" command available by default (diff)
downloadipxe-4f4369064b8ab1adee411f61f3cc24bd18c0d9a2.tar.gz
ipxe-4f4369064b8ab1adee411f61f3cc24bd18c0d9a2.tar.xz
ipxe-4f4369064b8ab1adee411f61f3cc24bd18c0d9a2.zip
[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.c24
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 );