iPXE
nii.c
Go to the documentation of this file.
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>
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 */
147  /** Mapping cookie created by PCI I/O protocol */
149 };
150 
151 /** An NII NIC */
152 struct nii_nic {
153  /** EFI device */
155  /** Network interface identifier protocol */
157  /** !PXE structure */
159  /** Entry point */
160  EFIAPI VOID ( * issue ) ( UINT64 cdb );
161  /** Generic device */
162  struct device dev;
163 
164  /** PCI device */
166  /** PCI I/O protocol */
168  /** Memory BAR */
169  unsigned int mem_bar;
170  /** I/O BAR */
171  unsigned int io_bar;
172 
173  /** Broadcast address */
175  /** Maximum packet length */
176  size_t mtu;
177 
178  /** Hardware transmit/receive buffer */
180  /** Hardware transmit/receive buffer length */
181  size_t buffer_len;
182 
183  /** Saved task priority level */
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 */
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  */
207 static int nii_pci_open ( struct nii_nic *nii ) {
209  EFI_HANDLE device = nii->efidev->device;
211  union {
212  EFI_PCI_IO_PROTOCOL *pci_io;
213  void *interface;
214  } pci_io;
215  union {
217  void *resource;
218  } desc;
219  int bar;
220  EFI_STATUS efirc;
221  int rc;
222 
223  /* Locate PCI I/O protocol */
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,
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:
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  */
295 static void nii_pci_close ( struct nii_nic *nii ) {
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 */
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  */
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 );
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  */
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 );
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:
386  break;
387  case FROM_DEVICE:
389  break;
390  case TO_DEVICE:
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  */
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  */
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  */
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  */
510 static EFIAPI VOID nii_block ( UINT64 unique_id, UINT32 acquire ) {
511  struct nii_nic *nii = ( ( void * ) ( intptr_t ) unique_id );
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  */
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 ) {
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  */
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  */
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  */
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  */
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  */
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  */
704 static int nii_get_init_info ( struct nii_nic *nii,
705  struct net_device *netdev ) {
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 = &ethernet_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;
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  */
751 static int nii_initialise_flags ( struct nii_nic *nii, unsigned int flags ) {
752  PXE_CPB_INITIALIZE cpb;
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 */
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
793  *
794  * @v nii NII NIC
795  * @ret rc Return status code
796  */
797 static int nii_initialise ( struct nii_nic *nii ) {
798  unsigned int flags;
799 
800  /* Initialise UNDI */
802  return nii_initialise_flags ( nii, flags );
803 }
804 
805 /**
806  * Shut down UNDI
807  *
808  * @v nii NII NIC
809  */
810 static void nii_shutdown ( struct nii_nic *nii ) {
811  int stat;
812  int rc;
813 
814  /* Issue command */
815  if ( ( stat = nii_issue ( nii, PXE_OPCODE_SHUTDOWN ) ) < 0 ) {
816  rc = -EIO_STAT ( stat );
817  DBGC ( nii, "NII %s could not shut down: %s\n",
818  nii->dev.name, strerror ( rc ) );
819  /* Leak memory to avoid corruption */
820  return;
821  }
822 
823  /* Free buffer */
824  ufree ( nii->buffer );
825 }
826 
827 /**
828  * Get station addresses
829  *
830  * @v nii NII NIC
831  * @v netdev Network device to fill in
832  * @ret rc Return status code
833  */
834 static int nii_get_station_address ( struct nii_nic *nii,
835  struct net_device *netdev ) {
837  unsigned int op;
838  int stat;
839  int rc;
840 
841  /* Initialise UNDI */
842  if ( ( rc = nii_initialise ( nii ) ) != 0 )
843  goto err_initialise;
844 
845  /* Issue command */
848  if ( ( stat = nii_issue_db ( nii, op, &db, sizeof ( db ) ) ) < 0 ) {
849  rc = -EIO_STAT ( stat );
850  DBGC ( nii, "NII %s could not get station address: %s\n",
851  nii->dev.name, strerror ( rc ) );
852  goto err_station_address;
853  }
854 
855  /* Copy MAC addresses */
856  memcpy ( netdev->ll_addr, db.StationAddr,
858  memcpy ( netdev->hw_addr, db.PermanentAddr,
860  memcpy ( nii->broadcast, db.BroadcastAddr,
861  sizeof ( nii->broadcast ) );
862 
863  err_station_address:
864  nii_shutdown ( nii );
865  err_initialise:
866  return rc;
867 }
868 
869 /**
870  * Set station address
871  *
872  * @v nii NII NIC
873  * @v netdev Network device
874  * @ret rc Return status code
875  */
876 static int nii_set_station_address ( struct nii_nic *nii,
877  struct net_device *netdev ) {
878  uint32_t implementation = nii->undi->Implementation;
880  unsigned int op;
881  int stat;
882  int rc;
883 
884  /* Fail if setting station address is unsupported */
886  return -ENOTSUP;
887 
888  /* Construct parameter block */
889  memset ( &cpb, 0, sizeof ( cpb ) );
892 
893  /* Issue command */
896  if ( ( stat = nii_issue_cpb ( nii, op, &cpb, sizeof ( cpb ) ) ) < 0 ) {
897  rc = -EIO_STAT ( stat );
898  DBGC ( nii, "NII %s could not set station address: %s\n",
899  nii->dev.name, strerror ( rc ) );
900  return rc;
901  }
902 
903  return 0;
904 }
905 
906 /**
907  * Set receive filters
908  *
909  * @v nii NII NIC
910  * @ret rc Return status code
911  */
912 static int nii_set_rx_filters ( struct nii_nic *nii ) {
913  uint32_t implementation = nii->undi->Implementation;
914  unsigned int flags;
915  unsigned int op;
916  int stat;
917  int rc;
918 
919  /* Construct receive filter set */
928 
929  /* Issue command */
931  if ( ( stat = nii_issue ( nii, op ) ) < 0 ) {
932  rc = -EIO_STAT ( stat );
933  DBGC ( nii, "NII %s could not set receive filters %#04x: %s\n",
934  nii->dev.name, flags, strerror ( rc ) );
935  return rc;
936  }
937 
938  return 0;
939 }
940 
941 /**
942  * Transmit packet
943  *
944  * @v netdev Network device
945  * @v iobuf I/O buffer
946  * @ret rc Return status code
947  */
948 static int nii_transmit ( struct net_device *netdev,
949  struct io_buffer *iobuf ) {
950  struct nii_nic *nii = netdev->priv;
951  PXE_CPB_TRANSMIT cpb;
952  unsigned int op;
953  int stat;
954  int rc;
955 
956  /* Defer the packet if there is already a transmission in progress */
957  if ( nii->txbuf ) {
958  netdev_tx_defer ( netdev, iobuf );
959  return 0;
960  }
961 
962  /* Construct parameter block */
963  memset ( &cpb, 0, sizeof ( cpb ) );
964  cpb.FrameAddr = virt_to_bus ( iobuf->data );
965  cpb.DataLen = iob_len ( iobuf );
967 
968  /* Transmit packet */
972  if ( ( stat = nii_issue_cpb ( nii, op, &cpb, sizeof ( cpb ) ) ) < 0 ) {
973  rc = -EIO_STAT ( stat );
974  DBGC ( nii, "NII %s could not transmit: %s\n",
975  nii->dev.name, strerror ( rc ) );
976  return rc;
977  }
978  nii->txbuf = iobuf;
979 
980  return 0;
981 }
982 
983 /**
984  * Poll for completed packets
985  *
986  * @v netdev Network device
987  * @v stat Status flags
988  */
989 static void nii_poll_tx ( struct net_device *netdev, unsigned int stat ) {
990  struct nii_nic *nii = netdev->priv;
991  struct io_buffer *iobuf;
992 
993  /* Do nothing unless we have a completion */
995  return;
996 
997  /* Sanity check */
998  assert ( nii->txbuf != NULL );
999 
1000  /* Complete transmission */
1001  iobuf = nii->txbuf;
1002  nii->txbuf = NULL;
1003  netdev_tx_complete ( netdev, iobuf );
1004 }
1005 
1006 /**
1007  * Poll for received packets
1008  *
1009  * @v netdev Network device
1010  */
1011 static void nii_poll_rx ( struct net_device *netdev ) {
1012  struct nii_nic *nii = netdev->priv;
1013  PXE_CPB_RECEIVE cpb;
1015  unsigned int quota;
1016  int stat;
1017  int rc;
1018 
1019  /* Retrieve up to NII_RX_QUOTA packets */
1020  for ( quota = NII_RX_QUOTA ; quota ; quota-- ) {
1021 
1022  /* Allocate buffer, if required */
1023  if ( ! nii->rxbuf ) {
1024  nii->rxbuf = alloc_iob ( nii->mtu );
1025  if ( ! nii->rxbuf ) {
1026  /* Leave for next poll */
1027  break;
1028  }
1029  }
1030 
1031  /* Construct parameter block */
1032  memset ( &cpb, 0, sizeof ( cpb ) );
1033  cpb.BufferAddr = virt_to_bus ( nii->rxbuf->data );
1034  cpb.BufferLen = iob_tailroom ( nii->rxbuf );
1035 
1036  /* Issue command */
1037  if ( ( stat = nii_issue_cpb_db ( nii, PXE_OPCODE_RECEIVE,
1038  &cpb, sizeof ( cpb ),
1039  &db, sizeof ( db ) ) ) < 0 ) {
1040 
1041  /* PXE_STATCODE_NO_DATA is just the usual "no packet"
1042  * status indicator; ignore it.
1043  */
1044  if ( stat == -PXE_STATCODE_NO_DATA )
1045  break;
1046 
1047  /* Anything else is an error */
1048  rc = -EIO_STAT ( stat );
1049  DBGC ( nii, "NII %s could not receive: %s\n",
1050  nii->dev.name, strerror ( rc ) );
1051  netdev_rx_err ( netdev, NULL, rc );
1052  break;
1053  }
1054 
1055  /* Hand off to network stack */
1056  iob_put ( nii->rxbuf, db.FrameLen );
1057  netdev_rx ( netdev, nii->rxbuf );
1058  nii->rxbuf = NULL;
1059  }
1060 }
1061 
1062 /**
1063  * Check for link state changes
1064  *
1065  * @v netdev Network device
1066  * @v stat Status flags
1067  */
1068 static void nii_poll_link ( struct net_device *netdev, unsigned int stat ) {
1069  int no_media = ( stat & PXE_STATFLAGS_GET_STATUS_NO_MEDIA );
1070 
1071  if ( no_media && netdev_link_ok ( netdev ) ) {
1073  } else if ( ( ! no_media ) && ( ! netdev_link_ok ( netdev ) ) ) {
1074  netdev_link_up ( netdev );
1075  }
1076 }
1077 
1078 /**
1079  * Poll for completed packets
1080  *
1081  * @v netdev Network device
1082  */
1083 static void nii_poll ( struct net_device *netdev ) {
1084  struct nii_nic *nii = netdev->priv;
1086  unsigned int op;
1087  int stat;
1088  int rc;
1089 
1090  /* Construct data block */
1091  memset ( &db, 0, sizeof ( db ) );
1092 
1093  /* Get status */
1096  ( nii->txbuf ? PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS : 0)|
1097  ( nii->media ? PXE_OPFLAGS_GET_MEDIA_STATUS : 0 ) ) );
1098  if ( ( stat = nii_issue_db ( nii, op, &db, sizeof ( db ) ) ) < 0 ) {
1099  rc = -EIO_STAT ( stat );
1100  DBGC ( nii, "NII %s could not get status: %s\n",
1101  nii->dev.name, strerror ( rc ) );
1102  return;
1103  }
1104 
1105  /* Process any TX completions */
1106  if ( nii->txbuf )
1107  nii_poll_tx ( netdev, stat );
1108 
1109  /* Process any RX completions */
1110  nii_poll_rx ( netdev );
1111 
1112  /* Check for link state changes */
1113  if ( nii->media )
1114  nii_poll_link ( netdev, stat );
1115 }
1116 
1117 /**
1118  * Open network device
1119  *
1120  * @v netdev Network device
1121  * @ret rc Return status code
1122  */
1123 static int nii_open ( struct net_device *netdev ) {
1124  struct nii_nic *nii = netdev->priv;
1125  unsigned int flags;
1126  int rc;
1127 
1128  /* Initialise NIC
1129  *
1130  * We don't care about link state here, and would prefer to
1131  * have the NIC initialise even if no cable is present, to
1132  * match the behaviour of all other iPXE drivers.
1133  *
1134  * Some Emulex NII drivers have a bug which prevents packets
1135  * from being sent or received unless we specifically ask it
1136  * to detect cable presence during initialisation.
1137  *
1138  * Unfortunately, some other NII drivers (e.g. Mellanox) may
1139  * time out and report failure if asked to detect cable
1140  * presence during initialisation on links that are physically
1141  * slow to reach link-up.
1142  *
1143  * Attempt to work around both of these problems by requesting
1144  * cable detection at this point if any only if the driver is
1145  * not capable of reporting link status changes at runtime via
1146  * PXE_OPCODE_GET_STATUS.
1147  */
1150  if ( ( rc = nii_initialise_flags ( nii, flags ) ) != 0 )
1151  goto err_initialise;
1152 
1153  /* Attempt to set station address */
1154  if ( ( rc = nii_set_station_address ( nii, netdev ) ) != 0 ) {
1155  DBGC ( nii, "NII %s could not set station address: %s\n",
1156  nii->dev.name, strerror ( rc ) );
1157  /* Treat as non-fatal */
1158  }
1159 
1160  /* Set receive filters */
1161  if ( ( rc = nii_set_rx_filters ( nii ) ) != 0 )
1162  goto err_set_rx_filters;
1163 
1164  return 0;
1165 
1166  err_set_rx_filters:
1167  nii_shutdown ( nii );
1168  err_initialise:
1169  return rc;
1170 }
1171 
1172 /**
1173  * Close network device
1174  *
1175  * @v netdev Network device
1176  */
1177 static void nii_close ( struct net_device *netdev ) {
1178  struct nii_nic *nii = netdev->priv;
1179 
1180  /* Shut down NIC */
1181  nii_shutdown ( nii );
1182 
1183  /* Discard transmit buffer, if applicable */
1184  if ( nii->txbuf ) {
1186  nii->txbuf = NULL;
1187  }
1188 
1189  /* Discard receive buffer, if applicable */
1190  if ( nii->rxbuf ) {
1191  free_iob ( nii->rxbuf );
1192  nii->rxbuf = NULL;
1193  }
1194 }
1195 
1196 /** NII network device operations */
1198  .open = nii_open,
1199  .close = nii_close,
1200  .transmit = nii_transmit,
1201  .poll = nii_poll,
1202 };
1203 
1204 /**
1205  * Attach driver to device
1206  *
1207  * @v efidev EFI device
1208  * @ret rc Return status code
1209  */
1210 int nii_start ( struct efi_device *efidev ) {
1212  EFI_HANDLE device = efidev->device;
1213  struct net_device *netdev;
1214  struct nii_nic *nii;
1215  void *interface;
1216  EFI_STATUS efirc;
1217  int rc;
1218 
1219  /* Allocate and initialise structure */
1220  netdev = alloc_netdev ( sizeof ( *nii ) );
1221  if ( ! netdev ) {
1222  rc = -ENOMEM;
1223  goto err_alloc;
1224  }
1226  nii = netdev->priv;
1227  nii->efidev = efidev;
1228  INIT_LIST_HEAD ( &nii->mappings );
1229  netdev->ll_broadcast = nii->broadcast;
1231 
1232  /* Populate underlying device information */
1233  efi_device_info ( device, "NII", &nii->dev );
1234  nii->dev.driver_name = "NII";
1235  nii->dev.parent = &efidev->dev;
1236  list_add ( &nii->dev.siblings, &efidev->dev.children );
1237  INIT_LIST_HEAD ( &nii->dev.children );
1238  netdev->dev = &nii->dev;
1239 
1240  /* Open NII protocol */
1241  if ( ( efirc = bs->OpenProtocol ( device, &efi_nii31_protocol_guid,
1245  rc = -EEFI ( efirc );
1246  DBGC ( nii, "NII %s cannot open NII protocol: %s\n",
1247  nii->dev.name, strerror ( rc ) );
1249  goto err_open_protocol;
1250  }
1251  nii->nii = interface;
1252 
1253  /* Locate UNDI and entry point */
1254  nii->undi = ( ( void * ) ( intptr_t ) nii->nii->Id );
1255  if ( ! nii->undi ) {
1256  DBGC ( nii, "NII %s has no UNDI\n", nii->dev.name );
1257  rc = -ENODEV;
1258  goto err_no_undi;
1259  }
1260  if ( nii->undi->Implementation & PXE_ROMID_IMP_HW_UNDI ) {
1261  DBGC ( nii, "NII %s is a mythical hardware UNDI\n",
1262  nii->dev.name );
1263  rc = -ENOTSUP;
1264  goto err_hw_undi;
1265  }
1266  if ( nii->undi->Implementation & PXE_ROMID_IMP_SW_VIRT_ADDR ) {
1267  nii->issue = ( ( void * ) ( intptr_t ) nii->undi->EntryPoint );
1268  } else {
1269  nii->issue = ( ( ( void * ) nii->undi ) +
1270  nii->undi->EntryPoint );
1271  }
1272  DBGC ( nii, "NII %s using UNDI v%x.%x at %p entry %p impl %#08x\n",
1273  nii->dev.name, nii->nii->MajorVer, nii->nii->MinorVer,
1274  nii->undi, nii->issue, nii->undi->Implementation );
1275 
1276  /* Open PCI I/O protocols and locate BARs */
1277  if ( ( rc = nii_pci_open ( nii ) ) != 0 )
1278  goto err_pci_open;
1279 
1280  /* Start UNDI */
1281  if ( ( rc = nii_start_undi ( nii ) ) != 0 )
1282  goto err_start_undi;
1283 
1284  /* Get initialisation information */
1285  if ( ( rc = nii_get_init_info ( nii, netdev ) ) != 0 )
1286  goto err_get_init_info;
1287 
1288  /* Get MAC addresses */
1289  if ( ( rc = nii_get_station_address ( nii, netdev ) ) != 0 )
1290  goto err_get_station_address;
1291 
1292  /* Register network device */
1293  if ( ( rc = register_netdev ( netdev ) ) != 0 )
1294  goto err_register_netdev;
1295  DBGC ( nii, "NII %s registered as %s for %s\n", nii->dev.name,
1297 
1298  /* Set initial link state (if media detection is not supported) */
1299  if ( ! nii->media )
1300  netdev_link_up ( netdev );
1301 
1302  return 0;
1303 
1305  err_register_netdev:
1306  err_get_station_address:
1307  err_get_init_info:
1308  nii_stop_undi ( nii );
1309  err_start_undi:
1310  nii_pci_close ( nii );
1311  err_pci_open:
1312  err_hw_undi:
1313  err_no_undi:
1316  err_open_protocol:
1317  list_del ( &nii->dev.siblings );
1318  netdev_nullify ( netdev );
1319  netdev_put ( netdev );
1320  err_alloc:
1321  return rc;
1322 }
1323 
1324 /**
1325  * Detach driver from device
1326  *
1327  * @v efidev EFI device
1328  */
1329 void nii_stop ( struct efi_device *efidev ) {
1331  struct net_device *netdev = efidev_get_drvdata ( efidev );
1332  struct nii_nic *nii = netdev->priv;
1334 
1335  /* Unregister network device */
1337 
1338  /* Stop UNDI */
1339  nii_stop_undi ( nii );
1340 
1341  /* Close PCI I/O protocols */
1342  nii_pci_close ( nii );
1343 
1344  /* Close NII protocol */
1347 
1348  /* Free network device */
1349  list_del ( &nii->dev.siblings );
1350  netdev_nullify ( netdev );
1351  netdev_put ( netdev );
1352 }
EFI_GUID efi_nii31_protocol_guid
Network interface identifier protocol GUID (new version)
Definition: efi_guid.c:212
NII driver.
EFI_TPL saved_tpl
Saved task priority level.
Definition: nii.c:184
#define NII_OPFLAGS(op)
Extract flags from operation.
Definition: nii.c:549
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2000
#define EFI_UNSUPPORTED
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:123
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
PACKED struct @457 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
The commond definition of QWORD, DWORD, and WORD Address Space Descriptors.
static void nii_poll_link(struct net_device *netdev, unsigned int stat)
Check for link state changes.
Definition: nii.c:1068
static void netdev_tx_complete(struct net_device *netdev, struct io_buffer *iobuf)
Complete network transmission.
Definition: netdevice.h:746
#define iob_put(iobuf, len)
Definition: iobuf.h:116
UINT64 addr
Mapped address.
Definition: nii.c:146
PXE_UINT32 BufferLen
Length of receive buffer.
Definition: UefiPxe.h:1748
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
Definition: netdevice.c:501
#define PXE_OPCODE_SHUTDOWN
Change the UNDI operational state from Initialized to Started.
Definition: UefiPxe.h:129
void netdev_tx_defer(struct net_device *netdev, struct io_buffer *iobuf)
Defer transmitted packet.
Definition: netdevice.c:344
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:157
static void nii_poll(struct net_device *netdev)
Poll for completed packets.
Definition: nii.c:1083
EFI_RAISE_TPL RaiseTPL
Definition: UefiSpec.h:1845
EFI_HANDLE pci_device
PCI device.
Definition: nii.c:165
PXE_UINT16 CPBsize
Definition: UefiPxe.h:885
uint8_t ll_header_len
Link-layer header length.
Definition: netdevice.h:200
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:198
EFI driver interface.
int(* open)(struct net_device *netdev)
Open network device.
Definition: netdevice.h:222
PXE_UINT32 MemoryLength
MemoryLength must be greater than or equal to MemoryRequired returned by the Get Init Info command.
Definition: UefiPxe.h:1263
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:69
PXE_UINT16 DBsize
Definition: UefiPxe.h:886
Error codes.
static int nii_issue_db(struct nii_nic *nii, unsigned int op, void *db, size_t db_len)
Issue command with data block.
Definition: nii.c:626
EFI_GUID efi_pci_io_protocol_guid
PCI I/O protocol GUID.
Definition: efi_guid.c:216
int nii_start(struct efi_device *efidev)
Attach driver to device.
Definition: nii.c:1210
static EFIAPI VOID nii_delay(UINT64 unique_id __unused, UINTN microseconds)
Delay callback.
Definition: nii.c:499
An optional protocol that is used to describe details about the software layer that is used to produc...
A read operation from system memory by a bus master.
Definition: PciIo.h:89
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
#define NII_OPCODE(op)
Extract opcode from operation.
Definition: nii.c:541
#define PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED
Definition: UefiPxe.h:875
PXE_UINT32 DataLen
Length of the data portion of the frame buffer in bytes.
Definition: UefiPxe.h:1684
PXE_OPFLAGS OpFlags
Definition: UefiPxe.h:884
EFI_PCI_IO_PROTOCOL_MAP Map
Definition: PciIo.h:532
#define DBGC(...)
Definition: compiler.h:505
#define PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN
This flag is set if no transmitted buffer addresses were written into the DB.
Definition: UefiPxe.h:578
char name[40]
Name.
Definition: device.h:75
static int nii_initialise_flags(struct nii_nic *nii, unsigned int flags)
Initialise UNDI.
Definition: nii.c:751
const uint8_t * ll_broadcast
Link-layer broadcast address.
Definition: netdevice.h:383
#define PXE_ROMID_IMP_STATION_ADDR_SETTABLE
Definition: UefiPxe.h:872
unsigned int UINT32
Definition: ProcessorBind.h:56
#define EFI_OPEN_PROTOCOL_BY_DRIVER
Definition: UefiSpec.h:1274
#define FROM_DEVICE
Definition: UefiPxe.h:1092
#define EFI_OPEN_PROTOCOL_EXCLUSIVE
Definition: UefiSpec.h:1275
EFI Network Interface Identifier Protocol.
void netdev_link_down(struct net_device *netdev)
Mark network device as having link down.
Definition: netdevice.c:186
#define DBGC_EFI_OPENERS(...)
Definition: efi.h:260
#define PXE_OPCODE_INITIALIZE
Changed UNDI operational state from Started to Initialized.
Definition: UefiPxe.h:119
#define EIO_STAT(stat)
Definition: nii.c:125
EFI_HANDLE device
EFI device handle.
Definition: efi_driver.h:21
#define PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS
Return list of transmitted buffers for recycling.
Definition: UefiPxe.h:371
void nii_stop(struct efi_device *efidev)
Detach driver from device.
Definition: nii.c:1329
PXE_MAC_ADDR StationAddr
If supplied and supported, the current station MAC address will be changed.
Definition: UefiPxe.h:1347
userptr_t buffer
Hardware transmit/receive buffer.
Definition: nii.c:179
unsigned long intptr_t
Definition: stdint.h:21
uint32_t implementation
Implementation.
Definition: ena.h:12
#define PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST
Enable broadcast packet receiving.
Definition: UefiPxe.h:299
#define PXE_OPFLAGS_INITIALIZE_DETECT_CABLE
Definition: UefiPxe.h:220
EFI_CLOSE_PROTOCOL CloseProtocol
Definition: UefiSpec.h:1906
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:128
static EFIAPI VOID nii_sync(UINT64 unique_id __unused, UINT64 addr, UINT32 len, UINT32 dir, UINT64 mapped)
Sync callback.
Definition: nii.c:471
unsigned char UINT8
Definition: ProcessorBind.h:62
UINT64 EFI_PHYSICAL_ADDRESS
64-bit physical memory address.
Definition: UefiBaseType.h:56
ACPI 1.0b definitions from the ACPI Specification, revision 1.0b.
#define TPL_NOTIFY
Definition: UefiSpec.h:592
#define PXE_IFTYPE_ETHERNET
This information is from the ARP section of RFC 1700.
Definition: UefiPxe.h:715
PXE_SW_UNDI * undi
!PXE structure
Definition: nii.c:158
EFI utilities.
#define PXE_OPCODE_STATION_ADDRESS
Read & change station MAC address.
Definition: UefiPxe.h:144
#define ECANCELED
Operation canceled.
Definition: errno.h:343
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
A doubly-linked list entry (or list head)
Definition: list.h:18
UINT64 Id
The address of the first byte of the identifying structure for this network interface.
static void nii_poll_tx(struct net_device *netdev, unsigned int stat)
Poll for completed packets.
Definition: nii.c:989
static EFIAPI VOID nii_map(UINT64 unique_id, UINT64 addr, UINT32 len, UINT32 dir, UINT64 mapped)
Map callback.
Definition: nii.c:369
#define ACPI_ADDRESS_SPACE_TYPE_MEM
Definition: Acpi10.h:105
static void nii_shutdown(struct nii_nic *nii)
Shut down UNDI.
Definition: nii.c:810
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition: netdevice.h:498
struct net_device * alloc_netdev(size_t priv_len)
Allocate network device.
Definition: netdevice.c:622
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
PXE_UINT64 FrameAddr
Address of first byte of frame buffer.
Definition: UefiPxe.h:1678
PXE_UINT64 MemoryAddr
Address of first (lowest) byte of the memory buffer.
Definition: UefiPxe.h:1257
#define ENOMEM
Not enough space.
Definition: errno.h:534
An NII NIC.
Definition: nii.c:152
A hardware device.
Definition: device.h:73
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static signed char phys[4]
Definition: epic100.c:88
#define PXE_OPFLAGS_TRANSMIT_WHOLE
Definition: UefiPxe.h:399
#define PXE_OPCODE_TRANSMIT
Transmit packet(s).
Definition: UefiPxe.h:174
static __always_inline unsigned long virt_to_bus(volatile const void *addr)
Convert virtual address to a bus address.
Definition: io.h:183
UINT64 Mem_IO
PXE_VOID Mem_IO(UINT64 UnqId, UINT8 read_write, UINT8 len, UINT64 port, UINT64 buf_addr);.
Definition: UefiPxe.h:1040
#define PXE_IO_WRITE
Definition: UefiPxe.h:1098
#define PXE_STATFLAGS_STATUS_MASK
Common StatFlags that can be returned by all commands.
Definition: UefiPxe.h:422
static int nii_set_station_address(struct nii_nic *nii, struct net_device *netdev)
Set station address.
Definition: nii.c:876
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:555
Ethernet protocol.
An object interface.
Definition: interface.h:109
uint8_t hw_addr_len
Hardware address length.
Definition: netdevice.h:196
static int nii_open(struct net_device *netdev)
Open network device.
Definition: nii.c:1123
void * priv
Driver private data.
Definition: netdevice.h:425
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
#define PCI_MAX_BAR
Maximum PCI BAR.
Definition: nii.c:139
EFI_STATUS(EFIAPI * EFI_PCI_IO_PROTOCOL_IO_MEM)(IN EFI_PCI_IO_PROTOCOL *This, IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN UINT8 BarIndex, IN UINT64 Offset, IN UINTN Count, IN OUT VOID *Buffer)
Enable a PCI driver to access PCI controller registers in the PCI memory or I/O space.
Definition: PciIo.h:188
static EFI_ACPI_TABLE_PROTOCOL * acpi
ACPI table protocol protocol.
Definition: efi_block.c:61
static void netdev_link_up(struct net_device *netdev)
Mark network device as having link up.
Definition: netdevice.h:768
void udelay(unsigned long usecs)
Delay for a fixed number of microseconds.
Definition: timer.c:60
EFI_PCI_IO_PROTOCOL * pci_io
PCI I/O protocol.
Definition: nii.c:167
static EFIAPI VOID nii_io(UINT64 unique_id, UINT8 op, UINT8 len, UINT64 addr, UINT64 data)
I/O callback.
Definition: nii.c:323
EFI_PCI_IO_PROTOCOL_GET_BAR_ATTRIBUTES GetBarAttributes
Definition: PciIo.h:539
static int netdev_link_ok(struct net_device *netdev)
Check link state of network device.
Definition: netdevice.h:630
static struct net_device * netdev
Definition: gdbudp.c:52
EFI_PCI_IO_PROTOCOL_WIDTH
Definition: PciIo.h:36
#define PXE_OPFLAGS_GET_INTERRUPT_STATUS
UNDI Get Status.
Definition: UefiPxe.h:361
#define PXE_OPFLAGS_RECEIVE_FILTER_ENABLE
Definition: UefiPxe.h:279
#define PXE_ROMID_IMP_HW_UNDI
Implementation flags.
Definition: UefiPxe.h:859
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition: netdevice.c:844
An NII memory mapping.
Definition: nii.c:142
static struct net_device_operations nii_operations
NII network device operations.
Definition: nii.c:1197
#define PXE_ROMID_IMP_SW_VIRT_ADDR
Definition: UefiPxe.h:860
#define EFI_OPEN_PROTOCOL_GET_PROTOCOL
Definition: UefiSpec.h:1271
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition: list.h:447
UINT64 Map_Mem
PXE_VOID Map_Mem(UINT64 unq_id, UINT64 virtual_addr, UINT32 size, UINT32 Direction,...
Definition: UefiPxe.h:1057
static __always_inline void off_t userptr_t src
Definition: efi_uaccess.h:66
unsigned int mem_bar
Memory BAR.
Definition: nii.c:169
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:713
PXE_UINT64 CPBaddr
Definition: UefiPxe.h:887
static int nii_set_rx_filters(struct nii_nic *nii)
Set receive filters.
Definition: nii.c:912
EFI_PCI_IO_PROTOCOL_UNMAP Unmap
Definition: PciIo.h:533
EFI_PCI_IO_PROTOCOL_IO_MEM Write
Write PCI controller registers in the PCI memory or I/O space.
Definition: PciIo.h:205
PXE_UINT64 BufferAddr
Address of first byte of receive buffer.
Definition: UefiPxe.h:1741
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#define EFIAPI
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
EFI Boot Services Table.
Definition: UefiSpec.h:1836
#define DBGC2_HD(...)
Definition: compiler.h:524
EFI_HANDLE efi_image_handle
Image handle passed to entry point.
Definition: efi_init.c:30
int media
Media status is supported.
Definition: nii.c:187
#define TO_DEVICE
Definition: UefiPxe.h:1093
#define PXE_OPFLAGS_STATION_ADDRESS_WRITE
Definition: UefiPxe.h:323
A PCI device.
Definition: pci.h:187
int register_netdev(struct net_device *netdev)
Register network device.
Definition: netdevice.c:667
PXE_MAC_ADDR broadcast
Broadcast address.
Definition: nii.c:174
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
static void * efidev_get_drvdata(struct efi_device *efidev)
Get EFI driver-private data.
Definition: efi_driver.h:83
static EFIAPI VOID nii_block(UINT64 unique_id, UINT32 acquire)
Block callback.
Definition: nii.c:510
uint8_t * tmp
Definition: entropy.h:156
User memory allocation.
#define PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED
Definition: UefiPxe.h:874
#define PXE_STATFLAGS_GET_STATUS_NO_MEDIA
This flag is set if there is no media detected.
Definition: UefiPxe.h:583
A network device.
Definition: netdevice.h:348
struct efi_device * efidev
EFI device.
Definition: nii.c:154
static size_t iob_tailroom(struct io_buffer *iobuf)
Calculate available space at end of an I/O buffer.
Definition: iobuf.h:171
#define TPL_CALLBACK
Definition: UefiSpec.h:591
#define ENODEV
No such device.
Definition: errno.h:509
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition: netdevice.h:511
#define ACPI_ADDRESS_SPACE_TYPE_IO
Definition: Acpi10.h:106
u32 addr
Definition: sky2.h:8
#define PXE_OPFLAGS_TRANSMIT_DONT_BLOCK
Definition: UefiPxe.h:395
EFIAPI VOID(* issue)(UINT64 cdb)
Entry point.
Definition: nii.c:160
UINT64 UINTN
Unsigned value of native width.
Definition: ProcessorBind.h:71
static int nii_issue_cpb_db(struct nii_nic *nii, unsigned int op, void *cpb, size_t cpb_len, void *db, size_t db_len)
Issue command with parameter block and data block.
Definition: nii.c:562
#define PXE_OPFLAGS_RECEIVE_FILTER_UNICAST
Enable unicast packet receiving.
Definition: UefiPxe.h:293
#define PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED
Definition: UefiPxe.h:450
An EFI device.
Definition: efi_driver.h:17
unsigned int io_bar
I/O BAR.
Definition: nii.c:171
static void nii_close(struct net_device *netdev)
Close network device.
Definition: nii.c:1177
#define PXE_OPCODE_STOP
Change UNDI operational state from Started to Stopped.
Definition: UefiPxe.h:104
#define PXE_OPCODE_GET_STATUS
Get & clear interrupt status.
Definition: UefiPxe.h:164
Provides both read and write access to system memory by both the processor and a bus master.
Definition: PciIo.h:98
static int nii_issue(struct nii_nic *nii, unsigned int op)
Issue command.
Definition: nii.c:640
#define VOID
Undeclared type.
Definition: Base.h:319
struct io_buffer * txbuf
Current transmit buffer.
Definition: nii.c:190
unsigned int uint32_t
Definition: stdint.h:12
unsigned long long UINT64
Definition: ProcessorBind.h:54
EFI_FREE_POOL FreePool
Definition: UefiSpec.h:1855
EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL * nii
Network interface identifier protocol.
Definition: nii.c:156
EFI_PCI_IO_PROTOCOL_OPERATION
Definition: PciIo.h:85
static int nii_initialise(struct nii_nic *nii)
Initialise UNDI.
Definition: nii.c:797
EFI API.
static int nii_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet.
Definition: nii.c:948
Network device operations.
Definition: netdevice.h:213
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition: netdevice.c:470
struct device * dev
Underlying hardware device.
Definition: netdevice.h:360
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
Network device management.
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
static struct dmfe_private * db
Definition: dmfe.c:177
static int nii_get_station_address(struct nii_nic *nii, struct net_device *netdev)
Get station addresses.
Definition: nii.c:834
VOID * mapping
Mapping cookie created by PCI I/O protocol.
Definition: nii.c:148
static uint16_t struct vmbus_xfer_pages_operations * op
Definition: netvsc.h:327
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
void netdev_tx_complete_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Complete network transmission.
Definition: netdevice.c:395
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:358
UINTN EFI_TPL
Task priority level.
Definition: UefiBaseType.h:47
#define PXE_STATCODE_NO_DATA
Definition: UefiPxe.h:631
static __always_inline void ufree(userptr_t userptr)
Free external memory.
Definition: umalloc.h:65
uint32_t len
Length.
Definition: ena.h:14
static __always_inline userptr_t umalloc(size_t size)
Allocate external memory.
Definition: umalloc.h:54
#define DBGC2(...)
Definition: compiler.h:522
UINT64 Delay
PXE_VOID Delay(UINT64 UnqId, UINTN microseconds);.
Definition: UefiPxe.h:999
UINT64 Sync_Mem
PXE_VOID Sync_Mem(UINT64 unq_id, UINT64 virtual, UINT32 size, UINT32 Direction, UINT64 mapped_addr);.
Definition: UefiPxe.h:1080
static int nii_start_undi(struct nii_nic *nii)
Start UNDI.
Definition: nii.c:651
EFI_PCI_IO_PROTOCOL_IO_MEM Read
Read PCI controller registers in the PCI memory or I/O space.
Definition: PciIo.h:201
PXE_UINT16 MediaheaderLen
Length of the media header in bytes.
Definition: UefiPxe.h:1689
void * data
Start of data.
Definition: iobuf.h:44
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:35
struct list_head children
Devices attached to this device.
Definition: device.h:83
struct device dev
Generic device.
Definition: nii.c:162
#define TO_AND_FROM_DEVICE
Definition: UefiPxe.h:1091
EFI driver interface.
struct list_head list
List of mappings.
Definition: nii.c:144
uint16_t count
Number of entries.
Definition: ena.h:22
UINT64 Block
PXE_VOID Block(UINT64 unq_id, UINT32 enable);.
Definition: UefiPxe.h:1015
UINT64 Unique_ID
protocol driver can provide anything for this Unique_ID, UNDI remembers that as just a 64bit value as...
Definition: UefiPxe.h:1088
#define PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST
Enable promiscuous multicast packet receiving.
Definition: UefiPxe.h:317
#define PXE_OPCODE_RECEIVE
Receive packet.
Definition: UefiPxe.h:179
static void nii_pci_close(struct nii_nic *nii)
Close PCI I/O protocol.
Definition: nii.c:295
static int nii_get_init_info(struct nii_nic *nii, struct net_device *netdev)
Get initialisation information.
Definition: nii.c:704
#define PXE_OPCODE_RECEIVE_FILTERS
Read & change state of packet receive filters.
Definition: UefiPxe.h:139
#define PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS
Enable promiscuous packet receiving.
Definition: UefiPxe.h:311
int efi_locate_device(EFI_HANDLE device, EFI_GUID *protocol, EFI_HANDLE *parent)
Locate parent device supporting a given protocol.
Definition: efi_utils.c:73
size_t buffer_len
Hardware transmit/receive buffer length.
Definition: nii.c:181
PXE_UINT8 PXE_MAC_ADDR[PXE_MAC_LENGTH]
Definition: UefiPxe.h:683
static EFIAPI VOID nii_unmap(UINT64 unique_id, UINT64 addr, UINT32 len, UINT32 dir __unused, UINT64 mapped)
Unmap callback.
Definition: nii.c:439
size_t mtu
Maximum packet length.
Definition: nii.c:176
EFI_SYSTEM_TABLE * efi_systab
EFI_OPEN_PROTOCOL OpenProtocol
Definition: UefiSpec.h:1905
A write operation from system memory by a bus master.
Definition: PciIo.h:93
static void nii_stop_undi(struct nii_nic *nii)
Stop UNDI.
Definition: nii.c:683
UINT16 IfNum
The network interface number that is being identified by this Network Interface Identifier Protocol.
#define PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED
Definition: UefiPxe.h:873
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:381
size_t max_pkt_len
Maximum packet length.
Definition: netdevice.h:403
EFI_RESTORE_TPL RestoreTPL
Definition: UefiSpec.h:1846
#define NII_RX_QUOTA
Maximum number of received packets per poll.
Definition: nii.c:199
static void nii_poll_rx(struct net_device *netdev)
Poll for received packets.
Definition: nii.c:1011
#define PXE_OPCODE_GET_INIT_INFO
Get UNDI initialization information.
Definition: UefiPxe.h:109
#define PXE_MEM_READ
Definition: UefiPxe.h:1099
#define PXE_OPFLAGS_STATION_ADDRESS_READ
UNDI Station Address.
Definition: UefiPxe.h:322
#define fls(x)
Find last (i.e.
Definition: strings.h:166
static void efidev_set_drvdata(struct efi_device *efidev, void *priv)
Set EFI driver-private data.
Definition: efi_driver.h:72
The EFI_PCI_IO_PROTOCOL provides the basic Memory, I/O, PCI configuration, and DMA interfaces used to...
Definition: PciIo.h:525
struct device dev
Generic device.
Definition: efi_driver.h:19
#define PXE_MEM_WRITE
Definition: UefiPxe.h:1100
uint8_t hw_addr[MAX_HW_ADDR_LEN]
Hardware address.
Definition: netdevice.h:375
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
struct list_head mappings
Mapping list.
Definition: nii.c:195
PXE_UINT16 IFnum
Definition: UefiPxe.h:891
#define PXE_OPCODE_START
Change UNDI operational state from Stopped to Started.
Definition: UefiPxe.h:99
String functions.
UINT64 UnMap_Mem
PXE_VOID UnMap_Mem(UINT64 unq_id, UINT64 virtual_addr, UINT32 size, UINT32 Direction,...
Definition: UefiPxe.h:1068
PXE_OPCODE OpCode
Definition: UefiPxe.h:883
#define PXE_OPFLAGS_GET_MEDIA_STATUS
Return current media status.
Definition: UefiPxe.h:376
Definition: efi.h:55
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:366
static int nii_issue_cpb(struct nii_nic *nii, unsigned int op, void *cpb, size_t cpb_len)
Issue command with parameter block.
Definition: nii.c:611
void efi_device_info(EFI_HANDLE device, const char *prefix, struct device *dev)
Get underlying device information.
Definition: efi_utils.c:211
#define NII_OP(opcode, opflags)
Construct operation from opcode and flags.
Definition: nii.c:533
unsigned long userptr_t
A pointer to a user buffer.
Definition: uaccess.h:33
String functions.
static int nii_pci_open(struct nii_nic *nii)
Open PCI I/O protocol and identify BARs.
Definition: nii.c:207
PXE_UINT64 DBaddr
Definition: UefiPxe.h:888
#define PXE_STATCODE_SUCCESS
Common StatCodes returned by all UNDI commands, UNDI protocol functions and BC protocol functions.
Definition: UefiPxe.h:611
void * memset(void *dest, int character, size_t len) __nonnull
A persistent I/O buffer.
Definition: iobuf.h:32
struct io_buffer * rxbuf
Current receive buffer.
Definition: nii.c:192
uint8_t flags
Flags.
Definition: ena.h:18
#define PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE
Definition: UefiPxe.h:221