]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[efi] Split efi_netdev_path() out to a separate function
authorMichael Brown <mcb30@ipxe.org>
Mon, 19 Oct 2020 12:44:43 +0000 (13:44 +0100)
committerMichael Brown <mcb30@ipxe.org>
Mon, 19 Oct 2020 13:45:49 +0000 (14:45 +0100)
Provide efi_netdev_path() as a standalone function, to allow for reuse
when constructing child device paths.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/include/ipxe/efi/efi_path.h
src/interface/efi/efi_path.c
src/interface/efi/efi_snp.c

index f52410e364a7fd9c8e24f6f95fe670d87a48acf7..d4d43852fb45a7f94e7f3bfae9ece359dfe4d2a4 100644 (file)
@@ -13,12 +13,14 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/efi/efi.h>
 #include <ipxe/efi/Protocol/DevicePath.h>
 
+struct net_device;
 struct uri;
 struct usb_function;
 
 extern EFI_DEVICE_PATH_PROTOCOL *
 efi_path_end ( EFI_DEVICE_PATH_PROTOCOL *path );
 extern size_t efi_path_len ( EFI_DEVICE_PATH_PROTOCOL *path );
+extern EFI_DEVICE_PATH_PROTOCOL * efi_netdev_path ( struct net_device *netdev );
 extern EFI_DEVICE_PATH_PROTOCOL * efi_uri_path ( struct uri *uri );
 extern EFI_DEVICE_PATH_PROTOCOL * efi_usb_path ( struct usb_function *func );
 
index 6201c023ea6cb75033c0d9a4271325d56fb28266..3faf47617710a4edd89cd8c77274adc417defa29 100644 (file)
@@ -19,6 +19,9 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <byteswap.h>
+#include <ipxe/netdevice.h>
+#include <ipxe/vlan.h>
 #include <ipxe/uri.h>
 #include <ipxe/usb.h>
 #include <ipxe/efi/efi.h>
@@ -61,6 +64,68 @@ size_t efi_path_len ( EFI_DEVICE_PATH_PROTOCOL *path ) {
        return ( ( ( void * ) end ) - ( ( void * ) path ) );
 }
 
