diff options
author | Michael Brown <mcb30@ipxe.org> | 2024-03-22 15:30:45 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2024-03-25 17:58:33 +0000 |
commit | dcad73ca5ad3e1fe011c52a24036f67ad69fadc1 (patch) | |
tree | ecb05e55a634d6d63cc46f6f3a02eb3930e30eb6 /src/drivers/net/efi/snpnet.c | |
parent | da5188f3ea73900f1c6a4e44a8345b48320d396f (diff) | |
download | ipxe-dcad73ca5ad3e1fe011c52a24036f67ad69fadc1.tar.gz |
[efi] Add support for driving EFI_MANAGED_NETWORK_PROTOCOL devices
We want exclusive access to the network device, both for performance
reasons and because we perform operations such as EAPoL that affect
the entire link. We currently drive the network card via either a
native hardware driver or via the SNP or NII/UNDI interfaces, both of
which grant us this exclusive access.
Add an alternative driver that drives the network card non-exclusively
via the EFI_MANAGED_NETWORK_PROTOCOL interface. This can function as
a fallback for situations where neither SNP nor NII/UNDI interfaces
are functional, and also opens up the possibility of non-destructively
installing a temporary network device over which to download the
autoexec.ipxe script.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers/net/efi/snpnet.c')
-rw-r--r-- | src/drivers/net/efi/snpnet.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/drivers/net/efi/snpnet.c b/src/drivers/net/efi/snpnet.c index b8bf963e9..6ce731d78 100644 --- a/src/drivers/net/efi/snpnet.c +++ b/src/drivers/net/efi/snpnet.c @@ -33,6 +33,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <ipxe/efi/Protocol/SimpleNetwork.h> #include <ipxe/efi/efi_driver.h> #include <ipxe/efi/efi_utils.h> +#include <ipxe/efi/efi_snp.h> #include "snpnet.h" /** @file @@ -485,6 +486,53 @@ static struct net_device_operations snpnet_operations = { }; /** + * Check to see if driver supports a device + * + * @v device EFI device handle + * @v protocol Protocol GUID + * @ret rc Return status code + */ +int snpnet_supported ( EFI_HANDLE device, EFI_GUID *protocol ) { + EFI_BOOT_SERVICES *bs = efi_systab->BootServices; + EFI_HANDLE parent; + EFI_STATUS efirc; + int rc; + + /* Check that this is not a device we are providing ourselves */ + if ( find_snpdev ( device ) != NULL ) { + DBGCP ( device, "HANDLE %s is provided by this binary\n", + efi_handle_name ( device ) ); + return -ENOTTY; + } + + /* Test for presence of protocol */ + if ( ( efirc = bs->OpenProtocol ( device, protocol, + NULL, efi_image_handle, device, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL))!=0){ + DBGCP ( device, "HANDLE %s is not a %s device\n", + efi_handle_name ( device ), + efi_guid_ntoa ( protocol ) ); + return -EEFI ( efirc ); + } + + /* Check that there are no instances of this protocol further + * up this device path. + */ + if ( ( rc = efi_locate_device ( device, protocol, + &parent, 1 ) ) == 0 ) { + DBGC2 ( device, "HANDLE %s has %s-supporting parent ", + efi_handle_name ( device ), + efi_guid_ntoa ( protocol ) ); + DBGC2 ( device, "%s\n", efi_handle_name ( parent ) ); + return -ENOTTY; + } + + DBGC ( device, "HANDLE %s is a %s device\n", + efi_handle_name ( device ), efi_guid_ntoa ( protocol ) ); + return 0; +} + +/** * Attach driver to device * * @v efidev EFI device |