summaryrefslogtreecommitdiffstats
path: root/src/drivers/net/efi/snponly.c
diff options
context:
space:
mode:
authorMichael Brown2014-07-04 17:52:10 +0200
committerMichael Brown2014-07-08 15:01:55 +0200
commitd0cfbd01f51661994a8e8379ddda6d592177a29b (patch)
tree0d215d4b9b43352229526262bab6250c905908c0 /src/drivers/net/efi/snponly.c
parent[efi] Attempt to start only drivers claiming support for a device (diff)
downloadipxe-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.c112
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,
};