+/**
+ * Construct EFI device path for network device
+ *
+ * @v netdev           Network device
+ * @ret path           EFI device path, or NULL on error
+ *
+ * The caller is responsible for eventually calling free() on the
+ * allocated device path.
+ */
+EFI_DEVICE_PATH_PROTOCOL * efi_netdev_path ( struct net_device *netdev ) {
+       struct efi_device *efidev;
+       EFI_DEVICE_PATH_PROTOCOL *path;
+       MAC_ADDR_DEVICE_PATH *macpath;
+       VLAN_DEVICE_PATH *vlanpath;
+       EFI_DEVICE_PATH_PROTOCOL *end;
+       unsigned int tag;
+       size_t prefix_len;
+       size_t len;
+
+       /* Find parent EFI device */
+       efidev = efidev_parent ( netdev->dev );
+       if ( ! efidev )
+               return NULL;
+
+       /* Calculate device path length */
+       prefix_len = efi_path_len ( efidev->path );
+       len = ( prefix_len + sizeof ( *macpath ) + sizeof ( *vlanpath ) +
+               sizeof ( *end ) );
+
+       /* Allocate device path */
+       path = zalloc ( len );
+       if ( ! path )
+               return NULL;
+
+       /* Construct device path */
+       memcpy ( path, efidev->path, prefix_len );
+       macpath = ( ( ( void * ) path ) + prefix_len );
+       macpath->Header.Type = MESSAGING_DEVICE_PATH;
+       macpath->Header.SubType = MSG_MAC_ADDR_DP;
+       macpath->Header.Length[0] = sizeof ( *macpath );
+       assert ( netdev->ll_protocol->ll_addr_len <
+                sizeof ( macpath->MacAddress ) );
+       memcpy ( &macpath->MacAddress, netdev->ll_addr,
+                netdev->ll_protocol->ll_addr_len );
+       macpath->IfType = ntohs ( netdev->ll_protocol->ll_proto );
+       if ( ( tag = vlan_tag ( netdev ) ) ) {
+               vlanpath = ( ( ( void * ) macpath ) + sizeof ( *macpath ) );
+               vlanpath->Header.Type = MESSAGING_DEVICE_PATH;
+               vlanpath->Header.SubType = MSG_VLAN_DP;
+               vlanpath->Header.Length[0] = sizeof ( *vlanpath );
+               vlanpath->VlanId = tag;
+               end = ( ( ( void * ) vlanpath ) + sizeof ( *vlanpath ) );
+       } else {
+               end = ( ( ( void * ) macpath ) + sizeof ( *macpath ) );
+       }
+       end->Type = END_DEVICE_PATH_TYPE;
+       end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
+       end->Length[0] = sizeof ( *end );
+
+       return path;
+}
+
 /**
  * Construct EFI device path for URI
  *
index f5c736a11c5dd0d75f69485a28d33798fe501ebe..91e796a2e8b62b7062a588e0784556c87a538874 100644 (file)
@@ -1624,12 +1624,7 @@ static int efi_snp_probe ( struct net_device *netdev ) {
        EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
        struct efi_device *efidev;
        struct efi_snp_device *snpdev;
-       EFI_DEVICE_PATH_PROTOCOL *path_end;
-       MAC_ADDR_DEVICE_PATH *macpath;
-       VLAN_DEVICE_PATH *vlanpath;
-       size_t path_prefix_len = 0;
        unsigned int ifcnt;
-       unsigned int tag;
        void *interface;
        EFI_STATUS efirc;
        int rc;
@@ -1714,41 +1709,13 @@ static int efi_snp_probe ( struct net_device *netdev ) {
                                       sizeof ( snpdev->name[0] ) ),
                       "%s", netdev->name );
 
-       /* Allocate the new device path */
-       path_prefix_len = efi_path_len ( efidev->path );
-       snpdev->path = zalloc ( path_prefix_len + sizeof ( *macpath ) +
-                               sizeof ( *vlanpath ) + sizeof ( *path_end ) );
+       /* Construct device path */
+       snpdev->path = efi_netdev_path ( netdev );
        if ( ! snpdev->path ) {
                rc = -ENOMEM;
-               goto err_alloc_device_path;
+               goto err_path;
        }
 
-       /* Populate the device path */
-       memcpy ( snpdev->path, efidev->path, path_prefix_len );
-       macpath = ( ( ( void * ) snpdev->path ) + path_prefix_len );
-       memset ( macpath, 0, sizeof ( *macpath ) );
-       macpath->Header.Type = MESSAGING_DEVICE_PATH;
-       macpath->Header.SubType = MSG_MAC_ADDR_DP;
-       macpath->Header.Length[0] = sizeof ( *macpath );
-       memcpy ( &macpath->MacAddress, netdev->ll_addr,
-                netdev->ll_protocol->ll_addr_len );
-       macpath->IfType = ntohs ( netdev->ll_protocol->ll_proto );
-       if ( ( tag = vlan_tag ( netdev ) ) ) {
-               vlanpath = ( ( ( void * ) macpath ) + sizeof ( *macpath ) );
-               memset ( vlanpath, 0, sizeof ( *vlanpath ) );
-               vlanpath->Header.Type = MESSAGING_DEVICE_PATH;
-               vlanpath->Header.SubType = MSG_VLAN_DP;
-               vlanpath->Header.Length[0] = sizeof ( *vlanpath );
-               vlanpath->VlanId = tag;
-               path_end = ( ( ( void * ) vlanpath ) + sizeof ( *vlanpath ) );
-       } else {
-               path_end = ( ( ( void * ) macpath ) + sizeof ( *macpath ) );
-       }
-       memset ( path_end, 0, sizeof ( *path_end ) );
-       path_end->Type = END_DEVICE_PATH_TYPE;
-       path_end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
-       path_end->Length[0] = sizeof ( *path_end );
-
        /* Install the SNP */
        if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
                        &snpdev->handle,
@@ -1847,7 +1814,7 @@ static int efi_snp_probe ( struct net_device *netdev ) {
                        NULL );
  err_install_protocol_interface:
        free ( snpdev->path );
- err_alloc_device_path:
+ err_path:
        bs->CloseEvent ( snpdev->snp.WaitForPacket );
  err_create_event:
  err_ll_addr_len: