iPXE
nii.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License as
00006  * published by the Free Software Foundation; either version 2 of the
00007  * License, or any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017  * 02110-1301, USA.
00018  *
00019  * You can also choose to distribute this program under the terms of
00020  * the Unmodified Binary Distribution Licence (as given in the file
00021  * COPYING.UBDL), provided that you have satisfied its requirements.
00022  */
00023 
00024 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00025 
00026 #include <string.h>
00027 #include <strings.h>
00028 #include <stdlib.h>
00029 #include <unistd.h>
00030 #include <errno.h>
00031 #include <ipxe/netdevice.h>
00032 #include <ipxe/ethernet.h>
00033 #include <ipxe/umalloc.h>
00034 #include <ipxe/efi/efi.h>
00035 #include <ipxe/efi/efi_driver.h>
00036 #include <ipxe/efi/efi_pci.h>
00037 #include <ipxe/efi/efi_utils.h>
00038 #include <ipxe/efi/Protocol/NetworkInterfaceIdentifier.h>
00039 #include <ipxe/efi/IndustryStandard/Acpi10.h>
00040 #include "nii.h"
00041 
00042 /** @file
00043  *
00044  * NII driver
00045  *
00046  */
00047 
00048 /* Error numbers generated by NII */
00049 #define EIO_INVALID_CDB __einfo_error ( EINFO_EIO_INVALID_CDB )
00050 #define EINFO_EIO_INVALID_CDB                                                 \
00051         __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_INVALID_CDB,                \
00052                           "Invalid CDB" )
00053 #define EIO_INVALID_CPB __einfo_error ( EINFO_EIO_INVALID_CPB )
00054 #define EINFO_EIO_INVALID_CPB                                                 \
00055         __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_INVALID_CPB,                \
00056                           "Invalid CPB" )
00057 #define EIO_BUSY __einfo_error ( EINFO_EIO_BUSY )
00058 #define EINFO_EIO_BUSY                                                        \
00059         __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_BUSY,                       \
00060                           "Busy" )
00061 #define EIO_QUEUE_FULL __einfo_error ( EINFO_EIO_QUEUE_FULL )
00062 #define EINFO_EIO_QUEUE_FULL                                                  \
00063         __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_QUEUE_FULL,                 \
00064                           "Queue full" )
00065 #define EIO_ALREADY_STARTED __einfo_error ( EINFO_EIO_ALREADY_STARTED )
00066 #define EINFO_EIO_ALREADY_STARTED                                             \
00067         __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_ALREADY_STARTED,            \
00068                           "Already started" )
00069 #define EIO_NOT_STARTED __einfo_error ( EINFO_EIO_NOT_STARTED )
00070 #define EINFO_EIO_NOT_STARTED                                                 \
00071         __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NOT_STARTED,                \
00072                           "Not started" )
00073 #define EIO_NOT_SHUTDOWN __einfo_error ( EINFO_EIO_NOT_SHUTDOWN )
00074 #define EINFO_EIO_NOT_SHUTDOWN                                                \
00075         __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NOT_SHUTDOWN,               \
00076                           "Not shutdown" )
00077 #define EIO_ALREADY_INITIALIZED __einfo_error ( EINFO_EIO_ALREADY_INITIALIZED )
00078 #define EINFO_EIO_ALREADY_INITIALIZED                                         \
00079         __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_ALREADY_INITIALIZED,        \
00080                           "Already initialized" )
00081 #define EIO_NOT_INITIALIZED __einfo_error ( EINFO_EIO_NOT_INITIALIZED )
00082 #define EINFO_EIO_NOT_INITIALIZED                                             \
00083         __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NOT_INITIALIZED,            \
00084                           "Not initialized" )
00085 #define EIO_DEVICE_FAILURE __einfo_error ( EINFO_EIO_DEVICE_FAILURE )
00086 #define EINFO_EIO_DEVICE_FAILURE                                              \
00087         __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_DEVICE_FAILURE,             \
00088                           "Device failure" )
00089 #define EIO_NVDATA_FAILURE __einfo_error ( EINFO_EIO_NVDATA_FAILURE )
00090 #define EINFO_EIO_NVDATA_FAILURE                                              \
00091         __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NVDATA_FAILURE,             \
00092                           "Non-volatile data failure" )
00093 #define EIO_UNSUPPORTED __einfo_error ( EINFO_EIO_UNSUPPORTED )
00094 #define EINFO_EIO_UNSUPPORTED                                                 \
00095         __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_UNSUPPORTED,                \
00096                           "Unsupported" )
00097 #define EIO_BUFFER_FULL __einfo_error ( EINFO_EIO_BUFFER_FULL )
00098 #define EINFO_EIO_BUFFER_FULL                                                 \
00099         __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_BUFFER_FULL,                \
00100                           "Buffer full" )
00101 #define EIO_INVALID_PARAMETER __einfo_error ( EINFO_EIO_INVALID_PARAMETER )
00102 #define EINFO_EIO_INVALID_PARAMETER                                           \
00103         __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_INVALID_PARAMETER,          \
00104                           "Invalid parameter" )
00105 #define EIO_INVALID_UNDI __einfo_error ( EINFO_EIO_INVALID_UNDI )
00106 #define EINFO_EIO_INVALID_UNDI                                                \
00107         __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_INVALID_UNDI,               \
00108                           "Invalid UNDI" )
00109 #define EIO_IPV4_NOT_SUPPORTED __einfo_error ( EINFO_EIO_IPV4_NOT_SUPPORTED )
00110 #define EINFO_EIO_IPV4_NOT_SUPPORTED                                          \
00111         __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_IPV4_NOT_SUPPORTED,         \
00112                           "IPv4 not supported" )
00113 #define EIO_IPV6_NOT_SUPPORTED __einfo_error ( EINFO_EIO_IPV6_NOT_SUPPORTED )
00114 #define EINFO_EIO_IPV6_NOT_SUPPORTED                                          \
00115         __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_IPV6_NOT_SUPPORTED,         \
00116                           "IPv6 not supported" )
00117 #define EIO_NOT_ENOUGH_MEMORY __einfo_error ( EINFO_EIO_NOT_ENOUGH_MEMORY )
00118 #define EINFO_EIO_NOT_ENOUGH_MEMORY                                           \
00119         __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NOT_ENOUGH_MEMORY,          \
00120                           "Not enough memory" )
00121 #define EIO_NO_DATA __einfo_error ( EINFO_EIO_NO_DATA )
00122 #define EINFO_EIO_NO_DATA                                                     \
00123         __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NO_DATA,                    \
00124                           "No data" )
00125 #define EIO_STAT( stat )                                                      \
00126         EUNIQ ( EINFO_EIO, -(stat), EIO_INVALID_CDB, EIO_INVALID_CPB,         \
00127                 EIO_BUSY, EIO_QUEUE_FULL, EIO_ALREADY_STARTED,                \
00128                 EIO_NOT_STARTED, EIO_NOT_SHUTDOWN, EIO_ALREADY_INITIALIZED,   \
00129                 EIO_NOT_INITIALIZED, EIO_DEVICE_FAILURE, EIO_NVDATA_FAILURE,  \
00130                 EIO_UNSUPPORTED, EIO_BUFFER_FULL, EIO_INVALID_PARAMETER,      \
00131                 EIO_INVALID_UNDI, EIO_IPV4_NOT_SUPPORTED,                     \
00132                 EIO_IPV6_NOT_SUPPORTED, EIO_NOT_ENOUGH_MEMORY, EIO_NO_DATA )
00133 
00134 /** Maximum PCI BAR
00135  *
00136  * This is defined in <ipxe/efi/IndustryStandard/Pci22.h>, but we
00137  * can't #include that since it collides with <ipxe/pci.h>.
00138  */
00139 #define PCI_MAX_BAR 6
00140 
00141 /** An NII memory mapping */
00142 struct nii_mapping {
00143         /** List of mappings */
00144         struct list_head list;
00145         /** Mapped address */
00146         UINT64 addr;
00147         /** Mapping cookie created by PCI I/O protocol */
00148         VOID *mapping;
00149 };
00150 
00151 /** An NII NIC */
00152 struct nii_nic {
00153         /** EFI device */
00154         struct efi_device *efidev;
00155         /** Network interface identifier protocol */
00156         EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *nii;
00157         /** !PXE structure */
00158         PXE_SW_UNDI *undi;
00159         /** Entry point */
00160         EFIAPI VOID ( * issue ) ( UINT64 cdb );
00161         /** Generic device */
00162         struct device dev;
00163 
00164         /** PCI device */
00165         EFI_HANDLE pci_device;
00166         /** PCI I/O protocol */
00167         EFI_PCI_IO_PROTOCOL *pci_io;
00168         /** Memory BAR */
00169         unsigned int mem_bar;
00170         /** I/O BAR */
00171         unsigned int io_bar;
00172 
00173         /** Broadcast address */
00174         PXE_MAC_ADDR broadcast;
00175         /** Maximum packet length */
00176         size_t mtu;
00177 
00178         /** Hardware transmit/receive buffer */
00179         userptr_t buffer;
00180         /** Hardware transmit/receive buffer length */
00181         size_t buffer_len;
00182 
00183         /** Saved task priority level */
00184         EFI_TPL saved_tpl;
00185 
00186         /** Media status is supported */
00187         int media;
00188 
00189         /** Current transmit buffer */
00190         struct io_buffer *txbuf;
00191         /** Current receive buffer */
00192         struct io_buffer *rxbuf;
00193 
00194         /** Mapping list */
00195         struct list_head mappings;
00196 };
00197 
00198 /** Maximum number of received packets per poll */
00199 #define NII_RX_QUOTA 4
00200 
00201 /**
00202  * Open PCI I/O protocol and identify BARs
00203  *
00204  * @v nii               NII NIC
00205  * @ret rc              Return status code
00206  */
00207 static int nii_pci_open ( struct nii_nic *nii ) {
00208         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00209         EFI_HANDLE device = nii->efidev->device;
00210         EFI_HANDLE pci_device;
00211         union {
00212                 EFI_PCI_IO_PROTOCOL *pci_io;
00213                 void *interface;
00214         } pci_io;
00215         union {
00216                 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *acpi;
00217                 void *resource;
00218         } desc;
00219         int bar;
00220         EFI_STATUS efirc;
00221         int rc;
00222 
00223         /* Locate PCI I/O protocol */
00224         if ( ( rc = efi_locate_device ( device, &efi_pci_io_protocol_guid,
00225                                         &pci_device ) ) != 0 ) {
00226                 DBGC ( nii, "NII %s could not locate PCI I/O protocol: %s\n",
00227                        nii->dev.name, strerror ( rc ) );
00228                 goto err_locate;
00229         }
00230         nii->pci_device = pci_device;
00231 
00232         /* Open PCI I/O protocol */
00233         if ( ( efirc = bs->OpenProtocol ( pci_device, &efi_pci_io_protocol_guid,
00234                                           &pci_io.interface, efi_image_handle,
00235                                           device,
00236                                           EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
00237                 rc = -EEFI ( efirc );
00238                 DBGC ( nii, "NII %s could not open PCI I/O protocol: %s\n",
00239                        nii->dev.name, strerror ( rc ) );
00240                 goto err_open;
00241         }
00242         nii->pci_io = pci_io.pci_io;
00243 
00244         /* Identify memory and I/O BARs */
00245         nii->mem_bar = PCI_MAX_BAR;
00246         nii->io_bar = PCI_MAX_BAR;
00247         for ( bar = ( PCI_MAX_BAR - 1 ) ; bar >= 0 ; bar-- ) {
00248                 efirc = nii->pci_io->GetBarAttributes ( nii->pci_io, bar, NULL,
00249                                                         &desc.resource );
00250                 if ( efirc == EFI_UNSUPPORTED ) {
00251                         /* BAR not present; ignore */
00252                         continue;
00253                 }
00254                 if ( efirc != 0 ) {
00255                         rc = -EEFI ( efirc );
00256                         DBGC ( nii, "NII %s could not get BAR %d attributes: "
00257                                "%s\n", nii->dev.name, bar, strerror ( rc ) );
00258                         goto err_get_bar_attributes;
00259                 }
00260                 if ( desc.acpi->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM ) {
00261                         nii->mem_bar = bar;
00262                 } else if ( desc.acpi->ResType == ACPI_ADDRESS_SPACE_TYPE_IO ) {
00263                         nii->io_bar = bar;
00264                 }
00265                 bs->FreePool ( desc.resource );
00266         }
00267         DBGC ( nii, "NII %s has ", nii->dev.name );
00268         if ( nii->mem_bar < PCI_MAX_BAR ) {
00269                 DBGC ( nii, "memory BAR %d and ", nii->mem_bar );
00270         } else {
00271                 DBGC ( nii, "no memory BAR and " );
00272         }
00273         if ( nii->io_bar < PCI_MAX_BAR ) {
00274                 DBGC ( nii, "I/O BAR %d\n", nii->io_bar );
00275         } else {
00276                 DBGC ( nii, "no I/O BAR\n" );
00277         }
00278 
00279         return 0;
00280 
00281  err_get_bar_attributes:
00282         bs->CloseProtocol ( pci_device, &efi_pci_io_protocol_guid,
00283                             efi_image_handle, device );
00284  err_open:
00285  err_locate:
00286         return rc;
00287 }
00288 
00289 /**
00290  * Close PCI I/O protocol
00291  *
00292  * @v nii               NII NIC
00293  * @ret rc              Return status code
00294  */
00295 static void nii_pci_close ( struct nii_nic *nii ) {
00296         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00297         struct nii_mapping *map;
00298         struct nii_mapping *tmp;
00299 
00300         /* Remove any stale mappings */
00301         list_for_each_entry_safe ( map, tmp, &nii->mappings, list ) {
00302                 DBGC ( nii, "NII %s removing stale mapping %#llx\n",
00303                        nii->dev.name, ( ( unsigned long long ) map->addr ) );
00304                 nii->pci_io->Unmap ( nii->pci_io, map->mapping );
00305                 list_del ( &map->list );
00306                 free ( map );
00307         }
00308 
00309         /* Close protocols */
00310         bs->CloseProtocol ( nii->pci_device, &efi_pci_io_protocol_guid,
00311                             efi_image_handle, nii->efidev->device );
00312 }
00313 
00314 /**
00315  * I/O callback
00316  *
00317  * @v unique_id         NII NIC
00318  * @v op                Operations
00319  * @v len               Length of data
00320  * @v addr              Address
00321  * @v data              Data buffer
00322  */
00323 static EFIAPI VOID nii_io ( UINT64 unique_id, UINT8 op, UINT8 len, UINT64 addr,
00324                             UINT64 data ) {
00325         struct nii_nic *nii = ( ( void * ) ( intptr_t ) unique_id );
00326         EFI_PCI_IO_PROTOCOL_ACCESS *access;
00327         EFI_PCI_IO_PROTOCOL_IO_MEM io;
00328         EFI_PCI_IO_PROTOCOL_WIDTH width;
00329         unsigned int bar;
00330         EFI_STATUS efirc;
00331         int rc;
00332 
00333         /* Determine accessor and BAR */
00334         if ( op & ( PXE_MEM_READ | PXE_MEM_WRITE ) ) {
00335                 access = &nii->pci_io->Mem;
00336                 bar = nii->mem_bar;
00337         } else {
00338                 access = &nii->pci_io->Io;
00339                 bar = nii->io_bar;
00340         }
00341 
00342         /* Determine operaton */
00343         io = ( ( op & ( PXE_IO_WRITE | PXE_MEM_WRITE ) ) ?
00344                access->Write : access->Read );
00345 
00346         /* Determine width */
00347         width = ( fls ( len ) - 1 );
00348 
00349         /* Issue operation */
00350         if ( ( efirc = io ( nii->pci_io, width, bar, addr, 1,
00351                             ( ( void * ) ( intptr_t ) data ) ) ) != 0 ) {
00352                 rc = -EEFI ( efirc );
00353                 DBGC ( nii, "NII %s I/O operation %#x failed: %s\n",
00354                        nii->dev.name, op, strerror ( rc ) );
00355                 /* No way to report failure */
00356                 return;
00357         }
00358 }
00359 
00360 /**
00361  * Map callback
00362  *
00363  * @v unique_id         NII NIC
00364  * @v addr              Address of memory to be mapped
00365  * @v len               Length of memory to be mapped
00366  * @v dir               Direction of data flow
00367  * @v mapped            Device mapped address to fill in
00368  */
00369 static EFIAPI VOID nii_map ( UINT64 unique_id, UINT64 addr, UINT32 len,
00370                              UINT32 dir, UINT64 mapped ) {
00371         struct nii_nic *nii = ( ( void * ) ( intptr_t ) unique_id );
00372         EFI_PHYSICAL_ADDRESS *phys = ( ( void * ) ( intptr_t ) mapped );
00373         EFI_PCI_IO_PROTOCOL_OPERATION op;
00374         struct nii_mapping *map;
00375         UINTN count = len;
00376         EFI_STATUS efirc;
00377         int rc;
00378 
00379         /* Return a zero mapped address on failure */
00380         *phys = 0;
00381 
00382         /* Determine PCI mapping operation */
00383         switch ( dir ) {
00384         case TO_AND_FROM_DEVICE:
00385                 op = EfiPciIoOperationBusMasterCommonBuffer;
00386                 break;
00387         case FROM_DEVICE:
00388                 op = EfiPciIoOperationBusMasterWrite;
00389                 break;
00390         case TO_DEVICE:
00391                 op = EfiPciIoOperationBusMasterRead;
00392                 break;
00393         default:
00394                 DBGC ( nii, "NII %s unsupported mapping direction %d\n",
00395                        nii->dev.name, dir );
00396                 goto err_dir;
00397         }
00398 
00399         /* Allocate a mapping record */
00400         map = zalloc ( sizeof ( *map ) );
00401         if ( ! map )
00402                 goto err_alloc;
00403         map->addr = addr;
00404 
00405         /* Create map */
00406         if ( ( efirc = nii->pci_io->Map ( nii->pci_io, op,
00407                                           ( ( void * ) ( intptr_t ) addr ),
00408                                           &count, phys, &map->mapping ) ) != 0){
00409                 rc = -EEFI ( efirc );
00410                 DBGC ( nii, "NII %s map operation failed: %s\n",
00411                        nii->dev.name, strerror ( rc ) );
00412                 goto err_map;
00413         }
00414 
00415         /* Add to list of mappings */
00416         list_add ( &map->list, &nii->mappings );
00417         DBGC2 ( nii, "NII %s mapped %#llx+%#x->%#llx\n",
00418                 nii->dev.name, ( ( unsigned long long ) addr ),
00419                 len, ( ( unsigned long long ) *phys ) );
00420         return;
00421 
00422         list_del ( &map->list );
00423  err_map:
00424         free ( map );
00425  err_alloc:
00426  err_dir:
00427         return;
00428 }
00429 
00430 /**
00431  * Unmap callback
00432  *
00433  * @v unique_id         NII NIC
00434  * @v addr              Address of mapped memory
00435  * @v len               Length of mapped memory
00436  * @v dir               Direction of data flow
00437  * @v mapped            Device mapped address
00438  */
00439 static EFIAPI VOID nii_unmap ( UINT64 unique_id, UINT64 addr, UINT32 len,
00440                                UINT32 dir __unused, UINT64 mapped ) {
00441         struct nii_nic *nii = ( ( void * ) ( intptr_t ) unique_id );
00442         struct nii_mapping *map;
00443 
00444         /* Locate mapping record */
00445         list_for_each_entry ( map, &nii->mappings, list ) {
00446                 if ( map->addr == addr ) {
00447                         nii->pci_io->Unmap ( nii->pci_io, map->mapping );
00448                         list_del ( &map->list );
00449                         free ( map );
00450                         DBGC2 ( nii, "NII %s unmapped %#llx+%#x->%#llx\n",
00451                                 nii->dev.name, ( ( unsigned long long ) addr ),
00452                                 len, ( ( unsigned long long ) mapped ) );
00453                         return;
00454                 }
00455         }
00456 
00457         DBGC ( nii, "NII %s non-existent mapping %#llx+%#x->%#llx\n",
00458                nii->dev.name, ( ( unsigned long long ) addr ),
00459                len, ( ( unsigned long long ) mapped ) );
00460 }
00461 
00462 /**
00463  * Sync callback
00464  *
00465  * @v unique_id         NII NIC
00466  * @v addr              Address of mapped memory
00467  * @v len               Length of mapped memory
00468  * @v dir               Direction of data flow
00469  * @v mapped            Device mapped address
00470  */
00471 static EFIAPI VOID nii_sync ( UINT64 unique_id __unused, UINT64 addr,
00472                               UINT32 len, UINT32 dir, UINT64 mapped ) {
00473         const void *src;
00474         void *dst;
00475 
00476         /* Do nothing if this is an identity mapping */
00477         if ( addr == mapped )
00478                 return;
00479 
00480         /* Determine direction */
00481         if ( dir == FROM_DEVICE ) {
00482                 src = ( ( void * ) ( intptr_t ) mapped );
00483                 dst = ( ( void * ) ( intptr_t ) addr );
00484         } else {
00485                 src = ( ( void * ) ( intptr_t ) addr );
00486                 dst = ( ( void * ) ( intptr_t ) mapped );
00487         }
00488 
00489         /* Copy data */
00490         memcpy ( dst, src, len );
00491 }
00492 
00493 /**
00494  * Delay callback
00495  *
00496  * @v unique_id         NII NIC
00497  * @v microseconds      Delay in microseconds
00498  */
00499 static EFIAPI VOID nii_delay ( UINT64 unique_id __unused, UINTN microseconds ) {
00500 
00501         udelay ( microseconds );
00502 }
00503 
00504 /**
00505  * Block callback
00506  *
00507  * @v unique_id         NII NIC
00508  * @v acquire           Acquire lock
00509  */
00510 static EFIAPI VOID nii_block ( UINT64 unique_id, UINT32 acquire ) {
00511         struct nii_nic *nii = ( ( void * ) ( intptr_t ) unique_id );
00512         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00513 
00514         /* This functionality (which is copied verbatim from the
00515          * SnpDxe implementation of this function) appears to be
00516          * totally brain-dead, since it produces no actual blocking
00517          * behaviour.
00518          */
00519         if ( acquire ) {
00520                 nii->saved_tpl = bs->RaiseTPL ( TPL_NOTIFY );
00521         } else {
00522                 bs->RestoreTPL ( nii->saved_tpl );
00523         }
00524 }
00525 
00526 /**
00527  * Construct operation from opcode and flags
00528  *
00529  * @v opcode            Opcode
00530  * @v opflags           Flags
00531  * @ret op              Operation
00532  */
00533 #define NII_OP( opcode, opflags ) ( (opcode) | ( (opflags) << 16 ) )
00534 
00535 /**
00536  * Extract opcode from operation
00537  *
00538  * @v op                Operation
00539  * @ret opcode          Opcode
00540  */
00541 #define NII_OPCODE( op ) ( (op) & 0xffff )
00542 
00543 /**
00544  * Extract flags from operation
00545  *
00546  * @v op                Operation
00547  * @ret opflags         Flags
00548  */
00549 #define NII_OPFLAGS( op ) ( (op) >> 16 )
00550 
00551 /**
00552  * Issue command with parameter block and data block
00553  *
00554  * @v nii               NII NIC
00555  * @v op                Operation
00556  * @v cpb               Command parameter block, or NULL
00557  * @v cpb_len           Command parameter block length
00558  * @v db                Data block, or NULL
00559  * @v db_len            Data block length
00560  * @ret stat            Status flags, or negative status code
00561  */
00562 static int nii_issue_cpb_db ( struct nii_nic *nii, unsigned int op, void *cpb,
00563                               size_t cpb_len, void *db, size_t db_len ) {
00564         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
00565         PXE_CDB cdb;
00566         UINTN tpl;
00567 
00568         /* Prepare command descriptor block */
00569         memset ( &cdb, 0, sizeof ( cdb ) );
00570         cdb.OpCode = NII_OPCODE ( op );
00571         cdb.OpFlags = NII_OPFLAGS ( op );
00572         cdb.CPBaddr = ( ( intptr_t ) cpb );
00573         cdb.CPBsize = cpb_len;
00574         cdb.DBaddr = ( ( intptr_t ) db );
00575         cdb.DBsize = db_len;
00576         cdb.IFnum = nii->nii->IfNum;
00577 
00578         /* Raise task priority level */
00579         tpl = bs->RaiseTPL ( TPL_CALLBACK );
00580 
00581         /* Issue command */
00582         DBGC2 ( nii, "NII %s issuing %02x:%04x ifnum %d%s%s\n",
00583                 nii->dev.name, cdb.OpCode, cdb.OpFlags, cdb.IFnum,
00584                 ( cpb ? " cpb" : "" ), ( db ? " db" : "" ) );
00585         if ( cpb )
00586                 DBGC2_HD ( nii, cpb, cpb_len );
00587         if ( db )
00588                 DBGC2_HD ( nii, db, db_len );
00589         nii->issue ( ( intptr_t ) &cdb );
00590 
00591         /* Restore task priority level */
00592         bs->RestoreTPL ( tpl );
00593 
00594         /* Check completion status */
00595         if ( cdb.StatCode != PXE_STATCODE_SUCCESS )
00596                 return -cdb.StatCode;
00597 
00598         /* Return command-specific status flags */
00599         return ( cdb.StatFlags & ~PXE_STATFLAGS_STATUS_MASK );
00600 }
00601 
00602 /**
00603  * Issue command with parameter block
00604  *
00605  * @v nii               NII NIC
00606  * @v op                Operation
00607  * @v cpb               Command parameter block, or NULL
00608  * @v cpb_len           Command parameter block length
00609  * @ret stat            Status flags, or negative status code
00610  */
00611 static int nii_issue_cpb ( struct nii_nic *nii, unsigned int op, void *cpb,
00612                            size_t cpb_len ) {
00613 
00614         return nii_issue_cpb_db ( nii, op, cpb, cpb_len, NULL, 0 );
00615 }
00616 
00617 /**
00618  * Issue command with data block
00619  *
00620  * @v nii               NII NIC
00621  * @v op                Operation
00622  * @v db                Data block, or NULL
00623  * @v db_len            Data block length
00624  * @ret stat            Status flags, or negative status code
00625  */
00626 static int nii_issue_db ( struct nii_nic *nii, unsigned int op, void *db,
00627                           size_t db_len ) {
00628 
00629         return nii_issue_cpb_db ( nii, op, NULL, 0, db, db_len );
00630 }
00631 
00632 /**
00633  * Issue command
00634  *
00635  *
00636  * @v nii               NII NIC
00637  * @v op                Operation
00638  * @ret stat            Status flags, or negative status code
00639  */
00640 static int nii_issue ( struct nii_nic *nii, unsigned int op ) {
00641 
00642         return nii_issue_cpb_db ( nii, op, NULL, 0, NULL, 0 );
00643 }
00644 
00645 /**
00646  * Start UNDI
00647  *
00648  * @v nii               NII NIC
00649  * @ret rc              Return status code
00650  */
00651 static int nii_start_undi ( struct nii_nic *nii ) {
00652         PXE_CPB_START_31 cpb;
00653         int stat;
00654         int rc;
00655 
00656         /* Construct parameter block */
00657         memset ( &cpb, 0, sizeof ( cpb ) );
00658         cpb.Delay = ( ( intptr_t ) nii_delay );
00659         cpb.Block = ( ( intptr_t ) nii_block );
00660         cpb.Mem_IO = ( ( intptr_t ) nii_io );
00661         cpb.Map_Mem = ( ( intptr_t ) nii_map );
00662         cpb.UnMap_Mem = ( ( intptr_t ) nii_unmap );
00663         cpb.Sync_Mem = ( ( intptr_t ) nii_sync );
00664         cpb.Unique_ID = ( ( intptr_t ) nii );
00665 
00666         /* Issue command */
00667         if ( ( stat = nii_issue_cpb ( nii, PXE_OPCODE_START, &cpb,
00668                                       sizeof ( cpb ) ) ) < 0 ) {
00669                 rc = -EIO_STAT ( stat );
00670                 DBGC ( nii, "NII %s could not start: %s\n",
00671                        nii->dev.name, strerror ( rc ) );
00672                 return rc;
00673         }
00674 
00675         return 0;
00676 }
00677 
00678 /**
00679  * Stop UNDI
00680  *
00681  * @v nii               NII NIC
00682  */
00683 static void nii_stop_undi ( struct nii_nic *nii ) {
00684         int stat;
00685         int rc;
00686 
00687         /* Issue command */
00688         if ( ( stat = nii_issue ( nii, PXE_OPCODE_STOP ) ) < 0 ) {
00689                 rc = -EIO_STAT ( stat );
00690                 DBGC ( nii, "NII %s could not stop: %s\n",
00691                        nii->dev.name, strerror ( rc ) );
00692                 /* Nothing we can do about it */
00693                 return;
00694         }
00695 }
00696 
00697 /**
00698  * Get initialisation information
00699  *
00700  * @v nii               NII NIC
00701  * @v netdev            Network device to fill in
00702  * @ret rc              Return status code
00703  */
00704 static int nii_get_init_info ( struct nii_nic *nii,
00705                                struct net_device *netdev ) {
00706         PXE_DB_GET_INIT_INFO db;
00707         int stat;
00708         int rc;
00709 
00710         /* Issue command */
00711         if ( ( stat = nii_issue_db ( nii, PXE_OPCODE_GET_INIT_INFO, &db,
00712                                      sizeof ( db ) ) ) < 0 ) {
00713                 rc = -EIO_STAT ( stat );
00714                 DBGC ( nii, "NII %s could not get initialisation info: %s\n",
00715                        nii->dev.name, strerror ( rc ) );
00716                 return rc;
00717         }
00718 
00719         /* Determine link layer protocol */
00720         switch ( db.IFtype ) {
00721         case PXE_IFTYPE_ETHERNET :
00722                 netdev->ll_protocol = &ethernet_protocol;
00723                 break;
00724         default:
00725                 DBGC ( nii, "NII %s unknown interface type %#02x\n",
00726                        nii->dev.name, db.IFtype );
00727                 return -ENOTSUP;
00728         }
00729 
00730         /* Sanity checks */
00731         assert ( db.MediaHeaderLen == netdev->ll_protocol->ll_header_len );
00732         assert ( db.HWaddrLen == netdev->ll_protocol->hw_addr_len );
00733         assert ( db.HWaddrLen == netdev->ll_protocol->ll_addr_len );
00734 
00735         /* Extract parameters */
00736         nii->buffer_len = db.MemoryRequired;
00737         nii->mtu = ( db.FrameDataLen + db.MediaHeaderLen );
00738         netdev->max_pkt_len = nii->mtu;
00739         nii->media = ( stat & PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED );
00740 
00741         return 0;
00742 }
00743 
00744 /**
00745  * Initialise UNDI
00746  *
00747  * @v nii               NII NIC
00748  * @v flags             Flags
00749  * @ret rc              Return status code
00750  */
00751 static int nii_initialise_flags ( struct nii_nic *nii, unsigned int flags ) {
00752         PXE_CPB_INITIALIZE cpb;
00753         PXE_DB_INITIALIZE db;
00754         unsigned int op;
00755         int stat;
00756         int rc;
00757 
00758         /* Allocate memory buffer */
00759         nii->buffer = umalloc ( nii->buffer_len );
00760         if ( ! nii->buffer ) {
00761                 rc = -ENOMEM;
00762                 goto err_alloc;
00763         }
00764 
00765         /* Construct parameter block */
00766         memset ( &cpb, 0, sizeof ( cpb ) );
00767         cpb.MemoryAddr = ( ( intptr_t ) nii->buffer );
00768         cpb.MemoryLength = nii->buffer_len;
00769 
00770         /* Construct data block */
00771         memset ( &db, 0, sizeof ( db ) );
00772 
00773         /* Issue command */
00774         op = NII_OP ( PXE_OPCODE_INITIALIZE, flags );
00775         if ( ( stat = nii_issue_cpb_db ( nii, op, &cpb, sizeof ( cpb ),
00776                                          &db, sizeof ( db ) ) ) < 0 ) {
00777                 rc = -EIO_STAT ( stat );
00778                 DBGC ( nii, "NII %s could not initialise: %s\n",
00779                        nii->dev.name, strerror ( rc ) );
00780                 goto err_initialize;
00781         }
00782 
00783         return 0;
00784 
00785  err_initialize:
00786         ufree ( nii->buffer );
00787  err_alloc:
00788         return rc;
00789 }
00790 
00791 /**
00792  * Initialise UNDI
00793  *
00794  * @v nii               NII NIC
00795  * @ret rc              Return status code
00796  */
00797 static int nii_initialise ( struct nii_nic *nii ) {
00798         unsigned int flags;
00799 
00800         /* Initialise UNDI */
00801         flags = PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE;
00802         return nii_initialise_flags ( nii, flags );
00803 }
00804 
00805 /**
00806  * Shut down UNDI
00807  *
00808  * @v nii               NII NIC
00809  */
00810 static void nii_shutdown ( struct nii_nic *nii ) {
00811         int stat;
00812         int rc;
00813 
00814         /* Issue command */
00815         if ( ( stat = nii_issue ( nii, PXE_OPCODE_SHUTDOWN ) ) < 0 ) {
00816                 rc = -EIO_STAT ( stat );
00817                 DBGC ( nii, "NII %s could not shut down: %s\n",
00818                        nii->dev.name, strerror ( rc ) );
00819                 /* Leak memory to avoid corruption */
00820                 return;
00821         }
00822 
00823         /* Free buffer */
00824         ufree ( nii->buffer );
00825 }
00826 
00827 /**
00828  * Get station addresses
00829  *
00830  * @v nii               NII NIC
00831  * @v netdev            Network device to fill in
00832  * @ret rc              Return status code
00833  */
00834 static int nii_get_station_address ( struct nii_nic *nii,
00835                                      struct net_device *netdev ) {
00836         PXE_DB_STATION_ADDRESS db;
00837         unsigned int op;
00838         int stat;
00839         int rc;
00840 
00841         /* Initialise UNDI */
00842         if ( ( rc = nii_initialise ( nii ) ) != 0 )
00843                 goto err_initialise;
00844 
00845         /* Issue command */
00846         op = NII_OP ( PXE_OPCODE_STATION_ADDRESS,
00847                       PXE_OPFLAGS_STATION_ADDRESS_READ );
00848         if ( ( stat = nii_issue_db ( nii, op, &db, sizeof ( db ) ) ) < 0 ) {
00849                 rc = -EIO_STAT ( stat );
00850                 DBGC ( nii, "NII %s could not get station address: %s\n",
00851                        nii->dev.name, strerror ( rc ) );
00852                 goto err_station_address;
00853         }
00854 
00855         /* Copy MAC addresses */
00856         memcpy ( netdev->ll_addr, db.StationAddr,
00857                  netdev->ll_protocol->ll_addr_len );
00858         memcpy ( netdev->hw_addr, db.PermanentAddr,
00859                  netdev->ll_protocol->hw_addr_len );
00860         memcpy ( nii->broadcast, db.BroadcastAddr,
00861                  sizeof ( nii->broadcast ) );
00862 
00863  err_station_address:
00864         nii_shutdown ( nii );
00865  err_initialise:
00866         return rc;
00867 }
00868 
00869 /**
00870  * Set station address
00871  *
00872  * @v nii               NII NIC
00873  * @v netdev            Network device
00874  * @ret rc              Return status code
00875  */
00876 static int nii_set_station_address ( struct nii_nic *nii,
00877                                      struct net_device *netdev ) {
00878         uint32_t implementation = nii->undi->Implementation;
00879         PXE_CPB_STATION_ADDRESS cpb;
00880         unsigned int op;
00881         int stat;
00882         int rc;
00883 
00884         /* Fail if setting station address is unsupported */
00885         if ( ! ( implementation & PXE_ROMID_IMP_STATION_ADDR_SETTABLE ) )
00886                 return -ENOTSUP;
00887 
00888         /* Construct parameter block */
00889         memset ( &cpb, 0, sizeof ( cpb ) );
00890         memcpy ( cpb.StationAddr, netdev->ll_addr,
00891                  netdev->ll_protocol->ll_addr_len );
00892 
00893         /* Issue command */
00894         op = NII_OP ( PXE_OPCODE_STATION_ADDRESS,
00895                       PXE_OPFLAGS_STATION_ADDRESS_WRITE );
00896         if ( ( stat = nii_issue_cpb ( nii, op, &cpb, sizeof ( cpb ) ) ) < 0 ) {
00897                 rc = -EIO_STAT ( stat );
00898                 DBGC ( nii, "NII %s could not set station address: %s\n",
00899                        nii->dev.name, strerror ( rc ) );
00900                 return rc;
00901         }
00902 
00903         return 0;
00904 }
00905 
00906 /**
00907  * Set receive filters
00908  *
00909  * @v nii               NII NIC
00910  * @ret rc              Return status code
00911  */
00912 static int nii_set_rx_filters ( struct nii_nic *nii ) {
00913         uint32_t implementation = nii->undi->Implementation;
00914         unsigned int flags;
00915         unsigned int op;
00916         int stat;
00917         int rc;
00918 
00919         /* Construct receive filter set */
00920         flags = ( PXE_OPFLAGS_RECEIVE_FILTER_ENABLE |
00921                   PXE_OPFLAGS_RECEIVE_FILTER_UNICAST );
00922         if ( implementation & PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED )
00923                 flags |= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;
00924         if ( implementation & PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED )
00925                 flags |= PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS;
00926         if ( implementation & PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED )
00927                 flags |= PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;
00928 
00929         /* Issue command */
00930         op = NII_OP ( PXE_OPCODE_RECEIVE_FILTERS, flags );
00931         if ( ( stat = nii_issue ( nii, op ) ) < 0 ) {
00932                 rc = -EIO_STAT ( stat );
00933                 DBGC ( nii, "NII %s could not set receive filters %#04x: %s\n",
00934                        nii->dev.name, flags, strerror ( rc ) );
00935                 return rc;
00936         }
00937 
00938         return 0;
00939 }
00940 
00941 /**
00942  * Transmit packet
00943  *
00944  * @v netdev            Network device
00945  * @v iobuf             I/O buffer
00946  * @ret rc              Return status code
00947  */
00948 static int nii_transmit ( struct net_device *netdev,
00949                           struct io_buffer *iobuf ) {
00950         struct nii_nic *nii = netdev->priv;
00951         PXE_CPB_TRANSMIT cpb;
00952         unsigned int op;
00953         int stat;
00954         int rc;
00955 
00956         /* Defer the packet if there is already a transmission in progress */
00957         if ( nii->txbuf ) {
00958                 netdev_tx_defer ( netdev, iobuf );
00959                 return 0;
00960         }
00961 
00962         /* Construct parameter block */
00963         memset ( &cpb, 0, sizeof ( cpb ) );
00964         cpb.FrameAddr = virt_to_bus ( iobuf->data );
00965         cpb.DataLen = iob_len ( iobuf );
00966         cpb.MediaheaderLen = netdev->ll_protocol->ll_header_len;
00967 
00968         /* Transmit packet */
00969         op = NII_OP ( PXE_OPCODE_TRANSMIT,
00970                       ( PXE_OPFLAGS_TRANSMIT_WHOLE |
00971                         PXE_OPFLAGS_TRANSMIT_DONT_BLOCK ) );
00972         if ( ( stat = nii_issue_cpb ( nii, op, &cpb, sizeof ( cpb ) ) ) < 0 ) {
00973                 rc = -EIO_STAT ( stat );
00974                 DBGC ( nii, "NII %s could not transmit: %s\n",
00975                        nii->dev.name, strerror ( rc ) );
00976                 return rc;
00977         }
00978         nii->txbuf = iobuf;
00979 
00980         return 0;
00981 }
00982 
00983 /**
00984  * Poll for completed packets
00985  *
00986  * @v netdev            Network device
00987  * @v stat              Status flags
00988  */
00989 static void nii_poll_tx ( struct net_device *netdev, unsigned int stat ) {
00990         struct nii_nic *nii = netdev->priv;
00991         struct io_buffer *iobuf;
00992 
00993         /* Do nothing unless we have a completion */
00994         if ( stat & PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN )
00995                 return;
00996 
00997         /* Sanity check */
00998         assert ( nii->txbuf != NULL );
00999 
01000         /* Complete transmission */
01001         iobuf = nii->txbuf;
01002         nii->txbuf = NULL;
01003         netdev_tx_complete ( netdev, iobuf );
01004 }
01005 
01006 /**
01007  * Poll for received packets
01008  *
01009  * @v netdev            Network device
01010  */
01011 static void nii_poll_rx ( struct net_device *netdev ) {
01012         struct nii_nic *nii = netdev->priv;
01013         PXE_CPB_RECEIVE cpb;
01014         PXE_DB_RECEIVE db;
01015         unsigned int quota;
01016         int stat;
01017         int rc;
01018 
01019         /* Retrieve up to NII_RX_QUOTA packets */
01020         for ( quota = NII_RX_QUOTA ; quota ; quota-- ) {
01021 
01022                 /* Allocate buffer, if required */
01023                 if ( ! nii->rxbuf ) {
01024                         nii->rxbuf = alloc_iob ( nii->mtu );
01025                         if ( ! nii->rxbuf ) {
01026                                 /* Leave for next poll */
01027                                 break;
01028                         }
01029                 }
01030 
01031                 /* Construct parameter block */
01032                 memset ( &cpb, 0, sizeof ( cpb ) );
01033                 cpb.BufferAddr = virt_to_bus ( nii->rxbuf->data );
01034                 cpb.BufferLen = iob_tailroom ( nii->rxbuf );
01035 
01036                 /* Issue command */
01037                 if ( ( stat = nii_issue_cpb_db ( nii, PXE_OPCODE_RECEIVE,
01038                                                  &cpb, sizeof ( cpb ),
01039                                                  &db, sizeof ( db ) ) ) < 0 ) {
01040 
01041                         /* PXE_STATCODE_NO_DATA is just the usual "no packet"
01042                          * status indicator; ignore it.
01043                          */
01044                         if ( stat == -PXE_STATCODE_NO_DATA )
01045                                 break;
01046 
01047                         /* Anything else is an error */
01048                         rc = -EIO_STAT ( stat );
01049                         DBGC ( nii, "NII %s could not receive: %s\n",
01050                                nii->dev.name, strerror ( rc ) );
01051                         netdev_rx_err ( netdev, NULL, rc );
01052                         break;
01053                 }
01054 
01055                 /* Hand off to network stack */
01056                 iob_put ( nii->rxbuf, db.FrameLen );
01057                 netdev_rx ( netdev, nii->rxbuf );
01058                 nii->rxbuf = NULL;
01059         }
01060 }
01061 
01062 /**
01063  * Check for link state changes
01064  *
01065  * @v netdev            Network device
01066  * @v stat              Status flags
01067  */
01068 static void nii_poll_link ( struct net_device *netdev, unsigned int stat ) {
01069         int no_media = ( stat & PXE_STATFLAGS_GET_STATUS_NO_MEDIA );
01070 
01071         if ( no_media && netdev_link_ok ( netdev ) ) {
01072                 netdev_link_down ( netdev );
01073         } else if ( ( ! no_media ) && ( ! netdev_link_ok ( netdev ) ) ) {
01074                 netdev_link_up ( netdev );
01075         }
01076 }
01077 
01078 /**
01079  * Poll for completed packets
01080  *
01081  * @v netdev            Network device
01082  */
01083 static void nii_poll ( struct net_device *netdev ) {
01084         struct nii_nic *nii = netdev->priv;
01085         PXE_DB_GET_STATUS db;
01086         unsigned int op;
01087         int stat;
01088         int rc;
01089 
01090         /* Construct data block */
01091         memset ( &db, 0, sizeof ( db ) );
01092 
01093         /* Get status */
01094         op = NII_OP ( PXE_OPCODE_GET_STATUS,
01095                       ( PXE_OPFLAGS_GET_INTERRUPT_STATUS |
01096                         ( nii->txbuf ? PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS : 0)|
01097                         ( nii->media ? PXE_OPFLAGS_GET_MEDIA_STATUS : 0 ) ) );
01098         if ( ( stat = nii_issue_db ( nii, op, &db, sizeof ( db ) ) ) < 0 ) {
01099                 rc = -EIO_STAT ( stat );
01100                 DBGC ( nii, "NII %s could not get status: %s\n",
01101                        nii->dev.name, strerror ( rc ) );
01102                 return;
01103         }
01104 
01105         /* Process any TX completions */
01106         if ( nii->txbuf )
01107                 nii_poll_tx ( netdev, stat );
01108 
01109         /* Process any RX completions */
01110         nii_poll_rx ( netdev );
01111 
01112         /* Check for link state changes */
01113         if ( nii->media )
01114                 nii_poll_link ( netdev, stat );
01115 }
01116 
01117 /**
01118  * Open network device
01119  *
01120  * @v netdev            Network device
01121  * @ret rc              Return status code
01122  */
01123 static int nii_open ( struct net_device *netdev ) {
01124         struct nii_nic *nii = netdev->priv;
01125         unsigned int flags;
01126         int rc;
01127 
01128         /* Initialise NIC
01129          *
01130          * We don't care about link state here, and would prefer to
01131          * have the NIC initialise even if no cable is present, to
01132          * match the behaviour of all other iPXE drivers.
01133          *
01134          * Some Emulex NII drivers have a bug which prevents packets
01135          * from being sent or received unless we specifically ask it
01136          * to detect cable presence during initialisation.
01137          *
01138          * Unfortunately, some other NII drivers (e.g. Mellanox) may
01139          * time out and report failure if asked to detect cable
01140          * presence during initialisation on links that are physically
01141          * slow to reach link-up.
01142          *
01143          * Attempt to work around both of these problems by requesting
01144          * cable detection at this point if any only if the driver is
01145          * not capable of reporting link status changes at runtime via
01146          * PXE_OPCODE_GET_STATUS.
01147          */
01148         flags = ( nii->media ? PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE
01149                   : PXE_OPFLAGS_INITIALIZE_DETECT_CABLE );
01150         if ( ( rc = nii_initialise_flags ( nii, flags ) ) != 0 )
01151                 goto err_initialise;
01152 
01153         /* Attempt to set station address */
01154         if ( ( rc = nii_set_station_address ( nii, netdev ) ) != 0 ) {
01155                 DBGC ( nii, "NII %s could not set station address: %s\n",
01156                        nii->dev.name, strerror ( rc ) );
01157                 /* Treat as non-fatal */
01158         }
01159 
01160         /* Set receive filters */
01161         if ( ( rc = nii_set_rx_filters ( nii ) ) != 0 )
01162                 goto err_set_rx_filters;
01163 
01164         return 0;
01165 
01166  err_set_rx_filters:
01167         nii_shutdown ( nii );
01168  err_initialise:
01169         return rc;
01170 }
01171 
01172 /**
01173  * Close network device
01174  *
01175  * @v netdev            Network device
01176  */
01177 static void nii_close ( struct net_device *netdev ) {
01178         struct nii_nic *nii = netdev->priv;
01179 
01180         /* Shut down NIC */
01181         nii_shutdown ( nii );
01182 
01183         /* Discard transmit buffer, if applicable */
01184         if ( nii->txbuf ) {
01185                 netdev_tx_complete_err ( netdev, nii->txbuf, -ECANCELED );
01186                 nii->txbuf = NULL;
01187         }
01188 
01189         /* Discard receive buffer, if applicable */
01190         if ( nii->rxbuf ) {
01191                 free_iob ( nii->rxbuf );
01192                 nii->rxbuf = NULL;
01193         }
01194 }
01195 
01196 /** NII network device operations */
01197 static struct net_device_operations nii_operations = {
01198         .open = nii_open,
01199         .close = nii_close,
01200         .transmit = nii_transmit,
01201         .poll = nii_poll,
01202 };
01203 
01204 /**
01205  * Attach driver to device
01206  *
01207  * @v efidev            EFI device
01208  * @ret rc              Return status code
01209  */
01210 int nii_start ( struct efi_device *efidev ) {
01211         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
01212         EFI_HANDLE device = efidev->device;
01213         struct net_device *netdev;
01214         struct nii_nic *nii;
01215         void *interface;
01216         EFI_STATUS efirc;
01217         int rc;
01218 
01219         /* Allocate and initialise structure */
01220         netdev = alloc_netdev ( sizeof ( *nii ) );
01221         if ( ! netdev ) {
01222                 rc = -ENOMEM;
01223                 goto err_alloc;
01224         }
01225         netdev_init ( netdev, &nii_operations );
01226         nii = netdev->priv;
01227         nii->efidev = efidev;
01228         INIT_LIST_HEAD ( &nii->mappings );
01229         netdev->ll_broadcast = nii->broadcast;
01230         efidev_set_drvdata ( efidev, netdev );
01231 
01232         /* Populate underlying device information */
01233         efi_device_info ( device, "NII", &nii->dev );
01234         nii->dev.driver_name = "NII";
01235         nii->dev.parent = &efidev->dev;
01236         list_add ( &nii->dev.siblings, &efidev->dev.children );
01237         INIT_LIST_HEAD ( &nii->dev.children );
01238         netdev->dev = &nii->dev;
01239 
01240         /* Open NII protocol */
01241         if ( ( efirc = bs->OpenProtocol ( device, &efi_nii31_protocol_guid,
01242                                           &interface, efi_image_handle, device,
01243                                           ( EFI_OPEN_PROTOCOL_BY_DRIVER |
01244                                             EFI_OPEN_PROTOCOL_EXCLUSIVE )))!=0){
01245                 rc = -EEFI ( efirc );
01246                 DBGC ( nii, "NII %s cannot open NII protocol: %s\n",
01247                        nii->dev.name, strerror ( rc ) );
01248                 DBGC_EFI_OPENERS ( device, device, &efi_nii31_protocol_guid );
01249                 goto err_open_protocol;
01250         }
01251         nii->nii = interface;
01252 
01253         /* Locate UNDI and entry point */
01254         nii->undi = ( ( void * ) ( intptr_t ) nii->nii->Id );
01255         if ( ! nii->undi ) {
01256                 DBGC ( nii, "NII %s has no UNDI\n", nii->dev.name );
01257                 rc = -ENODEV;
01258                 goto err_no_undi;
01259         }
01260         if ( nii->undi->Implementation & PXE_ROMID_IMP_HW_UNDI ) {
01261                 DBGC ( nii, "NII %s is a mythical hardware UNDI\n",
01262                        nii->dev.name );
01263                 rc = -ENOTSUP;
01264                 goto err_hw_undi;
01265         }
01266         if ( nii->undi->Implementation & PXE_ROMID_IMP_SW_VIRT_ADDR ) {
01267                 nii->issue = ( ( void * ) ( intptr_t ) nii->undi->EntryPoint );
01268         } else {
01269                 nii->issue = ( ( ( void * ) nii->undi ) +
01270                                nii->undi->EntryPoint );
01271         }
01272         DBGC ( nii, "NII %s using UNDI v%x.%x at %p entry %p impl %#08x\n",
01273                nii->dev.name, nii->nii->MajorVer, nii->nii->MinorVer,
01274                nii->undi, nii->issue, nii->undi->Implementation );
01275 
01276         /* Open PCI I/O protocols and locate BARs */
01277         if ( ( rc = nii_pci_open ( nii ) ) != 0 )
01278                 goto err_pci_open;
01279 
01280         /* Start UNDI */
01281         if ( ( rc = nii_start_undi ( nii ) ) != 0 )
01282                 goto err_start_undi;
01283 
01284         /* Get initialisation information */
01285         if ( ( rc = nii_get_init_info ( nii, netdev ) ) != 0 )
01286                 goto err_get_init_info;
01287 
01288         /* Get MAC addresses */
01289         if ( ( rc = nii_get_station_address ( nii, netdev ) ) != 0 )
01290                 goto err_get_station_address;
01291 
01292         /* Register network device */
01293         if ( ( rc = register_netdev ( netdev ) ) != 0 )
01294                 goto err_register_netdev;
01295         DBGC ( nii, "NII %s registered as %s for %s\n", nii->dev.name,
01296                netdev->name, efi_handle_name ( device ) );
01297 
01298         /* Set initial link state (if media detection is not supported) */
01299         if ( ! nii->media )
01300                 netdev_link_up ( netdev );
01301 
01302         return 0;
01303 
01304         unregister_netdev ( netdev );
01305  err_register_netdev:
01306  err_get_station_address:
01307  err_get_init_info:
01308         nii_stop_undi ( nii );
01309  err_start_undi:
01310         nii_pci_close ( nii );
01311  err_pci_open:
01312  err_hw_undi:
01313  err_no_undi:
01314         bs->CloseProtocol ( device, &efi_nii31_protocol_guid,
01315                             efi_image_handle, device );
01316  err_open_protocol:
01317         list_del ( &nii->dev.siblings );
01318         netdev_nullify ( netdev );
01319         netdev_put ( netdev );
01320  err_alloc:
01321         return rc;
01322 }
01323 
01324 /**
01325  * Detach driver from device
01326  *
01327  * @v efidev            EFI device
01328  */
01329 void nii_stop ( struct efi_device *efidev ) {
01330         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
01331         struct net_device *netdev = efidev_get_drvdata ( efidev );
01332         struct nii_nic *nii = netdev->priv;
01333         EFI_HANDLE device = efidev->device;
01334 
01335         /* Unregister network device */
01336         unregister_netdev ( netdev );
01337 
01338         /* Stop UNDI */
01339         nii_stop_undi ( nii );
01340 
01341         /* Close PCI I/O protocols */
01342         nii_pci_close ( nii );
01343 
01344         /* Close NII protocol */
01345         bs->CloseProtocol ( device, &efi_nii31_protocol_guid,
01346                             efi_image_handle, device );
01347 
01348         /* Free network device */
01349         list_del ( &nii->dev.siblings );
01350         netdev_nullify ( netdev );
01351         netdev_put ( netdev );
01352 }