aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2020-10-19 13:44:43 +0100
committerMichael Brown <mcb30@ipxe.org>2020-10-19 14:45:49 +0100
commit6154b1fb2003bafa56ce35365f681d0c2fb1a503 (patch)
treee9818caf6e70a4063b637ff09f30d55c6110cd3e /src
parentb50ad5f09ab11f7d5b61a9a5c21637ea139fda08 (diff)
downloadipxe-6154b1fb2003bafa56ce35365f681d0c2fb1a503.zip
ipxe-6154b1fb2003bafa56ce35365f681d0c2fb1a503.tar.gz
ipxe-6154b1fb2003bafa56ce35365f681d0c2fb1a503.tar.bz2
[efi] Split efi_netdev_path() out to a separate function
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>
Diffstat (limited to 'src')
-rw-r--r--src/include/ipxe/efi/efi_path.h2
-rw-r--r--src/interface/efi/efi_path.c65
-rw-r--r--src/interface/efi/efi_snp.c41
3 files changed, 71 insertions, 37 deletions
diff --git a/src/include/ipxe/efi/efi_path.h b/src/include/ipxe/efi/efi_path.h
index f52410e..d4d4385 100644
--- a/src/include/ipxe/efi/efi_path.h
+++ b/src/include/ipxe/efi/efi_path.h
@@ -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 );
diff --git a/src/interface/efi/efi_path.c b/src/interface/efi/efi_path.c
index 6201c02..3faf476 100644
--- a/src/interface/efi/efi_path.c
+++ b/src/interface/efi/efi_path.c
@@ -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>
@@ -62,6 +65,68 @@ size_t efi_path_len ( EFI_DEVICE_PATH_PROTOCOL *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
*
* @v uri URI
diff --git a/src/interface/efi/efi_snp.c b/src/interface/efi/efi_snp.c
index f5c736a..91e796a 100644
--- a/src/interface/efi/efi_snp.c
+++ b/src/interface/efi/efi_snp.c
@@ -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: