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