diff options
author | Michael Brown | 2014-07-04 17:52:10 +0200 |
---|---|---|
committer | Michael Brown | 2014-07-08 15:01:55 +0200 |
commit | d0cfbd01f51661994a8e8379ddda6d592177a29b (patch) | |
tree | 0d215d4b9b43352229526262bab6250c905908c0 /src/drivers/net/efi/snponly.c | |
parent | [efi] Attempt to start only drivers claiming support for a device (diff) | |
download | ipxe-d0cfbd01f51661994a8e8379ddda6d592177a29b.tar.gz ipxe-d0cfbd01f51661994a8e8379ddda6d592177a29b.tar.xz ipxe-d0cfbd01f51661994a8e8379ddda6d592177a29b.zip |
[efi] Rewrite SNP NIC driver
Rewrite the SNP NIC driver to use non-blocking and deferrable
transmissions, to provide link status detection, to provide
information about the underlying (PCI) hardware device, and to avoid
unnecessary I/O buffer allocations during receive polling.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers/net/efi/snponly.c')
-rw-r--r-- | src/drivers/net/efi/snponly.c | 112 |
1 files changed, 20 insertions, 92 deletions
diff --git a/src/drivers/net/efi/snponly.c b/src/drivers/net/efi/snponly.c index 6fcc54a0..de55bd0d 100644 --- a/src/drivers/net/efi/snponly.c +++ b/src/drivers/net/efi/snponly.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 VMware, Inc. All Rights Reserved. + * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -13,117 +13,45 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. */ FILE_LICENCE ( GPL2_OR_LATER ); -#include <string.h> #include <errno.h> -#include <ipxe/device.h> -#include <ipxe/init.h> #include <ipxe/efi/efi.h> -#include <ipxe/efi/Protocol/SimpleNetwork.h> -#include "snp.h" +#include <ipxe/efi/efi_driver.h> #include "snpnet.h" /** @file * - * Chain-loading Simple Network Protocol Bus Driver + * SNP chainloaded-device-only driver * - * This bus driver allows iPXE to use the EFI Simple Network Protocol provided - * by the platform to transmit and receive packets. It attaches to only the - * device handle that iPXE was loaded from, that is, it will only use the - * Simple Network Protocol on the current loaded image's device handle. - * - * Eseentially, this driver provides the EFI equivalent of the "undionly" - * driver. */ -/** The one and only SNP network device */ -static struct snp_device snponly_dev; - -/** EFI simple network protocol GUID */ -static EFI_GUID efi_simple_network_protocol_guid - = EFI_SIMPLE_NETWORK_PROTOCOL_GUID; - /** - * Probe SNP root bus + * Check to see if driver supports a device * - * @v rootdev SNP bus root device - * - * Look at the loaded image's device handle and see if the simple network - * protocol exists. If so, register a driver for it. + * @v device EFI device handle + * @ret rc Return status code */ -static int snpbus_probe ( struct root_device *rootdev ) { - EFI_BOOT_SERVICES *bs = efi_systab->BootServices; - EFI_STATUS efirc; - int rc; - void *snp; - - efirc = bs->OpenProtocol ( efi_loaded_image->DeviceHandle, - &efi_simple_network_protocol_guid, - &snp, efi_image_handle, NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL ); - if ( efirc ) { - DBG ( "Could not find Simple Network Protocol!\n" ); - return -ENODEV; - } - snponly_dev.snp = snp; +static int snponly_supported ( EFI_HANDLE device ) { - /* Add to device hierarchy */ - strncpy ( snponly_dev.dev.name, "EFI SNP", - ( sizeof ( snponly_dev.dev.name ) - 1 ) ); - snponly_dev.dev.parent = &rootdev->dev; - list_add ( &snponly_dev.dev.siblings, &rootdev->dev.children); - INIT_LIST_HEAD ( &snponly_dev.dev.children ); + /* Check that this device is our loaded image's device */ + if ( device != efi_loaded_image->DeviceHandle ) + return -ENOTTY; - /* Create network device */ - if ( ( rc = snpnet_probe ( &snponly_dev ) ) != 0 ) - goto err; + DBGC ( device, "SNP %p %s is the SNP chainloading device\n", + device, efi_handle_devpath_text ( device ) ); return 0; - -err: - list_del ( &snponly_dev.dev.siblings ); - return rc; -} - -/** - * Remove SNP root bus - * - * @v rootdev SNP bus root device - */ -static void snpbus_remove ( struct root_device *rootdev __unused ) { - snpnet_remove ( &snponly_dev ); - list_del ( &snponly_dev.dev.siblings ); -} - -/** SNP bus root device driver */ -static struct root_driver snp_root_driver = { - .probe = snpbus_probe, - .remove = snpbus_remove, -}; - -/** SNP bus root device */ -struct root_device snp_root_device __root_device = { - .dev = { .name = "EFI SNP" }, - .driver = &snp_root_driver, -}; - -/** - * Prepare for exit - * - * @v booting System is shutting down for OS boot - */ -static void snponly_shutdown ( int booting ) { - /* If we are shutting down to boot an OS, make sure the SNP does not - * stay active. - */ - if ( booting ) - snponly_dev.removal_state = EfiSimpleNetworkStopped; } -struct startup_fn startup_snponly __startup_fn ( STARTUP_LATE ) = { - .shutdown = snponly_shutdown, +/** EFI SNP driver */ +struct efi_driver snponly_driver __efi_driver ( EFI_DRIVER_NORMAL ) = { + .name = "SNPONLY", + .supported = snponly_supported, + .start = snpnet_start, + .stop = snpnet_stop, }; |