Home | History | Annotate | Download | only in Uefi
      1 /** @file
      2   This header file contains all of the PXE type definitions,
      3   structure prototypes, global variables and constants that
      4   are needed for porting PXE to EFI.
      5 
      6 Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
      7 This program and the accompanying materials are licensed and made available under
      8 the terms and conditions of the BSD License that accompanies this distribution.
      9 The full text of the license may be found at
     10 http://opensource.org/licenses/bsd-license.php.
     11 
     12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     14 
     15   @par Revision Reference:
     16   32/64-bit PXE specification:
     17   alpha-4, 99-Dec-17.
     18 
     19 **/
     20 
     21 #ifndef __EFI_PXE_H__
     22 #define __EFI_PXE_H__
     23 
     24 #pragma pack(1)
     25 
     26 #define PXE_BUSTYPE(a, b, c, d) \
     27     ( \
     28       (((PXE_UINT32) (d) & 0xFF) << 24) | (((PXE_UINT32) (c) & 0xFF) << 16) | (((PXE_UINT32) (b) & 0xFF) << 8) | \
     29         ((PXE_UINT32) (a) & 0xFF) \
     30     )
     31 
     32 ///
     33 /// UNDI ROM ID and devive ID signature.
     34 ///
     35 #define PXE_BUSTYPE_PXE PXE_BUSTYPE ('!', 'P', 'X', 'E')
     36 
     37 ///
     38 /// BUS ROM ID signatures.
     39 ///
     40 #define PXE_BUSTYPE_PCI     PXE_BUSTYPE ('P', 'C', 'I', 'R')
     41 #define PXE_BUSTYPE_PC_CARD PXE_BUSTYPE ('P', 'C', 'C', 'R')
     42 #define PXE_BUSTYPE_USB     PXE_BUSTYPE ('U', 'S', 'B', 'R')
     43 #define PXE_BUSTYPE_1394    PXE_BUSTYPE ('1', '3', '9', '4')
     44 
     45 #define PXE_SWAP_UINT16(n)  ((((PXE_UINT16) (n) & 0x00FF) << 8) | (((PXE_UINT16) (n) & 0xFF00) >> 8))
     46 
     47 #define PXE_SWAP_UINT32(n) \
     48   ((((PXE_UINT32)(n) & 0x000000FF) << 24) | \
     49    (((PXE_UINT32)(n) & 0x0000FF00) << 8)  | \
     50    (((PXE_UINT32)(n) & 0x00FF0000) >> 8)  | \
     51    (((PXE_UINT32)(n) & 0xFF000000) >> 24))
     52 
     53 #define PXE_SWAP_UINT64(n) \
     54   ((((PXE_UINT64)(n) & 0x00000000000000FFULL) << 56) | \
     55    (((PXE_UINT64)(n) & 0x000000000000FF00ULL) << 40) | \
     56    (((PXE_UINT64)(n) & 0x0000000000FF0000ULL) << 24) | \
     57    (((PXE_UINT64)(n) & 0x00000000FF000000ULL) << 8)  | \
     58    (((PXE_UINT64)(n) & 0x000000FF00000000ULL) >> 8)  | \
     59    (((PXE_UINT64)(n) & 0x0000FF0000000000ULL) >> 24) | \
     60    (((PXE_UINT64)(n) & 0x00FF000000000000ULL) >> 40) | \
     61    (((PXE_UINT64)(n) & 0xFF00000000000000ULL) >> 56))
     62 
     63 
     64 #define PXE_CPBSIZE_NOT_USED  0               ///< zero
     65 #define PXE_DBSIZE_NOT_USED   0               ///< zero
     66 #define PXE_CPBADDR_NOT_USED  (PXE_UINT64) 0  ///< zero
     67 #define PXE_DBADDR_NOT_USED   (PXE_UINT64) 0  ///< zero
     68 #define PXE_CONST             CONST
     69 
     70 #define PXE_VOLATILE          volatile
     71 
     72 typedef VOID           PXE_VOID;
     73 typedef UINT8          PXE_UINT8;
     74 typedef UINT16         PXE_UINT16;
     75 typedef UINT32         PXE_UINT32;
     76 typedef UINTN          PXE_UINTN;
     77 
     78 ///
     79 /// Typedef unsigned long PXE_UINT64.
     80 ///
     81 typedef UINT64      PXE_UINT64;
     82 
     83 typedef PXE_UINT8 PXE_BOOL;
     84 #define PXE_FALSE 0            ///< zero
     85 #define PXE_TRUE  (!PXE_FALSE)
     86 
     87 typedef PXE_UINT16      PXE_OPCODE;
     88 
     89 ///
     90 /// Return UNDI operational state.
     91 ///
     92 #define PXE_OPCODE_GET_STATE  0x0000
     93 
     94 ///
     95 /// Change UNDI operational state from Stopped to Started.
     96 ///
     97 #define PXE_OPCODE_START  0x0001
     98 
     99 ///
    100 /// Change UNDI operational state from Started to Stopped.
    101 ///
    102 #define PXE_OPCODE_STOP 0x0002
    103 
    104 ///
    105 /// Get UNDI initialization information.
    106 ///
    107 #define PXE_OPCODE_GET_INIT_INFO  0x0003
    108 
    109 ///
    110 /// Get NIC configuration information.
    111 ///
    112 #define PXE_OPCODE_GET_CONFIG_INFO  0x0004
    113 
    114 ///
    115 /// Changed UNDI operational state from Started to Initialized.
    116 ///
    117 #define PXE_OPCODE_INITIALIZE 0x0005
    118 
    119 ///
    120 /// Re-initialize the NIC H/W.
    121 ///
    122 #define PXE_OPCODE_RESET  0x0006
    123 
    124 ///
    125 /// Change the UNDI operational state from Initialized to Started.
    126 ///
    127 #define PXE_OPCODE_SHUTDOWN 0x0007
    128 
    129 ///
    130 /// Read & change state of external interrupt enables.
    131 ///
    132 #define PXE_OPCODE_INTERRUPT_ENABLES  0x0008
    133 
    134 ///
    135 /// Read & change state of packet receive filters.
    136 ///
    137 #define PXE_OPCODE_RECEIVE_FILTERS  0x0009
    138 
    139 ///
    140 /// Read & change station MAC address.
    141 ///
    142 #define PXE_OPCODE_STATION_ADDRESS  0x000A
    143 
    144 ///
    145 /// Read traffic statistics.
    146 ///
    147 #define PXE_OPCODE_STATISTICS 0x000B
    148 
    149 ///
    150 /// Convert multicast IP address to multicast MAC address.
    151 ///
    152 #define PXE_OPCODE_MCAST_IP_TO_MAC  0x000C
    153 
    154 ///
    155 /// Read or change non-volatile storage on the NIC.
    156 ///
    157 #define PXE_OPCODE_NVDATA 0x000D
    158 
    159 ///
    160 /// Get & clear interrupt status.
    161 ///
    162 #define PXE_OPCODE_GET_STATUS 0x000E
    163 
    164 ///
    165 /// Fill media header in packet for transmit.
    166 ///
    167 #define PXE_OPCODE_FILL_HEADER  0x000F
    168 
    169 ///
    170 /// Transmit packet(s).
    171 ///
    172 #define PXE_OPCODE_TRANSMIT 0x0010
    173 
    174 ///
    175 /// Receive packet.
    176 ///
    177 #define PXE_OPCODE_RECEIVE  0x0011
    178 
    179 ///
    180 /// Last valid PXE UNDI OpCode number.
    181 ///
    182 #define PXE_OPCODE_LAST_VALID 0x0011
    183 
    184 typedef PXE_UINT16  PXE_OPFLAGS;
    185 
    186 #define PXE_OPFLAGS_NOT_USED  0x0000
    187 
    188 //
    189 // //////////////////////////////////////
    190 // UNDI Get State
    191 //
    192 // No OpFlags
    193 
    194 ////////////////////////////////////////
    195 // UNDI Start
    196 //
    197 // No OpFlags
    198 
    199 ////////////////////////////////////////
    200 // UNDI Stop
    201 //
    202 // No OpFlags
    203 
    204 ////////////////////////////////////////
    205 // UNDI Get Init Info
    206 //
    207 // No Opflags
    208 
    209 ////////////////////////////////////////
    210 // UNDI Get Config Info
    211 //
    212 // No Opflags
    213 
    214 ///
    215 /// UNDI Initialize
    216 ///
    217 #define PXE_OPFLAGS_INITIALIZE_CABLE_DETECT_MASK    0x0001
    218 #define PXE_OPFLAGS_INITIALIZE_DETECT_CABLE         0x0000
    219 #define PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE  0x0001
    220 
    221 ///
    222 ///
    223 /// UNDI Reset
    224 ///
    225 #define PXE_OPFLAGS_RESET_DISABLE_INTERRUPTS  0x0001
    226 #define PXE_OPFLAGS_RESET_DISABLE_FILTERS     0x0002
    227 
    228 ///
    229 /// UNDI Shutdown.
    230 ///
    231 /// No OpFlags.
    232 
    233 ///
    234 /// UNDI Interrupt Enables.
    235 ///
    236 ///
    237 /// Select whether to enable or disable external interrupt signals.
    238 /// Setting both enable and disable will return PXE_STATCODE_INVALID_OPFLAGS.
    239 ///
    240 #define PXE_OPFLAGS_INTERRUPT_OPMASK  0xC000
    241 #define PXE_OPFLAGS_INTERRUPT_ENABLE  0x8000
    242 #define PXE_OPFLAGS_INTERRUPT_DISABLE 0x4000
    243 #define PXE_OPFLAGS_INTERRUPT_READ    0x0000
    244 
    245 ///
    246 /// Enable receive interrupts.  An external interrupt will be generated
    247 /// after a complete non-error packet has been received.
    248 ///
    249 #define PXE_OPFLAGS_INTERRUPT_RECEIVE 0x0001
    250 
    251 ///
    252 /// Enable transmit interrupts.  An external interrupt will be generated
    253 /// after a complete non-error packet has been transmitted.
    254 ///
    255 #define PXE_OPFLAGS_INTERRUPT_TRANSMIT  0x0002
    256 
    257 ///
    258 /// Enable command interrupts.  An external interrupt will be generated
    259 /// when command execution stops.
    260 ///
    261 #define PXE_OPFLAGS_INTERRUPT_COMMAND 0x0004
    262 
    263 ///
    264 /// Generate software interrupt.  Setting this bit generates an external
    265 /// interrupt, if it is supported by the hardware.
    266 ///
    267 #define PXE_OPFLAGS_INTERRUPT_SOFTWARE  0x0008
    268 
    269 ///
    270 /// UNDI Receive Filters.
    271 ///
    272 ///
    273 /// Select whether to enable or disable receive filters.
    274 /// Setting both enable and disable will return PXE_STATCODE_INVALID_OPCODE.
    275 ///
    276 #define PXE_OPFLAGS_RECEIVE_FILTER_OPMASK   0xC000
    277 #define PXE_OPFLAGS_RECEIVE_FILTER_ENABLE   0x8000
    278 #define PXE_OPFLAGS_RECEIVE_FILTER_DISABLE  0x4000
    279 #define PXE_OPFLAGS_RECEIVE_FILTER_READ     0x0000
    280 
    281 ///
    282 /// To reset the contents of the multicast MAC address filter list,
    283 /// set this OpFlag:
    284 ///
    285 #define PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST 0x2000
    286 
    287 ///
    288 /// Enable unicast packet receiving.  Packets sent to the current station
    289 /// MAC address will be received.
    290 ///
    291 #define PXE_OPFLAGS_RECEIVE_FILTER_UNICAST  0x0001
    292 
    293 ///
    294 /// Enable broadcast packet receiving.  Packets sent to the broadcast
    295 /// MAC address will be received.
    296 ///
    297 #define PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST  0x0002
    298 
    299 ///
    300 /// Enable filtered multicast packet receiving.  Packets sent to any
    301 /// of the multicast MAC addresses in the multicast MAC address filter
    302 /// list will be received.  If the filter list is empty, no multicast
    303 ///
    304 #define PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST 0x0004
    305 
    306 ///
    307 /// Enable promiscuous packet receiving.  All packets will be received.
    308 ///
    309 #define PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS  0x0008
    310 
    311 ///
    312 /// Enable promiscuous multicast packet receiving.  All multicast
    313 /// packets will be received.
    314 ///
    315 #define PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST  0x0010
    316 
    317 ///
    318 /// UNDI Station Address.
    319 ///
    320 #define PXE_OPFLAGS_STATION_ADDRESS_READ   0x0000
    321 #define PXE_OPFLAGS_STATION_ADDRESS_WRITE  0x0000
    322 #define PXE_OPFLAGS_STATION_ADDRESS_RESET  0x0001
    323 
    324 ///
    325 /// UNDI Statistics.
    326 ///
    327 #define PXE_OPFLAGS_STATISTICS_READ   0x0000
    328 #define PXE_OPFLAGS_STATISTICS_RESET  0x0001
    329 
    330 ///
    331 /// UNDI MCast IP to MAC.
    332 ///
    333 ///
    334 /// Identify the type of IP address in the CPB.
    335 ///
    336 #define PXE_OPFLAGS_MCAST_IP_TO_MAC_OPMASK  0x0003
    337 #define PXE_OPFLAGS_MCAST_IPV4_TO_MAC       0x0000
    338 #define PXE_OPFLAGS_MCAST_IPV6_TO_MAC       0x0001
    339 
    340 ///
    341 /// UNDI NvData.
    342 ///
    343 ///
    344 /// Select the type of non-volatile data operation.
    345 ///
    346 #define PXE_OPFLAGS_NVDATA_OPMASK 0x0001
    347 #define PXE_OPFLAGS_NVDATA_READ   0x0000
    348 #define PXE_OPFLAGS_NVDATA_WRITE  0x0001
    349 
    350 ///
    351 /// UNDI Get Status.
    352 ///
    353 ///
    354 /// Return current interrupt status.  This will also clear any interrupts
    355 /// that are currently set.  This can be used in a polling routine.  The
    356 /// interrupt flags are still set and cleared even when the interrupts
    357 /// are disabled.
    358 ///
    359 #define PXE_OPFLAGS_GET_INTERRUPT_STATUS  0x0001
    360 
    361 ///
    362 /// Return list of transmitted buffers for recycling.  Transmit buffers
    363 /// must not be changed or unallocated until they have recycled.  After
    364 /// issuing a transmit command, wait for a transmit complete interrupt.
    365 /// When a transmit complete interrupt is received, read the transmitted
    366 /// buffers.  Do not plan on getting one buffer per interrupt.  Some
    367 /// NICs and UNDIs may transmit multiple buffers per interrupt.
    368 ///
    369 #define PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS 0x0002
    370 
    371 ///
    372 /// Return current media status.
    373 ///
    374 #define PXE_OPFLAGS_GET_MEDIA_STATUS    0x0004
    375 
    376 ///
    377 /// UNDI Fill Header.
    378 ///
    379 #define PXE_OPFLAGS_FILL_HEADER_OPMASK      0x0001
    380 #define PXE_OPFLAGS_FILL_HEADER_FRAGMENTED  0x0001
    381 #define PXE_OPFLAGS_FILL_HEADER_WHOLE       0x0000
    382 
    383 ///
    384 /// UNDI Transmit.
    385 ///
    386 ///
    387 /// S/W UNDI only.  Return after the packet has been transmitted.  A
    388 /// transmit complete interrupt will still be generated and the transmit
    389 /// buffer will have to be recycled.
    390 ///
    391 #define PXE_OPFLAGS_SWUNDI_TRANSMIT_OPMASK  0x0001
    392 #define PXE_OPFLAGS_TRANSMIT_BLOCK          0x0001
    393 #define PXE_OPFLAGS_TRANSMIT_DONT_BLOCK     0x0000
    394 
    395 #define PXE_OPFLAGS_TRANSMIT_OPMASK     0x0002
    396 #define PXE_OPFLAGS_TRANSMIT_FRAGMENTED 0x0002
    397 #define PXE_OPFLAGS_TRANSMIT_WHOLE      0x0000
    398 
    399 ///
    400 /// UNDI Receive.
    401 ///
    402 /// No OpFlags.
    403 ///
    404 
    405 ///
    406 /// PXE STATFLAGS.
    407 ///
    408 typedef PXE_UINT16  PXE_STATFLAGS;
    409 
    410 #define PXE_STATFLAGS_INITIALIZE  0x0000
    411 
    412 ///
    413 /// Common StatFlags that can be returned by all commands.
    414 ///
    415 ///
    416 /// The COMMAND_COMPLETE and COMMAND_FAILED status flags must be
    417 /// implemented by all UNDIs.  COMMAND_QUEUED is only needed by UNDIs
    418 /// that support command queuing.
    419 ///
    420 #define PXE_STATFLAGS_STATUS_MASK       0xC000
    421 #define PXE_STATFLAGS_COMMAND_COMPLETE  0xC000
    422 #define PXE_STATFLAGS_COMMAND_FAILED    0x8000
    423 #define PXE_STATFLAGS_COMMAND_QUEUED    0x4000
    424 
    425 ///
    426 /// UNDI Get State.
    427 ///
    428 #define PXE_STATFLAGS_GET_STATE_MASK        0x0003
    429 #define PXE_STATFLAGS_GET_STATE_INITIALIZED 0x0002
    430 #define PXE_STATFLAGS_GET_STATE_STARTED     0x0001
    431 #define PXE_STATFLAGS_GET_STATE_STOPPED     0x0000
    432 
    433 ///
    434 /// UNDI Start.
    435 ///
    436 /// No additional StatFlags.
    437 ///
    438 
    439 ///
    440 /// UNDI Get Init Info.
    441 ///
    442 #define PXE_STATFLAGS_CABLE_DETECT_MASK           0x0001
    443 #define PXE_STATFLAGS_CABLE_DETECT_NOT_SUPPORTED  0x0000
    444 #define PXE_STATFLAGS_CABLE_DETECT_SUPPORTED      0x0001
    445 
    446 #define PXE_STATFLAGS_GET_STATUS_NO_MEDIA_MASK           0x0002
    447 #define PXE_STATFLAGS_GET_STATUS_NO_MEDIA_NOT_SUPPORTED  0x0000
    448 #define PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED      0x0002
    449 
    450 ///
    451 /// UNDI Initialize.
    452 ///
    453 #define PXE_STATFLAGS_INITIALIZED_NO_MEDIA  0x0001
    454 
    455 ///
    456 /// UNDI Reset.
    457 ///
    458 #define PXE_STATFLAGS_RESET_NO_MEDIA  0x0001
    459 
    460 ///
    461 /// UNDI Shutdown.
    462 ///
    463 /// No additional StatFlags.
    464 
    465 ///
    466 /// UNDI Interrupt Enables.
    467 ///
    468 ///
    469 /// If set, receive interrupts are enabled.
    470 ///
    471 #define PXE_STATFLAGS_INTERRUPT_RECEIVE 0x0001
    472 
    473 ///
    474 /// If set, transmit interrupts are enabled.
    475 ///
    476 #define PXE_STATFLAGS_INTERRUPT_TRANSMIT  0x0002
    477 
    478 ///
    479 /// If set, command interrupts are enabled.
    480 ///
    481 #define PXE_STATFLAGS_INTERRUPT_COMMAND 0x0004
    482 
    483 ///
    484 /// UNDI Receive Filters.
    485 ///
    486 
    487 ///
    488 /// If set, unicast packets will be received.
    489 ///
    490 #define PXE_STATFLAGS_RECEIVE_FILTER_UNICAST  0x0001
    491 
    492 ///
    493 /// If set, broadcast packets will be received.
    494 ///
    495 #define PXE_STATFLAGS_RECEIVE_FILTER_BROADCAST  0x0002
    496 
    497 ///
    498 /// If set, multicast packets that match up with the multicast address
    499 /// filter list will be received.
    500 ///
    501 #define PXE_STATFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST 0x0004
    502 
    503 ///
    504 /// If set, all packets will be received.
    505 ///
    506 #define PXE_STATFLAGS_RECEIVE_FILTER_PROMISCUOUS  0x0008
    507 
    508 ///
    509 /// If set, all multicast packets will be received.
    510 ///
    511 #define PXE_STATFLAGS_RECEIVE_FILTER_ALL_MULTICAST  0x0010
    512 
    513 ///
    514 /// UNDI Station Address.
    515 ///
    516 /// No additional StatFlags.
    517 ///
    518 
    519 ///
    520 /// UNDI Statistics.
    521 ///
    522 /// No additional StatFlags.
    523 ///
    524 
    525 ///
    526 //// UNDI MCast IP to MAC.
    527 ////
    528 //// No additional StatFlags.
    529 
    530 ///
    531 /// UNDI NvData.
    532 ///
    533 /// No additional StatFlags.
    534 ///
    535 
    536 ///
    537 /// UNDI Get Status.
    538 ///
    539 
    540 ///
    541 /// Use to determine if an interrupt has occurred.
    542 ///
    543 #define PXE_STATFLAGS_GET_STATUS_INTERRUPT_MASK 0x000F
    544 #define PXE_STATFLAGS_GET_STATUS_NO_INTERRUPTS  0x0000
    545 
    546 ///
    547 /// If set, at least one receive interrupt occurred.
    548 ///
    549 #define PXE_STATFLAGS_GET_STATUS_RECEIVE  0x0001
    550 
    551 ///
    552 /// If set, at least one transmit interrupt occurred.
    553 ///
    554 #define PXE_STATFLAGS_GET_STATUS_TRANSMIT 0x0002
    555 
    556 ///
    557 /// If set, at least one command interrupt occurred.
    558 ///
    559 #define PXE_STATFLAGS_GET_STATUS_COMMAND  0x0004
    560 
    561 ///
    562 /// If set, at least one software interrupt occurred.
    563 ///
    564 #define PXE_STATFLAGS_GET_STATUS_SOFTWARE 0x0008
    565 
    566 ///
    567 /// This flag is set if the transmitted buffer queue is empty.  This flag
    568 /// will be set if all transmitted buffer addresses get written into the DB.
    569 ///
    570 #define PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY  0x0010
    571 
    572 ///
    573 /// This flag is set if no transmitted buffer addresses were written
    574 /// into the DB.  (This could be because DBsize was too small.)
    575 ///
    576 #define PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN  0x0020
    577 
    578 ///
    579 /// This flag is set if there is no media detected.
    580 ///
    581 #define PXE_STATFLAGS_GET_STATUS_NO_MEDIA  0x0040
    582 
    583 ///
    584 /// UNDI Fill Header.
    585 ///
    586 /// No additional StatFlags.
    587 ///
    588 
    589 ///
    590 /// UNDI Transmit.
    591 ///
    592 /// No additional StatFlags.
    593 
    594 ///
    595 /// UNDI Receive
    596 ///.
    597 
    598 ///
    599 /// No additional StatFlags.
    600 ///
    601 typedef PXE_UINT16  PXE_STATCODE;
    602 
    603 #define PXE_STATCODE_INITIALIZE 0x0000
    604 
    605 ///
    606 /// Common StatCodes returned by all UNDI commands, UNDI protocol functions
    607 /// and BC protocol functions.
    608 ///
    609 #define PXE_STATCODE_SUCCESS              0x0000
    610 
    611 #define PXE_STATCODE_INVALID_CDB          0x0001
    612 #define PXE_STATCODE_INVALID_CPB          0x0002
    613 #define PXE_STATCODE_BUSY                 0x0003
    614 #define PXE_STATCODE_QUEUE_FULL           0x0004
    615 #define PXE_STATCODE_ALREADY_STARTED      0x0005
    616 #define PXE_STATCODE_NOT_STARTED          0x0006
    617 #define PXE_STATCODE_NOT_SHUTDOWN         0x0007
    618 #define PXE_STATCODE_ALREADY_INITIALIZED  0x0008
    619 #define PXE_STATCODE_NOT_INITIALIZED      0x0009
    620 #define PXE_STATCODE_DEVICE_FAILURE       0x000A
    621 #define PXE_STATCODE_NVDATA_FAILURE       0x000B
    622 #define PXE_STATCODE_UNSUPPORTED          0x000C
    623 #define PXE_STATCODE_BUFFER_FULL          0x000D
    624 #define PXE_STATCODE_INVALID_PARAMETER    0x000E
    625 #define PXE_STATCODE_INVALID_UNDI         0x000F
    626 #define PXE_STATCODE_IPV4_NOT_SUPPORTED   0x0010
    627 #define PXE_STATCODE_IPV6_NOT_SUPPORTED   0x0011
    628 #define PXE_STATCODE_NOT_ENOUGH_MEMORY    0x0012
    629 #define PXE_STATCODE_NO_DATA              0x0013
    630 
    631 typedef PXE_UINT16  PXE_IFNUM;
    632 
    633 ///
    634 /// This interface number must be passed to the S/W UNDI Start command.
    635 ///
    636 #define PXE_IFNUM_START 0x0000
    637 
    638 ///
    639 /// This interface number is returned by the S/W UNDI Get State and
    640 /// Start commands if information in the CDB, CPB or DB is invalid.
    641 ///
    642 #define PXE_IFNUM_INVALID 0x0000
    643 
    644 typedef PXE_UINT16  PXE_CONTROL;
    645 
    646 ///
    647 /// Setting this flag directs the UNDI to queue this command for later
    648 /// execution if the UNDI is busy and it supports command queuing.
    649 /// If queuing is not supported, a PXE_STATCODE_INVALID_CONTROL error
    650 /// is returned.  If the queue is full, a PXE_STATCODE_CDB_QUEUE_FULL
    651 /// error is returned.
    652 ///
    653 #define PXE_CONTROL_QUEUE_IF_BUSY 0x0002
    654 
    655 ///
    656 /// These two bit values are used to determine if there are more UNDI
    657 /// CDB structures following this one.  If the link bit is set, there
    658 /// must be a CDB structure following this one.  Execution will start
    659 /// on the next CDB structure as soon as this one completes successfully.
    660 /// If an error is generated by this command, execution will stop.
    661 ///
    662 #define PXE_CONTROL_LINK              0x0001
    663 #define PXE_CONTROL_LAST_CDB_IN_LIST  0x0000
    664 
    665 typedef PXE_UINT8   PXE_FRAME_TYPE;
    666 
    667 #define PXE_FRAME_TYPE_NONE                     0x00
    668 #define PXE_FRAME_TYPE_UNICAST                  0x01
    669 #define PXE_FRAME_TYPE_BROADCAST                0x02
    670 #define PXE_FRAME_TYPE_FILTERED_MULTICAST       0x03
    671 #define PXE_FRAME_TYPE_PROMISCUOUS              0x04
    672 #define PXE_FRAME_TYPE_PROMISCUOUS_MULTICAST    0x05
    673 
    674 #define PXE_FRAME_TYPE_MULTICAST                PXE_FRAME_TYPE_FILTERED_MULTICAST
    675 
    676 typedef PXE_UINT32  PXE_IPV4;
    677 
    678 typedef PXE_UINT32  PXE_IPV6[4];
    679 #define PXE_MAC_LENGTH  32
    680 
    681 typedef PXE_UINT8   PXE_MAC_ADDR[PXE_MAC_LENGTH];
    682 
    683 typedef PXE_UINT8   PXE_IFTYPE;
    684 typedef UINT16      PXE_MEDIA_PROTOCOL;
    685 
    686 ///
    687 /// This information is from the ARP section of RFC 1700.
    688 ///
    689 ///     1 Ethernet (10Mb)                                    [JBP]
    690 ///     2 Experimental Ethernet (3Mb)                        [JBP]
    691 ///     3 Amateur Radio AX.25                                [PXK]
    692 ///     4 Proteon ProNET Token Ring                          [JBP]
    693 ///     5 Chaos                                              [GXP]
    694 ///     6 IEEE 802 Networks                                  [JBP]
    695 ///     7 ARCNET                                             [JBP]
    696 ///     8 Hyperchannel                                       [JBP]
    697 ///     9 Lanstar                                             [TU]
    698 ///    10 Autonet Short Address                             [MXB1]
    699 ///    11 LocalTalk                                         [JKR1]
    700 ///    12 LocalNet (IBM* PCNet or SYTEK* LocalNET)           [JXM]
    701 ///    13 Ultra link                                        [RXD2]
    702 ///    14 SMDS                                              [GXC1]
    703 ///    15 Frame Relay                                        [AGM]
    704 ///    16 Asynchronous Transmission Mode (ATM)              [JXB2]
    705 ///    17 HDLC                                               [JBP]
    706 ///    18 Fibre Channel                            [Yakov Rekhter]
    707 ///    19 Asynchronous Transmission Mode (ATM)      [Mark Laubach]
    708 ///    20 Serial Line                                        [JBP]
    709 ///    21 Asynchronous Transmission Mode (ATM)              [MXB1]
    710 ///
    711 /// * Other names and brands may be claimed as the property of others.
    712 ///
    713 #define PXE_IFTYPE_ETHERNET       0x01
    714 #define PXE_IFTYPE_TOKENRING      0x04
    715 #define PXE_IFTYPE_FIBRE_CHANNEL  0x12
    716 
    717 typedef struct s_pxe_hw_undi {
    718   PXE_UINT32  Signature;      ///< PXE_ROMID_SIGNATURE.
    719   PXE_UINT8   Len;            ///< sizeof(PXE_HW_UNDI).
    720   PXE_UINT8   Fudge;          ///< makes 8-bit cksum equal zero.
    721   PXE_UINT8   Rev;            ///< PXE_ROMID_REV.
    722   PXE_UINT8   IFcnt;          ///< physical connector count lower byte.
    723   PXE_UINT8   MajorVer;       ///< PXE_ROMID_MAJORVER.
    724   PXE_UINT8   MinorVer;       ///< PXE_ROMID_MINORVER.
    725   PXE_UINT8   IFcntExt;       ///< physical connector count upper byte.
    726   PXE_UINT8   reserved;       ///< zero, not used.
    727   PXE_UINT32  Implementation; ///< implementation flags.
    728   ///< reserved             ///< vendor use.
    729   ///< UINT32 Status;       ///< status port.
    730   ///< UINT32 Command;      ///< command port.
    731   ///< UINT64 CDBaddr;      ///< CDB address port.
    732   ///<
    733 } PXE_HW_UNDI;
    734 
    735 ///
    736 /// Status port bit definitions.
    737 ///
    738 
    739 ///
    740 /// UNDI operation state.
    741 ///
    742 #define PXE_HWSTAT_STATE_MASK   0xC0000000
    743 #define PXE_HWSTAT_BUSY         0xC0000000
    744 #define PXE_HWSTAT_INITIALIZED  0x80000000
    745 #define PXE_HWSTAT_STARTED      0x40000000
    746 #define PXE_HWSTAT_STOPPED      0x00000000
    747 
    748 ///
    749 /// If set, last command failed.
    750 ///
    751 #define PXE_HWSTAT_COMMAND_FAILED 0x20000000
    752 
    753 ///
    754 /// If set, identifies enabled receive filters.
    755 ///
    756 #define PXE_HWSTAT_PROMISCUOUS_MULTICAST_RX_ENABLED 0x00001000
    757 #define PXE_HWSTAT_PROMISCUOUS_RX_ENABLED           0x00000800
    758 #define PXE_HWSTAT_BROADCAST_RX_ENABLED             0x00000400
    759 #define PXE_HWSTAT_MULTICAST_RX_ENABLED             0x00000200
    760 #define PXE_HWSTAT_UNICAST_RX_ENABLED               0x00000100
    761 
    762 ///
    763 /// If set, identifies enabled external interrupts.
    764 ///
    765 #define PXE_HWSTAT_SOFTWARE_INT_ENABLED     0x00000080
    766 #define PXE_HWSTAT_TX_COMPLETE_INT_ENABLED  0x00000040
    767 #define PXE_HWSTAT_PACKET_RX_INT_ENABLED    0x00000020
    768 #define PXE_HWSTAT_CMD_COMPLETE_INT_ENABLED 0x00000010
    769 
    770 ///
    771 /// If set, identifies pending interrupts.
    772 ///
    773 #define PXE_HWSTAT_SOFTWARE_INT_PENDING     0x00000008
    774 #define PXE_HWSTAT_TX_COMPLETE_INT_PENDING  0x00000004
    775 #define PXE_HWSTAT_PACKET_RX_INT_PENDING    0x00000002
    776 #define PXE_HWSTAT_CMD_COMPLETE_INT_PENDING 0x00000001
    777 
    778 ///
    779 /// Command port definitions.
    780 ///
    781 
    782 ///
    783 /// If set, CDB identified in CDBaddr port is given to UNDI.
    784 /// If not set, other bits in this word will be processed.
    785 ///
    786 #define PXE_HWCMD_ISSUE_COMMAND   0x80000000
    787 #define PXE_HWCMD_INTS_AND_FILTS  0x00000000
    788 
    789 ///
    790 /// Use these to enable/disable receive filters.
    791 ///
    792 #define PXE_HWCMD_PROMISCUOUS_MULTICAST_RX_ENABLE 0x00001000
    793 #define PXE_HWCMD_PROMISCUOUS_RX_ENABLE           0x00000800
    794 #define PXE_HWCMD_BROADCAST_RX_ENABLE             0x00000400
    795 #define PXE_HWCMD_MULTICAST_RX_ENABLE             0x00000200
    796 #define PXE_HWCMD_UNICAST_RX_ENABLE               0x00000100
    797 
    798 ///
    799 /// Use these to enable/disable external interrupts.
    800 ///
    801 #define PXE_HWCMD_SOFTWARE_INT_ENABLE     0x00000080
    802 #define PXE_HWCMD_TX_COMPLETE_INT_ENABLE  0x00000040
    803 #define PXE_HWCMD_PACKET_RX_INT_ENABLE    0x00000020
    804 #define PXE_HWCMD_CMD_COMPLETE_INT_ENABLE 0x00000010
    805 
    806 ///
    807 /// Use these to clear pending external interrupts.
    808 ///
    809 #define PXE_HWCMD_CLEAR_SOFTWARE_INT      0x00000008
    810 #define PXE_HWCMD_CLEAR_TX_COMPLETE_INT   0x00000004
    811 #define PXE_HWCMD_CLEAR_PACKET_RX_INT     0x00000002
    812 #define PXE_HWCMD_CLEAR_CMD_COMPLETE_INT  0x00000001
    813 
    814 typedef struct s_pxe_sw_undi {
    815   PXE_UINT32  Signature;      ///< PXE_ROMID_SIGNATURE.
    816   PXE_UINT8   Len;            ///< sizeof(PXE_SW_UNDI).
    817   PXE_UINT8   Fudge;          ///< makes 8-bit cksum zero.
    818   PXE_UINT8   Rev;            ///< PXE_ROMID_REV.
    819   PXE_UINT8   IFcnt;          ///< physical connector count lower byte.
    820   PXE_UINT8   MajorVer;       ///< PXE_ROMID_MAJORVER.
    821   PXE_UINT8   MinorVer;       ///< PXE_ROMID_MINORVER.
    822   PXE_UINT8   IFcntExt;       ///< physical connector count upper byte.
    823   PXE_UINT8   reserved1;      ///< zero, not used.
    824   PXE_UINT32  Implementation; ///< Implementation flags.
    825   PXE_UINT64  EntryPoint;     ///< API entry point.
    826   PXE_UINT8   reserved2[3];   ///< zero, not used.
    827   PXE_UINT8   BusCnt;         ///< number of bustypes supported.
    828   PXE_UINT32  BusType[1];     ///< list of supported bustypes.
    829 } PXE_SW_UNDI;
    830 
    831 typedef union u_pxe_undi {
    832   PXE_HW_UNDI hw;
    833   PXE_SW_UNDI sw;
    834 } PXE_UNDI;
    835 
    836 ///
    837 /// Signature of !PXE structure.
    838 ///
    839 #define PXE_ROMID_SIGNATURE PXE_BUSTYPE ('!', 'P', 'X', 'E')
    840 
    841 ///
    842 /// !PXE structure format revision
    843 ///.
    844 #define PXE_ROMID_REV 0x02
    845 
    846 ///
    847 /// UNDI command interface revision.  These are the values that get sent
    848 /// in option 94 (Client Network Interface Identifier) in the DHCP Discover
    849 /// and PXE Boot Server Request packets.
    850 ///
    851 #define PXE_ROMID_MAJORVER    0x03
    852 #define PXE_ROMID_MINORVER    0x01
    853 
    854 ///
    855 /// Implementation flags.
    856 ///
    857 #define PXE_ROMID_IMP_HW_UNDI                             0x80000000
    858 #define PXE_ROMID_IMP_SW_VIRT_ADDR                        0x40000000
    859 #define PXE_ROMID_IMP_64BIT_DEVICE                        0x00010000
    860 #define PXE_ROMID_IMP_FRAG_SUPPORTED                      0x00008000
    861 #define PXE_ROMID_IMP_CMD_LINK_SUPPORTED                  0x00004000
    862 #define PXE_ROMID_IMP_CMD_QUEUE_SUPPORTED                 0x00002000
    863 #define PXE_ROMID_IMP_MULTI_FRAME_SUPPORTED               0x00001000
    864 #define PXE_ROMID_IMP_NVDATA_SUPPORT_MASK                 0x00000C00
    865 #define PXE_ROMID_IMP_NVDATA_BULK_WRITABLE                0x00000C00
    866 #define PXE_ROMID_IMP_NVDATA_SPARSE_WRITABLE              0x00000800
    867 #define PXE_ROMID_IMP_NVDATA_READ_ONLY                    0x00000400
    868 #define PXE_ROMID_IMP_NVDATA_NOT_AVAILABLE                0x00000000
    869 #define PXE_ROMID_IMP_STATISTICS_SUPPORTED                0x00000200
    870 #define PXE_ROMID_IMP_STATION_ADDR_SETTABLE               0x00000100
    871 #define PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED  0x00000080
    872 #define PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED            0x00000040
    873 #define PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED              0x00000020
    874 #define PXE_ROMID_IMP_FILTERED_MULTICAST_RX_SUPPORTED     0x00000010
    875 #define PXE_ROMID_IMP_SOFTWARE_INT_SUPPORTED              0x00000008
    876 #define PXE_ROMID_IMP_TX_COMPLETE_INT_SUPPORTED           0x00000004
    877 #define PXE_ROMID_IMP_PACKET_RX_INT_SUPPORTED             0x00000002
    878 #define PXE_ROMID_IMP_CMD_COMPLETE_INT_SUPPORTED          0x00000001
    879 
    880 typedef struct s_pxe_cdb {
    881   PXE_OPCODE    OpCode;
    882   PXE_OPFLAGS   OpFlags;
    883   PXE_UINT16    CPBsize;
    884   PXE_UINT16    DBsize;
    885   PXE_UINT64    CPBaddr;
    886   PXE_UINT64    DBaddr;
    887   PXE_STATCODE  StatCode;
    888   PXE_STATFLAGS StatFlags;
    889   PXE_UINT16    IFnum;
    890   PXE_CONTROL   Control;
    891 } PXE_CDB;
    892 
    893 typedef union u_pxe_ip_addr {
    894   PXE_IPV6  IPv6;
    895   PXE_IPV4  IPv4;
    896 } PXE_IP_ADDR;
    897 
    898 typedef union pxe_device {
    899   ///
    900   /// PCI and PC Card NICs are both identified using bus, device
    901   /// and function numbers.  For PC Card, this may require PC
    902   /// Card services to be loaded in the BIOS or preboot
    903   /// environment.
    904   ///
    905   struct {
    906     ///
    907     /// See S/W UNDI ROMID structure definition for PCI and
    908     /// PCC BusType definitions.
    909     ///
    910     PXE_UINT32  BusType;
    911 
    912     ///
    913     /// Bus, device & function numbers that locate this device.
    914     ///
    915     PXE_UINT16  Bus;
    916     PXE_UINT8   Device;
    917     PXE_UINT8   Function;
    918   }
    919   PCI, PCC;
    920 
    921 } PXE_DEVICE;
    922 
    923 ///
    924 /// cpb and db definitions
    925 ///
    926 #define MAX_PCI_CONFIG_LEN    64  ///< # of dwords.
    927 #define MAX_EEPROM_LEN        128 ///< # of dwords.
    928 #define MAX_XMIT_BUFFERS      32  ///< recycling Q length for xmit_done.
    929 #define MAX_MCAST_ADDRESS_CNT 8
    930 
    931 typedef struct s_pxe_cpb_start_30 {
    932   ///
    933   /// PXE_VOID Delay(UINTN microseconds);
    934   ///
    935   /// UNDI will never request a delay smaller than 10 microseconds
    936   /// and will always request delays in increments of 10 microseconds.
    937   /// The Delay() CallBack routine must delay between n and n + 10
    938   /// microseconds before returning control to the UNDI.
    939   ///
    940   /// This field cannot be set to zero.
    941   ///
    942   UINT64  Delay;
    943 
    944   ///
    945   /// PXE_VOID Block(UINT32 enable);
    946   ///
    947   /// UNDI may need to block multi-threaded/multi-processor access to
    948   /// critical code sections when programming or accessing the network
    949   /// device.  To this end, a blocking service is needed by the UNDI.
    950   /// When UNDI needs a block, it will call Block() passing a non-zero
    951   /// value.  When UNDI no longer needs a block, it will call Block()
    952   /// with a zero value.  When called, if the Block() is already enabled,
    953   /// do not return control to the UNDI until the previous Block() is
    954   /// disabled.
    955   ///
    956   /// This field cannot be set to zero.
    957   ///
    958   UINT64  Block;
    959 
    960   ///
    961   /// PXE_VOID Virt2Phys(UINT64 virtual, UINT64 physical_ptr);
    962   ///
    963   /// UNDI will pass the virtual address of a buffer and the virtual
    964   /// address of a 64-bit physical buffer.  Convert the virtual address
    965   /// to a physical address and write the result to the physical address
    966   /// buffer.  If virtual and physical addresses are the same, just
    967   /// copy the virtual address to the physical address buffer.
    968   ///
    969   /// This field can be set to zero if virtual and physical addresses
    970   /// are equal.
    971   ///
    972   UINT64  Virt2Phys;
    973   ///
    974   /// PXE_VOID Mem_IO(UINT8 read_write, UINT8 len, UINT64 port,
    975   ///              UINT64 buf_addr);
    976   ///
    977   /// UNDI will read or write the device io space using this call back
    978   /// function. It passes the number of bytes as the len parameter and it
    979   /// will be either 1,2,4 or 8.
    980   ///
    981   /// This field can not be set to zero.
    982   ///
    983   UINT64  Mem_IO;
    984 } PXE_CPB_START_30;
    985 
    986 typedef struct s_pxe_cpb_start_31 {
    987   ///
    988   /// PXE_VOID Delay(UINT64 UnqId, UINTN microseconds);
    989   ///
    990   /// UNDI will never request a delay smaller than 10 microseconds
    991   /// and will always request delays in increments of 10 microseconds.
    992   /// The Delay() CallBack routine must delay between n and n + 10
    993   /// microseconds before returning control to the UNDI.
    994   ///
    995   /// This field cannot be set to zero.
    996   ///
    997   UINT64  Delay;
    998 
    999   ///
   1000   /// PXE_VOID Block(UINT64 unq_id, UINT32 enable);
   1001   ///
   1002   /// UNDI may need to block multi-threaded/multi-processor access to
   1003   /// critical code sections when programming or accessing the network
   1004   /// device.  To this end, a blocking service is needed by the UNDI.
   1005   /// When UNDI needs a block, it will call Block() passing a non-zero
   1006   /// value.  When UNDI no longer needs a block, it will call Block()
   1007   /// with a zero value.  When called, if the Block() is already enabled,
   1008   /// do not return control to the UNDI until the previous Block() is
   1009   /// disabled.
   1010   ///
   1011   /// This field cannot be set to zero.
   1012   ///
   1013   UINT64  Block;
   1014 
   1015   ///
   1016   /// PXE_VOID Virt2Phys(UINT64 UnqId, UINT64 virtual, UINT64 physical_ptr);
   1017   ///
   1018   /// UNDI will pass the virtual address of a buffer and the virtual
   1019   /// address of a 64-bit physical buffer.  Convert the virtual address
   1020   /// to a physical address and write the result to the physical address
   1021   /// buffer.  If virtual and physical addresses are the same, just
   1022   /// copy the virtual address to the physical address buffer.
   1023   ///
   1024   /// This field can be set to zero if virtual and physical addresses
   1025   /// are equal.
   1026   ///
   1027   UINT64  Virt2Phys;
   1028   ///
   1029   /// PXE_VOID Mem_IO(UINT64 UnqId, UINT8 read_write, UINT8 len, UINT64 port,
   1030   ///              UINT64 buf_addr);
   1031   ///
   1032   /// UNDI will read or write the device io space using this call back
   1033   /// function. It passes the number of bytes as the len parameter and it
   1034   /// will be either 1,2,4 or 8.
   1035   ///
   1036   /// This field can not be set to zero.
   1037   ///
   1038   UINT64  Mem_IO;
   1039   ///
   1040   /// PXE_VOID Map_Mem(UINT64 unq_id, UINT64 virtual_addr, UINT32 size,
   1041   ///                 UINT32 Direction, UINT64 mapped_addr);
   1042   ///
   1043   /// UNDI will pass the virtual address of a buffer, direction of the data
   1044   /// flow from/to the mapped buffer (the constants are defined below)
   1045   /// and a place holder (pointer) for the mapped address.
   1046   /// This call will Map the given address to a physical DMA address and write
   1047   /// the result to the mapped_addr pointer.  If there is no need to
   1048   /// map the given address to a lower address (i.e. the given address is
   1049   /// associated with a physical address that is already compatible to be
   1050   /// used with the DMA, it converts the given virtual address to it's
   1051   /// physical address and write that in the mapped address pointer.
   1052   ///
   1053   /// This field can be set to zero if there is no mapping service available.
   1054   ///
   1055   UINT64  Map_Mem;
   1056 
   1057   ///
   1058   /// PXE_VOID UnMap_Mem(UINT64 unq_id, UINT64 virtual_addr, UINT32 size,
   1059   ///            UINT32 Direction, UINT64 mapped_addr);
   1060   ///
   1061   /// UNDI will pass the virtual and mapped addresses of a buffer.
   1062   /// This call will un map the given address.
   1063   ///
   1064   /// This field can be set to zero if there is no unmapping service available.
   1065   ///
   1066   UINT64  UnMap_Mem;
   1067 
   1068   ///
   1069   /// PXE_VOID Sync_Mem(UINT64 unq_id, UINT64 virtual,
   1070   ///            UINT32 size, UINT32 Direction, UINT64 mapped_addr);
   1071   ///
   1072   /// UNDI will pass the virtual and mapped addresses of a buffer.
   1073   /// This call will synchronize the contents of both the virtual and mapped.
   1074   /// buffers for the given Direction.
   1075   ///
   1076   /// This field can be set to zero if there is no service available.
   1077   ///
   1078   UINT64  Sync_Mem;
   1079 
   1080   ///
   1081   /// protocol driver can provide anything for this Unique_ID, UNDI remembers
   1082   /// that as just a 64bit value assocaited to the interface specified by
   1083   /// the ifnum and gives it back as a parameter to all the call-back routines
   1084   /// when calling for that interface!
   1085   ///
   1086   UINT64  Unique_ID;
   1087 } PXE_CPB_START_31;
   1088 
   1089 #define TO_AND_FROM_DEVICE    0
   1090 #define FROM_DEVICE           1
   1091 #define TO_DEVICE             2
   1092 
   1093 #define PXE_DELAY_MILLISECOND 1000
   1094 #define PXE_DELAY_SECOND      1000000
   1095 #define PXE_IO_READ           0
   1096 #define PXE_IO_WRITE          1
   1097 #define PXE_MEM_READ          2
   1098 #define PXE_MEM_WRITE         4
   1099 
   1100 typedef struct s_pxe_db_get_init_info {
   1101   ///
   1102   /// Minimum length of locked memory buffer that must be given to
   1103   /// the Initialize command. Giving UNDI more memory will generally
   1104   /// give better performance.
   1105   ///
   1106   /// If MemoryRequired is zero, the UNDI does not need and will not
   1107   /// use system memory to receive and transmit packets.
   1108   ///
   1109   PXE_UINT32  MemoryRequired;
   1110 
   1111   ///
   1112   /// Maximum frame data length for Tx/Rx excluding the media header.
   1113   ///
   1114   PXE_UINT32  FrameDataLen;
   1115 
   1116   ///
   1117   /// Supported link speeds are in units of mega bits.  Common ethernet
   1118   /// values are 10, 100 and 1000.  Unused LinkSpeeds[] entries are zero
   1119   /// filled.
   1120   ///
   1121   PXE_UINT32  LinkSpeeds[4];
   1122 
   1123   ///
   1124   /// Number of non-volatile storage items.
   1125   ///
   1126   PXE_UINT32  NvCount;
   1127 
   1128   ///
   1129   /// Width of non-volatile storage item in bytes.  0, 1, 2 or 4
   1130   ///
   1131   PXE_UINT16  NvWidth;
   1132 
   1133   ///
   1134   /// Media header length.  This is the typical media header length for
   1135   /// this UNDI.  This information is needed when allocating receive
   1136   /// and transmit buffers.
   1137   ///
   1138   PXE_UINT16  MediaHeaderLen;
   1139 
   1140   ///
   1141   /// Number of bytes in the NIC hardware (MAC) address.
   1142   ///
   1143   PXE_UINT16  HWaddrLen;
   1144 
   1145   ///
   1146   /// Maximum number of multicast MAC addresses in the multicast
   1147   /// MAC address filter list.
   1148   ///
   1149   PXE_UINT16  MCastFilterCnt;
   1150 
   1151   ///
   1152   /// Default number and size of transmit and receive buffers that will
   1153   /// be allocated by the UNDI.  If MemoryRequired is non-zero, this
   1154   /// allocation will come out of the memory buffer given to the Initialize
   1155   /// command.  If MemoryRequired is zero, this allocation will come out of
   1156   /// memory on the NIC.
   1157   ///
   1158   PXE_UINT16  TxBufCnt;
   1159   PXE_UINT16  TxBufSize;
   1160   PXE_UINT16  RxBufCnt;
   1161   PXE_UINT16  RxBufSize;
   1162 
   1163   ///
   1164   /// Hardware interface types defined in the Assigned Numbers RFC
   1165   /// and used in DHCP and ARP packets.
   1166   /// See the PXE_IFTYPE typedef and PXE_IFTYPE_xxx macros.
   1167   ///
   1168   PXE_UINT8   IFtype;
   1169 
   1170   ///
   1171   /// Supported duplex.  See PXE_DUPLEX_xxxxx #defines below.
   1172   ///
   1173   PXE_UINT8   SupportedDuplexModes;
   1174 
   1175   ///
   1176   /// Supported loopback options.  See PXE_LOOPBACK_xxxxx #defines below.
   1177   ///
   1178   PXE_UINT8   SupportedLoopBackModes;
   1179 } PXE_DB_GET_INIT_INFO;
   1180 
   1181 #define PXE_MAX_TXRX_UNIT_ETHER           1500
   1182 
   1183 #define PXE_HWADDR_LEN_ETHER              0x0006
   1184 #define PXE_MAC_HEADER_LEN_ETHER          0x000E
   1185 
   1186 #define PXE_DUPLEX_ENABLE_FULL_SUPPORTED  1
   1187 #define PXE_DUPLEX_FORCE_FULL_SUPPORTED   2
   1188 
   1189 #define PXE_LOOPBACK_INTERNAL_SUPPORTED   1
   1190 #define PXE_LOOPBACK_EXTERNAL_SUPPORTED   2
   1191 
   1192 typedef struct s_pxe_pci_config_info {
   1193   ///
   1194   /// This is the flag field for the PXE_DB_GET_CONFIG_INFO union.
   1195   /// For PCI bus devices, this field is set to PXE_BUSTYPE_PCI.
   1196   ///
   1197   UINT32  BusType;
   1198 
   1199   ///
   1200   /// This identifies the PCI network device that this UNDI interface.
   1201   /// is bound to.
   1202   ///
   1203   UINT16  Bus;
   1204   UINT8   Device;
   1205   UINT8   Function;
   1206 
   1207   ///
   1208   /// This is a copy of the PCI configuration space for this
   1209   /// network device.
   1210   ///
   1211   union {
   1212     UINT8   Byte[256];
   1213     UINT16  Word[128];
   1214     UINT32  Dword[64];
   1215   } Config;
   1216 } PXE_PCI_CONFIG_INFO;
   1217 
   1218 typedef struct s_pxe_pcc_config_info {
   1219   ///
   1220   /// This is the flag field for the PXE_DB_GET_CONFIG_INFO union.
   1221   /// For PCC bus devices, this field is set to PXE_BUSTYPE_PCC.
   1222   ///
   1223   PXE_UINT32  BusType;
   1224 
   1225   ///
   1226   /// This identifies the PCC network device that this UNDI interface
   1227   /// is bound to.
   1228   ///
   1229   PXE_UINT16  Bus;
   1230   PXE_UINT8   Device;
   1231   PXE_UINT8   Function;
   1232 
   1233   ///
   1234   /// This is a copy of the PCC configuration space for this
   1235   /// network device.
   1236   ///
   1237   union {
   1238     PXE_UINT8   Byte[256];
   1239     PXE_UINT16  Word[128];
   1240     PXE_UINT32  Dword[64];
   1241   } Config;
   1242 } PXE_PCC_CONFIG_INFO;
   1243 
   1244 typedef union u_pxe_db_get_config_info {
   1245   PXE_PCI_CONFIG_INFO   pci;
   1246   PXE_PCC_CONFIG_INFO   pcc;
   1247 } PXE_DB_GET_CONFIG_INFO;
   1248 
   1249 typedef struct s_pxe_cpb_initialize {
   1250   ///
   1251   /// Address of first (lowest) byte of the memory buffer.  This buffer must
   1252   /// be in contiguous physical memory and cannot be swapped out.  The UNDI
   1253   /// will be using this for transmit and receive buffering.
   1254   ///
   1255   PXE_UINT64  MemoryAddr;
   1256 
   1257   ///
   1258   /// MemoryLength must be greater than or equal to MemoryRequired
   1259   /// returned by the Get Init Info command.
   1260   ///
   1261   PXE_UINT32  MemoryLength;
   1262 
   1263   ///
   1264   /// Desired link speed in Mbit/sec.  Common ethernet values are 10, 100
   1265   /// and 1000.  Setting a value of zero will auto-detect and/or use the
   1266   /// default link speed (operation depends on UNDI/NIC functionality).
   1267   ///
   1268   PXE_UINT32  LinkSpeed;
   1269 
   1270   ///
   1271   /// Suggested number and size of receive and transmit buffers to
   1272   /// allocate.  If MemoryAddr and MemoryLength are non-zero, this
   1273   /// allocation comes out of the supplied memory buffer.  If MemoryAddr
   1274   /// and MemoryLength are zero, this allocation comes out of memory
   1275   /// on the NIC.
   1276   ///
   1277   /// If these fields are set to zero, the UNDI will allocate buffer
   1278   /// counts and sizes as it sees fit.
   1279   ///
   1280   PXE_UINT16  TxBufCnt;
   1281   PXE_UINT16  TxBufSize;
   1282   PXE_UINT16  RxBufCnt;
   1283   PXE_UINT16  RxBufSize;
   1284 
   1285   ///
   1286   /// The following configuration parameters are optional and must be zero
   1287   /// to use the default values.
   1288   ///
   1289   PXE_UINT8   DuplexMode;
   1290 
   1291   PXE_UINT8   LoopBackMode;
   1292 } PXE_CPB_INITIALIZE;
   1293 
   1294 #define PXE_DUPLEX_DEFAULT      0x00
   1295 #define PXE_FORCE_FULL_DUPLEX   0x01
   1296 #define PXE_ENABLE_FULL_DUPLEX  0x02
   1297 #define PXE_FORCE_HALF_DUPLEX   0x04
   1298 #define PXE_DISABLE_FULL_DUPLEX 0x08
   1299 
   1300 #define LOOPBACK_NORMAL         0
   1301 #define LOOPBACK_INTERNAL       1
   1302 #define LOOPBACK_EXTERNAL       2
   1303 
   1304 typedef struct s_pxe_db_initialize {
   1305   ///
   1306   /// Actual amount of memory used from the supplied memory buffer.  This
   1307   /// may be less that the amount of memory suppllied and may be zero if
   1308   /// the UNDI and network device do not use external memory buffers.
   1309   ///
   1310   /// Memory used by the UNDI and network device is allocated from the
   1311   /// lowest memory buffer address.
   1312   ///
   1313   PXE_UINT32  MemoryUsed;
   1314 
   1315   ///
   1316   /// Actual number and size of receive and transmit buffers that were
   1317   /// allocated.
   1318   ///
   1319   PXE_UINT16  TxBufCnt;
   1320   PXE_UINT16  TxBufSize;
   1321   PXE_UINT16  RxBufCnt;
   1322   PXE_UINT16  RxBufSize;
   1323 } PXE_DB_INITIALIZE;
   1324 
   1325 typedef struct s_pxe_cpb_receive_filters {
   1326   ///
   1327   /// List of multicast MAC addresses.  This list, if present, will
   1328   /// replace the existing multicast MAC address filter list.
   1329   ///
   1330   PXE_MAC_ADDR  MCastList[MAX_MCAST_ADDRESS_CNT];
   1331 } PXE_CPB_RECEIVE_FILTERS;
   1332 
   1333 typedef struct s_pxe_db_receive_filters {
   1334   ///
   1335   /// Filtered multicast MAC address list.
   1336   ///
   1337   PXE_MAC_ADDR  MCastList[MAX_MCAST_ADDRESS_CNT];
   1338 } PXE_DB_RECEIVE_FILTERS;
   1339 
   1340 typedef struct s_pxe_cpb_station_address {
   1341   ///
   1342   /// If supplied and supported, the current station MAC address
   1343   /// will be changed.
   1344   ///
   1345   PXE_MAC_ADDR  StationAddr;
   1346 } PXE_CPB_STATION_ADDRESS;
   1347 
   1348 typedef struct s_pxe_dpb_station_address {
   1349   ///
   1350   /// Current station MAC address.
   1351   ///
   1352   PXE_MAC_ADDR  StationAddr;
   1353 
   1354   ///
   1355   /// Station broadcast MAC address.
   1356   ///
   1357   PXE_MAC_ADDR  BroadcastAddr;
   1358 
   1359   ///
   1360   /// Permanent station MAC address.
   1361   ///
   1362   PXE_MAC_ADDR  PermanentAddr;
   1363 } PXE_DB_STATION_ADDRESS;
   1364 
   1365 typedef struct s_pxe_db_statistics {
   1366   ///
   1367   /// Bit field identifying what statistic data is collected by the
   1368   /// UNDI/NIC.
   1369   /// If bit 0x00 is set, Data[0x00] is collected.
   1370   /// If bit 0x01 is set, Data[0x01] is collected.
   1371   /// If bit 0x20 is set, Data[0x20] is collected.
   1372   /// If bit 0x21 is set, Data[0x21] is collected.
   1373   /// Etc.
   1374   ///
   1375   PXE_UINT64  Supported;
   1376 
   1377   ///
   1378   /// Statistic data.
   1379   ///
   1380   PXE_UINT64  Data[64];
   1381 } PXE_DB_STATISTICS;
   1382 
   1383 ///
   1384 /// Total number of frames received.  Includes frames with errors and
   1385 /// dropped frames.
   1386 ///
   1387 #define PXE_STATISTICS_RX_TOTAL_FRAMES  0x00
   1388 
   1389 ///
   1390 /// Number of valid frames received and copied into receive buffers.
   1391 ///
   1392 #define PXE_STATISTICS_RX_GOOD_FRAMES 0x01
   1393 
   1394 ///
   1395 /// Number of frames below the minimum length for the media.
   1396 /// This would be <64 for ethernet.
   1397 ///
   1398 #define PXE_STATISTICS_RX_UNDERSIZE_FRAMES  0x02
   1399 
   1400 ///
   1401 /// Number of frames longer than the maxminum length for the
   1402 /// media.  This would be >1500 for ethernet.
   1403 ///
   1404 #define PXE_STATISTICS_RX_OVERSIZE_FRAMES 0x03
   1405 
   1406 ///
   1407 /// Valid frames that were dropped because receive buffers were full.
   1408 ///
   1409 #define PXE_STATISTICS_RX_DROPPED_FRAMES  0x04
   1410 
   1411 ///
   1412 /// Number of valid unicast frames received and not dropped.
   1413 ///
   1414 #define PXE_STATISTICS_RX_UNICAST_FRAMES  0x05
   1415 
   1416 ///
   1417 /// Number of valid broadcast frames received and not dropped.
   1418 ///
   1419 #define PXE_STATISTICS_RX_BROADCAST_FRAMES  0x06
   1420 
   1421 ///
   1422 /// Number of valid mutlicast frames received and not dropped.
   1423 ///
   1424 #define PXE_STATISTICS_RX_MULTICAST_FRAMES  0x07
   1425 
   1426 ///
   1427 /// Number of frames w/ CRC or alignment errors.
   1428 ///
   1429 #define PXE_STATISTICS_RX_CRC_ERROR_FRAMES  0x08
   1430 
   1431 ///
   1432 /// Total number of bytes received.  Includes frames with errors
   1433 /// and dropped frames.
   1434 ///
   1435 #define PXE_STATISTICS_RX_TOTAL_BYTES 0x09
   1436 
   1437 ///
   1438 /// Transmit statistics.
   1439 ///
   1440 #define PXE_STATISTICS_TX_TOTAL_FRAMES      0x0A
   1441 #define PXE_STATISTICS_TX_GOOD_FRAMES       0x0B
   1442 #define PXE_STATISTICS_TX_UNDERSIZE_FRAMES  0x0C
   1443 #define PXE_STATISTICS_TX_OVERSIZE_FRAMES   0x0D
   1444 #define PXE_STATISTICS_TX_DROPPED_FRAMES    0x0E
   1445 #define PXE_STATISTICS_TX_UNICAST_FRAMES    0x0F
   1446 #define PXE_STATISTICS_TX_BROADCAST_FRAMES  0x10
   1447 #define PXE_STATISTICS_TX_MULTICAST_FRAMES  0x11
   1448 #define PXE_STATISTICS_TX_CRC_ERROR_FRAMES  0x12
   1449 #define PXE_STATISTICS_TX_TOTAL_BYTES       0x13
   1450 
   1451 ///
   1452 /// Number of collisions detection on this subnet.
   1453 ///
   1454 #define PXE_STATISTICS_COLLISIONS 0x14
   1455 
   1456 ///
   1457 /// Number of frames destined for unsupported protocol.
   1458 ///
   1459 #define PXE_STATISTICS_UNSUPPORTED_PROTOCOL 0x15
   1460 
   1461 typedef struct s_pxe_cpb_mcast_ip_to_mac {
   1462   ///
   1463   /// Multicast IP address to be converted to multicast MAC address.
   1464   ///
   1465   PXE_IP_ADDR IP;
   1466 } PXE_CPB_MCAST_IP_TO_MAC;
   1467 
   1468 typedef struct s_pxe_db_mcast_ip_to_mac {
   1469   ///
   1470   /// Multicast MAC address.
   1471   ///
   1472   PXE_MAC_ADDR  MAC;
   1473 } PXE_DB_MCAST_IP_TO_MAC;
   1474 
   1475 typedef struct s_pxe_cpb_nvdata_sparse {
   1476   ///
   1477   /// NvData item list.  Only items in this list will be updated.
   1478   ///
   1479   struct {
   1480     ///
   1481     ///  Non-volatile storage address to be changed.
   1482     ///
   1483     PXE_UINT32  Addr;
   1484 
   1485     ///
   1486     /// Data item to write into above storage address.
   1487     ///
   1488     union {
   1489       PXE_UINT8   Byte;
   1490       PXE_UINT16  Word;
   1491       PXE_UINT32  Dword;
   1492     } Data;
   1493   } Item[MAX_EEPROM_LEN];
   1494 } PXE_CPB_NVDATA_SPARSE;
   1495 
   1496 ///
   1497 /// When using bulk update, the size of the CPB structure must be
   1498 /// the same size as the non-volatile NIC storage.
   1499 ///
   1500 typedef union u_pxe_cpb_nvdata_bulk {
   1501   ///
   1502   /// Array of byte-wide data items.
   1503   ///
   1504   PXE_UINT8   Byte[MAX_EEPROM_LEN << 2];
   1505 
   1506   ///
   1507   /// Array of word-wide data items.
   1508   ///
   1509   PXE_UINT16  Word[MAX_EEPROM_LEN << 1];
   1510 
   1511   ///
   1512   /// Array of dword-wide data items.
   1513   ///
   1514   PXE_UINT32  Dword[MAX_EEPROM_LEN];
   1515 } PXE_CPB_NVDATA_BULK;
   1516 
   1517 typedef struct s_pxe_db_nvdata {
   1518   ///
   1519   /// Arrays of data items from non-volatile storage.
   1520   ///
   1521   union {
   1522     ///
   1523     /// Array of byte-wide data items.
   1524     ///
   1525     PXE_UINT8   Byte[MAX_EEPROM_LEN << 2];
   1526 
   1527     ///
   1528     /// Array of word-wide data items.
   1529     ///
   1530     PXE_UINT16  Word[MAX_EEPROM_LEN << 1];
   1531 
   1532     ///
   1533     /// Array of dword-wide data items.
   1534     ///
   1535     PXE_UINT32  Dword[MAX_EEPROM_LEN];
   1536   } Data;
   1537 } PXE_DB_NVDATA;
   1538 
   1539 typedef struct s_pxe_db_get_status {
   1540   ///
   1541   /// Length of next receive frame (header + data).  If this is zero,
   1542   /// there is no next receive frame available.
   1543   ///
   1544   PXE_UINT32  RxFrameLen;
   1545 
   1546   ///
   1547   /// Reserved, set to zero.
   1548   ///
   1549   PXE_UINT32  reserved;
   1550 
   1551   ///
   1552   ///  Addresses of transmitted buffers that need to be recycled.
   1553   ///
   1554   PXE_UINT64  TxBuffer[MAX_XMIT_BUFFERS];
   1555 } PXE_DB_GET_STATUS;
   1556 
   1557 typedef struct s_pxe_cpb_fill_header {
   1558   ///
   1559   /// Source and destination MAC addresses.  These will be copied into
   1560   /// the media header without doing byte swapping.
   1561   ///
   1562   PXE_MAC_ADDR  SrcAddr;
   1563   PXE_MAC_ADDR  DestAddr;
   1564 
   1565   ///
   1566   /// Address of first byte of media header.  The first byte of packet data
   1567   /// follows the last byte of the media header.
   1568   ///
   1569   PXE_UINT64        MediaHeader;
   1570 
   1571   ///
   1572   /// Length of packet data in bytes (not including the media header).
   1573   ///
   1574   PXE_UINT32        PacketLen;
   1575 
   1576   ///
   1577   /// Protocol type.  This will be copied into the media header without
   1578   /// doing byte swapping.  Protocol type numbers can be obtained from
   1579   /// the Assigned Numbers RFC 1700.
   1580   ///
   1581   PXE_UINT16        Protocol;
   1582 
   1583   ///
   1584   /// Length of the media header in bytes.
   1585   ///
   1586   PXE_UINT16        MediaHeaderLen;
   1587 } PXE_CPB_FILL_HEADER;
   1588 
   1589 #define PXE_PROTOCOL_ETHERNET_IP  0x0800
   1590 #define PXE_PROTOCOL_ETHERNET_ARP 0x0806
   1591 #define MAX_XMIT_FRAGMENTS        16
   1592 
   1593 typedef struct s_pxe_cpb_fill_header_fragmented {
   1594   ///
   1595   /// Source and destination MAC addresses.  These will be copied into
   1596   /// the media header without doing byte swapping.
   1597   ///
   1598   PXE_MAC_ADDR        SrcAddr;
   1599   PXE_MAC_ADDR        DestAddr;
   1600 
   1601   ///
   1602   /// Length of packet data in bytes (not including the media header).
   1603   ///
   1604   PXE_UINT32          PacketLen;
   1605 
   1606   ///
   1607   /// Protocol type.  This will be copied into the media header without
   1608   /// doing byte swapping.  Protocol type numbers can be obtained from
   1609   /// the Assigned Numbers RFC 1700.
   1610   ///
   1611   PXE_MEDIA_PROTOCOL  Protocol;
   1612 
   1613   ///
   1614   /// Length of the media header in bytes.
   1615   ///
   1616   PXE_UINT16          MediaHeaderLen;
   1617 
   1618   ///
   1619   /// Number of packet fragment descriptors.
   1620   ///
   1621   PXE_UINT16          FragCnt;
   1622 
   1623   ///
   1624   /// Reserved, must be set to zero.
   1625   ///
   1626   PXE_UINT16          reserved;
   1627 
   1628   ///
   1629   /// Array of packet fragment descriptors.  The first byte of the media
   1630   /// header is the first byte of the first fragment.
   1631   ///
   1632   struct {
   1633     ///
   1634     /// Address of this packet fragment.
   1635     ///
   1636     PXE_UINT64  FragAddr;
   1637 
   1638     ///
   1639     /// Length of this packet fragment.
   1640     ///
   1641     PXE_UINT32  FragLen;
   1642 
   1643     ///
   1644     /// Reserved, must be set to zero.
   1645     ///
   1646     PXE_UINT32  reserved;
   1647   } FragDesc[MAX_XMIT_FRAGMENTS];
   1648 }
   1649 PXE_CPB_FILL_HEADER_FRAGMENTED;
   1650 
   1651 typedef struct s_pxe_cpb_transmit {
   1652   ///
   1653   /// Address of first byte of frame buffer.  This is also the first byte
   1654   /// of the media header.
   1655   ///
   1656   PXE_UINT64  FrameAddr;
   1657 
   1658   ///
   1659   /// Length of the data portion of the frame buffer in bytes.  Do not
   1660   /// include the length of the media header.
   1661   ///
   1662   PXE_UINT32  DataLen;
   1663 
   1664   ///
   1665   /// Length of the media header in bytes.
   1666   ///
   1667   PXE_UINT16  MediaheaderLen;
   1668 
   1669   ///
   1670   /// Reserved, must be zero.
   1671   ///
   1672   PXE_UINT16  reserved;
   1673 } PXE_CPB_TRANSMIT;
   1674 
   1675 typedef struct s_pxe_cpb_transmit_fragments {
   1676   ///
   1677   /// Length of packet data in bytes (not including the media header).
   1678   ///
   1679   PXE_UINT32  FrameLen;
   1680 
   1681   ///
   1682   /// Length of the media header in bytes.
   1683   ///
   1684   PXE_UINT16  MediaheaderLen;
   1685 
   1686   ///
   1687   /// Number of packet fragment descriptors.
   1688   ///
   1689   PXE_UINT16  FragCnt;
   1690 
   1691   ///
   1692   /// Array of frame fragment descriptors.  The first byte of the first
   1693   /// fragment is also the first byte of the media header.
   1694   ///
   1695   struct {
   1696     ///
   1697     /// Address of this frame fragment.
   1698     ///
   1699     PXE_UINT64  FragAddr;
   1700 
   1701     ///
   1702     /// Length of this frame fragment.
   1703     ///
   1704     PXE_UINT32  FragLen;
   1705 
   1706     ///
   1707     /// Reserved, must be set to zero.
   1708     ///
   1709     PXE_UINT32  reserved;
   1710   } FragDesc[MAX_XMIT_FRAGMENTS];
   1711 }
   1712 PXE_CPB_TRANSMIT_FRAGMENTS;
   1713 
   1714 typedef struct s_pxe_cpb_receive {
   1715   ///
   1716   /// Address of first byte of receive buffer.  This is also the first byte
   1717   /// of the frame header.
   1718   ///
   1719   PXE_UINT64  BufferAddr;
   1720 
   1721   ///
   1722   /// Length of receive buffer.  This must be large enough to hold the
   1723   /// received frame (media header + data).  If the length of smaller than
   1724   /// the received frame, data will be lost.
   1725   ///
   1726   PXE_UINT32  BufferLen;
   1727 
   1728   ///
   1729   /// Reserved, must be set to zero.
   1730   ///
   1731   PXE_UINT32  reserved;
   1732 } PXE_CPB_RECEIVE;
   1733 
   1734 typedef struct s_pxe_db_receive {
   1735   ///
   1736   /// Source and destination MAC addresses from media header.
   1737   ///
   1738   PXE_MAC_ADDR        SrcAddr;
   1739   PXE_MAC_ADDR        DestAddr;
   1740 
   1741   ///
   1742   /// Length of received frame.  May be larger than receive buffer size.
   1743   /// The receive buffer will not be overwritten.  This is how to tell
   1744   /// if data was lost because the receive buffer was too small.
   1745   ///
   1746   PXE_UINT32          FrameLen;
   1747 
   1748   ///
   1749   /// Protocol type from media header.
   1750   ///
   1751   PXE_MEDIA_PROTOCOL  Protocol;
   1752 
   1753   ///
   1754   /// Length of media header in received frame.
   1755   ///
   1756   PXE_UINT16          MediaHeaderLen;
   1757 
   1758   ///
   1759   /// Type of receive frame.
   1760   ///
   1761   PXE_FRAME_TYPE      Type;
   1762 
   1763   ///
   1764   /// Reserved, must be zero.
   1765   ///
   1766   PXE_UINT8           reserved[7];
   1767 
   1768 } PXE_DB_RECEIVE;
   1769 
   1770 #pragma pack()
   1771 
   1772 #endif
   1773