]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[netdevice] Allow driver to preinitialise the link-layer address
authorMichael Brown <mcb30@ipxe.org>
Fri, 28 Oct 2011 21:32:33 +0000 (22:32 +0100)
committerMichael Brown <mcb30@ipxe.org>
Fri, 28 Oct 2011 21:32:33 +0000 (22:32 +0100)
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>
src/net/netdevice.c

index d1ae8af30b1f49f922a7819742c628eb9057bbe3..b9b1337a1620d7fd1bf94dacea8890a4ae717fd9 100644 (file)
@@ -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 );