summaryrefslogtreecommitdiffstats
path: root/qemu/roms/ipxe/src/drivers/net/efi
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/ipxe/src/drivers/net/efi')
-rw-r--r--qemu/roms/ipxe/src/drivers/net/efi/nii.c1185
-rw-r--r--qemu/roms/ipxe/src/drivers/net/efi/nii.h17
-rw-r--r--qemu/roms/ipxe/src/drivers/net/efi/snp.c117
-rw-r--r--qemu/roms/ipxe/src/drivers/net/efi/snpnet.c563
-rw-r--r--qemu/roms/ipxe/src/drivers/net/efi/snpnet.h17
-rw-r--r--qemu/roms/ipxe/src/drivers/net/efi/snponly.c212
6 files changed, 0 insertions, 2111 deletions
diff --git a/qemu/roms/ipxe/src/drivers/net/efi/nii.c b/qemu/roms/ipxe/src/drivers/net/efi/nii.c
deleted file mode 100644
index b91848f5c..000000000
--- a/qemu/roms/ipxe/src/drivers/net/efi/nii.c
+++ /dev/null
@@ -1,1185 +0,0 @@
-/*
- * 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
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * 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 Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <string.h>
-#include <strings.h>
-#include <unistd.h>
-#include <errno.h>
-#include <ipxe/netdevice.h>
-#include <ipxe/ethernet.h>
-#include <ipxe/umalloc.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/efi_driver.h>
-#include <ipxe/efi/efi_pci.h>
-#include <ipxe/efi/efi_utils.h>
-#include <ipxe/efi/Protocol/NetworkInterfaceIdentifier.h>
-#include <ipxe/efi/IndustryStandard/Acpi10.h>
-#include "nii.h"
-
-/** @file
- *
- * NII driver
- *
- */
-
-/* Error numbers generated by NII */
-#define EIO_INVALID_CDB __einfo_error ( EINFO_EIO_INVALID_CDB )
-#define EINFO_EIO_INVALID_CDB \
- __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_INVALID_CDB, \
- "Invalid CDB" )
-#define EIO_INVALID_CPB __einfo_error ( EINFO_EIO_INVALID_CPB )
-#define EINFO_EIO_INVALID_CPB \
- __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_INVALID_CPB, \
- "Invalid CPB" )
-#define EIO_BUSY __einfo_error ( EINFO_EIO_BUSY )
-#define EINFO_EIO_BUSY \
- __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_BUSY, \
- "Busy" )
-#define EIO_QUEUE_FULL __einfo_error ( EINFO_EIO_QUEUE_FULL )
-#define EINFO_EIO_QUEUE_FULL \
- __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_QUEUE_FULL, \
- "Queue full" )
-#define EIO_ALREADY_STARTED __einfo_error ( EINFO_EIO_ALREADY_STARTED )
-#define EINFO_EIO_ALREADY_STARTED \
- __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_ALREADY_STARTED, \
- "Already started" )
-#define EIO_NOT_STARTED __einfo_error ( EINFO_EIO_NOT_STARTED )
-#define EINFO_EIO_NOT_STARTED \
- __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NOT_STARTED, \
- "Not started" )
-#define EIO_NOT_SHUTDOWN __einfo_error ( EINFO_EIO_NOT_SHUTDOWN )
-#define EINFO_EIO_NOT_SHUTDOWN \
- __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NOT_SHUTDOWN, \
- "Not shutdown" )
-#define EIO_ALREADY_INITIALIZED __einfo_error ( EINFO_EIO_ALREADY_INITIALIZED )
-#define EINFO_EIO_ALREADY_INITIALIZED \
- __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_ALREADY_INITIALIZED, \
- "Already initialized" )
-#define EIO_NOT_INITIALIZED __einfo_error ( EINFO_EIO_NOT_INITIALIZED )
-#define EINFO_EIO_NOT_INITIALIZED \
- __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NOT_INITIALIZED, \
- "Not initialized" )
-#define EIO_DEVICE_FAILURE __einfo_error ( EINFO_EIO_DEVICE_FAILURE )
-#define EINFO_EIO_DEVICE_FAILURE \
- __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_DEVICE_FAILURE, \
- "Device failure" )
-#define EIO_NVDATA_FAILURE __einfo_error ( EINFO_EIO_NVDATA_FAILURE )
-#define EINFO_EIO_NVDATA_FAILURE \
- __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NVDATA_FAILURE, \
- "Non-volatile data failure" )
-#define EIO_UNSUPPORTED __einfo_error ( EINFO_EIO_UNSUPPORTED )
-#define EINFO_EIO_UNSUPPORTED \
- __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_UNSUPPORTED, \
- "Unsupported" )
-#define EIO_BUFFER_FULL __einfo_error ( EINFO_EIO_BUFFER_FULL )
-#define EINFO_EIO_BUFFER_FULL \
- __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_BUFFER_FULL, \
- "Buffer full" )
-#define EIO_INVALID_PARAMETER __einfo_error ( EINFO_EIO_INVALID_PARAMETER )
-#define EINFO_EIO_INVALID_PARAMETER \
- __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_INVALID_PARAMETER, \
- "Invalid parameter" )
-#define EIO_INVALID_UNDI __einfo_error ( EINFO_EIO_INVALID_UNDI )
-#define EINFO_EIO_INVALID_UNDI \
- __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_INVALID_UNDI, \
- "Invalid UNDI" )
-#define EIO_IPV4_NOT_SUPPORTED __einfo_error ( EINFO_EIO_IPV4_NOT_SUPPORTED )
-#define EINFO_EIO_IPV4_NOT_SUPPORTED \
- __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_IPV4_NOT_SUPPORTED, \
- "IPv4 not supported" )
-#define EIO_IPV6_NOT_SUPPORTED __einfo_error ( EINFO_EIO_IPV6_NOT_SUPPORTED )
-#define EINFO_EIO_IPV6_NOT_SUPPORTED \
- __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_IPV6_NOT_SUPPORTED, \
- "IPv6 not supported" )
-#define EIO_NOT_ENOUGH_MEMORY __einfo_error ( EINFO_EIO_NOT_ENOUGH_MEMORY )
-#define EINFO_EIO_NOT_ENOUGH_MEMORY \
- __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NOT_ENOUGH_MEMORY, \
- "Not enough memory" )
-#define EIO_NO_DATA __einfo_error ( EINFO_EIO_NO_DATA )
-#define EINFO_EIO_NO_DATA \
- __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NO_DATA, \
- "No data" )
-#define EIO_STAT( stat ) \
- EUNIQ ( EINFO_EIO, -(stat), EIO_INVALID_CDB, EIO_INVALID_CPB, \
- EIO_BUSY, EIO_QUEUE_FULL, EIO_ALREADY_STARTED, \
- EIO_NOT_STARTED, EIO_NOT_SHUTDOWN, EIO_ALREADY_INITIALIZED, \
- EIO_NOT_INITIALIZED, EIO_DEVICE_FAILURE, EIO_NVDATA_FAILURE, \
- EIO_UNSUPPORTED, EIO_BUFFER_FULL, EIO_INVALID_PARAMETER, \
- EIO_INVALID_UNDI, EIO_IPV4_NOT_SUPPORTED, \
- EIO_IPV6_NOT_SUPPORTED, EIO_NOT_ENOUGH_MEMORY, EIO_NO_DATA )
-
-/** Maximum PCI BAR
- *
- * This is defined in <ipxe/efi/IndustryStandard/Pci22.h>, but we
- * can't #include that since it collides with <ipxe/pci.h>.
- */
-#define PCI_MAX_BAR 6
-
-/** An NII NIC */
-struct nii_nic {
- /** EFI device */
- struct efi_device *efidev;
- /** Network interface identifier protocol */
- EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *nii;
- /** !PXE structure */
- PXE_SW_UNDI *undi;
- /** Entry point */
- EFIAPI VOID ( * issue ) ( UINT64 cdb );
- /** Generic device */
- struct device dev;
-
- /** PCI device */
- EFI_HANDLE pci_device;
- /** PCI I/O protocol */
- EFI_PCI_IO_PROTOCOL *pci_io;
- /** Memory BAR */
- unsigned int mem_bar;
- /** I/O BAR */
- unsigned int io_bar;
-
- /** Broadcast address */
- PXE_MAC_ADDR broadcast;
- /** Maximum packet length */
- size_t mtu;
-
- /** Hardware transmit/receive buffer */
- userptr_t buffer;
- /** Hardware transmit/receive buffer length */
- size_t buffer_len;
-
- /** Saved task priority level */
- EFI_TPL saved_tpl;
-
- /** Media status is supported */
- int media;
-
- /** Current transmit buffer */
- struct io_buffer *txbuf;
- /** Current receive buffer */
- struct io_buffer *rxbuf;
-};
-
-/** Maximum number of received packets per poll */
-#define NII_RX_QUOTA 4
-
-/**
- * Open PCI I/O protocol and identify BARs
- *
- * @v nii NII NIC
- * @ret rc Return status code
- */
-static int nii_pci_open ( struct nii_nic *nii ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- EFI_HANDLE device = nii->efidev->device;
- EFI_HANDLE pci_device;
- union {
- EFI_PCI_IO_PROTOCOL *pci_io;
- void *interface;
- } pci_io;
- union {
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *acpi;
- void *resource;
- } desc;
- unsigned int bar;
- EFI_STATUS efirc;
- int rc;
-
- /* Locate PCI I/O protocol */
- if ( ( rc = efi_locate_device ( device, &efi_pci_io_protocol_guid,
- &pci_device ) ) != 0 ) {
- DBGC ( nii, "NII %s could not locate PCI I/O protocol: %s\n",
- nii->dev.name, strerror ( rc ) );
- goto err_locate;
- }
- nii->pci_device = pci_device;
-
- /* Open PCI I/O protocol */
- if ( ( efirc = bs->OpenProtocol ( pci_device, &efi_pci_io_protocol_guid,
- &pci_io.interface, efi_image_handle,
- device,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
- rc = -EEFI ( efirc );
- DBGC ( nii, "NII %s could not open PCI I/O protocol: %s\n",
- nii->dev.name, strerror ( rc ) );
- goto err_open;
- }
- nii->pci_io = pci_io.pci_io;
-
- /* Identify memory and I/O BARs */
- nii->mem_bar = PCI_MAX_BAR;
- nii->io_bar = PCI_MAX_BAR;
- for ( bar = 0 ; bar < PCI_MAX_BAR ; bar++ ) {
- efirc = nii->pci_io->GetBarAttributes ( nii->pci_io, bar, NULL,
- &desc.resource );
- if ( efirc == EFI_UNSUPPORTED ) {
- /* BAR not present; ignore */
- continue;
- }
- if ( efirc != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( nii, "NII %s could not get BAR %d attributes: "
- "%s\n", nii->dev.name, bar, strerror ( rc ) );
- goto err_get_bar_attributes;
- }
- if ( desc.acpi->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM ) {
- nii->mem_bar = bar;
- } else if ( desc.acpi->ResType == ACPI_ADDRESS_SPACE_TYPE_IO ) {
- nii->io_bar = bar;
- }
- bs->FreePool ( desc.resource );
- }
- DBGC ( nii, "NII %s has ", nii->dev.name );
- if ( nii->mem_bar < PCI_MAX_BAR ) {
- DBGC ( nii, "memory BAR %d and ", nii->mem_bar );
- } else {
- DBGC ( nii, "no memory BAR and " );
- }
- if ( nii->io_bar < PCI_MAX_BAR ) {
- DBGC ( nii, "I/O BAR %d\n", nii->io_bar );
- } else {
- DBGC ( nii, "no I/O BAR\n" );
- }
-
- return 0;
-
- err_get_bar_attributes:
- bs->CloseProtocol ( pci_device, &efi_pci_io_protocol_guid,
- efi_image_handle, device );
- err_open:
- err_locate:
- return rc;
-}
-
-/**
- * Close PCI I/O protocol
- *
- * @v nii NII NIC
- * @ret rc Return status code
- */
-static void nii_pci_close ( struct nii_nic *nii ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-
- bs->CloseProtocol ( nii->pci_device, &efi_pci_io_protocol_guid,
- efi_image_handle, nii->efidev->device );
-}
-
-/**
- * I/O callback
- *
- * @v unique_id NII NIC
- * @v op Operations
- * @v len Length of data
- * @v addr Address
- * @v data Data buffer
- */
-static EFIAPI VOID nii_io ( UINT64 unique_id, UINT8 op, UINT8 len, UINT64 addr,
- UINT64 data ) {
- struct nii_nic *nii = ( ( void * ) ( intptr_t ) unique_id );
- EFI_PCI_IO_PROTOCOL_ACCESS *access;
- EFI_PCI_IO_PROTOCOL_IO_MEM io;
- EFI_PCI_IO_PROTOCOL_WIDTH width;
- unsigned int bar;
- EFI_STATUS efirc;
- int rc;
-
- /* Determine accessor and BAR */
- if ( op & ( PXE_MEM_READ | PXE_MEM_WRITE ) ) {
- access = &nii->pci_io->Mem;
- bar = nii->mem_bar;
- } else {
- access = &nii->pci_io->Io;
- bar = nii->io_bar;
- }
-
- /* Determine operaton */
- io = ( ( op & ( PXE_IO_WRITE | PXE_MEM_WRITE ) ) ?
- access->Write : access->Read );
-
- /* Determine width */
- width = ( fls ( len ) - 1 );
-
- /* Issue operation */
- if ( ( efirc = io ( nii->pci_io, width, bar, addr, 1,
- ( ( void * ) ( intptr_t ) data ) ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( nii, "NII %s I/O operation %#x failed: %s\n",
- nii->dev.name, op, strerror ( rc ) );
- /* No way to report failure */
- return;
- }
-}
-
-/**
- * Delay callback
- *
- * @v unique_id NII NIC
- * @v microseconds Delay in microseconds
- */
-static EFIAPI VOID nii_delay ( UINT64 unique_id __unused, UINTN microseconds ) {
-
- udelay ( microseconds );
-}
-
-/**
- * Block callback
- *
- * @v unique_id NII NIC
- * @v acquire Acquire lock
- */
-static EFIAPI VOID nii_block ( UINT64 unique_id, UINT32 acquire ) {
- struct nii_nic *nii = ( ( void * ) ( intptr_t ) unique_id );
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
-
- /* This functionality (which is copied verbatim from the
- * SnpDxe implementation of this function) appears to be
- * totally brain-dead, since it produces no actual blocking
- * behaviour.
- */
- if ( acquire ) {
- nii->saved_tpl = bs->RaiseTPL ( TPL_NOTIFY );
- } else {
- bs->RestoreTPL ( nii->saved_tpl );
- }
-}
-
-/**
- * Construct operation from opcode and flags
- *
- * @v opcode Opcode
- * @v opflags Flags
- * @ret op Operation
- */
-#define NII_OP( opcode, opflags ) ( (opcode) | ( (opflags) << 16 ) )
-
-/**
- * Extract opcode from operation
- *
- * @v op Operation
- * @ret opcode Opcode
- */
-#define NII_OPCODE( op ) ( (op) & 0xffff )
-
-/**
- * Extract flags from operation
- *
- * @v op Operation
- * @ret opflags Flags
- */
-#define NII_OPFLAGS( op ) ( (op) >> 16 )
-
-/**
- * Issue command with parameter block and data block
- *
- * @v nii NII NIC
- * @v op Operation
- * @v cpb Command parameter block, or NULL
- * @v cpb_len Command parameter block length
- * @v db Data block, or NULL
- * @v db_len Data block length
- * @ret stat Status flags, or negative status code
- */
-static int nii_issue_cpb_db ( struct nii_nic *nii, unsigned int op, void *cpb,
- size_t cpb_len, void *db, size_t db_len ) {
- PXE_CDB cdb;
-
- /* Prepare command descriptor block */
- memset ( &cdb, 0, sizeof ( cdb ) );
- cdb.OpCode = NII_OPCODE ( op );
- cdb.OpFlags = NII_OPFLAGS ( op );
- cdb.CPBaddr = ( ( intptr_t ) cpb );
- cdb.CPBsize = cpb_len;
- cdb.DBaddr = ( ( intptr_t ) db );
- cdb.DBsize = db_len;
- cdb.IFnum = nii->nii->IfNum;
-
- /* Issue command */
- DBGC2 ( nii, "NII %s issuing %02x:%04x ifnum %d%s%s\n",
- nii->dev.name, cdb.OpCode, cdb.OpFlags, cdb.IFnum,
- ( cpb ? " cpb" : "" ), ( db ? " db" : "" ) );
- if ( cpb )
- DBGC2_HD ( nii, cpb, cpb_len );
- if ( db )
- DBGC2_HD ( nii, db, db_len );
- nii->issue ( ( intptr_t ) &cdb );
-
- /* Check completion status */
- if ( cdb.StatCode != PXE_STATCODE_SUCCESS )
- return -cdb.StatCode;
-
- /* Return command-specific status flags */
- return ( cdb.StatFlags & ~PXE_STATFLAGS_STATUS_MASK );
-}
-
-/**
- * Issue command with parameter block
- *
- * @v nii NII NIC
- * @v op Operation
- * @v cpb Command parameter block, or NULL
- * @v cpb_len Command parameter block length
- * @ret stat Status flags, or negative status code
- */
-static int nii_issue_cpb ( struct nii_nic *nii, unsigned int op, void *cpb,
- size_t cpb_len ) {
-
- return nii_issue_cpb_db ( nii, op, cpb, cpb_len, NULL, 0 );
-}
-
-/**
- * Issue command with data block
- *
- * @v nii NII NIC
- * @v op Operation
- * @v db Data block, or NULL
- * @v db_len Data block length
- * @ret stat Status flags, or negative status code
- */
-static int nii_issue_db ( struct nii_nic *nii, unsigned int op, void *db,
- size_t db_len ) {
-
- return nii_issue_cpb_db ( nii, op, NULL, 0, db, db_len );
-}
-
-/**
- * Issue command
- *
- *
- * @v nii NII NIC
- * @v op Operation
- * @ret stat Status flags, or negative status code
- */
-static int nii_issue ( struct nii_nic *nii, unsigned int op ) {
-
- return nii_issue_cpb_db ( nii, op, NULL, 0, NULL, 0 );
-}
-
-/**
- * Start UNDI
- *
- * @v nii NII NIC
- * @ret rc Return status code
- */
-static int nii_start_undi ( struct nii_nic *nii ) {
- PXE_CPB_START_31 cpb;
- int stat;
- int rc;
-
- /* Construct parameter block */
- memset ( &cpb, 0, sizeof ( cpb ) );
- cpb.Delay = ( ( intptr_t ) nii_delay );
- cpb.Block = ( ( intptr_t ) nii_block );
- cpb.Mem_IO = ( ( intptr_t ) nii_io );
- cpb.Unique_ID = ( ( intptr_t ) nii );
-
- /* Issue command */
- if ( ( stat = nii_issue_cpb ( nii, PXE_OPCODE_START, &cpb,
- sizeof ( cpb ) ) ) < 0 ) {
- rc = -EIO_STAT ( stat );
- DBGC ( nii, "NII %s could not start: %s\n",
- nii->dev.name, strerror ( rc ) );
- return rc;
- }
-
- return 0;
-}
-
-/**
- * Stop UNDI
- *
- * @v nii NII NIC
- */
-static void nii_stop_undi ( struct nii_nic *nii ) {
- int stat;
- int rc;
-
- /* Issue command */
- if ( ( stat = nii_issue ( nii, PXE_OPCODE_STOP ) ) < 0 ) {
- rc = -EIO_STAT ( stat );
- DBGC ( nii, "NII %s could not stop: %s\n",
- nii->dev.name, strerror ( rc ) );
- /* Nothing we can do about it */
- return;
- }
-}
-
-/**
- * Get initialisation information
- *
- * @v nii NII NIC
- * @v netdev Network device to fill in
- * @ret rc Return status code
- */
-static int nii_get_init_info ( struct nii_nic *nii,
- struct net_device *netdev ) {
- PXE_DB_GET_INIT_INFO db;
- int stat;
- int rc;
-
- /* Issue command */
- if ( ( stat = nii_issue_db ( nii, PXE_OPCODE_GET_INIT_INFO, &db,
- sizeof ( db ) ) ) < 0 ) {
- rc = -EIO_STAT ( stat );
- DBGC ( nii, "NII %s could not get initialisation info: %s\n",
- nii->dev.name, strerror ( rc ) );
- return rc;
- }
-
- /* Determine link layer protocol */
- switch ( db.IFtype ) {
- case PXE_IFTYPE_ETHERNET :
- netdev->ll_protocol = &ethernet_protocol;
- break;
- default:
- DBGC ( nii, "NII %s unknown interface type %#02x\n",
- nii->dev.name, db.IFtype );
- return -ENOTSUP;
- }
-
- /* Sanity checks */
- assert ( db.MediaHeaderLen == netdev->ll_protocol->ll_header_len );
- assert ( db.HWaddrLen == netdev->ll_protocol->hw_addr_len );
- assert ( db.HWaddrLen == netdev->ll_protocol->ll_addr_len );
-
- /* Extract parameters */
- nii->buffer_len = db.MemoryRequired;
- nii->mtu = ( db.FrameDataLen + db.MediaHeaderLen );
- netdev->max_pkt_len = nii->mtu;
- nii->media = ( stat & PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED );
-
- return 0;
-}
-
-/**
- * Initialise UNDI
- *
- * @v nii NII NIC
- * @v flags Flags
- * @ret rc Return status code
- */
-static int nii_initialise_flags ( struct nii_nic *nii, unsigned int flags ) {
- PXE_CPB_INITIALIZE cpb;
- PXE_DB_INITIALIZE db;
- unsigned int op;
- int stat;
- int rc;
-
- /* Allocate memory buffer */
- nii->buffer = umalloc ( nii->buffer_len );
- if ( ! nii->buffer ) {
- rc = -ENOMEM;
- goto err_alloc;
- }
-
- /* Construct parameter block */
- memset ( &cpb, 0, sizeof ( cpb ) );
- cpb.MemoryAddr = ( ( intptr_t ) nii->buffer );
- cpb.MemoryLength = nii->buffer_len;
-
- /* Construct data block */
- memset ( &db, 0, sizeof ( db ) );
-
- /* Issue command */
- op = NII_OP ( PXE_OPCODE_INITIALIZE, flags );
- if ( ( stat = nii_issue_cpb_db ( nii, op, &cpb, sizeof ( cpb ),
- &db, sizeof ( db ) ) ) < 0 ) {
- rc = -EIO_STAT ( stat );
- DBGC ( nii, "NII %s could not initialise: %s\n",
- nii->dev.name, strerror ( rc ) );
- goto err_initialize;
- }
-
- return 0;
-
- err_initialize:
- ufree ( nii->buffer );
- err_alloc:
- return rc;
-}
-
-/**
- * Initialise UNDI
- *
- * @v nii NII NIC
- * @ret rc Return status code
- */
-static int nii_initialise ( struct nii_nic *nii ) {
- unsigned int flags;
-
- /* Initialise UNDI */
- flags = PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE;
- return nii_initialise_flags ( nii, flags );
-}
-
-/**
- * Initialise UNDI and detect cable
- *
- * @v nii NII NIC
- * @ret rc Return status code
- */
-static int nii_initialise_and_detect ( struct nii_nic *nii ) {
- unsigned int flags;
-
- /* Initialise UNDI and detect cable. This is required to work
- * around bugs in some Emulex NII drivers.
- */
- flags = PXE_OPFLAGS_INITIALIZE_DETECT_CABLE;
- return nii_initialise_flags ( nii, flags );
-}
-
-/**
- * Shut down UNDI
- *
- * @v nii NII NIC
- */
-static void nii_shutdown ( struct nii_nic *nii ) {
- int stat;
- int rc;
-
- /* Issue command */
- if ( ( stat = nii_issue ( nii, PXE_OPCODE_SHUTDOWN ) ) < 0 ) {
- rc = -EIO_STAT ( stat );
- DBGC ( nii, "NII %s could not shut down: %s\n",
- nii->dev.name, strerror ( rc ) );
- /* Leak memory to avoid corruption */
- return;
- }
-
- /* Free buffer */
- ufree ( nii->buffer );
-}
-
-/**
- * Get station addresses
- *
- * @v nii NII NIC
- * @v netdev Network device to fill in
- * @ret rc Return status code
- */
-static int nii_get_station_address ( struct nii_nic *nii,
- struct net_device *netdev ) {
- PXE_DB_STATION_ADDRESS db;
- unsigned int op;
- int stat;
- int rc;
-
- /* Initialise UNDI */
- if ( ( rc = nii_initialise ( nii ) ) != 0 )
- goto err_initialise;
-
- /* Issue command */
- op = NII_OP ( PXE_OPCODE_STATION_ADDRESS,
- PXE_OPFLAGS_STATION_ADDRESS_READ );
- if ( ( stat = nii_issue_db ( nii, op, &db, sizeof ( db ) ) ) < 0 ) {
- rc = -EIO_STAT ( stat );
- DBGC ( nii, "NII %s could not get station address: %s\n",
- nii->dev.name, strerror ( rc ) );
- goto err_station_address;
- }
-
- /* Copy MAC addresses */
- memcpy ( netdev->ll_addr, db.StationAddr,
- netdev->ll_protocol->ll_addr_len );
- memcpy ( netdev->hw_addr, db.PermanentAddr,
- netdev->ll_protocol->hw_addr_len );
- memcpy ( nii->broadcast, db.BroadcastAddr,
- sizeof ( nii->broadcast ) );
-
- err_station_address:
- nii_shutdown ( nii );
- err_initialise:
- return rc;
-}
-
-/**
- * Set station address
- *
- * @v nii NII NIC
- * @v netdev Network device
- * @ret rc Return status code
- */
-static int nii_set_station_address ( struct nii_nic *nii,
- struct net_device *netdev ) {
- uint32_t implementation = nii->undi->Implementation;
- PXE_CPB_STATION_ADDRESS cpb;
- unsigned int op;
- int stat;
- int rc;
-
- /* Fail if setting station address is unsupported */
- if ( ! ( implementation & PXE_ROMID_IMP_STATION_ADDR_SETTABLE ) )
- return -ENOTSUP;
-
- /* Construct parameter block */
- memset ( &cpb, 0, sizeof ( cpb ) );
- memcpy ( cpb.StationAddr, netdev->ll_addr,
- netdev->ll_protocol->ll_addr_len );
-
- /* Issue command */
- op = NII_OP ( PXE_OPCODE_STATION_ADDRESS,
- PXE_OPFLAGS_STATION_ADDRESS_WRITE );
- if ( ( stat = nii_issue_cpb ( nii, op, &cpb, sizeof ( cpb ) ) ) < 0 ) {
- rc = -EIO_STAT ( stat );
- DBGC ( nii, "NII %s could not set station address: %s\n",
- nii->dev.name, strerror ( rc ) );
- return rc;
- }
-
- return 0;
-}
-
-/**
- * Set receive filters
- *
- * @v nii NII NIC
- * @ret rc Return status code
- */
-static int nii_set_rx_filters ( struct nii_nic *nii ) {
- uint32_t implementation = nii->undi->Implementation;
- unsigned int flags;
- unsigned int op;
- int stat;
- int rc;
-
- /* Construct receive filter set */
- flags = ( PXE_OPFLAGS_RECEIVE_FILTER_ENABLE |
- PXE_OPFLAGS_RECEIVE_FILTER_UNICAST );
- if ( implementation & PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED )
- flags |= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;
- if ( implementation & PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED )
- flags |= PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS;
- if ( implementation & PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED )
- flags |= PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;
-
- /* Issue command */
- op = NII_OP ( PXE_OPCODE_RECEIVE_FILTERS, flags );
- if ( ( stat = nii_issue ( nii, op ) ) < 0 ) {
- rc = -EIO_STAT ( stat );
- DBGC ( nii, "NII %s could not set receive filters %#04x: %s\n",
- nii->dev.name, flags, strerror ( rc ) );
- return rc;
- }
-
- return 0;
-}
-
-/**
- * Transmit packet
- *
- * @v netdev Network device
- * @v iobuf I/O buffer
- * @ret rc Return status code
- */
-static int nii_transmit ( struct net_device *netdev,
- struct io_buffer *iobuf ) {
- struct nii_nic *nii = netdev->priv;
- PXE_CPB_TRANSMIT cpb;
- unsigned int op;
- int stat;
- int rc;
-
- /* Defer the packet if there is already a transmission in progress */
- if ( nii->txbuf ) {
- netdev_tx_defer ( netdev, iobuf );
- return 0;
- }
-
- /* Construct parameter block */
- memset ( &cpb, 0, sizeof ( cpb ) );
- cpb.FrameAddr = virt_to_bus ( iobuf->data );
- cpb.DataLen = iob_len ( iobuf );
- cpb.MediaheaderLen = netdev->ll_protocol->ll_header_len;
-
- /* Transmit packet */
- op = NII_OP ( PXE_OPCODE_TRANSMIT,
- ( PXE_OPFLAGS_TRANSMIT_WHOLE |
- PXE_OPFLAGS_TRANSMIT_DONT_BLOCK ) );
- if ( ( stat = nii_issue_cpb ( nii, op, &cpb, sizeof ( cpb ) ) ) < 0 ) {
- rc = -EIO_STAT ( stat );
- DBGC ( nii, "NII %s could not transmit: %s\n",
- nii->dev.name, strerror ( rc ) );
- return rc;
- }
- nii->txbuf = iobuf;
-
- return 0;
-}
-
-/**
- * Poll for completed packets
- *
- * @v netdev Network device
- * @v stat Status flags
- */
-static void nii_poll_tx ( struct net_device *netdev, unsigned int stat ) {
- struct nii_nic *nii = netdev->priv;
- struct io_buffer *iobuf;
-
- /* Do nothing unless we have a completion */
- if ( stat & PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN )
- return;
-
- /* Sanity check */
- assert ( nii->txbuf != NULL );
-
- /* Complete transmission */
- iobuf = nii->txbuf;
- nii->txbuf = NULL;
- netdev_tx_complete ( netdev, iobuf );
-}
-
-/**
- * Poll for received packets
- *
- * @v netdev Network device
- */
-static void nii_poll_rx ( struct net_device *netdev ) {
- struct nii_nic *nii = netdev->priv;
- PXE_CPB_RECEIVE cpb;
- PXE_DB_RECEIVE db;
- unsigned int quota;
- int stat;
- int rc;
-
- /* Retrieve up to NII_RX_QUOTA packets */
- for ( quota = NII_RX_QUOTA ; quota ; quota-- ) {
-
- /* Allocate buffer, if required */
- if ( ! nii->rxbuf ) {
- nii->rxbuf = alloc_iob ( nii->mtu );
- if ( ! nii->rxbuf ) {
- /* Leave for next poll */
- break;
- }
- }
-
- /* Construct parameter block */
- memset ( &cpb, 0, sizeof ( cpb ) );
- cpb.BufferAddr = virt_to_bus ( nii->rxbuf->data );
- cpb.BufferLen = iob_tailroom ( nii->rxbuf );
-
- /* Issue command */
- if ( ( stat = nii_issue_cpb_db ( nii, PXE_OPCODE_RECEIVE,
- &cpb, sizeof ( cpb ),
- &db, sizeof ( db ) ) ) < 0 ) {
-
- /* PXE_STATCODE_NO_DATA is just the usual "no packet"
- * status indicator; ignore it.
- */
- if ( stat == -PXE_STATCODE_NO_DATA )
- break;
-
- /* Anything else is an error */
- rc = -EIO_STAT ( stat );
- DBGC ( nii, "NII %s could not receive: %s\n",
- nii->dev.name, strerror ( rc ) );
- netdev_rx_err ( netdev, NULL, rc );
- break;
- }
-
- /* Hand off to network stack */
- iob_put ( nii->rxbuf, db.FrameLen );
- netdev_rx ( netdev, nii->rxbuf );
- nii->rxbuf = NULL;
- }
-}
-
-/**
- * Check for link state changes
- *
- * @v netdev Network device
- * @v stat Status flags
- */
-static void nii_poll_link ( struct net_device *netdev, unsigned int stat ) {
- int no_media = ( stat & PXE_STATFLAGS_GET_STATUS_NO_MEDIA );
-
- if ( no_media && netdev_link_ok ( netdev ) ) {
- netdev_link_down ( netdev );
- } else if ( ( ! no_media ) && ( ! netdev_link_ok ( netdev ) ) ) {
- netdev_link_up ( netdev );
- }
-}
-
-/**
- * Poll for completed packets
- *
- * @v netdev Network device
- */
-static void nii_poll ( struct net_device *netdev ) {
- struct nii_nic *nii = netdev->priv;
- PXE_DB_GET_STATUS db;
- unsigned int op;
- int stat;
- int rc;
-
- /* Construct data block */
- memset ( &db, 0, sizeof ( db ) );
-
- /* Get status */
- op = NII_OP ( PXE_OPCODE_GET_STATUS,
- ( PXE_OPFLAGS_GET_INTERRUPT_STATUS |
- ( nii->txbuf ? PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS : 0)|
- ( nii->media ? PXE_OPFLAGS_GET_MEDIA_STATUS : 0 ) ) );
- if ( ( stat = nii_issue_db ( nii, op, &db, sizeof ( db ) ) ) < 0 ) {
- rc = -EIO_STAT ( stat );
- DBGC ( nii, "NII %s could not get status: %s\n",
- nii->dev.name, strerror ( rc ) );
- return;
- }
-
- /* Process any TX completions */
- if ( nii->txbuf )
- nii_poll_tx ( netdev, stat );
-
- /* Process any RX completions */
- nii_poll_rx ( netdev );
-
- /* Check for link state changes */
- if ( nii->media )
- nii_poll_link ( netdev, stat );
-}
-
-/**
- * Open network device
- *
- * @v netdev Network device
- * @ret rc Return status code
- */
-static int nii_open ( struct net_device *netdev ) {
- struct nii_nic *nii = netdev->priv;
- int rc;
-
- /* Initialise NIC
- *
- * Some Emulex NII drivers have a bug which prevents packets
- * from being sent or received unless we specifically ask it
- * to detect cable presence during initialisation. Work
- * around these buggy drivers by requesting cable detection at
- * this point, even though we don't care about link state here
- * (and would prefer to have the NIC initialise even if no
- * cable is present, to match the behaviour of all other iPXE
- * drivers).
- */
- if ( ( rc = nii_initialise_and_detect ( nii ) ) != 0 )
- goto err_initialise;
-
- /* Attempt to set station address */
- if ( ( rc = nii_set_station_address ( nii, netdev ) ) != 0 ) {
- DBGC ( nii, "NII %s could not set station address: %s\n",
- nii->dev.name, strerror ( rc ) );
- /* Treat as non-fatal */
- }
-
- /* Set receive filters */
- if ( ( rc = nii_set_rx_filters ( nii ) ) != 0 )
- goto err_set_rx_filters;
-
- return 0;
-
- err_set_rx_filters:
- nii_shutdown ( nii );
- err_initialise:
- return rc;
-}
-
-/**
- * Close network device
- *
- * @v netdev Network device
- */
-static void nii_close ( struct net_device *netdev ) {
- struct nii_nic *nii = netdev->priv;
-
- /* Shut down NIC */
- nii_shutdown ( nii );
-
- /* Discard transmit buffer, if applicable */
- if ( nii->txbuf ) {
- netdev_tx_complete_err ( netdev, nii->txbuf, -ECANCELED );
- nii->txbuf = NULL;
- }
-
- /* Discard receive buffer, if applicable */
- if ( nii->rxbuf ) {
- free_iob ( nii->rxbuf );
- nii->rxbuf = NULL;
- }
-}
-
-/** NII network device operations */
-static struct net_device_operations nii_operations = {
- .open = nii_open,
- .close = nii_close,
- .transmit = nii_transmit,
- .poll = nii_poll,
-};
-
-/**
- * Attach driver to device
- *
- * @v efidev EFI device
- * @ret rc Return status code
- */
-int nii_start ( struct efi_device *efidev ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- EFI_HANDLE device = efidev->device;
- struct net_device *netdev;
- struct nii_nic *nii;
- void *interface;
- EFI_STATUS efirc;
- int rc;
-
- /* Allocate and initialise structure */
- netdev = alloc_netdev ( sizeof ( *nii ) );
- if ( ! netdev ) {
- rc = -ENOMEM;
- goto err_alloc;
- }
- netdev_init ( netdev, &nii_operations );
- nii = netdev->priv;
- nii->efidev = efidev;
- netdev->ll_broadcast = nii->broadcast;
- efidev_set_drvdata ( efidev, netdev );
-
- /* Populate underlying device information */
- efi_device_info ( device, "NII", &nii->dev );
- nii->dev.driver_name = "NII";
- nii->dev.parent = &efidev->dev;
- list_add ( &nii->dev.siblings, &efidev->dev.children );
- INIT_LIST_HEAD ( &nii->dev.children );
- netdev->dev = &nii->dev;
-
- /* Open NII protocol */
- if ( ( efirc = bs->OpenProtocol ( device, &efi_nii31_protocol_guid,
- &interface, efi_image_handle, device,
- ( EFI_OPEN_PROTOCOL_BY_DRIVER |
- EFI_OPEN_PROTOCOL_EXCLUSIVE )))!=0){
- rc = -EEFI ( efirc );
- DBGC ( nii, "NII %s cannot open NII protocol: %s\n",
- nii->dev.name, strerror ( rc ) );
- DBGC_EFI_OPENERS ( device, device, &efi_nii31_protocol_guid );
- goto err_open_protocol;
- }
- nii->nii = interface;
-
- /* Locate UNDI and entry point */
- nii->undi = ( ( void * ) ( intptr_t ) nii->nii->Id );
- if ( ! nii->undi ) {
- DBGC ( nii, "NII %s has no UNDI\n", nii->dev.name );
- rc = -ENODEV;
- goto err_no_undi;
- }
- if ( nii->undi->Implementation & PXE_ROMID_IMP_HW_UNDI ) {
- DBGC ( nii, "NII %s is a mythical hardware UNDI\n",
- nii->dev.name );
- rc = -ENOTSUP;
- goto err_hw_undi;
- }
- if ( nii->undi->Implementation & PXE_ROMID_IMP_SW_VIRT_ADDR ) {
- nii->issue = ( ( void * ) ( intptr_t ) nii->undi->EntryPoint );
- } else {
- nii->issue = ( ( ( void * ) nii->undi ) +
- nii->undi->EntryPoint );
- }
- DBGC ( nii, "NII %s using UNDI v%x.%x at %p entry %p impl %#08x\n",
- nii->dev.name, nii->nii->MajorVer, nii->nii->MinorVer,
- nii->undi, nii->issue, nii->undi->Implementation );
-
- /* Open PCI I/O protocols and locate BARs */
- if ( ( rc = nii_pci_open ( nii ) ) != 0 )
- goto err_pci_open;
-
- /* Start UNDI */
- if ( ( rc = nii_start_undi ( nii ) ) != 0 )
- goto err_start_undi;
-
- /* Get initialisation information */
- if ( ( rc = nii_get_init_info ( nii, netdev ) ) != 0 )
- goto err_get_init_info;
-
- /* Get MAC addresses */
- if ( ( rc = nii_get_station_address ( nii, netdev ) ) != 0 )
- goto err_get_station_address;
-
- /* Register network device */
- if ( ( rc = register_netdev ( netdev ) ) != 0 )
- goto err_register_netdev;
- DBGC ( nii, "NII %s registered as %s for %p %s\n", nii->dev.name,
- netdev->name, device, efi_handle_name ( device ) );
-
- /* Set initial link state (if media detection is not supported) */
- if ( ! nii->media )
- netdev_link_up ( netdev );
-
- return 0;
-
- unregister_netdev ( netdev );
- err_register_netdev:
- err_get_station_address:
- err_get_init_info:
- nii_stop_undi ( nii );
- err_start_undi:
- nii_pci_close ( nii );
- err_pci_open:
- err_hw_undi:
- err_no_undi:
- bs->CloseProtocol ( device, &efi_nii31_protocol_guid,
- efi_image_handle, device );
- err_open_protocol:
- list_del ( &nii->dev.siblings );
- netdev_nullify ( netdev );
- netdev_put ( netdev );
- err_alloc:
- return rc;
-}
-
-/**
- * Detach driver from device
- *
- * @v efidev EFI device
- */
-void nii_stop ( struct efi_device *efidev ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- struct net_device *netdev = efidev_get_drvdata ( efidev );
- struct nii_nic *nii = netdev->priv;
- EFI_HANDLE device = efidev->device;
-
- /* Unregister network device */
- unregister_netdev ( netdev );
-
- /* Stop UNDI */
- nii_stop_undi ( nii );
-
- /* Close PCI I/O protocols */
- nii_pci_close ( nii );
-
- /* Close NII protocol */
- bs->CloseProtocol ( device, &efi_nii31_protocol_guid,
- efi_image_handle, device );
-
- /* Free network device */
- list_del ( &nii->dev.siblings );
- netdev_nullify ( netdev );
- netdev_put ( netdev );
-}
diff --git a/qemu/roms/ipxe/src/drivers/net/efi/nii.h b/qemu/roms/ipxe/src/drivers/net/efi/nii.h
deleted file mode 100644
index c10be9db5..000000000
--- a/qemu/roms/ipxe/src/drivers/net/efi/nii.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef _NII_H
-#define _NII_H
-
-/** @file
- *
- * NII driver
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-struct efi_device;
-
-extern int nii_start ( struct efi_device *efidev );
-extern void nii_stop ( struct efi_device *efidev );
-
-#endif /* _NII_H */
diff --git a/qemu/roms/ipxe/src/drivers/net/efi/snp.c b/qemu/roms/ipxe/src/drivers/net/efi/snp.c
deleted file mode 100644
index acfcfba9f..000000000
--- a/qemu/roms/ipxe/src/drivers/net/efi/snp.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * 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 Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <errno.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/efi_driver.h>
-#include <ipxe/efi/efi_snp.h>
-#include "snpnet.h"
-#include "nii.h"
-
-/** @file
- *
- * SNP driver
- *
- */
-
-/**
- * Check to see if driver supports a device
- *
- * @v device EFI device handle
- * @ret rc Return status code
- */
-static int snp_supported ( EFI_HANDLE device ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- EFI_STATUS efirc;
-
- /* Check that this is not a device we are providing ourselves */
- if ( find_snpdev ( device ) != NULL ) {
- DBGCP ( device, "SNP %p %s is provided by this binary\n",
- device, efi_handle_name ( device ) );
- return -ENOTTY;
- }
-
- /* Test for presence of simple network protocol */
- if ( ( efirc = bs->OpenProtocol ( device,
- &efi_simple_network_protocol_guid,
- NULL, efi_image_handle, device,
- EFI_OPEN_PROTOCOL_TEST_PROTOCOL))!=0){
- DBGCP ( device, "SNP %p %s is not an SNP device\n",
- device, efi_handle_name ( device ) );
- return -EEFI ( efirc );
- }
- DBGC ( device, "SNP %p %s is an SNP device\n",
- device, efi_handle_name ( device ) );
-
- return 0;
-}
-
-/**
- * Check to see if driver supports a device
- *
- * @v device EFI device handle
- * @ret rc Return status code
- */
-static int nii_supported ( EFI_HANDLE device ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- EFI_STATUS efirc;
-
- /* Check that this is not a device we are providing ourselves */
- if ( find_snpdev ( device ) != NULL ) {
- DBGCP ( device, "NII %p %s is provided by this binary\n",
- device, efi_handle_name ( device ) );
- return -ENOTTY;
- }
-
- /* Test for presence of NII protocol */
- if ( ( efirc = bs->OpenProtocol ( device,
- &efi_nii31_protocol_guid,
- NULL, efi_image_handle, device,
- EFI_OPEN_PROTOCOL_TEST_PROTOCOL))!=0){
- DBGCP ( device, "NII %p %s is not an NII device\n",
- device, efi_handle_name ( device ) );
- return -EEFI ( efirc );
- }
- DBGC ( device, "NII %p %s is an NII device\n",
- device, efi_handle_name ( device ) );
-
- return 0;
-}
-
-/** EFI SNP driver */
-struct efi_driver snp_driver __efi_driver ( EFI_DRIVER_NORMAL ) = {
- .name = "SNP",
- .supported = snp_supported,
- .start = snpnet_start,
- .stop = snpnet_stop,
-};
-
-/** EFI NII driver */
-struct efi_driver nii_driver __efi_driver ( EFI_DRIVER_NORMAL ) = {
- .name = "NII",
- .supported = nii_supported,
- .start = nii_start,
- .stop = nii_stop,
-};
diff --git a/qemu/roms/ipxe/src/drivers/net/efi/snpnet.c b/qemu/roms/ipxe/src/drivers/net/efi/snpnet.c
deleted file mode 100644
index 96642c4ca..000000000
--- a/qemu/roms/ipxe/src/drivers/net/efi/snpnet.c
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- * 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
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * 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 Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <ipxe/iobuf.h>
-#include <ipxe/netdevice.h>
-#include <ipxe/ethernet.h>
-#include <ipxe/vsprintf.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/Protocol/SimpleNetwork.h>
-#include <ipxe/efi/efi_driver.h>
-#include <ipxe/efi/efi_utils.h>
-#include "snpnet.h"
-
-/** @file
- *
- * SNP NIC driver
- *
- */
-
-/** An SNP NIC */
-struct snp_nic {
- /** EFI device */
- struct efi_device *efidev;
- /** Simple network protocol */
- EFI_SIMPLE_NETWORK_PROTOCOL *snp;
- /** Generic device */
- struct device dev;
-
- /** Maximum packet size
- *
- * This is calculated as the sum of MediaHeaderSize and
- * MaxPacketSize, and may therefore be an overestimate.
- */
- size_t mtu;
-
- /** Current transmit buffer */
- struct io_buffer *txbuf;
- /** Current receive buffer */
- struct io_buffer *rxbuf;
-};
-
-/** Maximum number of received packets per poll */
-#define SNP_RX_QUOTA 4
-
-/**
- * Format SNP MAC address (for debugging)
- *
- * @v mac MAC address
- * @v len Length of MAC address
- * @ret text MAC address as text
- */
-static const char * snpnet_mac_text ( EFI_MAC_ADDRESS *mac, size_t len ) {
- static char buf[ sizeof ( *mac ) * 3 /* "xx:" or "xx\0" */ ];
- size_t used = 0;
- unsigned int i;
-
- for ( i = 0 ; i < len ; i++ ) {
- used += ssnprintf ( &buf[used], ( sizeof ( buf ) - used ),
- "%s%02x", ( used ? ":" : "" ),
- mac->Addr[i] );
- }
- return buf;
-}
-
-/**
- * Dump SNP mode information (for debugging)
- *
- * @v netdev Network device
- */
-static void snpnet_dump_mode ( struct net_device *netdev ) {
- struct snp_nic *snp = netdev_priv ( netdev );
- EFI_SIMPLE_NETWORK_MODE *mode = snp->snp->Mode;
- size_t mac_len = mode->HwAddressSize;
- unsigned int i;
-
- /* Do nothing unless debugging is enabled */
- if ( ! DBG_EXTRA )
- return;
-
- DBGC2 ( snp, "SNP %s st %d type %d hdr %d pkt %d rxflt %#x/%#x%s "
- "nvram %d acc %d mcast %d/%d\n", netdev->name, mode->State,
- mode->IfType, mode->MediaHeaderSize, mode->MaxPacketSize,
- mode->ReceiveFilterSetting, mode->ReceiveFilterMask,
- ( mode->MultipleTxSupported ? " multitx" : "" ),
- mode->NvRamSize, mode->NvRamAccessSize,
- mode->MCastFilterCount, mode->MaxMCastFilterCount );
- DBGC2 ( snp, "SNP %s hw %s", netdev->name,
- snpnet_mac_text ( &mode->PermanentAddress, mac_len ) );
- DBGC2 ( snp, " addr %s%s",
- snpnet_mac_text ( &mode->CurrentAddress, mac_len ),
- ( mode->MacAddressChangeable ? "" : "(f)" ) );
- DBGC2 ( snp, " bcast %s\n",
- snpnet_mac_text ( &mode->BroadcastAddress, mac_len ) );
- for ( i = 0 ; i < mode->MCastFilterCount ; i++ ) {
- DBGC2 ( snp, "SNP %s mcast %s\n", netdev->name,
- snpnet_mac_text ( &mode->MCastFilter[i], mac_len ) );
- }
- DBGC2 ( snp, "SNP %s media %s\n", netdev->name,
- ( mode->MediaPresentSupported ?
- ( mode->MediaPresent ? "present" : "not present" ) :
- "presence not supported" ) );
-}
-
-/**
- * Check link state
- *
- * @v netdev Network device
- */
-static void snpnet_check_link ( struct net_device *netdev ) {
- struct snp_nic *snp = netdev_priv ( netdev );
- EFI_SIMPLE_NETWORK_MODE *mode = snp->snp->Mode;
-
- /* Do nothing unless media presence detection is supported */
- if ( ! mode->MediaPresentSupported )
- return;
-
- /* Report any link status change */
- if ( mode->MediaPresent && ( ! netdev_link_ok ( netdev ) ) ) {
- netdev_link_up ( netdev );
- } else if ( ( ! mode->MediaPresent ) && netdev_link_ok ( netdev ) ) {
- netdev_link_down ( netdev );
- }
-}
-
-/**
- * Transmit packet
- *
- * @v netdev Network device
- * @v iobuf I/O buffer
- * @ret rc Return status code
- */
-static int snpnet_transmit ( struct net_device *netdev,
- struct io_buffer *iobuf ) {
- struct snp_nic *snp = netdev_priv ( netdev );
- EFI_STATUS efirc;
- int rc;
-
- /* Defer the packet if there is already a transmission in progress */
- if ( snp->txbuf ) {
- netdev_tx_defer ( netdev, iobuf );
- return 0;
- }
-
- /* Transmit packet */
- if ( ( efirc = snp->snp->Transmit ( snp->snp, 0, iob_len ( iobuf ),
- iobuf->data, NULL, NULL,
- NULL ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( snp, "SNP %s could not transmit: %s\n",
- netdev->name, strerror ( rc ) );
- return rc;
- }
- snp->txbuf = iobuf;
-
- return 0;
-}
-
-/**
- * Poll for completed packets
- *
- * @v netdev Network device
- */
-static void snpnet_poll_tx ( struct net_device *netdev ) {
- struct snp_nic *snp = netdev->priv;
- struct io_buffer *iobuf;
- UINT32 irq;
- VOID *txbuf;
- EFI_STATUS efirc;
- int rc;
-
- /* Get status */
- if ( ( efirc = snp->snp->GetStatus ( snp->snp, &irq, &txbuf ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( snp, "SNP %s could not get status: %s\n",
- netdev->name, strerror ( rc ) );
- netdev_rx_err ( netdev, NULL, rc );
- return;
- }
-
- /* Do nothing unless we have a completion */
- if ( ! txbuf )
- return;
-
- /* Sanity check */
- if ( ! snp->txbuf ) {
- DBGC ( snp, "SNP %s reported spurious TX completion\n",
- netdev->name );
- netdev_tx_err ( netdev, NULL, -EPIPE );
- return;
- }
-
- /* Complete transmission */
- iobuf = snp->txbuf;
- snp->txbuf = NULL;
- netdev_tx_complete ( netdev, iobuf );
-}
-
-/**
- * Poll for received packets
- *
- * @v netdev Network device
- */
-static void snpnet_poll_rx ( struct net_device *netdev ) {
- struct snp_nic *snp = netdev->priv;
- UINTN len;
- unsigned int quota;
- EFI_STATUS efirc;
- int rc;
-
- /* Retrieve up to SNP_RX_QUOTA packets */
- for ( quota = SNP_RX_QUOTA ; quota ; quota-- ) {
-
- /* Allocate buffer, if required */
- if ( ! snp->rxbuf ) {
- snp->rxbuf = alloc_iob ( snp->mtu );
- if ( ! snp->rxbuf ) {
- /* Leave for next poll */
- break;
- }
- }
-
- /* Receive packet */
- len = iob_tailroom ( snp->rxbuf );
- if ( ( efirc = snp->snp->Receive ( snp->snp, NULL, &len,
- snp->rxbuf->data, NULL,
- NULL, NULL ) ) != 0 ) {
-
- /* EFI_NOT_READY is just the usual "no packet"
- * status indication; ignore it.
- */
- if ( efirc == EFI_NOT_READY )
- break;
-
- /* Anything else is an error */
- rc = -EEFI ( efirc );
- DBGC ( snp, "SNP %s could not receive: %s\n",
- netdev->name, strerror ( rc ) );
- netdev_rx_err ( netdev, NULL, rc );
- break;
- }
-
- /* Hand off to network stack */
- iob_put ( snp->rxbuf, len );
- netdev_rx ( netdev, snp->rxbuf );
- snp->rxbuf = NULL;
- }
-}
-
-/**
- * Poll for completed packets
- *
- * @v netdev Network device
- */
-static void snpnet_poll ( struct net_device *netdev ) {
-
- /* Process any TX completions */
- snpnet_poll_tx ( netdev );
-
- /* Process any RX completions */
- snpnet_poll_rx ( netdev );
-
- /* Check for link state changes */
- snpnet_check_link ( netdev );
-}
-
-/**
- * Set receive filters
- *
- * @v netdev Network device
- * @ret rc Return status code
- */
-static int snpnet_rx_filters ( struct net_device *netdev ) {
- struct snp_nic *snp = netdev->priv;
- UINT32 filters[] = {
- snp->snp->Mode->ReceiveFilterMask,
- ( EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
- EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST |
- EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST ),
- ( EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
- EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST ),
- ( EFI_SIMPLE_NETWORK_RECEIVE_UNICAST ),
- };
- unsigned int i;
- EFI_STATUS efirc;
- int rc;
-
- /* Try possible receive filters in turn */
- for ( i = 0; i < ( sizeof ( filters ) / sizeof ( filters[0] ) ); i++ ) {
- efirc = snp->snp->ReceiveFilters ( snp->snp, filters[i],
- 0, TRUE, 0, NULL );
- if ( efirc == 0 )
- return 0;
- rc = -EEFI ( efirc );
- DBGC ( snp, "SNP %s could not set receive filters %#02x (have "
- "%#02x): %s\n", netdev->name, filters[i],
- snp->snp->Mode->ReceiveFilterSetting, strerror ( rc ) );
- }
-
- return rc;
-}
-
-/**
- * Open network device
- *
- * @v netdev Network device
- * @ret rc Return status code
- */
-static int snpnet_open ( struct net_device *netdev ) {
- struct snp_nic *snp = netdev->priv;
- EFI_MAC_ADDRESS *mac = ( ( void * ) netdev->ll_addr );
- EFI_STATUS efirc;
- int rc;
-
- /* Try setting MAC address (before initialising) */
- if ( ( efirc = snp->snp->StationAddress ( snp->snp, FALSE, mac ) ) !=0){
- rc = -EEFI ( efirc );
- DBGC ( snp, "SNP %s could not set station address before "
- "initialising: %s\n", netdev->name, strerror ( rc ) );
- /* Ignore error */
- }
-
- /* Initialise NIC */
- if ( ( efirc = snp->snp->Initialize ( snp->snp, 0, 0 ) ) != 0 ) {
- rc = -EEFI ( efirc );
- snpnet_dump_mode ( netdev );
- DBGC ( snp, "SNP %s could not initialise: %s\n",
- netdev->name, strerror ( rc ) );
- return rc;
- }
-
- /* Try setting MAC address (after initialising) */
- if ( ( efirc = snp->snp->StationAddress ( snp->snp, FALSE, mac ) ) !=0){
- rc = -EEFI ( efirc );
- DBGC ( snp, "SNP %s could not set station address after "
- "initialising: %s\n", netdev->name, strerror ( rc ) );
- /* Ignore error */
- }
-
- /* Set receive filters */
- if ( ( rc = snpnet_rx_filters ( netdev ) ) != 0 ) {
- /* Ignore error */
- }
-
- /* Dump mode information (for debugging) */
- snpnet_dump_mode ( netdev );
-
- return 0;
-}
-
-/**
- * Close network device
- *
- * @v netdev Network device
- */
-static void snpnet_close ( struct net_device *netdev ) {
- struct snp_nic *snp = netdev->priv;
- EFI_STATUS efirc;
- int rc;
-
- /* Shut down NIC */
- if ( ( efirc = snp->snp->Shutdown ( snp->snp ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( snp, "SNP %s could not shut down: %s\n",
- netdev->name, strerror ( rc ) );
- /* Nothing we can do about this */
- }
-
- /* Discard transmit buffer, if applicable */
- if ( snp->txbuf ) {
- netdev_tx_complete_err ( netdev, snp->txbuf, -ECANCELED );
- snp->txbuf = NULL;
- }
-
- /* Discard receive buffer, if applicable */
- if ( snp->rxbuf ) {
- free_iob ( snp->rxbuf );
- snp->rxbuf = NULL;
- }
-}
-
-/** SNP network device operations */
-static struct net_device_operations snpnet_operations = {
- .open = snpnet_open,
- .close = snpnet_close,
- .transmit = snpnet_transmit,
- .poll = snpnet_poll,
-};
-
-/**
- * Attach driver to device
- *
- * @v efidev EFI device
- * @ret rc Return status code
- */
-int snpnet_start ( struct efi_device *efidev ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- EFI_HANDLE device = efidev->device;
- EFI_SIMPLE_NETWORK_MODE *mode;
- struct net_device *netdev;
- struct snp_nic *snp;
- void *interface;
- EFI_STATUS efirc;
- int rc;
-
- /* Open SNP protocol */
- if ( ( efirc = bs->OpenProtocol ( device,
- &efi_simple_network_protocol_guid,
- &interface, efi_image_handle, device,
- ( EFI_OPEN_PROTOCOL_BY_DRIVER |
- EFI_OPEN_PROTOCOL_EXCLUSIVE )))!=0){
- rc = -EEFI ( efirc );
- DBGC ( device, "SNP %p %s cannot open SNP protocol: %s\n",
- device, efi_handle_name ( device ), strerror ( rc ) );
- DBGC_EFI_OPENERS ( device, device,
- &efi_simple_network_protocol_guid );
- goto err_open_protocol;
- }
-
- /* Allocate and initialise structure */
- netdev = alloc_etherdev ( sizeof ( *snp ) );
- if ( ! netdev ) {
- rc = -ENOMEM;
- goto err_alloc;
- }
- netdev_init ( netdev, &snpnet_operations );
- snp = netdev->priv;
- snp->efidev = efidev;
- snp->snp = interface;
- mode = snp->snp->Mode;
- efidev_set_drvdata ( efidev, netdev );
-
- /* Populate underlying device information */
- efi_device_info ( device, "SNP", &snp->dev );
- snp->dev.driver_name = "SNP";
- snp->dev.parent = &efidev->dev;
- list_add ( &snp->dev.siblings, &efidev->dev.children );
- INIT_LIST_HEAD ( &snp->dev.children );
- netdev->dev = &snp->dev;
-
- /* Bring to the Started state */
- if ( ( mode->State == EfiSimpleNetworkStopped ) &&
- ( ( efirc = snp->snp->Start ( snp->snp ) ) != 0 ) ) {
- rc = -EEFI ( efirc );
- DBGC ( device, "SNP %p %s could not start: %s\n", device,
- efi_handle_name ( device ), strerror ( rc ) );
- goto err_start;
- }
- if ( ( mode->State == EfiSimpleNetworkInitialized ) &&
- ( ( efirc = snp->snp->Shutdown ( snp->snp ) ) != 0 ) ) {
- rc = -EEFI ( efirc );
- DBGC ( device, "SNP %p %s could not shut down: %s\n", device,
- efi_handle_name ( device ), strerror ( rc ) );
- goto err_shutdown;
- }
-
- /* Populate network device parameters */
- if ( mode->HwAddressSize != netdev->ll_protocol->hw_addr_len ) {
- DBGC ( device, "SNP %p %s has invalid hardware address "
- "length %d\n", device, efi_handle_name ( device ),
- mode->HwAddressSize );
- rc = -ENOTSUP;
- goto err_hw_addr_len;
- }
- memcpy ( netdev->hw_addr, &mode->PermanentAddress,
- netdev->ll_protocol->hw_addr_len );
- if ( mode->HwAddressSize != netdev->ll_protocol->ll_addr_len ) {
- DBGC ( device, "SNP %p %s has invalid link-layer address "
- "length %d\n", device, efi_handle_name ( device ),
- mode->HwAddressSize );
- rc = -ENOTSUP;
- goto err_ll_addr_len;
- }
- memcpy ( netdev->ll_addr, &mode->CurrentAddress,
- netdev->ll_protocol->ll_addr_len );
- snp->mtu = ( snp->snp->Mode->MaxPacketSize +
- snp->snp->Mode->MediaHeaderSize );
-
- /* Register network device */
- if ( ( rc = register_netdev ( netdev ) ) != 0 )
- goto err_register_netdev;
- DBGC ( device, "SNP %p %s registered as %s\n",
- device, efi_handle_name ( device ), netdev->name );
-
- /* Set initial link state */
- if ( snp->snp->Mode->MediaPresentSupported ) {
- snpnet_check_link ( netdev );
- } else {
- netdev_link_up ( netdev );
- }
-
- return 0;
-
- unregister_netdev ( netdev );
- err_register_netdev:
- err_ll_addr_len:
- err_hw_addr_len:
- err_shutdown:
- err_start:
- list_del ( &snp->dev.siblings );
- netdev_nullify ( netdev );
- netdev_put ( netdev );
- err_alloc:
- bs->CloseProtocol ( device, &efi_simple_network_protocol_guid,
- efi_image_handle, device );
- err_open_protocol:
- return rc;
-}
-
-/**
- * Detach driver from device
- *
- * @v efidev EFI device
- */
-void snpnet_stop ( struct efi_device *efidev ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- struct net_device *netdev = efidev_get_drvdata ( efidev );
- struct snp_nic *snp = netdev->priv;
- EFI_HANDLE device = efidev->device;
- EFI_STATUS efirc;
- int rc;
-
- /* Unregister network device */
- unregister_netdev ( netdev );
-
- /* Stop SNP protocol */
- if ( ( efirc = snp->snp->Stop ( snp->snp ) ) != 0 ) {
- rc = -EEFI ( efirc );
- DBGC ( device, "SNP %p %s could not stop: %s\n", device,
- efi_handle_name ( device ), strerror ( rc ) );
- /* Nothing we can do about this */
- }
-
- /* Free network device */
- list_del ( &snp->dev.siblings );
- netdev_nullify ( netdev );
- netdev_put ( netdev );
-
- /* Close SNP protocol */
- bs->CloseProtocol ( device, &efi_simple_network_protocol_guid,
- efi_image_handle, device );
-}
diff --git a/qemu/roms/ipxe/src/drivers/net/efi/snpnet.h b/qemu/roms/ipxe/src/drivers/net/efi/snpnet.h
deleted file mode 100644
index e6d31d5e4..000000000
--- a/qemu/roms/ipxe/src/drivers/net/efi/snpnet.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef _SNPNET_H
-#define _SNPNET_H
-
-/** @file
- *
- * SNP NIC driver
- *
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-struct efi_device;
-
-extern int snpnet_start ( struct efi_device *efidev );
-extern void snpnet_stop ( struct efi_device *efidev );
-
-#endif /* _SNPNET_H */
diff --git a/qemu/roms/ipxe/src/drivers/net/efi/snponly.c b/qemu/roms/ipxe/src/drivers/net/efi/snponly.c
deleted file mode 100644
index 73abfdbf4..000000000
--- a/qemu/roms/ipxe/src/drivers/net/efi/snponly.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * 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
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * 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 Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <string.h>
-#include <errno.h>
-#include <ipxe/init.h>
-#include <ipxe/efi/efi.h>
-#include <ipxe/efi/efi_driver.h>
-#include <ipxe/efi/efi_utils.h>
-#include <ipxe/efi/Protocol/SimpleNetwork.h>
-#include <ipxe/efi/Protocol/NetworkInterfaceIdentifier.h>
-#include "snpnet.h"
-#include "nii.h"
-
-/** @file
- *
- * EFI chainloaded-device-only driver
- *
- */
-
-/** A chainloaded protocol */
-struct chained_protocol {
- /** Protocol GUID */
- EFI_GUID *protocol;
- /**
- * Protocol instance installed on the loaded image's device handle
- *
- * We match against the protocol instance (rather than simply
- * matching against the device handle itself) because some
- * systems load us via a child of the underlying device, with
- * a duplicate protocol installed on the child handle.
- */
- void *interface;
-};
-
-/** Chainloaded SNP protocol */
-static struct chained_protocol chained_snp = {
- .protocol = &efi_simple_network_protocol_guid,
-};
-
-/** Chainloaded NII protocol */
-static struct chained_protocol chained_nii = {
- .protocol = &efi_nii31_protocol_guid,
-};
-
-/**
- * Locate chainloaded protocol instance
- *
- * @v chained Chainloaded protocol
- * @ret rc Return status code
- */
-static int chained_locate ( struct chained_protocol *chained ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- EFI_HANDLE device = efi_loaded_image->DeviceHandle;
- EFI_HANDLE parent;
- EFI_STATUS efirc;
- int rc;
-
- /* Locate handle supporting this protocol */
- if ( ( rc = efi_locate_device ( device, chained->protocol,
- &parent ) ) != 0 ) {
- DBGC ( device, "CHAINED %p %s does not support %s: %s\n",
- device, efi_handle_name ( device ),
- efi_guid_ntoa ( chained->protocol ), strerror ( rc ) );
- goto err_locate_device;
- }
- DBGC ( device, "CHAINED %p %s found %s on ", device,
- efi_handle_name ( device ), efi_guid_ntoa ( chained->protocol ));
- DBGC ( device, "%p %s\n", parent, efi_handle_name ( parent ) );
-
- /* Get protocol instance */
- if ( ( efirc = bs->OpenProtocol ( parent, chained->protocol,
- &chained->interface, efi_image_handle,
- device,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
- rc = -EEFI ( efirc );
- DBGC ( device, "CHAINED %p %s could not open %s on ",
- device, efi_handle_name ( device ),
- efi_guid_ntoa ( chained->protocol ) );
- DBGC ( device, "%p %s: %s\n",
- parent, efi_handle_name ( parent ), strerror ( rc ) );
- goto err_open_protocol;
- }
-
- err_locate_device:
- bs->CloseProtocol ( parent, chained->protocol, efi_image_handle,
- device );
- err_open_protocol:
- return rc;
-}
-
-/**
- * Check to see if driver supports a device
- *
- * @v device EFI device handle
- * @v chained Chainloaded protocol
- * @ret rc Return status code
- */
-static int chained_supported ( EFI_HANDLE device,
- struct chained_protocol *chained ) {
- EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
- EFI_STATUS efirc;
- void *interface;
- int rc;
-
- /* Get protocol */
- if ( ( efirc = bs->OpenProtocol ( device, chained->protocol, &interface,
- efi_image_handle, device,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
- rc = -EEFI ( efirc );
- DBGCP ( device, "CHAINED %p %s is not a %s device\n",
- device, efi_handle_name ( device ),
- efi_guid_ntoa ( chained->protocol ) );
- goto err_open_protocol;
- }
-
- /* Test for a match against the chainloading device */
- if ( interface != chained->interface ) {
- DBGC ( device, "CHAINED %p %s %p is not the chainloaded "
- "%s\n", device, efi_handle_name ( device ),
- interface, efi_guid_ntoa ( chained->protocol ) );
- rc = -ENOTTY;
- goto err_no_match;
- }
-
- /* Success */
- rc = 0;
- DBGC ( device, "CHAINED %p %s %p is the chainloaded %s\n",
- device, efi_handle_name ( device ), interface,
- efi_guid_ntoa ( chained->protocol ) );
-
- err_no_match:
- bs->CloseProtocol ( device, chained->protocol, efi_image_handle,
- device );
- err_open_protocol:
- return rc;
-}
-
-/**
- * Check to see if driver supports a device
- *
- * @v device EFI device handle
- * @ret rc Return status code
- */
-static int snponly_supported ( EFI_HANDLE device ) {
-
- return chained_supported ( device, &chained_snp );
-}
-
-/**
- * Check to see if driver supports a device
- *
- * @v device EFI device handle
- * @ret rc Return status code
- */
-static int niionly_supported ( EFI_HANDLE device ) {
-
- return chained_supported ( device, &chained_nii );
-}
-
-/** EFI SNP chainloading-device-only driver */
-struct efi_driver snponly_driver __efi_driver ( EFI_DRIVER_NORMAL ) = {
- .name = "SNPONLY",
- .supported = snponly_supported,
- .start = snpnet_start,
- .stop = snpnet_stop,
-};
-
-/** EFI NII chainloading-device-only driver */
-struct efi_driver niionly_driver __efi_driver ( EFI_DRIVER_NORMAL ) = {
- .name = "NIIONLY",
- .supported = niionly_supported,
- .start = nii_start,
- .stop = nii_stop,
-};
-
-/**
- * Initialise EFI chainloaded-device-only driver
- *
- */
-static void chained_init ( void ) {
-
- chained_locate ( &chained_snp );
- chained_locate ( &chained_nii );
-}
-
-/** EFI chainloaded-device-only initialisation function */
-struct init_fn chained_init_fn __init_fn ( INIT_LATE ) = {
- .initialise = chained_init,
-};