2 * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 FILE_LICENCE ( GPL2_OR_LATER );
26 #include <ipxe/netdevice.h>
27 #include <ipxe/ethernet.h>
28 #include <ipxe/umalloc.h>
29 #include <ipxe/efi/efi.h>
30 #include <ipxe/efi/efi_driver.h>
31 #include <ipxe/efi/efi_pci.h>
32 #include <ipxe/efi/efi_utils.h>
33 #include <ipxe/efi/Protocol/NetworkInterfaceIdentifier.h>
34 #include <ipxe/efi/IndustryStandard/Acpi10.h>
43 /* Error numbers generated by NII */
44 #define EIO_INVALID_CDB __einfo_error ( EINFO_EIO_INVALID_CDB )
45 #define EINFO_EIO_INVALID_CDB \
46 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_INVALID_CDB, \
48 #define EIO_INVALID_CPB __einfo_error ( EINFO_EIO_INVALID_CPB )
49 #define EINFO_EIO_INVALID_CPB \
50 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_INVALID_CPB, \
52 #define EIO_BUSY __einfo_error ( EINFO_EIO_BUSY )
53 #define EINFO_EIO_BUSY \
54 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_BUSY, \
56 #define EIO_QUEUE_FULL __einfo_error ( EINFO_EIO_QUEUE_FULL )
57 #define EINFO_EIO_QUEUE_FULL \
58 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_QUEUE_FULL, \
60 #define EIO_ALREADY_STARTED __einfo_error ( EINFO_EIO_ALREADY_STARTED )
61 #define EINFO_EIO_ALREADY_STARTED \
62 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_ALREADY_STARTED, \
64 #define EIO_NOT_STARTED __einfo_error ( EINFO_EIO_NOT_STARTED )
65 #define EINFO_EIO_NOT_STARTED \
66 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NOT_STARTED, \
68 #define EIO_NOT_SHUTDOWN __einfo_error ( EINFO_EIO_NOT_SHUTDOWN )
69 #define EINFO_EIO_NOT_SHUTDOWN \
70 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NOT_SHUTDOWN, \
72 #define EIO_ALREADY_INITIALIZED __einfo_error ( EINFO_EIO_ALREADY_INITIALIZED )
73 #define EINFO_EIO_ALREADY_INITIALIZED \
74 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_ALREADY_INITIALIZED, \
75 "Already initialized" )
76 #define EIO_NOT_INITIALIZED __einfo_error ( EINFO_EIO_NOT_INITIALIZED )
77 #define EINFO_EIO_NOT_INITIALIZED \
78 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NOT_INITIALIZED, \
80 #define EIO_DEVICE_FAILURE __einfo_error ( EINFO_EIO_DEVICE_FAILURE )
81 #define EINFO_EIO_DEVICE_FAILURE \
82 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_DEVICE_FAILURE, \
84 #define EIO_NVDATA_FAILURE __einfo_error ( EINFO_EIO_NVDATA_FAILURE )
85 #define EINFO_EIO_NVDATA_FAILURE \
86 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NVDATA_FAILURE, \
87 "Non-volatile data failure" )
88 #define EIO_UNSUPPORTED __einfo_error ( EINFO_EIO_UNSUPPORTED )
89 #define EINFO_EIO_UNSUPPORTED \
90 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_UNSUPPORTED, \
92 #define EIO_BUFFER_FULL __einfo_error ( EINFO_EIO_BUFFER_FULL )
93 #define EINFO_EIO_BUFFER_FULL \
94 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_BUFFER_FULL, \
96 #define EIO_INVALID_PARAMETER __einfo_error ( EINFO_EIO_INVALID_PARAMETER )
97 #define EINFO_EIO_INVALID_PARAMETER \
98 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_INVALID_PARAMETER, \
100 #define EIO_INVALID_UNDI __einfo_error ( EINFO_EIO_INVALID_UNDI )
101 #define EINFO_EIO_INVALID_UNDI \
102 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_INVALID_UNDI, \
104 #define EIO_IPV4_NOT_SUPPORTED __einfo_error ( EINFO_EIO_IPV4_NOT_SUPPORTED )
105 #define EINFO_EIO_IPV4_NOT_SUPPORTED \
106 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_IPV4_NOT_SUPPORTED, \
107 "IPv4 not supported" )
108 #define EIO_IPV6_NOT_SUPPORTED __einfo_error ( EINFO_EIO_IPV6_NOT_SUPPORTED )
109 #define EINFO_EIO_IPV6_NOT_SUPPORTED \
110 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_IPV6_NOT_SUPPORTED, \
111 "IPv6 not supported" )
112 #define EIO_NOT_ENOUGH_MEMORY __einfo_error ( EINFO_EIO_NOT_ENOUGH_MEMORY )
113 #define EINFO_EIO_NOT_ENOUGH_MEMORY \
114 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NOT_ENOUGH_MEMORY, \
115 "Not enough memory" )
116 #define EIO_NO_DATA __einfo_error ( EINFO_EIO_NO_DATA )
117 #define EINFO_EIO_NO_DATA \
118 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NO_DATA, \
120 #define EIO_STAT( stat ) \
121 EUNIQ ( EINFO_EIO, -(stat), EIO_INVALID_CDB, EIO_INVALID_CPB, \
122 EIO_BUSY, EIO_QUEUE_FULL, EIO_ALREADY_STARTED, \
123 EIO_NOT_STARTED, EIO_NOT_SHUTDOWN, EIO_ALREADY_INITIALIZED, \
124 EIO_NOT_INITIALIZED, EIO_DEVICE_FAILURE, EIO_NVDATA_FAILURE, \
125 EIO_UNSUPPORTED, EIO_BUFFER_FULL, EIO_INVALID_PARAMETER, \
126 EIO_INVALID_UNDI, EIO_IPV4_NOT_SUPPORTED, \
127 EIO_IPV6_NOT_SUPPORTED, EIO_NOT_ENOUGH_MEMORY, EIO_NO_DATA )
131 * This is defined in <ipxe/efi/IndustryStandard/Pci22.h>, but we
132 * can't #include that since it collides with <ipxe/pci.h>.
134 #define PCI_MAX_BAR 6
139 struct efi_device *efidev;
140 /** Network interface identifier protocol */
141 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *nii;
142 /** !PXE structure */
145 EFIAPI VOID ( * issue ) ( UINT64 cdb );
146 /** Generic device */
150 EFI_HANDLE pci_device;
151 /** PCI I/O protocol */
152 EFI_PCI_IO_PROTOCOL *pci_io;
154 unsigned int mem_bar;
158 /** Broadcast address */
159 PXE_MAC_ADDR broadcast;
160 /** Maximum packet length */
163 /** Hardware transmit/receive buffer */
165 /** Hardware transmit/receive buffer length */
168 /** Saved task priority level */
171 /** Current transmit buffer */
172 struct io_buffer *txbuf;
173 /** Current receive buffer */
174 struct io_buffer *rxbuf;
177 /** Maximum number of received packets per poll */
178 #define NII_RX_QUOTA 4
181 * Open PCI I/O protocol and identify BARs
184 * @ret rc Return status code
186 static int nii_pci_open ( struct nii_nic *nii ) {
187 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
188 EFI_HANDLE device = nii->efidev->device;
189 EFI_HANDLE pci_device;
191 EFI_PCI_IO_PROTOCOL *pci_io;
195 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *acpi;
202 /* Locate PCI I/O protocol */
203 if ( ( rc = efi_locate_device ( device, &efi_pci_io_protocol_guid,
204 &pci_device ) ) != 0 ) {
205 DBGC ( nii, "NII %s could not locate PCI I/O protocol: %s\n",
206 nii->dev.name, strerror ( rc ) );
209 nii->pci_device = pci_device;
211 /* Open PCI I/O protocol */
212 if ( ( efirc = bs->OpenProtocol ( pci_device, &efi_pci_io_protocol_guid,
213 &pci_io.interface, efi_image_handle,
215 EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
216 rc = -EEFI ( efirc );
217 DBGC ( nii, "NII %s could not open PCI I/O protocol: %s\n",
218 nii->dev.name, strerror ( rc ) );
221 nii->pci_io = pci_io.pci_io;
223 /* Identify memory and I/O BARs */
224 nii->mem_bar = PCI_MAX_BAR;
225 nii->io_bar = PCI_MAX_BAR;
226 for ( bar = 0 ; bar < PCI_MAX_BAR ; bar++ ) {
227 efirc = nii->pci_io->GetBarAttributes ( nii->pci_io, bar, NULL,
229 if ( efirc == EFI_UNSUPPORTED ) {
230 /* BAR not present; ignore */
234 rc = -EEFI ( efirc );
235 DBGC ( nii, "NII %s could not get BAR %d attributes: "
236 "%s\n", nii->dev.name, bar, strerror ( rc ) );
237 goto err_get_bar_attributes;
239 if ( desc.acpi->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM ) {
241 } else if ( desc.acpi->ResType == ACPI_ADDRESS_SPACE_TYPE_IO ) {
244 bs->FreePool ( desc.resource );
246 DBGC ( nii, "NII %s has ", nii->dev.name );
247 if ( nii->mem_bar < PCI_MAX_BAR ) {
248 DBGC ( nii, "memory BAR %d and ", nii->mem_bar );
250 DBGC ( nii, "no memory BAR and " );
252 if ( nii->io_bar < PCI_MAX_BAR ) {
253 DBGC ( nii, "I/O BAR %d\n", nii->io_bar );
255 DBGC ( nii, "no I/O BAR\n" );
260 err_get_bar_attributes:
261 bs->CloseProtocol ( pci_device, &efi_pci_io_protocol_guid,
262 efi_image_handle, device );
269 * Close PCI I/O protocol
272 * @ret rc Return status code
274 static void nii_pci_close ( struct nii_nic *nii ) {
275 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
277 bs->CloseProtocol ( nii->pci_device, &efi_pci_io_protocol_guid,
278 efi_image_handle, nii->efidev->device );
284 * @v unique_id NII NIC
286 * @v len Length of data
288 * @v data Data buffer
290 static EFIAPI VOID nii_io ( UINT64 unique_id, UINT8 op, UINT8 len, UINT64 addr,
292 struct nii_nic *nii = ( ( void * ) ( intptr_t ) unique_id );
293 EFI_PCI_IO_PROTOCOL_ACCESS *access;
294 EFI_PCI_IO_PROTOCOL_IO_MEM io;
295 EFI_PCI_IO_PROTOCOL_WIDTH width;
300 /* Determine accessor and BAR */
301 if ( op & ( PXE_MEM_READ | PXE_MEM_WRITE ) ) {
302 access = &nii->pci_io->Mem;
305 access = &nii->pci_io->Io;
309 /* Determine operaton */
310 io = ( ( op & ( PXE_IO_WRITE | PXE_MEM_WRITE ) ) ?
311 access->Write : access->Read );
313 /* Determine width */
314 width = ( fls ( len ) - 1 );
316 /* Issue operation */
317 if ( ( efirc = io ( nii->pci_io, width, bar, addr, 1,
318 ( ( void * ) ( intptr_t ) data ) ) ) != 0 ) {
319 rc = -EEFI ( efirc );
320 DBGC ( nii, "NII %s I/O operation %#x failed: %s\n",
321 nii->dev.name, op, strerror ( rc ) );
322 /* No way to report failure */
330 * @v unique_id NII NIC
331 * @v microseconds Delay in microseconds
333 static EFIAPI VOID nii_delay ( UINT64 unique_id __unused, UINTN microseconds ) {
335 udelay ( microseconds );
341 * @v unique_id NII NIC
342 * @v acquire Acquire lock
344 static EFIAPI VOID nii_block ( UINT64 unique_id, UINT32 acquire ) {
345 struct nii_nic *nii = ( ( void * ) ( intptr_t ) unique_id );
346 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
348 /* This functionality (which is copied verbatim from the
349 * SnpDxe implementation of this function) appears to be
350 * totally brain-dead, since it produces no actual blocking
354 nii->saved_tpl = bs->RaiseTPL ( TPL_NOTIFY );
356 bs->RestoreTPL ( nii->saved_tpl );
361 * Construct operation from opcode and flags
367 #define NII_OP( opcode, opflags ) ( (opcode) | ( (opflags) << 16 ) )
370 * Extract opcode from operation
375 #define NII_OPCODE( op ) ( (op) & 0xffff )
378 * Extract flags from operation
383 #define NII_OPFLAGS( op ) ( (op) >> 16 )
386 * Issue command with parameter block and data block
390 * @v cpb Command parameter block, or NULL
391 * @v cpb_len Command parameter block length
392 * @v db Data block, or NULL
393 * @v db_len Data block length
394 * @ret stat Status flags, or negative status code
396 static int nii_issue_cpb_db ( struct nii_nic *nii, unsigned int op, void *cpb,
397 size_t cpb_len, void *db, size_t db_len ) {
400 /* Prepare command descriptor block */
401 memset ( &cdb, 0, sizeof ( cdb ) );
402 cdb.OpCode = NII_OPCODE ( op );
403 cdb.OpFlags = NII_OPFLAGS ( op );
404 cdb.CPBaddr = ( ( intptr_t ) cpb );
405 cdb.CPBsize = cpb_len;
406 cdb.DBaddr = ( ( intptr_t ) db );
408 cdb.IFnum = nii->nii->IfNum;
411 nii->issue ( ( intptr_t ) &cdb );
413 /* Check completion status */
414 if ( cdb.StatCode != PXE_STATCODE_SUCCESS )
415 return -cdb.StatCode;
417 /* Return command-specific status flags */
418 return ( cdb.StatFlags & ~PXE_STATFLAGS_STATUS_MASK );
422 * Issue command with parameter block
426 * @v cpb Command parameter block, or NULL
427 * @v cpb_len Command parameter block length
428 * @ret stat Status flags, or negative status code
430 static int nii_issue_cpb ( struct nii_nic *nii, unsigned int op, void *cpb,
433 return nii_issue_cpb_db ( nii, op, cpb, cpb_len, NULL, 0 );
437 * Issue command with data block
441 * @v db Data block, or NULL
442 * @v db_len Data block length
443 * @ret stat Status flags, or negative status code
445 static int nii_issue_db ( struct nii_nic *nii, unsigned int op, void *db,
448 return nii_issue_cpb_db ( nii, op, NULL, 0, db, db_len );
457 * @ret stat Status flags, or negative status code
459 static int nii_issue ( struct nii_nic *nii, unsigned int op ) {
461 return nii_issue_cpb_db ( nii, op, NULL, 0, NULL, 0 );
468 * @ret rc Return status code
470 static int nii_start_undi ( struct nii_nic *nii ) {
471 PXE_CPB_START_31 cpb;
475 /* Construct parameter block */
476 memset ( &cpb, 0, sizeof ( cpb ) );
477 cpb.Delay = ( ( intptr_t ) nii_delay );
478 cpb.Block = ( ( intptr_t ) nii_block );
479 cpb.Mem_IO = ( ( intptr_t ) nii_io );
480 cpb.Unique_ID = ( ( intptr_t ) nii );
483 if ( ( stat = nii_issue_cpb ( nii, PXE_OPCODE_START, &cpb,
484 sizeof ( cpb ) ) ) < 0 ) {
485 rc = -EIO_STAT ( stat );
486 DBGC ( nii, "NII %s could not start: %s\n",
487 nii->dev.name, strerror ( rc ) );
499 static void nii_stop_undi ( struct nii_nic *nii ) {
504 if ( ( stat = nii_issue ( nii, PXE_OPCODE_STOP ) ) < 0 ) {
505 rc = -EIO_STAT ( stat );
506 DBGC ( nii, "NII %s could not stop: %s\n",
507 nii->dev.name, strerror ( rc ) );
508 /* Nothing we can do about it */
514 * Get initialisation information
517 * @v netdev Network device to fill in
518 * @ret rc Return status code
520 static int nii_get_init_info ( struct nii_nic *nii,
521 struct net_device *netdev ) {
522 PXE_DB_GET_INIT_INFO db;
527 if ( ( stat = nii_issue_db ( nii, PXE_OPCODE_GET_INIT_INFO, &db,
528 sizeof ( db ) ) ) < 0 ) {
529 rc = -EIO_STAT ( stat );
530 DBGC ( nii, "NII %s could not get initialisation info: %s\n",
531 nii->dev.name, strerror ( rc ) );
535 /* Determine link layer protocol */
536 switch ( db.IFtype ) {
537 case PXE_IFTYPE_ETHERNET :
538 netdev->ll_protocol = ðernet_protocol;
541 DBGC ( nii, "NII %s unknown interface type %#02x\n",
542 nii->dev.name, db.IFtype );
547 assert ( db.MediaHeaderLen == netdev->ll_protocol->ll_header_len );
548 assert ( db.HWaddrLen == netdev->ll_protocol->hw_addr_len );
549 assert ( db.HWaddrLen == netdev->ll_protocol->ll_addr_len );
551 /* Extract parameters */
552 nii->buffer_len = db.MemoryRequired;
553 nii->mtu = ( db.FrameDataLen + db.MediaHeaderLen );
554 netdev->max_pkt_len = nii->mtu;
563 * @ret rc Return status code
565 static int nii_initialise ( struct nii_nic *nii ) {
566 PXE_CPB_INITIALIZE cpb;
571 /* Allocate memory buffer */
572 nii->buffer = umalloc ( nii->buffer_len );
573 if ( ! nii->buffer ) {
578 /* Construct parameter block */
579 memset ( &cpb, 0, sizeof ( cpb ) );
580 cpb.MemoryAddr = ( ( intptr_t ) nii->buffer );
581 cpb.MemoryLength = nii->buffer_len;
584 op = NII_OP ( PXE_OPCODE_INITIALIZE,
585 PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE );
586 if ( ( stat = nii_issue_cpb ( nii, op, &cpb, sizeof ( cpb ) ) ) < 0 ) {
587 rc = -EIO_STAT ( stat );
588 DBGC ( nii, "NII %s could not initialise: %s\n",
589 nii->dev.name, strerror ( rc ) );
596 ufree ( nii->buffer );
606 static void nii_shutdown ( struct nii_nic *nii ) {
611 if ( ( stat = nii_issue ( nii, PXE_OPCODE_SHUTDOWN ) ) < 0 ) {
612 rc = -EIO_STAT ( stat );
613 DBGC ( nii, "NII %s could not shut down: %s\n",
614 nii->dev.name, strerror ( rc ) );
615 /* Leak memory to avoid corruption */
620 ufree ( nii->buffer );
624 * Get station addresses
627 * @v netdev Network device to fill in
628 * @ret rc Return status code
630 static int nii_get_station_address ( struct nii_nic *nii,
631 struct net_device *netdev ) {
632 PXE_DB_STATION_ADDRESS db;
636 /* Initialise UNDI */
637 if ( ( rc = nii_initialise ( nii ) ) != 0 )
641 if ( ( stat = nii_issue_db ( nii, PXE_OPCODE_STATION_ADDRESS, &db,
642 sizeof ( db ) ) ) < 0 ) {
643 rc = -EIO_STAT ( stat );
644 DBGC ( nii, "NII %s could not get station address: %s\n",
645 nii->dev.name, strerror ( rc ) );
646 goto err_station_address;
649 /* Copy MAC addresses */
650 memcpy ( netdev->ll_addr, db.StationAddr,
651 netdev->ll_protocol->ll_addr_len );
652 memcpy ( netdev->hw_addr, db.PermanentAddr,
653 netdev->ll_protocol->hw_addr_len );
654 memcpy ( nii->broadcast, db.BroadcastAddr,
655 sizeof ( nii->broadcast ) );
658 nii_shutdown ( nii );
664 * Set station address
667 * @v netdev Network device
668 * @ret rc Return status code
670 static int nii_set_station_address ( struct nii_nic *nii,
671 struct net_device *netdev ) {
672 PXE_CPB_STATION_ADDRESS cpb;
676 /* Construct parameter block */
677 memset ( &cpb, 0, sizeof ( cpb ) );
678 memcpy ( cpb.StationAddr, netdev->ll_addr,
679 netdev->ll_protocol->ll_addr_len );
682 if ( ( stat = nii_issue_cpb ( nii, PXE_OPCODE_STATION_ADDRESS,
683 &cpb, sizeof ( cpb ) ) ) < 0 ) {
684 rc = -EIO_STAT ( stat );
685 DBGC ( nii, "NII %s could not set station address: %s\n",
686 nii->dev.name, strerror ( rc ) );
694 * Set receive filters
697 * @ret rc Return status code
699 static int nii_set_rx_filters ( struct nii_nic *nii ) {
705 op = NII_OP ( PXE_OPCODE_RECEIVE_FILTERS,
706 ( PXE_OPFLAGS_RECEIVE_FILTER_ENABLE |
707 PXE_OPFLAGS_RECEIVE_FILTER_UNICAST |
708 PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST |
709 PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS |
710 PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST ) );
711 if ( ( stat = nii_issue ( nii, op ) ) < 0 ) {
712 rc = -EIO_STAT ( stat );
713 DBGC ( nii, "NII %s could not set receive filters: %s\n",
714 nii->dev.name, strerror ( rc ) );
724 * @v netdev Network device
725 * @v iobuf I/O buffer
726 * @ret rc Return status code
728 static int nii_transmit ( struct net_device *netdev,
729 struct io_buffer *iobuf ) {
730 struct nii_nic *nii = netdev->priv;
731 PXE_CPB_TRANSMIT cpb;
735 /* Defer the packet if there is already a transmission in progress */
737 netdev_tx_defer ( netdev, iobuf );
741 /* Construct parameter block */
742 memset ( &cpb, 0, sizeof ( cpb ) );
743 cpb.FrameAddr = virt_to_bus ( iobuf->data );
744 cpb.DataLen = iob_len ( iobuf );
745 cpb.MediaheaderLen = netdev->ll_protocol->ll_header_len;
747 /* Transmit packet */
748 if ( ( stat = nii_issue_cpb ( nii, PXE_OPCODE_TRANSMIT, &cpb,
749 sizeof ( cpb ) ) ) < 0 ) {
750 rc = -EIO_STAT ( stat );
751 DBGC ( nii, "NII %s could not transmit: %s\n",
752 nii->dev.name, strerror ( rc ) );
761 * Poll for completed packets
763 * @v netdev Network device
764 * @v stat Status flags
766 static void nii_poll_tx ( struct net_device *netdev, unsigned int stat ) {
767 struct nii_nic *nii = netdev->priv;
768 struct io_buffer *iobuf;
770 /* Do nothing unless we have a completion */
771 if ( stat & PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN )
775 if ( ! nii->txbuf ) {
776 DBGC ( nii, "NII %s reported spurious TX completion\n",
778 netdev_tx_err ( netdev, NULL, -EPIPE );
782 /* Complete transmission */
785 netdev_tx_complete ( netdev, iobuf );
789 * Poll for received packets
791 * @v netdev Network device
793 static void nii_poll_rx ( struct net_device *netdev ) {
794 struct nii_nic *nii = netdev->priv;
801 /* Retrieve up to NII_RX_QUOTA packets */
802 for ( quota = NII_RX_QUOTA ; quota ; quota-- ) {
804 /* Allocate buffer, if required */
805 if ( ! nii->rxbuf ) {
806 nii->rxbuf = alloc_iob ( nii->mtu );
807 if ( ! nii->rxbuf ) {
808 /* Leave for next poll */
813 /* Construct parameter block */
814 memset ( &cpb, 0, sizeof ( cpb ) );
815 cpb.BufferAddr = virt_to_bus ( nii->rxbuf->data );
816 cpb.BufferLen = iob_tailroom ( nii->rxbuf );
819 if ( ( stat = nii_issue_cpb_db ( nii, PXE_OPCODE_RECEIVE,
820 &cpb, sizeof ( cpb ),
821 &db, sizeof ( db ) ) ) < 0 ) {
823 /* PXE_STATCODE_NO_DATA is just the usual "no packet"
824 * status indicator; ignore it.
826 if ( stat == -PXE_STATCODE_NO_DATA )
829 /* Anything else is an error */
830 rc = -EIO_STAT ( stat );
831 DBGC ( nii, "NII %s could not receive: %s\n",
832 nii->dev.name, strerror ( rc ) );
833 netdev_rx_err ( netdev, NULL, rc );
837 /* Hand off to network stack */
838 iob_put ( nii->rxbuf, db.FrameLen );
839 netdev_rx ( netdev, nii->rxbuf );
845 * Check for link state changes
847 * @v netdev Network device
848 * @v stat Status flags
850 static void nii_poll_link ( struct net_device *netdev, unsigned int stat ) {
851 int no_media = ( stat & PXE_STATFLAGS_GET_STATUS_NO_MEDIA );
853 if ( no_media && netdev_link_ok ( netdev ) ) {
854 netdev_link_down ( netdev );
855 } else if ( ( ! no_media ) && ( ! netdev_link_ok ( netdev ) ) ) {
856 netdev_link_up ( netdev );
861 * Poll for completed packets
863 * @v netdev Network device
865 static void nii_poll ( struct net_device *netdev ) {
866 struct nii_nic *nii = netdev->priv;
867 PXE_DB_GET_STATUS db;
873 op = NII_OP ( PXE_OPCODE_GET_STATUS,
874 ( PXE_OPFLAGS_GET_INTERRUPT_STATUS |
875 PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS |
876 PXE_OPFLAGS_GET_MEDIA_STATUS ) );
877 if ( ( stat = nii_issue_db ( nii, op, &db, sizeof ( db ) ) ) < 0 ) {
878 rc = -EIO_STAT ( stat );
879 DBGC ( nii, "NII %s could not get status: %s\n",
880 nii->dev.name, strerror ( rc ) );
884 /* Process any TX completions */
885 nii_poll_tx ( netdev, stat );
887 /* Process any RX completions */
888 nii_poll_rx ( netdev );
890 /* Check for link state changes */
891 nii_poll_link ( netdev, stat );
895 * Open network device
897 * @v netdev Network device
898 * @ret rc Return status code
900 static int nii_open ( struct net_device *netdev ) {
901 struct nii_nic *nii = netdev->priv;
905 if ( ( rc = nii_initialise ( nii ) ) != 0 )
908 /* Attempt to set station address */
909 if ( ( rc = nii_set_station_address ( nii, netdev ) ) != 0 ) {
910 DBGC ( nii, "NII %s could not set station address: %s\n",
911 nii->dev.name, strerror ( rc ) );
912 /* Treat as non-fatal */
915 /* Set receive filters */
916 if ( ( rc = nii_set_rx_filters ( nii ) ) != 0 )
917 goto err_set_rx_filters;
922 nii_shutdown ( nii );
928 * Close network device
930 * @v netdev Network device
932 static void nii_close ( struct net_device *netdev ) {
933 struct nii_nic *nii = netdev->priv;
936 nii_shutdown ( nii );
938 /* Discard transmit buffer, if applicable */
940 netdev_tx_complete_err ( netdev, nii->txbuf, -ECANCELED );
944 /* Discard receive buffer, if applicable */
946 free_iob ( nii->rxbuf );
951 /** NII network device operations */
952 static struct net_device_operations nii_operations = {
955 .transmit = nii_transmit,
960 * Attach driver to device
962 * @v efidev EFI device
963 * @ret rc Return status code
965 int nii_start ( struct efi_device *efidev ) {
966 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
967 EFI_HANDLE device = efidev->device;
968 struct net_device *netdev;
974 /* Allocate and initialise structure */
975 netdev = alloc_netdev ( sizeof ( *nii ) );
980 netdev_init ( netdev, &nii_operations );
982 nii->efidev = efidev;
983 netdev->ll_broadcast = nii->broadcast;
984 efidev_set_drvdata ( efidev, netdev );
986 /* Populate underlying device information */
987 efi_device_info ( device, "NII", &nii->dev );
988 nii->dev.driver_name = "NII";
989 nii->dev.parent = &efidev->dev;
990 list_add ( &nii->dev.siblings, &efidev->dev.children );
991 INIT_LIST_HEAD ( &nii->dev.children );
992 netdev->dev = &nii->dev;
994 /* Open NII protocol */
995 if ( ( efirc = bs->OpenProtocol ( device, &efi_nii31_protocol_guid,
996 &interface, efi_image_handle, device,
997 ( EFI_OPEN_PROTOCOL_BY_DRIVER |
998 EFI_OPEN_PROTOCOL_EXCLUSIVE )))!=0){
999 rc = -EEFI ( efirc );
1000 DBGC ( nii, "NII %s cannot open NII protocol: %s\n",
1001 nii->dev.name, strerror ( rc ) );
1002 DBGC_EFI_OPENERS ( device, device, &efi_nii31_protocol_guid );
1003 goto err_open_protocol;
1005 nii->nii = interface;
1007 /* Locate UNDI and entry point */
1008 nii->undi = ( ( void * ) ( intptr_t ) nii->nii->Id );
1009 if ( ! nii->undi ) {
1010 DBGC ( nii, "NII %s has no UNDI\n", nii->dev.name );
1014 if ( nii->undi->Implementation & PXE_ROMID_IMP_HW_UNDI ) {
1015 DBGC ( nii, "NII %s is a mythical hardware UNDI\n",
1020 if ( nii->undi->Implementation & PXE_ROMID_IMP_SW_VIRT_ADDR ) {
1021 nii->issue = ( ( void * ) ( intptr_t ) nii->undi->EntryPoint );
1023 nii->issue = ( ( ( void * ) nii->undi ) +
1024 nii->undi->EntryPoint );
1026 DBGC ( nii, "NII %s using UNDI v%x.%x at %p entry %p\n", nii->dev.name,
1027 nii->nii->MajorVer, nii->nii->MinorVer, nii->undi, nii->issue );
1029 /* Open PCI I/O protocols and locate BARs */
1030 if ( ( rc = nii_pci_open ( nii ) ) != 0 )
1034 if ( ( rc = nii_start_undi ( nii ) ) != 0 )
1035 goto err_start_undi;
1037 /* Get initialisation information */
1038 if ( ( rc = nii_get_init_info ( nii, netdev ) ) != 0 )
1039 goto err_get_init_info;
1041 /* Get MAC addresses */
1042 if ( ( rc = nii_get_station_address ( nii, netdev ) ) != 0 )
1043 goto err_get_station_address;
1045 /* Register network device */
1046 if ( ( rc = register_netdev ( netdev ) ) != 0 )
1047 goto err_register_netdev;
1048 DBGC ( nii, "NII %s registered as %s for %p %s\n", nii->dev.name,
1049 netdev->name, device, efi_handle_name ( device ) );
1053 unregister_netdev ( netdev );
1054 err_register_netdev:
1055 err_get_station_address:
1057 nii_stop_undi ( nii );
1059 nii_pci_close ( nii );
1063 bs->CloseProtocol ( device, &efi_nii31_protocol_guid,
1064 efi_image_handle, device );
1066 list_del ( &nii->dev.siblings );
1067 netdev_nullify ( netdev );
1068 netdev_put ( netdev );
1074 * Detach driver from device
1076 * @v efidev EFI device
1078 void nii_stop ( struct efi_device *efidev ) {
1079 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
1080 struct net_device *netdev = efidev_get_drvdata ( efidev );
1081 struct nii_nic *nii = netdev->priv;
1082 EFI_HANDLE device = efidev->device;
1084 /* Unregister network device */
1085 unregister_netdev ( netdev );
1088 nii_stop_undi ( nii );
1090 /* Close PCI I/O protocols */
1091 nii_pci_close ( nii );
1093 /* Close NII protocol */
1094 bs->CloseProtocol ( device, &efi_nii31_protocol_guid,
1095 efi_image_handle, device );
1097 /* Free network device */
1098 list_del ( &nii->dev.siblings );
1099 netdev_nullify ( netdev );
1100 netdev_put ( netdev );