[efi] Skip cable detection at initialisation where possible
[ipxe.git] / src / drivers / net / efi / nii.c
1 /*
2 * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
3 *
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.
8 *
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.
13 *
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
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26 #include <string.h>
27 #include <strings.h>
28 #include <unistd.h>
29 #include <errno.h>
30 #include <ipxe/netdevice.h>
31 #include <ipxe/ethernet.h>
32 #include <ipxe/umalloc.h>
33 #include <ipxe/efi/efi.h>
34 #include <ipxe/efi/efi_driver.h>
35 #include <ipxe/efi/efi_pci.h>
36 #include <ipxe/efi/efi_utils.h>
37 #include <ipxe/efi/Protocol/NetworkInterfaceIdentifier.h>
38 #include <ipxe/efi/IndustryStandard/Acpi10.h>
39 #include "nii.h"
40
41 /** @file
42 *
43 * NII driver
44 *
45 */
46
47 /* Error numbers generated by NII */
48 #define EIO_INVALID_CDB __einfo_error ( EINFO_EIO_INVALID_CDB )
49 #define EINFO_EIO_INVALID_CDB \
50 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_INVALID_CDB, \
51 "Invalid CDB" )
52 #define EIO_INVALID_CPB __einfo_error ( EINFO_EIO_INVALID_CPB )
53 #define EINFO_EIO_INVALID_CPB \
54 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_INVALID_CPB, \
55 "Invalid CPB" )
56 #define EIO_BUSY __einfo_error ( EINFO_EIO_BUSY )
57 #define EINFO_EIO_BUSY \
58 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_BUSY, \
59 "Busy" )
60 #define EIO_QUEUE_FULL __einfo_error ( EINFO_EIO_QUEUE_FULL )
61 #define EINFO_EIO_QUEUE_FULL \
62 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_QUEUE_FULL, \
63 "Queue full" )
64 #define EIO_ALREADY_STARTED __einfo_error ( EINFO_EIO_ALREADY_STARTED )
65 #define EINFO_EIO_ALREADY_STARTED \
66 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_ALREADY_STARTED, \
67 "Already started" )
68 #define EIO_NOT_STARTED __einfo_error ( EINFO_EIO_NOT_STARTED )
69 #define EINFO_EIO_NOT_STARTED \
70 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NOT_STARTED, \
71 "Not started" )
72 #define EIO_NOT_SHUTDOWN __einfo_error ( EINFO_EIO_NOT_SHUTDOWN )
73 #define EINFO_EIO_NOT_SHUTDOWN \
74 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NOT_SHUTDOWN, \
75 "Not shutdown" )
76 #define EIO_ALREADY_INITIALIZED __einfo_error ( EINFO_EIO_ALREADY_INITIALIZED )
77 #define EINFO_EIO_ALREADY_INITIALIZED \
78 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_ALREADY_INITIALIZED, \
79 "Already initialized" )
80 #define EIO_NOT_INITIALIZED __einfo_error ( EINFO_EIO_NOT_INITIALIZED )
81 #define EINFO_EIO_NOT_INITIALIZED \
82 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NOT_INITIALIZED, \
83 "Not initialized" )
84 #define EIO_DEVICE_FAILURE __einfo_error ( EINFO_EIO_DEVICE_FAILURE )
85 #define EINFO_EIO_DEVICE_FAILURE \
86 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_DEVICE_FAILURE, \
87 "Device failure" )
88 #define EIO_NVDATA_FAILURE __einfo_error ( EINFO_EIO_NVDATA_FAILURE )
89 #define EINFO_EIO_NVDATA_FAILURE \
90 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NVDATA_FAILURE, \
91 "Non-volatile data failure" )
92 #define EIO_UNSUPPORTED __einfo_error ( EINFO_EIO_UNSUPPORTED )
93 #define EINFO_EIO_UNSUPPORTED \
94 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_UNSUPPORTED, \
95 "Unsupported" )
96 #define EIO_BUFFER_FULL __einfo_error ( EINFO_EIO_BUFFER_FULL )
97 #define EINFO_EIO_BUFFER_FULL \
98 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_BUFFER_FULL, \
99 "Buffer full" )
100 #define EIO_INVALID_PARAMETER __einfo_error ( EINFO_EIO_INVALID_PARAMETER )
101 #define EINFO_EIO_INVALID_PARAMETER \
102 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_INVALID_PARAMETER, \
103 "Invalid parameter" )
104 #define EIO_INVALID_UNDI __einfo_error ( EINFO_EIO_INVALID_UNDI )
105 #define EINFO_EIO_INVALID_UNDI \
106 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_INVALID_UNDI, \
107 "Invalid UNDI" )
108 #define EIO_IPV4_NOT_SUPPORTED __einfo_error ( EINFO_EIO_IPV4_NOT_SUPPORTED )
109 #define EINFO_EIO_IPV4_NOT_SUPPORTED \
110 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_IPV4_NOT_SUPPORTED, \
111 "IPv4 not supported" )
112 #define EIO_IPV6_NOT_SUPPORTED __einfo_error ( EINFO_EIO_IPV6_NOT_SUPPORTED )
113 #define EINFO_EIO_IPV6_NOT_SUPPORTED \
114 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_IPV6_NOT_SUPPORTED, \
115 "IPv6 not supported" )
116 #define EIO_NOT_ENOUGH_MEMORY __einfo_error ( EINFO_EIO_NOT_ENOUGH_MEMORY )
117 #define EINFO_EIO_NOT_ENOUGH_MEMORY \
118 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NOT_ENOUGH_MEMORY, \
119 "Not enough memory" )
120 #define EIO_NO_DATA __einfo_error ( EINFO_EIO_NO_DATA )
121 #define EINFO_EIO_NO_DATA \
122 __einfo_uniqify ( EINFO_EIO, PXE_STATCODE_NO_DATA, \
123 "No data" )
124 #define EIO_STAT( stat ) \
125 EUNIQ ( EINFO_EIO, -(stat), EIO_INVALID_CDB, EIO_INVALID_CPB, \
126 EIO_BUSY, EIO_QUEUE_FULL, EIO_ALREADY_STARTED, \
127 EIO_NOT_STARTED, EIO_NOT_SHUTDOWN, EIO_ALREADY_INITIALIZED, \
128 EIO_NOT_INITIALIZED, EIO_DEVICE_FAILURE, EIO_NVDATA_FAILURE, \
129 EIO_UNSUPPORTED, EIO_BUFFER_FULL, EIO_INVALID_PARAMETER, \
130 EIO_INVALID_UNDI, EIO_IPV4_NOT_SUPPORTED, \
131 EIO_IPV6_NOT_SUPPORTED, EIO_NOT_ENOUGH_MEMORY, EIO_NO_DATA )
132
133 /** Maximum PCI BAR
134 *
135 * This is defined in <ipxe/efi/IndustryStandard/Pci22.h>, but we
136 * can't #include that since it collides with <ipxe/pci.h>.
137 */
138 #define PCI_MAX_BAR 6
139
140 /** An NII NIC */
141 struct nii_nic {
142 /** EFI device */
143 struct efi_device *efidev;
144 /** Network interface identifier protocol */
145 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *nii;
146 /** !PXE structure */
147 PXE_SW_UNDI *undi;
148 /** Entry point */
149 EFIAPI VOID ( * issue ) ( UINT64 cdb );
150 /** Generic device */
151 struct device dev;
152
153 /** PCI device */
154 EFI_HANDLE pci_device;
155 /** PCI I/O protocol */
156 EFI_PCI_IO_PROTOCOL *pci_io;
157 /** Memory BAR */
158 unsigned int mem_bar;
159 /** I/O BAR */
160 unsigned int io_bar;
161
162 /** Broadcast address */
163 PXE_MAC_ADDR broadcast;
164 /** Maximum packet length */
165 size_t mtu;
166
167 /** Hardware transmit/receive buffer */
168 userptr_t buffer;
169 /** Hardware transmit/receive buffer length */
170 size_t buffer_len;
171
172 /** Saved task priority level */
173 EFI_TPL saved_tpl;
174
175 /** Media status is supported */
176 int media;
177
178 /** Current transmit buffer */
179 struct io_buffer *txbuf;
180 /** Current receive buffer */
181 struct io_buffer *rxbuf;
182 };
183
184 /** Maximum number of received packets per poll */
185 #define NII_RX_QUOTA 4
186
187 /**
188 * Open PCI I/O protocol and identify BARs
189 *
190 * @v nii NII NIC
191 * @ret rc Return status code
192 */
193 static int nii_pci_open ( struct nii_nic *nii ) {
194 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
195 EFI_HANDLE device = nii->efidev->device;
196 EFI_HANDLE pci_device;
197 union {
198 EFI_PCI_IO_PROTOCOL *pci_io;
199 void *interface;
200 } pci_io;
201 union {
202 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *acpi;
203 void *resource;
204 } desc;
205 unsigned int bar;
206 EFI_STATUS efirc;
207 int rc;
208
209 /* Locate PCI I/O protocol */
210 if ( ( rc = efi_locate_device ( device, &efi_pci_io_protocol_guid,
211 &pci_device ) ) != 0 ) {
212 DBGC ( nii, "NII %s could not locate PCI I/O protocol: %s\n",
213 nii->dev.name, strerror ( rc ) );
214 goto err_locate;
215 }
216 nii->pci_device = pci_device;
217
218 /* Open PCI I/O protocol */
219 if ( ( efirc = bs->OpenProtocol ( pci_device, &efi_pci_io_protocol_guid,
220 &pci_io.interface, efi_image_handle,
221 device,
222 EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
223 rc = -EEFI ( efirc );
224 DBGC ( nii, "NII %s could not open PCI I/O protocol: %s\n",
225 nii->dev.name, strerror ( rc ) );
226 goto err_open;
227 }
228 nii->pci_io = pci_io.pci_io;
229
230 /* Identify memory and I/O BARs */
231 nii->mem_bar = PCI_MAX_BAR;
232 nii->io_bar = PCI_MAX_BAR;
233 for ( bar = 0 ; bar < PCI_MAX_BAR ; bar++ ) {
234 efirc = nii->pci_io->GetBarAttributes ( nii->pci_io, bar, NULL,
235 &desc.resource );
236 if ( efirc == EFI_UNSUPPORTED ) {
237 /* BAR not present; ignore */
238 continue;
239 }
240 if ( efirc != 0 ) {
241 rc = -EEFI ( efirc );
242 DBGC ( nii, "NII %s could not get BAR %d attributes: "
243 "%s\n", nii->dev.name, bar, strerror ( rc ) );
244 goto err_get_bar_attributes;
245 }
246 if ( desc.acpi->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM ) {
247 nii->mem_bar = bar;
248 } else if ( desc.acpi->ResType == ACPI_ADDRESS_SPACE_TYPE_IO ) {
249 nii->io_bar = bar;
250 }
251 bs->FreePool ( desc.resource );
252 }
253 DBGC ( nii, "NII %s has ", nii->dev.name );
254 if ( nii->mem_bar < PCI_MAX_BAR ) {
255 DBGC ( nii, "memory BAR %d and ", nii->mem_bar );
256 } else {
257 DBGC ( nii, "no memory BAR and " );
258 }
259 if ( nii->io_bar < PCI_MAX_BAR ) {
260 DBGC ( nii, "I/O BAR %d\n", nii->io_bar );
261 } else {
262 DBGC ( nii, "no I/O BAR\n" );
263 }
264
265 return 0;
266
267 err_get_bar_attributes:
268 bs->CloseProtocol ( pci_device, &efi_pci_io_protocol_guid,
269 efi_image_handle, device );
270 err_open:
271 err_locate:
272 return rc;
273 }
274
275 /**
276 * Close PCI I/O protocol
277 *
278 * @v nii NII NIC
279 * @ret rc Return status code
280 */
281 static void nii_pci_close ( struct nii_nic *nii ) {
282 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
283
284 bs->CloseProtocol ( nii->pci_device, &efi_pci_io_protocol_guid,
285 efi_image_handle, nii->efidev->device );
286 }
287
288 /**
289 * I/O callback
290 *
291 * @v unique_id NII NIC
292 * @v op Operations
293 * @v len Length of data
294 * @v addr Address
295 * @v data Data buffer
296 */
297 static EFIAPI VOID nii_io ( UINT64 unique_id, UINT8 op, UINT8 len, UINT64 addr,
298 UINT64 data ) {
299 struct nii_nic *nii = ( ( void * ) ( intptr_t ) unique_id );
300 EFI_PCI_IO_PROTOCOL_ACCESS *access;
301 EFI_PCI_IO_PROTOCOL_IO_MEM io;
302 EFI_PCI_IO_PROTOCOL_WIDTH width;
303 unsigned int bar;
304 EFI_STATUS efirc;
305 int rc;
306
307 /* Determine accessor and BAR */
308 if ( op & ( PXE_MEM_READ | PXE_MEM_WRITE ) ) {
309 access = &nii->pci_io->Mem;
310 bar = nii->mem_bar;
311 } else {
312 access = &nii->pci_io->Io;
313 bar = nii->io_bar;
314 }
315
316 /* Determine operaton */
317 io = ( ( op & ( PXE_IO_WRITE | PXE_MEM_WRITE ) ) ?
318 access->Write : access->Read );
319
320 /* Determine width */
321 width = ( fls ( len ) - 1 );
322
323 /* Issue operation */
324 if ( ( efirc = io ( nii->pci_io, width, bar, addr, 1,
325 ( ( void * ) ( intptr_t ) data ) ) ) != 0 ) {
326 rc = -EEFI ( efirc );
327 DBGC ( nii, "NII %s I/O operation %#x failed: %s\n",
328 nii->dev.name, op, strerror ( rc ) );
329 /* No way to report failure */
330 return;
331 }
332 }
333
334 /**
335 * Delay callback
336 *
337 * @v unique_id NII NIC
338 * @v microseconds Delay in microseconds
339 */
340 static EFIAPI VOID nii_delay ( UINT64 unique_id __unused, UINTN microseconds ) {
341
342 udelay ( microseconds );
343 }
344
345 /**
346 * Block callback
347 *
348 * @v unique_id NII NIC
349 * @v acquire Acquire lock
350 */
351 static EFIAPI VOID nii_block ( UINT64 unique_id, UINT32 acquire ) {
352 struct nii_nic *nii = ( ( void * ) ( intptr_t ) unique_id );
353 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
354
355 /* This functionality (which is copied verbatim from the
356 * SnpDxe implementation of this function) appears to be
357 * totally brain-dead, since it produces no actual blocking
358 * behaviour.
359 */
360 if ( acquire ) {
361 nii->saved_tpl = bs->RaiseTPL ( TPL_NOTIFY );
362 } else {
363 bs->RestoreTPL ( nii->saved_tpl );
364 }
365 }
366
367 /**
368 * Construct operation from opcode and flags
369 *
370 * @v opcode Opcode
371 * @v opflags Flags
372 * @ret op Operation
373 */
374 #define NII_OP( opcode, opflags ) ( (opcode) | ( (opflags) << 16 ) )
375
376 /**
377 * Extract opcode from operation
378 *
379 * @v op Operation
380 * @ret opcode Opcode
381 */
382 #define NII_OPCODE( op ) ( (op) & 0xffff )
383
384 /**
385 * Extract flags from operation
386 *
387 * @v op Operation
388 * @ret opflags Flags
389 */
390 #define NII_OPFLAGS( op ) ( (op) >> 16 )
391
392 /**
393 * Issue command with parameter block and data block
394 *
395 * @v nii NII NIC
396 * @v op Operation
397 * @v cpb Command parameter block, or NULL
398 * @v cpb_len Command parameter block length
399 * @v db Data block, or NULL
400 * @v db_len Data block length
401 * @ret stat Status flags, or negative status code
402 */
403 static int nii_issue_cpb_db ( struct nii_nic *nii, unsigned int op, void *cpb,
404 size_t cpb_len, void *db, size_t db_len ) {
405 PXE_CDB cdb;
406
407 /* Prepare command descriptor block */
408 memset ( &cdb, 0, sizeof ( cdb ) );
409 cdb.OpCode = NII_OPCODE ( op );
410 cdb.OpFlags = NII_OPFLAGS ( op );
411 cdb.CPBaddr = ( ( intptr_t ) cpb );
412 cdb.CPBsize = cpb_len;
413 cdb.DBaddr = ( ( intptr_t ) db );
414 cdb.DBsize = db_len;
415 cdb.IFnum = nii->nii->IfNum;
416
417 /* Issue command */
418 DBGC2 ( nii, "NII %s issuing %02x:%04x ifnum %d%s%s\n",
419 nii->dev.name, cdb.OpCode, cdb.OpFlags, cdb.IFnum,
420 ( cpb ? " cpb" : "" ), ( db ? " db" : "" ) );
421 if ( cpb )
422 DBGC2_HD ( nii, cpb, cpb_len );
423 if ( db )
424 DBGC2_HD ( nii, db, db_len );
425 nii->issue ( ( intptr_t ) &cdb );
426
427 /* Check completion status */
428 if ( cdb.StatCode != PXE_STATCODE_SUCCESS )
429 return -cdb.StatCode;
430
431 /* Return command-specific status flags */
432 return ( cdb.StatFlags & ~PXE_STATFLAGS_STATUS_MASK );
433 }
434
435 /**
436 * Issue command with parameter block
437 *
438 * @v nii NII NIC
439 * @v op Operation
440 * @v cpb Command parameter block, or NULL
441 * @v cpb_len Command parameter block length
442 * @ret stat Status flags, or negative status code
443 */
444 static int nii_issue_cpb ( struct nii_nic *nii, unsigned int op, void *cpb,
445 size_t cpb_len ) {
446
447 return nii_issue_cpb_db ( nii, op, cpb, cpb_len, NULL, 0 );
448 }
449
450 /**
451 * Issue command with data block
452 *
453 * @v nii NII NIC
454 * @v op Operation
455 * @v db Data block, or NULL
456 * @v db_len Data block length
457 * @ret stat Status flags, or negative status code
458 */
459 static int nii_issue_db ( struct nii_nic *nii, unsigned int op, void *db,
460 size_t db_len ) {
461
462 return nii_issue_cpb_db ( nii, op, NULL, 0, db, db_len );
463 }
464
465 /**
466 * Issue command
467 *
468 *
469 * @v nii NII NIC
470 * @v op Operation
471 * @ret stat Status flags, or negative status code
472 */
473 static int nii_issue ( struct nii_nic *nii, unsigned int op ) {
474
475 return nii_issue_cpb_db ( nii, op, NULL, 0, NULL, 0 );
476 }
477
478 /**
479 * Start UNDI
480 *
481 * @v nii NII NIC
482 * @ret rc Return status code
483 */
484 static int nii_start_undi ( struct nii_nic *nii ) {
485 PXE_CPB_START_31 cpb;
486 int stat;
487 int rc;
488
489 /* Construct parameter block */
490 memset ( &cpb, 0, sizeof ( cpb ) );
491 cpb.Delay = ( ( intptr_t ) nii_delay );
492 cpb.Block = ( ( intptr_t ) nii_block );
493 cpb.Mem_IO = ( ( intptr_t ) nii_io );
494 cpb.Unique_ID = ( ( intptr_t ) nii );
495
496 /* Issue command */
497 if ( ( stat = nii_issue_cpb ( nii, PXE_OPCODE_START, &cpb,
498 sizeof ( cpb ) ) ) < 0 ) {
499 rc = -EIO_STAT ( stat );
500 DBGC ( nii, "NII %s could not start: %s\n",
501 nii->dev.name, strerror ( rc ) );
502 return rc;
503 }
504
505 return 0;
506 }
507
508 /**
509 * Stop UNDI
510 *
511 * @v nii NII NIC
512 */
513 static void nii_stop_undi ( struct nii_nic *nii ) {
514 int stat;
515 int rc;
516
517 /* Issue command */
518 if ( ( stat = nii_issue ( nii, PXE_OPCODE_STOP ) ) < 0 ) {
519 rc = -EIO_STAT ( stat );
520 DBGC ( nii, "NII %s could not stop: %s\n",
521 nii->dev.name, strerror ( rc ) );
522 /* Nothing we can do about it */
523 return;
524 }
525 }
526
527 /**
528 * Get initialisation information
529 *
530 * @v nii NII NIC
531 * @v netdev Network device to fill in
532 * @ret rc Return status code
533 */
534 static int nii_get_init_info ( struct nii_nic *nii,
535 struct net_device *netdev ) {
536 PXE_DB_GET_INIT_INFO db;
537 int stat;
538 int rc;
539
540 /* Issue command */
541 if ( ( stat = nii_issue_db ( nii, PXE_OPCODE_GET_INIT_INFO, &db,
542 sizeof ( db ) ) ) < 0 ) {
543 rc = -EIO_STAT ( stat );
544 DBGC ( nii, "NII %s could not get initialisation info: %s\n",
545 nii->dev.name, strerror ( rc ) );
546 return rc;
547 }
548
549 /* Determine link layer protocol */
550 switch ( db.IFtype ) {
551 case PXE_IFTYPE_ETHERNET :
552 netdev->ll_protocol = &ethernet_protocol;
553 break;
554 default:
555 DBGC ( nii, "NII %s unknown interface type %#02x\n",
556 nii->dev.name, db.IFtype );
557 return -ENOTSUP;
558 }
559
560 /* Sanity checks */
561 assert ( db.MediaHeaderLen == netdev->ll_protocol->ll_header_len );
562 assert ( db.HWaddrLen == netdev->ll_protocol->hw_addr_len );
563 assert ( db.HWaddrLen == netdev->ll_protocol->ll_addr_len );
564
565 /* Extract parameters */
566 nii->buffer_len = db.MemoryRequired;
567 nii->mtu = ( db.FrameDataLen + db.MediaHeaderLen );
568 netdev->max_pkt_len = nii->mtu;
569 nii->media = ( stat & PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED );
570
571 return 0;
572 }
573
574 /**
575 * Initialise UNDI
576 *
577 * @v nii NII NIC
578 * @v flags Flags
579 * @ret rc Return status code
580 */
581 static int nii_initialise_flags ( struct nii_nic *nii, unsigned int flags ) {
582 PXE_CPB_INITIALIZE cpb;
583 PXE_DB_INITIALIZE db;
584 unsigned int op;
585 int stat;
586 int rc;
587
588 /* Allocate memory buffer */
589 nii->buffer = umalloc ( nii->buffer_len );
590 if ( ! nii->buffer ) {
591 rc = -ENOMEM;
592 goto err_alloc;
593 }
594
595 /* Construct parameter block */
596 memset ( &cpb, 0, sizeof ( cpb ) );
597 cpb.MemoryAddr = ( ( intptr_t ) nii->buffer );
598 cpb.MemoryLength = nii->buffer_len;
599
600 /* Construct data block */
601 memset ( &db, 0, sizeof ( db ) );
602
603 /* Issue command */
604 op = NII_OP ( PXE_OPCODE_INITIALIZE, flags );
605 if ( ( stat = nii_issue_cpb_db ( nii, op, &cpb, sizeof ( cpb ),
606 &db, sizeof ( db ) ) ) < 0 ) {
607 rc = -EIO_STAT ( stat );
608 DBGC ( nii, "NII %s could not initialise: %s\n",
609 nii->dev.name, strerror ( rc ) );
610 goto err_initialize;
611 }
612
613 return 0;
614
615 err_initialize:
616 ufree ( nii->buffer );
617 err_alloc:
618 return rc;
619 }
620
621 /**
622 * Initialise UNDI
623 *
624 * @v nii NII NIC
625 * @ret rc Return status code
626 */
627 static int nii_initialise ( struct nii_nic *nii ) {
628 unsigned int flags;
629
630 /* Initialise UNDI */
631 flags = PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE;
632 return nii_initialise_flags ( nii, flags );
633 }
634
635 /**
636 * Shut down UNDI
637 *
638 * @v nii NII NIC
639 */
640 static void nii_shutdown ( struct nii_nic *nii ) {
641 int stat;
642 int rc;
643
644 /* Issue command */
645 if ( ( stat = nii_issue ( nii, PXE_OPCODE_SHUTDOWN ) ) < 0 ) {
646 rc = -EIO_STAT ( stat );
647 DBGC ( nii, "NII %s could not shut down: %s\n",
648 nii->dev.name, strerror ( rc ) );
649 /* Leak memory to avoid corruption */
650 return;
651 }
652
653 /* Free buffer */
654 ufree ( nii->buffer );
655 }
656
657 /**
658 * Get station addresses
659 *
660 * @v nii NII NIC
661 * @v netdev Network device to fill in
662 * @ret rc Return status code
663 */
664 static int nii_get_station_address ( struct nii_nic *nii,
665 struct net_device *netdev ) {
666 PXE_DB_STATION_ADDRESS db;
667 unsigned int op;
668 int stat;
669 int rc;
670
671 /* Initialise UNDI */
672 if ( ( rc = nii_initialise ( nii ) ) != 0 )
673 goto err_initialise;
674
675 /* Issue command */
676 op = NII_OP ( PXE_OPCODE_STATION_ADDRESS,
677 PXE_OPFLAGS_STATION_ADDRESS_READ );
678 if ( ( stat = nii_issue_db ( nii, op, &db, sizeof ( db ) ) ) < 0 ) {
679 rc = -EIO_STAT ( stat );
680 DBGC ( nii, "NII %s could not get station address: %s\n",
681 nii->dev.name, strerror ( rc ) );
682 goto err_station_address;
683 }
684
685 /* Copy MAC addresses */
686 memcpy ( netdev->ll_addr, db.StationAddr,
687 netdev->ll_protocol->ll_addr_len );
688 memcpy ( netdev->hw_addr, db.PermanentAddr,
689 netdev->ll_protocol->hw_addr_len );
690 memcpy ( nii->broadcast, db.BroadcastAddr,
691 sizeof ( nii->broadcast ) );
692
693 err_station_address:
694 nii_shutdown ( nii );
695 err_initialise:
696 return rc;
697 }
698
699 /**
700 * Set station address
701 *
702 * @v nii NII NIC
703 * @v netdev Network device
704 * @ret rc Return status code
705 */
706 static int nii_set_station_address ( struct nii_nic *nii,
707 struct net_device *netdev ) {
708 uint32_t implementation = nii->undi->Implementation;
709 PXE_CPB_STATION_ADDRESS cpb;
710 unsigned int op;
711 int stat;
712 int rc;
713
714 /* Fail if setting station address is unsupported */
715 if ( ! ( implementation & PXE_ROMID_IMP_STATION_ADDR_SETTABLE ) )
716 return -ENOTSUP;
717
718 /* Construct parameter block */
719 memset ( &cpb, 0, sizeof ( cpb ) );
720 memcpy ( cpb.StationAddr, netdev->ll_addr,
721 netdev->ll_protocol->ll_addr_len );
722
723 /* Issue command */
724 op = NII_OP ( PXE_OPCODE_STATION_ADDRESS,
725 PXE_OPFLAGS_STATION_ADDRESS_WRITE );
726 if ( ( stat = nii_issue_cpb ( nii, op, &cpb, sizeof ( cpb ) ) ) < 0 ) {
727 rc = -EIO_STAT ( stat );
728 DBGC ( nii, "NII %s could not set station address: %s\n",
729 nii->dev.name, strerror ( rc ) );
730 return rc;
731 }
732
733 return 0;
734 }
735
736 /**
737 * Set receive filters
738 *
739 * @v nii NII NIC
740 * @ret rc Return status code
741 */
742 static int nii_set_rx_filters ( struct nii_nic *nii ) {
743 uint32_t implementation = nii->undi->Implementation;
744 unsigned int flags;
745 unsigned int op;
746 int stat;
747 int rc;
748
749 /* Construct receive filter set */
750 flags = ( PXE_OPFLAGS_RECEIVE_FILTER_ENABLE |
751 PXE_OPFLAGS_RECEIVE_FILTER_UNICAST );
752 if ( implementation & PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED )
753 flags |= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;
754 if ( implementation & PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED )
755 flags |= PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS;
756 if ( implementation & PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED )
757 flags |= PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;
758
759 /* Issue command */
760 op = NII_OP ( PXE_OPCODE_RECEIVE_FILTERS, flags );
761 if ( ( stat = nii_issue ( nii, op ) ) < 0 ) {
762 rc = -EIO_STAT ( stat );
763 DBGC ( nii, "NII %s could not set receive filters %#04x: %s\n",
764 nii->dev.name, flags, strerror ( rc ) );
765 return rc;
766 }
767
768 return 0;
769 }
770
771 /**
772 * Transmit packet
773 *
774 * @v netdev Network device
775 * @v iobuf I/O buffer
776 * @ret rc Return status code
777 */
778 static int nii_transmit ( struct net_device *netdev,
779 struct io_buffer *iobuf ) {
780 struct nii_nic *nii = netdev->priv;
781 PXE_CPB_TRANSMIT cpb;
782 unsigned int op;
783 int stat;
784 int rc;
785
786 /* Defer the packet if there is already a transmission in progress */
787 if ( nii->txbuf ) {
788 netdev_tx_defer ( netdev, iobuf );
789 return 0;
790 }
791
792 /* Construct parameter block */
793 memset ( &cpb, 0, sizeof ( cpb ) );
794 cpb.FrameAddr = virt_to_bus ( iobuf->data );
795 cpb.DataLen = iob_len ( iobuf );
796 cpb.MediaheaderLen = netdev->ll_protocol->ll_header_len;
797
798 /* Transmit packet */
799 op = NII_OP ( PXE_OPCODE_TRANSMIT,
800 ( PXE_OPFLAGS_TRANSMIT_WHOLE |
801 PXE_OPFLAGS_TRANSMIT_DONT_BLOCK ) );
802 if ( ( stat = nii_issue_cpb ( nii, op, &cpb, sizeof ( cpb ) ) ) < 0 ) {
803 rc = -EIO_STAT ( stat );
804 DBGC ( nii, "NII %s could not transmit: %s\n",
805 nii->dev.name, strerror ( rc ) );
806 return rc;
807 }
808 nii->txbuf = iobuf;
809
810 return 0;
811 }
812
813 /**
814 * Poll for completed packets
815 *
816 * @v netdev Network device
817 * @v stat Status flags
818 */
819 static void nii_poll_tx ( struct net_device *netdev, unsigned int stat ) {
820 struct nii_nic *nii = netdev->priv;
821 struct io_buffer *iobuf;
822
823 /* Do nothing unless we have a completion */
824 if ( stat & PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN )
825 return;
826
827 /* Sanity check */
828 assert ( nii->txbuf != NULL );
829
830 /* Complete transmission */
831 iobuf = nii->txbuf;
832 nii->txbuf = NULL;
833 netdev_tx_complete ( netdev, iobuf );
834 }
835
836 /**
837 * Poll for received packets
838 *
839 * @v netdev Network device
840 */
841 static void nii_poll_rx ( struct net_device *netdev ) {
842 struct nii_nic *nii = netdev->priv;
843 PXE_CPB_RECEIVE cpb;
844 PXE_DB_RECEIVE db;
845 unsigned int quota;
846 int stat;
847 int rc;
848
849 /* Retrieve up to NII_RX_QUOTA packets */
850 for ( quota = NII_RX_QUOTA ; quota ; quota-- ) {
851
852 /* Allocate buffer, if required */
853 if ( ! nii->rxbuf ) {
854 nii->rxbuf = alloc_iob ( nii->mtu );
855 if ( ! nii->rxbuf ) {
856 /* Leave for next poll */
857 break;
858 }
859 }
860
861 /* Construct parameter block */
862 memset ( &cpb, 0, sizeof ( cpb ) );
863 cpb.BufferAddr = virt_to_bus ( nii->rxbuf->data );
864 cpb.BufferLen = iob_tailroom ( nii->rxbuf );
865
866 /* Issue command */
867 if ( ( stat = nii_issue_cpb_db ( nii, PXE_OPCODE_RECEIVE,
868 &cpb, sizeof ( cpb ),
869 &db, sizeof ( db ) ) ) < 0 ) {
870
871 /* PXE_STATCODE_NO_DATA is just the usual "no packet"
872 * status indicator; ignore it.
873 */
874 if ( stat == -PXE_STATCODE_NO_DATA )
875 break;
876
877 /* Anything else is an error */
878 rc = -EIO_STAT ( stat );
879 DBGC ( nii, "NII %s could not receive: %s\n",
880 nii->dev.name, strerror ( rc ) );
881 netdev_rx_err ( netdev, NULL, rc );
882 break;
883 }
884
885 /* Hand off to network stack */
886 iob_put ( nii->rxbuf, db.FrameLen );
887 netdev_rx ( netdev, nii->rxbuf );
888 nii->rxbuf = NULL;
889 }
890 }
891
892 /**
893 * Check for link state changes
894 *
895 * @v netdev Network device
896 * @v stat Status flags
897 */
898 static void nii_poll_link ( struct net_device *netdev, unsigned int stat ) {
899 int no_media = ( stat & PXE_STATFLAGS_GET_STATUS_NO_MEDIA );
900
901 if ( no_media && netdev_link_ok ( netdev ) ) {
902 netdev_link_down ( netdev );
903 } else if ( ( ! no_media ) && ( ! netdev_link_ok ( netdev ) ) ) {
904 netdev_link_up ( netdev );
905 }
906 }
907
908 /**
909 * Poll for completed packets
910 *
911 * @v netdev Network device
912 */
913 static void nii_poll ( struct net_device *netdev ) {
914 struct nii_nic *nii = netdev->priv;
915 PXE_DB_GET_STATUS db;
916 unsigned int op;
917 int stat;
918 int rc;
919
920 /* Construct data block */
921 memset ( &db, 0, sizeof ( db ) );
922
923 /* Get status */
924 op = NII_OP ( PXE_OPCODE_GET_STATUS,
925 ( PXE_OPFLAGS_GET_INTERRUPT_STATUS |
926 ( nii->txbuf ? PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS : 0)|
927 ( nii->media ? PXE_OPFLAGS_GET_MEDIA_STATUS : 0 ) ) );
928 if ( ( stat = nii_issue_db ( nii, op, &db, sizeof ( db ) ) ) < 0 ) {
929 rc = -EIO_STAT ( stat );
930 DBGC ( nii, "NII %s could not get status: %s\n",
931 nii->dev.name, strerror ( rc ) );
932 return;
933 }
934
935 /* Process any TX completions */
936 if ( nii->txbuf )
937 nii_poll_tx ( netdev, stat );
938
939 /* Process any RX completions */
940 nii_poll_rx ( netdev );
941
942 /* Check for link state changes */
943 if ( nii->media )
944 nii_poll_link ( netdev, stat );
945 }
946
947 /**
948 * Open network device
949 *
950 * @v netdev Network device
951 * @ret rc Return status code
952 */
953 static int nii_open ( struct net_device *netdev ) {
954 struct nii_nic *nii = netdev->priv;
955 unsigned int flags;
956 int rc;
957
958 /* Initialise NIC
959 *
960 * We don't care about link state here, and would prefer to
961 * have the NIC initialise even if no cable is present, to
962 * match the behaviour of all other iPXE drivers.
963 *
964 * Some Emulex NII drivers have a bug which prevents packets
965 * from being sent or received unless we specifically ask it
966 * to detect cable presence during initialisation.
967 *
968 * Unfortunately, some other NII drivers (e.g. Mellanox) may
969 * time out and report failure if asked to detect cable
970 * presence during initialisation on links that are physically
971 * slow to reach link-up.
972 *
973 * Attempt to work around both of these problems by requesting
974 * cable detection at this point if any only if the driver is
975 * not capable of reporting link status changes at runtime via
976 * PXE_OPCODE_GET_STATUS.
977 */
978 flags = ( nii->media ? PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE
979 : PXE_OPFLAGS_INITIALIZE_DETECT_CABLE );
980 if ( ( rc = nii_initialise_flags ( nii, flags ) ) != 0 )
981 goto err_initialise;
982
983 /* Attempt to set station address */
984 if ( ( rc = nii_set_station_address ( nii, netdev ) ) != 0 ) {
985 DBGC ( nii, "NII %s could not set station address: %s\n",
986 nii->dev.name, strerror ( rc ) );
987 /* Treat as non-fatal */
988 }
989
990 /* Set receive filters */
991 if ( ( rc = nii_set_rx_filters ( nii ) ) != 0 )
992 goto err_set_rx_filters;
993
994 return 0;
995
996 err_set_rx_filters:
997 nii_shutdown ( nii );
998 err_initialise:
999 return rc;
1000 }
1001
1002 /**
1003 * Close network device
1004 *
1005 * @v netdev Network device
1006 */
1007 static void nii_close ( struct net_device *netdev ) {
1008 struct nii_nic *nii = netdev->priv;
1009
1010 /* Shut down NIC */
1011 nii_shutdown ( nii );
1012
1013 /* Discard transmit buffer, if applicable */
1014 if ( nii->txbuf ) {
1015 netdev_tx_complete_err ( netdev, nii->txbuf, -ECANCELED );
1016 nii->txbuf = NULL;
1017 }
1018
1019 /* Discard receive buffer, if applicable */
1020 if ( nii->rxbuf ) {
1021 free_iob ( nii->rxbuf );
1022 nii->rxbuf = NULL;
1023 }
1024 }
1025
1026 /** NII network device operations */
1027 static struct net_device_operations nii_operations = {
1028 .open = nii_open,
1029 .close = nii_close,
1030 .transmit = nii_transmit,
1031 .poll = nii_poll,
1032 };
1033
1034 /**
1035 * Attach driver to device
1036 *
1037 * @v efidev EFI device
1038 * @ret rc Return status code
1039 */
1040 int nii_start ( struct efi_device *efidev ) {
1041 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
1042 EFI_HANDLE device = efidev->device;
1043 struct net_device *netdev;
1044 struct nii_nic *nii;
1045 void *interface;
1046 EFI_STATUS efirc;
1047 int rc;
1048
1049 /* Allocate and initialise structure */
1050 netdev = alloc_netdev ( sizeof ( *nii ) );
1051 if ( ! netdev ) {
1052 rc = -ENOMEM;
1053 goto err_alloc;
1054 }
1055 netdev_init ( netdev, &nii_operations );
1056 nii = netdev->priv;
1057 nii->efidev = efidev;
1058 netdev->ll_broadcast = nii->broadcast;
1059 efidev_set_drvdata ( efidev, netdev );
1060
1061 /* Populate underlying device information */
1062 efi_device_info ( device, "NII", &nii->dev );
1063 nii->dev.driver_name = "NII";
1064 nii->dev.parent = &efidev->dev;
1065 list_add ( &nii->dev.siblings, &efidev->dev.children );
1066 INIT_LIST_HEAD ( &nii->dev.children );
1067 netdev->dev = &nii->dev;
1068
1069 /* Open NII protocol */
1070 if ( ( efirc = bs->OpenProtocol ( device, &efi_nii31_protocol_guid,
1071 &interface, efi_image_handle, device,
1072 ( EFI_OPEN_PROTOCOL_BY_DRIVER |
1073 EFI_OPEN_PROTOCOL_EXCLUSIVE )))!=0){
1074 rc = -EEFI ( efirc );
1075 DBGC ( nii, "NII %s cannot open NII protocol: %s\n",
1076 nii->dev.name, strerror ( rc ) );
1077 DBGC_EFI_OPENERS ( device, device, &efi_nii31_protocol_guid );
1078 goto err_open_protocol;
1079 }
1080 nii->nii = interface;
1081
1082 /* Locate UNDI and entry point */
1083 nii->undi = ( ( void * ) ( intptr_t ) nii->nii->Id );
1084 if ( ! nii->undi ) {
1085 DBGC ( nii, "NII %s has no UNDI\n", nii->dev.name );
1086 rc = -ENODEV;
1087 goto err_no_undi;
1088 }
1089 if ( nii->undi->Implementation & PXE_ROMID_IMP_HW_UNDI ) {
1090 DBGC ( nii, "NII %s is a mythical hardware UNDI\n",
1091 nii->dev.name );
1092 rc = -ENOTSUP;
1093 goto err_hw_undi;
1094 }
1095 if ( nii->undi->Implementation & PXE_ROMID_IMP_SW_VIRT_ADDR ) {
1096 nii->issue = ( ( void * ) ( intptr_t ) nii->undi->EntryPoint );
1097 } else {
1098 nii->issue = ( ( ( void * ) nii->undi ) +
1099 nii->undi->EntryPoint );
1100 }
1101 DBGC ( nii, "NII %s using UNDI v%x.%x at %p entry %p impl %#08x\n",
1102 nii->dev.name, nii->nii->MajorVer, nii->nii->MinorVer,
1103 nii->undi, nii->issue, nii->undi->Implementation );
1104
1105 /* Open PCI I/O protocols and locate BARs */
1106 if ( ( rc = nii_pci_open ( nii ) ) != 0 )
1107 goto err_pci_open;
1108
1109 /* Start UNDI */
1110 if ( ( rc = nii_start_undi ( nii ) ) != 0 )
1111 goto err_start_undi;
1112
1113 /* Get initialisation information */
1114 if ( ( rc = nii_get_init_info ( nii, netdev ) ) != 0 )
1115 goto err_get_init_info;
1116
1117 /* Get MAC addresses */
1118 if ( ( rc = nii_get_station_address ( nii, netdev ) ) != 0 )
1119 goto err_get_station_address;
1120
1121 /* Register network device */
1122 if ( ( rc = register_netdev ( netdev ) ) != 0 )
1123 goto err_register_netdev;
1124 DBGC ( nii, "NII %s registered as %s for %s\n", nii->dev.name,
1125 netdev->name, efi_handle_name ( device ) );
1126
1127 /* Set initial link state (if media detection is not supported) */
1128 if ( ! nii->media )
1129 netdev_link_up ( netdev );
1130
1131 return 0;
1132
1133 unregister_netdev ( netdev );
1134 err_register_netdev:
1135 err_get_station_address:
1136 err_get_init_info:
1137 nii_stop_undi ( nii );
1138 err_start_undi:
1139 nii_pci_close ( nii );
1140 err_pci_open:
1141 err_hw_undi:
1142 err_no_undi:
1143 bs->CloseProtocol ( device, &efi_nii31_protocol_guid,
1144 efi_image_handle, device );
1145 err_open_protocol:
1146 list_del ( &nii->dev.siblings );
1147 netdev_nullify ( netdev );
1148 netdev_put ( netdev );
1149 err_alloc:
1150 return rc;
1151 }
1152
1153 /**
1154 * Detach driver from device
1155 *
1156 * @v efidev EFI device
1157 */
1158 void nii_stop ( struct efi_device *efidev ) {
1159 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
1160 struct net_device *netdev = efidev_get_drvdata ( efidev );
1161 struct nii_nic *nii = netdev->priv;
1162 EFI_HANDLE device = efidev->device;
1163
1164 /* Unregister network device */
1165 unregister_netdev ( netdev );
1166
1167 /* Stop UNDI */
1168 nii_stop_undi ( nii );
1169
1170 /* Close PCI I/O protocols */
1171 nii_pci_close ( nii );
1172
1173 /* Close NII protocol */
1174 bs->CloseProtocol ( device, &efi_nii31_protocol_guid,
1175 efi_image_handle, device );
1176
1177 /* Free network device */
1178 list_del ( &nii->dev.siblings );
1179 netdev_nullify ( netdev );
1180 netdev_put ( netdev );
1181 }