Home | History | Annotate | Download | only in SnpNt32Dxe
      1 /** @file
      2 
      3 Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
      4 This program and the accompanying materials
      5 are licensed and made available under the terms and conditions of the BSD License
      6 which accompanies this distribution.  The full text of the license may be found at
      7 http://opensource.org/licenses/bsd-license.php
      8 
      9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     11 
     12 Module Name:
     13 
     14   SnpNt32.c
     15 
     16 Abstract:
     17 
     18 -**/
     19 
     20 #include "SnpNt32.h"
     21 
     22 EFI_DRIVER_BINDING_PROTOCOL gSnpNt32DriverBinding = {
     23   SnpNt32DriverBindingSupported,
     24   SnpNt32DriverBindingStart,
     25   SnpNt32DriverBindingStop,
     26   0xa,
     27   NULL,
     28   NULL
     29 };
     30 
     31 SNPNT32_GLOBAL_DATA         gSnpNt32GlobalData = {
     32   SNP_NT32_DRIVER_SIGNATURE,  //  Signature
     33   {
     34     NULL,
     35     NULL
     36   },                          //  InstanceList
     37   NULL,                       //  WinNtThunk
     38   NULL,                       //  NetworkLibraryHandle
     39   {
     40     0
     41   },                          //  NtNetUtilityTable
     42   {
     43     0,
     44     0,
     45     EfiLockUninitialized
     46   },                          //  Lock
     47   //
     48   //  Private functions
     49   //
     50   SnpNt32InitializeGlobalData,            //  InitializeGlobalData
     51   SnpNt32InitializeInstanceData,          //  InitializeInstanceData
     52   SnpNt32CloseInstance                    //  CloseInstance
     53 };
     54 
     55 /**
     56   Changes the state of a network interface from "stopped" to "started".
     57 
     58   @param  This Protocol instance pointer.
     59 
     60   @retval EFI_SUCCESS           Always succeeds.
     61 
     62 **/
     63 EFI_STATUS
     64 EFIAPI
     65 SnpNt32Start (
     66   IN EFI_SIMPLE_NETWORK_PROTOCOL *This
     67   );
     68 
     69 /**
     70   Changes the state of a network interface from "started" to "stopped".
     71 
     72   @param  This Protocol instance pointer.
     73 
     74   @retval EFI_SUCCESS           Always succeeds.
     75 
     76 **/
     77 EFI_STATUS
     78 EFIAPI
     79 SnpNt32Stop (
     80   IN EFI_SIMPLE_NETWORK_PROTOCOL *This
     81   );
     82 
     83 /**
     84   Resets a network adapter and allocates the transmit and receive buffers
     85   required by the network interface; optionally, also requests allocation
     86   of additional transmit and receive buffers.
     87 
     88   @param  This              Protocol instance pointer.
     89   @param  ExtraRxBufferSize The size, in bytes, of the extra receive buffer space
     90                             that the driver should allocate for the network interface.
     91                             Some network interfaces will not be able to use the extra
     92                             buffer, and the caller will not know if it is actually
     93                             being used.
     94   @param  ExtraTxBufferSize The size, in bytes, of the extra transmit buffer space
     95                             that the driver should allocate for the network interface.
     96                             Some network interfaces will not be able to use the extra
     97                             buffer, and the caller will not know if it is actually
     98                             being used.
     99 
    100   @retval EFI_SUCCESS           Always succeeds.
    101 
    102 **/
    103 EFI_STATUS
    104 EFIAPI
    105 SnpNt32Initialize (
    106   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
    107   IN UINTN                       ExtraRxBufferSize OPTIONAL,
    108   IN UINTN                       ExtraTxBufferSize OPTIONAL
    109   );
    110 
    111 /**
    112   Resets a network adapter and re-initializes it with the parameters that were
    113   provided in the previous call to Initialize().
    114 
    115   @param  This                 Protocol instance pointer.
    116   @param  ExtendedVerification Indicates that the driver may perform a more
    117                                exhaustive verification operation of the device
    118                                during reset.
    119 
    120   @retval EFI_SUCCESS           Always succeeds.
    121 
    122 **/
    123 EFI_STATUS
    124 EFIAPI
    125 SnpNt32Reset (
    126   IN EFI_SIMPLE_NETWORK_PROTOCOL  *This,
    127   IN BOOLEAN                      ExtendedVerification
    128   );
    129 
    130 /**
    131   Resets a network adapter and leaves it in a state that is safe for
    132   another driver to initialize.
    133 
    134   @param  This Protocol instance pointer.
    135 
    136   @retval EFI_SUCCESS           Always succeeds.
    137 
    138 **/
    139 EFI_STATUS
    140 EFIAPI
    141 SnpNt32Shutdown (
    142   IN EFI_SIMPLE_NETWORK_PROTOCOL *This
    143   );
    144 
    145 /**
    146   Manages the multicast receive filters of a network interface.
    147 
    148   @param  This               Protocol instance pointer.
    149   @param  EnableBits         A bit mask of receive filters to enable on the network interface.
    150   @param  DisableBits        A bit mask of receive filters to disable on the network interface.
    151   @param  ResetMcastFilter   Set to TRUE to reset the contents of the multicast receive
    152                              filters on the network interface to their default values.
    153   @param  McastFilterCount   Number of multicast HW MAC addresses in the new
    154                              MCastFilter list. This value must be less than or equal to
    155                              the MCastFilterCnt field of EFI_SIMPLE_NETWORK_MODE. This
    156                              field is optional if ResetMCastFilter is TRUE.
    157   @param  McastFilter        A pointer to a list of new multicast receive filter HW MAC
    158                              addresses. This list will replace any existing multicast
    159                              HW MAC address list. This field is optional if
    160                              ResetMCastFilter is TRUE.
    161 
    162   @retval EFI_SUCCESS           The multicast receive filter list was updated.
    163   @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
    164 
    165 **/
    166 EFI_STATUS
    167 EFIAPI
    168 SnpNt32ReceiveFilters (
    169   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
    170   IN UINT32                      EnableBits,
    171   IN UINT32                      DisableBits,
    172   IN BOOLEAN                     ResetMcastFilter,
    173   IN UINTN                       McastFilterCount OPTIONAL,
    174   IN EFI_MAC_ADDRESS             *McastFilter     OPTIONAL
    175   );
    176 
    177 /**
    178   Modifies or resets the current station address, if supported.
    179 
    180   @param  This         Protocol instance pointer.
    181   @param  Reset        Flag used to reset the station address to the network interfaces
    182                        permanent address.
    183   @param  NewMacAddr   New station address to be used for the network interface.
    184 
    185   @retval EFI_UNSUPPORTED       Not supported yet.
    186 
    187 **/
    188 EFI_STATUS
    189 EFIAPI
    190 SnpNt32StationAddress (
    191   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
    192   IN BOOLEAN                     Reset,
    193   IN EFI_MAC_ADDRESS             *NewMacAddr OPTIONAL
    194   );
    195 
    196 /**
    197   Resets or collects the statistics on a network interface.
    198 
    199   @param  This            Protocol instance pointer.
    200   @param  Reset           Set to TRUE to reset the statistics for the network interface.
    201   @param  StatisticsSize  On input the size, in bytes, of StatisticsTable. On
    202                           output the size, in bytes, of the resulting table of
    203                           statistics.
    204   @param  StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
    205                           contains the statistics.
    206 
    207   @retval EFI_SUCCESS           The statistics were collected from the network interface.
    208   @retval EFI_NOT_STARTED       The network interface has not been started.
    209   @retval EFI_BUFFER_TOO_SMALL  The Statistics buffer was too small. The current buffer
    210                                 size needed to hold the statistics is returned in
    211                                 StatisticsSize.
    212   @retval EFI_UNSUPPORTED       Not supported yet.
    213 
    214 **/
    215 EFI_STATUS
    216 EFIAPI
    217 SnpNt32Statistics (
    218   IN EFI_SIMPLE_NETWORK_PROTOCOL  * This,
    219   IN BOOLEAN                      Reset,
    220   IN OUT UINTN                    *StatisticsSize OPTIONAL,
    221   OUT EFI_NETWORK_STATISTICS      *StatisticsTable OPTIONAL
    222   );
    223 
    224 /**
    225   Converts a multicast IP address to a multicast HW MAC address.
    226 
    227   @param  This  Protocol instance pointer.
    228   @param  Ipv6  Set to TRUE if the multicast IP address is IPv6 [RFC 2460]. Set
    229                 to FALSE if the multicast IP address is IPv4 [RFC 791].
    230   @param  Ip    The multicast IP address that is to be converted to a multicast
    231                 HW MAC address.
    232   @param  Mac   The multicast HW MAC address that is to be generated from IP.
    233 
    234   @retval EFI_SUCCESS           The multicast IP address was mapped to the multicast
    235                                 HW MAC address.
    236   @retval EFI_NOT_STARTED       The network interface has not been started.
    237   @retval EFI_BUFFER_TOO_SMALL  The Statistics buffer was too small. The current buffer
    238                                 size needed to hold the statistics is returned in
    239                                 StatisticsSize.
    240   @retval EFI_UNSUPPORTED       Not supported yet.
    241 
    242 **/
    243 EFI_STATUS
    244 EFIAPI
    245 SnpNt32McastIptoMac (
    246   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
    247   IN BOOLEAN                     Ipv6,
    248   IN EFI_IP_ADDRESS              *Ip,
    249   OUT EFI_MAC_ADDRESS            *Mac
    250   );
    251 
    252 /**
    253   Performs read and write operations on the NVRAM device attached to a
    254   network interface.
    255 
    256   @param  This         Protocol instance pointer.
    257   @param  ReadOrWrite  TRUE for read operations, FALSE for write operations.
    258   @param  Offset       Byte offset in the NVRAM device at which to start the read or
    259                        write operation. This must be a multiple of NvRamAccessSize and
    260                        less than NvRamSize.
    261   @param  BufferSize   The number of bytes to read or write from the NVRAM device.
    262                        This must also be a multiple of NvramAccessSize.
    263   @param  Buffer       A pointer to the data buffer.
    264 
    265   @retval EFI_UNSUPPORTED       Not supported yet.
    266 
    267 **/
    268 EFI_STATUS
    269 EFIAPI
    270 SnpNt32Nvdata (
    271   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
    272   IN BOOLEAN                     ReadOrWrite,
    273   IN UINTN                       Offset,
    274   IN UINTN                       BufferSize,
    275   IN OUT VOID                    *Buffer
    276   );
    277 
    278 /**
    279   Reads the current interrupt status and recycled transmit buffer status from
    280   a network interface.
    281 
    282   @param  This            Protocol instance pointer.
    283   @param  InterruptStatus A pointer to the bit mask of the currently active interrupts
    284                           If this is NULL, the interrupt status will not be read from
    285                           the device. If this is not NULL, the interrupt status will
    286                           be read from the device. When the  interrupt status is read,
    287                           it will also be cleared. Clearing the transmit  interrupt
    288                           does not empty the recycled transmit buffer array.
    289   @param  TxBuffer        Recycled transmit buffer address. The network interface will
    290                           not transmit if its internal recycled transmit buffer array
    291                           is full. Reading the transmit buffer does not clear the
    292                           transmit interrupt. If this is NULL, then the transmit buffer
    293                           status will not be read. If there are no transmit buffers to
    294                           recycle and TxBuf is not NULL, * TxBuf will be set to NULL.
    295 
    296   @retval EFI_SUCCESS           Always succeeds.
    297 
    298 **/
    299 EFI_STATUS
    300 EFIAPI
    301 SnpNt32GetStatus (
    302   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
    303   OUT UINT32                     *InterruptStatus,
    304   OUT VOID                       **TxBuffer
    305   );
    306 
    307 /**
    308   Places a packet in the transmit queue of a network interface.
    309 
    310   @param  This       Protocol instance pointer.
    311   @param  HeaderSize The size, in bytes, of the media header to be filled in by
    312                      the Transmit() function. If HeaderSize is non-zero, then it
    313                      must be equal to This->Mode->MediaHeaderSize and the DestAddr
    314                      and Protocol parameters must not be NULL.
    315   @param  BufferSize The size, in bytes, of the entire packet (media header and
    316                      data) to be transmitted through the network interface.
    317   @param  Buffer     A pointer to the packet (media header followed by data) to be
    318                      transmitted. This parameter cannot be NULL. If HeaderSize is zero,
    319                      then the media header in Buffer must already be filled in by the
    320                      caller. If HeaderSize is non-zero, then the media header will be
    321                      filled in by the Transmit() function.
    322   @param  SrcAddr    The source HW MAC address. If HeaderSize is zero, then this parameter
    323                      is ignored. If HeaderSize is non-zero and SrcAddr is NULL, then
    324                      This->Mode->CurrentAddress is used for the source HW MAC address.
    325   @param  DestAddr   The destination HW MAC address. If HeaderSize is zero, then this
    326                      parameter is ignored.
    327   @param  Protocol   The type of header to build. If HeaderSize is zero, then this
    328                      parameter is ignored. See RFC 1700, section "Ether Types", for
    329                      examples.
    330 
    331   @retval EFI_SUCCESS           The packet was placed on the transmit queue.
    332   @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
    333   @retval EFI_ACCESS_DENIED     Error acquire global lock for operation.
    334 
    335 **/
    336 EFI_STATUS
    337 EFIAPI
    338 SnpNt32Transmit (
    339   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
    340   IN UINTN                       HeaderSize,
    341   IN UINTN                       BufferSize,
    342   IN VOID                        *Buffer,
    343   IN EFI_MAC_ADDRESS             *SrcAddr OPTIONAL,
    344   IN EFI_MAC_ADDRESS             *DestAddr OPTIONAL,
    345   IN UINT16                      *Protocol OPTIONAL
    346   );
    347 
    348 /**
    349   Receives a packet from a network interface.
    350 
    351   @param  This             Protocol instance pointer.
    352   @param  HeaderSize       The size, in bytes, of the media header received on the network
    353                            interface. If this parameter is NULL, then the media header size
    354                            will not be returned.
    355   @param  BuffSize         On entry, the size, in bytes, of Buffer. On exit, the size, in
    356                            bytes, of the packet that was received on the network interface.
    357   @param  Buffer           A pointer to the data buffer to receive both the media header and
    358                            the data.
    359   @param  SourceAddr       The source HW MAC address. If this parameter is NULL, the
    360                            HW MAC source address will not be extracted from the media
    361                            header.
    362   @param  DestinationAddr  The destination HW MAC address. If this parameter is NULL,
    363                            the HW MAC destination address will not be extracted from the
    364                            media header.
    365   @param  Protocol         The media header type. If this parameter is NULL, then the
    366                            protocol will not be extracted from the media header. See
    367                            RFC 1700 section "Ether Types" for examples.
    368 
    369   @retval  EFI_SUCCESS           The received data was stored in Buffer, and BufferSize has
    370                                  been updated to the number of bytes received.
    371   @retval  EFI_NOT_READY         The network interface is too busy to accept this transmit
    372                                  request.
    373   @retval  EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
    374   @retval  EFI_DEVICE_ERROR      The command could not be sent to the network interface.
    375   @retval  EFI_ACCESS_DENIED     Error acquire global lock for operation.
    376 
    377 **/
    378 EFI_STATUS
    379 EFIAPI
    380 SnpNt32Receive (
    381   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
    382   OUT UINTN                      *HeaderSize,
    383   IN OUT UINTN                   *BuffSize,
    384   OUT VOID                       *Buffer,
    385   OUT EFI_MAC_ADDRESS            *SourceAddr,
    386   OUT EFI_MAC_ADDRESS            *DestinationAddr,
    387   OUT UINT16                     *Protocol
    388   );
    389 
    390 SNPNT32_INSTANCE_DATA gSnpNt32InstanceTemplate = {
    391   SNP_NT32_INSTANCE_SIGNATURE,            //  Signature
    392   {
    393     NULL,
    394     NULL
    395   },                                      //  Entry
    396   NULL,                                   //  GlobalData
    397   NULL,                                   //  DeviceHandle
    398   NULL,                                   //  DevicePath
    399   {                                       //  Snp
    400     EFI_SIMPLE_NETWORK_PROTOCOL_REVISION, //  Revision
    401     SnpNt32Start,                         //  Start
    402     SnpNt32Stop,                          //  Stop
    403     SnpNt32Initialize,                    //  Initialize
    404     SnpNt32Reset,                         //  Reset
    405     SnpNt32Shutdown,                      //  Shutdown
    406     SnpNt32ReceiveFilters,                //  ReceiveFilters
    407     SnpNt32StationAddress,                //  StationAddress
    408     SnpNt32Statistics,                    //  Statistics
    409     SnpNt32McastIptoMac,                  //  MCastIpToMac
    410     SnpNt32Nvdata,                        //  NvData
    411     SnpNt32GetStatus,                     //  GetStatus
    412     SnpNt32Transmit,                      //  Transmit
    413     SnpNt32Receive,                       //  Receive
    414     NULL,                                 //  WaitForPacket
    415     NULL                                  //  Mode
    416   },
    417   {                                       //  Mode
    418     EfiSimpleNetworkInitialized,          //  State
    419     NET_ETHER_ADDR_LEN,                   //  HwAddressSize
    420     NET_ETHER_HEADER_SIZE,                //  MediaHeaderSize
    421     1500,                                 //  MaxPacketSize
    422     0,                                    //  NvRamSize
    423     0,                                    //  NvRamAccessSize
    424     0,                                    //  ReceiveFilterMask
    425     0,                                    //  ReceiveFilterSetting
    426     MAX_MCAST_FILTER_CNT,                 //  MaxMCastFilterCount
    427     0,                                    //  MCastFilterCount
    428     {
    429       0
    430     },                                    //  MCastFilter
    431     {
    432       0
    433     },                                    //  CurrentAddress
    434     {
    435       0
    436     },                                    //  BroadcastAddress
    437     {
    438       0
    439     },                                    //  PermanentAddress
    440     NET_IFTYPE_ETHERNET,                  //  IfType
    441     FALSE,                                //  MacAddressChangeable
    442     FALSE,                                //  MultipleTxSupported
    443     TRUE,                                 //  MediaPresentSupported
    444     TRUE                                  //  MediaPresent
    445   },
    446   {
    447     0
    448   }                                       //  InterfaceInfo
    449 };
    450 
    451 /**
    452   Test to see if this driver supports ControllerHandle. This service
    453   is called by the EFI boot service ConnectController(). In
    454   order to make drivers as small as possible, there are a few calling
    455   restrictions for this service. ConnectController() must
    456   follow these calling restrictions. If any other agent wishes to call
    457   Supported() it must also follow these calling restrictions.
    458 
    459   @param  This                Protocol instance pointer.
    460   @param  ControllerHandle    Handle of device to test
    461   @param  RemainingDevicePath Optional parameter use to pick a specific child
    462                               device to start.
    463 
    464   @retval EFI_SUCCESS         This driver supports this device
    465   @retval EFI_UNSUPPORTED     This driver does not support this device
    466 
    467 **/
    468 EFI_STATUS
    469 EFIAPI
    470 SnpNt32DriverBindingSupported (
    471   IN EFI_DRIVER_BINDING_PROTOCOL  * This,
    472   IN EFI_HANDLE                   ControllerHandle,
    473   IN EFI_DEVICE_PATH_PROTOCOL     * RemainingDevicePath OPTIONAL
    474   )
    475 {
    476 
    477   SNPNT32_GLOBAL_DATA   *GlobalData;
    478   LIST_ENTRY            *Entry;
    479   SNPNT32_INSTANCE_DATA *Instance;
    480 
    481   GlobalData = &gSnpNt32GlobalData;
    482 
    483   NET_LIST_FOR_EACH (Entry, &GlobalData->InstanceList) {
    484 
    485     Instance = NET_LIST_USER_STRUCT_S (Entry, SNPNT32_INSTANCE_DATA, Entry, SNP_NT32_INSTANCE_SIGNATURE);
    486 
    487     if (Instance->DeviceHandle == ControllerHandle) {
    488       return EFI_SUCCESS;
    489     }
    490 
    491   }
    492 
    493   return EFI_UNSUPPORTED;
    494 }
    495 
    496 
    497 /**
    498   Start this driver on ControllerHandle. This service is called by the
    499   EFI boot service ConnectController(). In order to make
    500   drivers as small as possible, there are a few calling restrictions for
    501   this service. ConnectController() must follow these
    502   calling restrictions. If any other agent wishes to call Start() it
    503   must also follow these calling restrictions.
    504 
    505   @param  This                 Protocol instance pointer.
    506   @param  ControllerHandle     Handle of device to bind driver to
    507   @param  RemainingDevicePath  Optional parameter use to pick a specific child
    508                                device to start.
    509 
    510   @retval EFI_SUCCESS          Always succeeds.
    511 
    512 **/
    513 EFI_STATUS
    514 EFIAPI
    515 SnpNt32DriverBindingStart (
    516   IN EFI_DRIVER_BINDING_PROTOCOL  * This,
    517   IN EFI_HANDLE                   ControllerHandle,
    518   IN EFI_DEVICE_PATH_PROTOCOL     * RemainingDevicePath OPTIONAL
    519   )
    520 {
    521   return EFI_SUCCESS;
    522 }
    523 
    524 /**
    525   Stop this driver on ControllerHandle. This service is called by the
    526   EFI boot service DisconnectController(). In order to
    527   make drivers as small as possible, there are a few calling
    528   restrictions for this service. DisconnectController()
    529   must follow these calling restrictions. If any other agent wishes
    530   to call Stop() it must also follow these calling restrictions.
    531 
    532   @param  This              Protocol instance pointer.
    533   @param  ControllerHandle  Handle of device to stop driver on
    534   @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
    535                             children is zero stop the entire bus driver.
    536   @param  ChildHandleBuffer List of Child Handles to Stop.
    537 
    538   @retval EFI_SUCCESS       Always succeeds.
    539 
    540 **/
    541 EFI_STATUS
    542 EFIAPI
    543 SnpNt32DriverBindingStop (
    544   IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
    545   IN  EFI_HANDLE                   ControllerHandle,
    546   IN  UINTN                        NumberOfChildren,
    547   IN  EFI_HANDLE                   *ChildHandleBuffer
    548   )
    549 {
    550   return EFI_SUCCESS;
    551 }
    552 
    553 
    554 /**
    555   Changes the state of a network interface from "stopped" to "started".
    556 
    557   @param  This Protocol instance pointer.
    558 
    559   @retval EFI_SUCCESS           Always succeeds.
    560 
    561 **/
    562 EFI_STATUS
    563 EFIAPI
    564 SnpNt32Start (
    565   IN EFI_SIMPLE_NETWORK_PROTOCOL *This
    566   )
    567 {
    568   return EFI_SUCCESS;
    569 }
    570 
    571 
    572 /**
    573   Changes the state of a network interface from "started" to "stopped".
    574 
    575   @param  This Protocol instance pointer.
    576 
    577   @retval EFI_SUCCESS           Always succeeds.
    578 
    579 **/
    580 EFI_STATUS
    581 EFIAPI
    582 SnpNt32Stop (
    583   IN EFI_SIMPLE_NETWORK_PROTOCOL *This
    584   )
    585 {
    586   return EFI_SUCCESS;
    587 }
    588 
    589 /**
    590   Resets a network adapter and allocates the transmit and receive buffers
    591   required by the network interface; optionally, also requests allocation
    592   of additional transmit and receive buffers.
    593 
    594   @param  This              Protocol instance pointer.
    595   @param  ExtraRxBufferSize The size, in bytes, of the extra receive buffer space
    596                             that the driver should allocate for the network interface.
    597                             Some network interfaces will not be able to use the extra
    598                             buffer, and the caller will not know if it is actually
    599                             being used.
    600   @param  ExtraTxBufferSize The size, in bytes, of the extra transmit buffer space
    601                             that the driver should allocate for the network interface.
    602                             Some network interfaces will not be able to use the extra
    603                             buffer, and the caller will not know if it is actually
    604                             being used.
    605 
    606   @retval EFI_SUCCESS           Always succeeds.
    607 
    608 **/
    609 EFI_STATUS
    610 EFIAPI
    611 SnpNt32Initialize (
    612   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
    613   IN UINTN                       ExtraRxBufferSize OPTIONAL,
    614   IN UINTN                       ExtraTxBufferSize OPTIONAL
    615   )
    616 {
    617   return EFI_SUCCESS;
    618 }
    619 
    620 /**
    621   Resets a network adapter and re-initializes it with the parameters that were
    622   provided in the previous call to Initialize().
    623 
    624   @param  This                 Protocol instance pointer.
    625   @param  ExtendedVerification Indicates that the driver may perform a more
    626                                exhaustive verification operation of the device
    627                                during reset.
    628 
    629   @retval EFI_SUCCESS           Always succeeds.
    630 
    631 **/
    632 EFI_STATUS
    633 EFIAPI
    634 SnpNt32Reset (
    635   IN EFI_SIMPLE_NETWORK_PROTOCOL  *This,
    636   IN BOOLEAN                      ExtendedVerification
    637   )
    638 {
    639   return EFI_SUCCESS;
    640 }
    641 
    642 /**
    643   Resets a network adapter and leaves it in a state that is safe for
    644   another driver to initialize.
    645 
    646   @param  This Protocol instance pointer.
    647 
    648   @retval EFI_SUCCESS           Always succeeds.
    649 
    650 **/
    651 EFI_STATUS
    652 EFIAPI
    653 SnpNt32Shutdown (
    654   IN EFI_SIMPLE_NETWORK_PROTOCOL *This
    655   )
    656 {
    657   return EFI_SUCCESS;
    658 }
    659 
    660 /**
    661   Manages the multicast receive filters of a network interface.
    662 
    663   @param  This               Protocol instance pointer.
    664   @param  EnableBits         A bit mask of receive filters to enable on the network interface.
    665   @param  DisableBits        A bit mask of receive filters to disable on the network interface.
    666   @param  ResetMcastFilter   Set to TRUE to reset the contents of the multicast receive
    667                              filters on the network interface to their default values.
    668   @param  McastFilterCount   Number of multicast HW MAC addresses in the new
    669                              MCastFilter list. This value must be less than or equal to
    670                              the MCastFilterCnt field of EFI_SIMPLE_NETWORK_MODE. This
    671                              field is optional if ResetMCastFilter is TRUE.
    672   @param  McastFilter        A pointer to a list of new multicast receive filter HW MAC
    673                              addresses. This list will replace any existing multicast
    674                              HW MAC address list. This field is optional if
    675                              ResetMCastFilter is TRUE.
    676 
    677   @retval EFI_SUCCESS           The multicast receive filter list was updated.
    678   @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
    679 
    680 **/
    681 EFI_STATUS
    682 EFIAPI
    683 SnpNt32ReceiveFilters (
    684   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
    685   IN UINT32                      EnableBits,
    686   IN UINT32                      DisableBits,
    687   IN BOOLEAN                     ResetMcastFilter,
    688   IN UINTN                       McastFilterCount OPTIONAL,
    689   IN EFI_MAC_ADDRESS             *McastFilter     OPTIONAL
    690   )
    691 {
    692   SNPNT32_INSTANCE_DATA *Instance;
    693   SNPNT32_GLOBAL_DATA   *GlobalData;
    694   INT32                 ReturnValue;
    695 
    696   Instance    = SNP_NT32_INSTANCE_DATA_FROM_SNP_THIS (This);
    697 
    698   GlobalData  = Instance->GlobalData;
    699 
    700   if (EFI_ERROR (EfiAcquireLockOrFail (&GlobalData->Lock))) {
    701     return EFI_ACCESS_DENIED;
    702   }
    703 
    704   ReturnValue = GlobalData->NtNetUtilityTable.SetReceiveFilter (
    705                                                 Instance->InterfaceInfo.InterfaceIndex,
    706                                                 EnableBits,
    707                                                 (UINT32)McastFilterCount,
    708                                                 McastFilter
    709                                                 );
    710 
    711   EfiReleaseLock (&GlobalData->Lock);
    712 
    713   if (ReturnValue <= 0) {
    714     return EFI_DEVICE_ERROR;
    715   }
    716 
    717   return EFI_SUCCESS;
    718 }
    719 
    720 /**
    721   Modifies or resets the current station address, if supported.
    722 
    723   @param  This         Protocol instance pointer.
    724   @param  Reset        Flag used to reset the station address to the network interfaces
    725                        permanent address.
    726   @param  NewMacAddr   New station address to be used for the network interface.
    727 
    728   @retval EFI_UNSUPPORTED       Not supported yet.
    729 
    730 **/
    731 EFI_STATUS
    732 EFIAPI
    733 SnpNt32StationAddress (
    734   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
    735   IN BOOLEAN                     Reset,
    736   IN EFI_MAC_ADDRESS             *NewMacAddr OPTIONAL
    737   )
    738 {
    739   return EFI_UNSUPPORTED;
    740 }
    741 
    742 /**
    743   Resets or collects the statistics on a network interface.
    744 
    745   @param  This            Protocol instance pointer.
    746   @param  Reset           Set to TRUE to reset the statistics for the network interface.
    747   @param  StatisticsSize  On input the size, in bytes, of StatisticsTable. On
    748                           output the size, in bytes, of the resulting table of
    749                           statistics.
    750   @param  StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
    751                           contains the statistics.
    752 
    753   @retval EFI_SUCCESS           The statistics were collected from the network interface.
    754   @retval EFI_NOT_STARTED       The network interface has not been started.
    755   @retval EFI_BUFFER_TOO_SMALL  The Statistics buffer was too small. The current buffer
    756                                 size needed to hold the statistics is returned in
    757                                 StatisticsSize.
    758   @retval EFI_UNSUPPORTED       Not supported yet.
    759 
    760 **/
    761 EFI_STATUS
    762 EFIAPI
    763 SnpNt32Statistics (
    764   IN EFI_SIMPLE_NETWORK_PROTOCOL  * This,
    765   IN BOOLEAN                      Reset,
    766   IN OUT UINTN                    *StatisticsSize OPTIONAL,
    767   OUT EFI_NETWORK_STATISTICS      *StatisticsTable OPTIONAL
    768   )
    769 {
    770   return EFI_UNSUPPORTED;
    771 }
    772 
    773 /**
    774   Converts a multicast IP address to a multicast HW MAC address.
    775 
    776   @param  This Protocol instance pointer.
    777   @param  Ipv6 Set to TRUE if the multicast IP address is IPv6 [RFC 2460]. Set
    778                to FALSE if the multicast IP address is IPv4 [RFC 791].
    779   @param  Ip   The multicast IP address that is to be converted to a multicast
    780                HW MAC address.
    781   @param  Mac  The multicast HW MAC address that is to be generated from IP.
    782 
    783   @retval EFI_SUCCESS           The multicast IP address was mapped to the multicast
    784                                 HW MAC address.
    785   @retval EFI_NOT_STARTED       The network interface has not been started.
    786   @retval EFI_BUFFER_TOO_SMALL  The Statistics buffer was too small. The current buffer
    787                                 size needed to hold the statistics is returned in
    788                                 StatisticsSize.
    789   @retval EFI_UNSUPPORTED       Not supported yet.
    790 
    791 **/
    792 EFI_STATUS
    793 EFIAPI
    794 SnpNt32McastIptoMac (
    795   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
    796   IN BOOLEAN                     Ipv6,
    797   IN EFI_IP_ADDRESS              *Ip,
    798   OUT EFI_MAC_ADDRESS            *Mac
    799   )
    800 {
    801   return EFI_UNSUPPORTED;
    802 }
    803 
    804 
    805 /**
    806   Performs read and write operations on the NVRAM device attached to a
    807   network interface.
    808 
    809   @param  This         Protocol instance pointer.
    810   @param  ReadOrWrite  TRUE for read operations, FALSE for write operations.
    811   @param  Offset       Byte offset in the NVRAM device at which to start the read or
    812                        write operation. This must be a multiple of NvRamAccessSize and
    813                        less than NvRamSize.
    814   @param  BufferSize   The number of bytes to read or write from the NVRAM device.
    815                        This must also be a multiple of NvramAccessSize.
    816   @param  Buffer       A pointer to the data buffer.
    817 
    818   @retval EFI_UNSUPPORTED       Not supported yet.
    819 
    820 **/
    821 EFI_STATUS
    822 EFIAPI
    823 SnpNt32Nvdata (
    824   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
    825   IN BOOLEAN                     ReadOrWrite,
    826   IN UINTN                       Offset,
    827   IN UINTN                       BufferSize,
    828   IN OUT VOID                    *Buffer
    829   )
    830 {
    831   return EFI_UNSUPPORTED;
    832 }
    833 
    834 
    835 /**
    836   Reads the current interrupt status and recycled transmit buffer status from
    837   a network interface.
    838 
    839   @param  This            Protocol instance pointer.
    840   @param  InterruptStatus A pointer to the bit mask of the currently active interrupts
    841                           If this is NULL, the interrupt status will not be read from
    842                           the device. If this is not NULL, the interrupt status will
    843                           be read from the device. When the  interrupt status is read,
    844                           it will also be cleared. Clearing the transmit  interrupt
    845                           does not empty the recycled transmit buffer array.
    846   @param  TxBuffer        Recycled transmit buffer address. The network interface will
    847                           not transmit if its internal recycled transmit buffer array
    848                           is full. Reading the transmit buffer does not clear the
    849                           transmit interrupt. If this is NULL, then the transmit buffer
    850                           status will not be read. If there are no transmit buffers to
    851                           recycle and TxBuf is not NULL, * TxBuf will be set to NULL.
    852 
    853   @retval EFI_SUCCESS           Always succeeds.
    854 
    855 **/
    856 EFI_STATUS
    857 EFIAPI
    858 SnpNt32GetStatus (
    859   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
    860   OUT UINT32                     *InterruptStatus,
    861   OUT VOID                       **TxBuffer
    862   )
    863 {
    864 
    865   if (TxBuffer != NULL) {
    866     *((UINT8 **) TxBuffer) = (UINT8 *)(UINTN) 1;
    867   }
    868 
    869   if (InterruptStatus != NULL) {
    870     *InterruptStatus = EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
    871   }
    872 
    873   return EFI_SUCCESS;
    874 }
    875 
    876 
    877 /**
    878   Places a packet in the transmit queue of a network interface.
    879 
    880   @param  This       Protocol instance pointer.
    881   @param  HeaderSize The size, in bytes, of the media header to be filled in by
    882                      the Transmit() function. If HeaderSize is non-zero, then it
    883                      must be equal to This->Mode->MediaHeaderSize and the DestAddr
    884                      and Protocol parameters must not be NULL.
    885   @param  BufferSize The size, in bytes, of the entire packet (media header and
    886                      data) to be transmitted through the network interface.
    887   @param  Buffer     A pointer to the packet (media header followed by data) to be
    888                      transmitted. This parameter cannot be NULL. If HeaderSize is zero,
    889                      then the media header in Buffer must already be filled in by the
    890                      caller. If HeaderSize is non-zero, then the media header will be
    891                      filled in by the Transmit() function.
    892   @param  SrcAddr    The source HW MAC address. If HeaderSize is zero, then this parameter
    893                      is ignored. If HeaderSize is non-zero and SrcAddr is NULL, then
    894                      This->Mode->CurrentAddress is used for the source HW MAC address.
    895   @param  DestAddr   The destination HW MAC address. If HeaderSize is zero, then this
    896                      parameter is ignored.
    897   @param  Protocol   The type of header to build. If HeaderSize is zero, then this
    898                      parameter is ignored. See RFC 1700, section "Ether Types", for
    899                      examples.
    900 
    901   @retval EFI_SUCCESS           The packet was placed on the transmit queue.
    902   @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
    903   @retval EFI_ACCESS_DENIED     Error acquire global lock for operation.
    904 
    905 **/
    906 EFI_STATUS
    907 EFIAPI
    908 SnpNt32Transmit (
    909   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
    910   IN UINTN                       HeaderSize,
    911   IN UINTN                       BufferSize,
    912   IN VOID                        *Buffer,
    913   IN EFI_MAC_ADDRESS             *SrcAddr OPTIONAL,
    914   IN EFI_MAC_ADDRESS             *DestAddr OPTIONAL,
    915   IN UINT16                      *Protocol OPTIONAL
    916   )
    917 {
    918   SNPNT32_INSTANCE_DATA *Instance;
    919   SNPNT32_GLOBAL_DATA   *GlobalData;
    920   INT32                 ReturnValue;
    921 
    922   Instance    = SNP_NT32_INSTANCE_DATA_FROM_SNP_THIS (This);
    923 
    924   GlobalData  = Instance->GlobalData;
    925 
    926   if ((HeaderSize != 0) && (SrcAddr == NULL)) {
    927     SrcAddr = &Instance->Mode.CurrentAddress;
    928   }
    929 
    930   if (EFI_ERROR (EfiAcquireLockOrFail (&GlobalData->Lock))) {
    931     return EFI_ACCESS_DENIED;
    932   }
    933 
    934   ReturnValue = GlobalData->NtNetUtilityTable.Transmit (
    935                                                 Instance->InterfaceInfo.InterfaceIndex,
    936                                                 (UINT32)HeaderSize,
    937                                                 (UINT32)BufferSize,
    938                                                 Buffer,
    939                                                 SrcAddr,
    940                                                 DestAddr,
    941                                                 Protocol
    942                                                 );
    943 
    944   EfiReleaseLock (&GlobalData->Lock);
    945 
    946   if (ReturnValue < 0) {
    947     return EFI_DEVICE_ERROR;
    948   }
    949 
    950   return EFI_SUCCESS;
    951 }
    952 
    953 /**
    954   Receives a packet from a network interface.
    955 
    956   @param  This             Protocol instance pointer.
    957   @param  HeaderSize       The size, in bytes, of the media header received on the network
    958                            interface. If this parameter is NULL, then the media header size
    959                            will not be returned.
    960   @param  BuffSize         On entry, the size, in bytes, of Buffer. On exit, the size, in
    961                            bytes, of the packet that was received on the network interface.
    962   @param  Buffer           A pointer to the data buffer to receive both the media header and
    963                            the data.
    964   @param  SourceAddr       The source HW MAC address. If this parameter is NULL, the
    965                            HW MAC source address will not be extracted from the media
    966                            header.
    967   @param  DestinationAddr  The destination HW MAC address. If this parameter is NULL,
    968                            the HW MAC destination address will not be extracted from the
    969                            media header.
    970   @param  Protocol         The media header type. If this parameter is NULL, then the
    971                            protocol will not be extracted from the media header. See
    972                            RFC 1700 section "Ether Types" for examples.
    973 
    974   @retval  EFI_SUCCESS           The received data was stored in Buffer, and BufferSize has
    975                                  been updated to the number of bytes received.
    976   @retval  EFI_NOT_READY         The network interface is too busy to accept this transmit
    977                                  request.
    978   @retval  EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
    979   @retval  EFI_DEVICE_ERROR      The command could not be sent to the network interface.
    980   @retval  EFI_ACCESS_DENIED     Error acquire global lock for operation.
    981 
    982 **/
    983 EFI_STATUS
    984 EFIAPI
    985 SnpNt32Receive (
    986   IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
    987   OUT UINTN                      *HeaderSize,
    988   IN OUT UINTN                   *BuffSize,
    989   OUT VOID                       *Buffer,
    990   OUT EFI_MAC_ADDRESS            *SourceAddr,
    991   OUT EFI_MAC_ADDRESS            *DestinationAddr,
    992   OUT UINT16                     *Protocol
    993   )
    994 {
    995   SNPNT32_INSTANCE_DATA *Instance;
    996   SNPNT32_GLOBAL_DATA   *GlobalData;
    997   INT32                 ReturnValue;
    998   UINTN                 BufSize;
    999 
   1000   BufSize     = *BuffSize;
   1001 
   1002   Instance    = SNP_NT32_INSTANCE_DATA_FROM_SNP_THIS (This);
   1003 
   1004   GlobalData  = Instance->GlobalData;
   1005 
   1006   ASSERT (GlobalData->NtNetUtilityTable.Receive != NULL);
   1007 
   1008   if (EFI_ERROR (EfiAcquireLockOrFail (&GlobalData->Lock))) {
   1009     return EFI_ACCESS_DENIED;
   1010   }
   1011 
   1012   ReturnValue = GlobalData->NtNetUtilityTable.Receive (
   1013                                                 Instance->InterfaceInfo.InterfaceIndex,
   1014                                                 BuffSize,
   1015                                                 Buffer
   1016                                                 );
   1017 
   1018   EfiReleaseLock (&GlobalData->Lock);
   1019 
   1020   if (ReturnValue < 0) {
   1021     if (ReturnValue == -100) {
   1022       return EFI_BUFFER_TOO_SMALL;
   1023     }
   1024 
   1025     return EFI_DEVICE_ERROR;
   1026   } else if (ReturnValue == 0) {
   1027     return EFI_NOT_READY;
   1028   }
   1029 
   1030   if (HeaderSize != NULL) {
   1031     *HeaderSize = 14;
   1032   }
   1033 
   1034   if (SourceAddr != NULL) {
   1035     ZeroMem (SourceAddr, sizeof (EFI_MAC_ADDRESS));
   1036     CopyMem (SourceAddr, ((UINT8 *) Buffer) + 6, 6);
   1037   }
   1038 
   1039   if (DestinationAddr != NULL) {
   1040     ZeroMem (DestinationAddr, sizeof (EFI_MAC_ADDRESS));
   1041     CopyMem (DestinationAddr, ((UINT8 *) Buffer), 6);
   1042   }
   1043 
   1044   if (Protocol != NULL) {
   1045     *Protocol = NTOHS (*((UINT16 *) (((UINT8 *) Buffer) + 12)));
   1046   }
   1047 
   1048   return (*BuffSize <= BufSize) ? EFI_SUCCESS : EFI_BUFFER_TOO_SMALL;
   1049 }
   1050 
   1051 /**
   1052   Initialize the driver's global data.
   1053 
   1054   @param  This                  Pointer to the global context data.
   1055 
   1056   @retval EFI_SUCCESS           The global data is initialized.
   1057   @retval EFI_NOT_FOUND         The required DLL is not found.
   1058   @retval EFI_DEVICE_ERROR      Error initialize network utility library.
   1059   @retval EFI_OUT_OF_RESOURCES  Out of resource.
   1060   @retval other                 Other errors.
   1061 
   1062 **/
   1063 EFI_STATUS
   1064 SnpNt32InitializeGlobalData (
   1065   IN OUT SNPNT32_GLOBAL_DATA *This
   1066   )
   1067 {
   1068   EFI_STATUS            Status;
   1069   CHAR16                *DllFileNameU;
   1070   UINT32                Index;
   1071   INT32                 ReturnValue;
   1072   BOOLEAN               NetUtilityLibInitDone;
   1073   NT_NET_INTERFACE_INFO NetInterfaceInfoBuffer[MAX_INTERFACE_INFO_NUMBER];
   1074   SNPNT32_INSTANCE_DATA *Instance;
   1075   LIST_ENTRY            *Entry;
   1076   UINT32                InterfaceCount;
   1077 
   1078   ASSERT (This != NULL);
   1079 
   1080   NetUtilityLibInitDone = FALSE;
   1081   InterfaceCount        = MAX_INTERFACE_INFO_NUMBER;
   1082 
   1083   InitializeListHead (&This->InstanceList);
   1084   EfiInitializeLock (&This->Lock, TPL_CALLBACK);
   1085 
   1086   //
   1087   //  Get the WinNT thunk
   1088   //
   1089   Status = gBS->LocateProtocol (&gEfiWinNtThunkProtocolGuid, NULL, (VOID **)&This->WinNtThunk);
   1090 
   1091   if (EFI_ERROR (Status)) {
   1092     return Status;
   1093   }
   1094 
   1095   ASSERT (This->WinNtThunk != NULL);
   1096 
   1097   DllFileNameU = NETWORK_LIBRARY_NAME_U;
   1098 
   1099   //
   1100   //  Load network utility library
   1101   //
   1102   This->NetworkLibraryHandle = This->WinNtThunk->LoadLibraryEx (DllFileNameU, NULL, 0);
   1103 
   1104   if (NULL == This->NetworkLibraryHandle) {
   1105     return EFI_NOT_FOUND;
   1106   }
   1107 
   1108   This->NtNetUtilityTable.Initialize = (NT_NET_INITIALIZE) This->WinNtThunk->GetProcAddress (
   1109                                                                                This->NetworkLibraryHandle,
   1110                                                                                NETWORK_LIBRARY_INITIALIZE
   1111                                                                                );
   1112 
   1113   if (NULL == This->NtNetUtilityTable.Initialize) {
   1114     Status = EFI_NOT_FOUND;
   1115     goto ErrorReturn;
   1116   }
   1117 
   1118   This->NtNetUtilityTable.Finalize = (NT_NET_FINALIZE) This->WinNtThunk->GetProcAddress (
   1119                                                                            This->NetworkLibraryHandle,
   1120                                                                            NETWORK_LIBRARY_FINALIZE
   1121                                                                            );
   1122 
   1123   if (NULL == This->NtNetUtilityTable.Finalize) {
   1124     Status = EFI_NOT_FOUND;
   1125     goto ErrorReturn;
   1126   }
   1127 
   1128   This->NtNetUtilityTable.SetReceiveFilter = (NT_NET_SET_RECEIVE_FILTER) This->WinNtThunk->GetProcAddress (
   1129                                                                                              This->NetworkLibraryHandle,
   1130                                                                                              NETWORK_LIBRARY_SET_RCV_FILTER
   1131                                                                                              );
   1132 
   1133   if (NULL == This->NtNetUtilityTable.SetReceiveFilter) {
   1134     Status = EFI_NOT_FOUND;
   1135     goto ErrorReturn;
   1136   }
   1137 
   1138   This->NtNetUtilityTable.Receive = (NT_NET_RECEIVE) This->WinNtThunk->GetProcAddress (
   1139                                                                          This->NetworkLibraryHandle,
   1140                                                                          NETWORK_LIBRARY_RECEIVE
   1141                                                                          );
   1142 
   1143   if (NULL == This->NtNetUtilityTable.Receive) {
   1144     Status = EFI_NOT_FOUND;
   1145     goto ErrorReturn;
   1146   }
   1147 
   1148   This->NtNetUtilityTable.Transmit = (NT_NET_TRANSMIT) This->WinNtThunk->GetProcAddress (
   1149                                                                            This->NetworkLibraryHandle,
   1150                                                                            NETWORK_LIBRARY_TRANSMIT
   1151                                                                            );
   1152 
   1153   if (NULL == This->NtNetUtilityTable.Transmit) {
   1154     Status = EFI_NOT_FOUND;
   1155     goto ErrorReturn;
   1156   }
   1157   //
   1158   //  Initialize the network utility library
   1159   //  And enumerate the interfaces in NT32 host
   1160   //
   1161   ReturnValue = This->NtNetUtilityTable.Initialize (&InterfaceCount, &NetInterfaceInfoBuffer[0]);
   1162   if (ReturnValue <= 0) {
   1163     Status = EFI_DEVICE_ERROR;
   1164     goto ErrorReturn;
   1165   }
   1166 
   1167   NetUtilityLibInitDone = TRUE;
   1168 
   1169   if (InterfaceCount == 0) {
   1170     Status = EFI_NOT_FOUND;
   1171     goto ErrorReturn;
   1172   }
   1173   //
   1174   //  Create fake SNP instances
   1175   //
   1176   for (Index = 0; Index < InterfaceCount; Index++) {
   1177 
   1178     Instance = AllocatePool (sizeof (SNPNT32_INSTANCE_DATA));
   1179 
   1180     if (NULL == Instance) {
   1181       Status = EFI_OUT_OF_RESOURCES;
   1182       goto ErrorReturn;
   1183     }
   1184     //
   1185     //  Copy the content from a template
   1186     //
   1187     CopyMem (Instance, &gSnpNt32InstanceTemplate, sizeof (SNPNT32_INSTANCE_DATA));
   1188 
   1189     //
   1190     //  Set the interface information.
   1191     //
   1192     CopyMem (&Instance->InterfaceInfo, &NetInterfaceInfoBuffer[Index], sizeof(Instance->InterfaceInfo));
   1193     //
   1194     //  Initialize this instance
   1195     //
   1196     Status = This->InitializeInstanceData (This, Instance);
   1197     if (EFI_ERROR (Status)) {
   1198 
   1199       gBS->FreePool (Instance);
   1200       goto ErrorReturn;
   1201     }
   1202     //
   1203     //  Insert this instance into the instance list
   1204     //
   1205     InsertTailList (&This->InstanceList, &Instance->Entry);
   1206   }
   1207 
   1208   return EFI_SUCCESS;
   1209 
   1210 ErrorReturn:
   1211 
   1212   while (!IsListEmpty (&This->InstanceList)) {
   1213 
   1214     Entry     = This->InstanceList.ForwardLink;
   1215 
   1216     Instance  = NET_LIST_USER_STRUCT_S (Entry, SNPNT32_INSTANCE_DATA, Entry, SNP_NT32_INSTANCE_SIGNATURE);
   1217 
   1218     RemoveEntryList (Entry);
   1219 
   1220     This->CloseInstance (This, Instance);
   1221     gBS->FreePool (Instance);
   1222   }
   1223 
   1224   if (NetUtilityLibInitDone) {
   1225 
   1226     ASSERT (This->WinNtThunk != NULL);
   1227 
   1228     if (This->NtNetUtilityTable.Finalize != NULL) {
   1229       This->NtNetUtilityTable.Finalize ();
   1230       This->NtNetUtilityTable.Finalize = NULL;
   1231     }
   1232   }
   1233 
   1234   return Status;
   1235 }
   1236 
   1237 
   1238 /**
   1239   Initialize the snpnt32 driver instance.
   1240 
   1241   @param  This                  Pointer to the SnpNt32 global data.
   1242   @param  Instance              Pointer to the instance context data.
   1243 
   1244   @retval EFI_SUCCESS           The driver instance is initialized.
   1245   @retval other                 Initialization errors.
   1246 
   1247 **/
   1248 EFI_STATUS
   1249 SnpNt32InitializeInstanceData (
   1250   IN SNPNT32_GLOBAL_DATA        *This,
   1251   IN OUT SNPNT32_INSTANCE_DATA  *Instance
   1252   )
   1253 {
   1254   EFI_STATUS    Status;
   1255   EFI_DEV_PATH  EndNode;
   1256   EFI_DEV_PATH  Node;
   1257 
   1258   Instance->GlobalData  = This;
   1259   Instance->Snp.Mode    = &Instance->Mode;
   1260   //
   1261   //  Set broadcast address
   1262   //
   1263   SetMem (&Instance->Mode.BroadcastAddress, sizeof (EFI_MAC_ADDRESS), 0xFF);
   1264 
   1265   //
   1266   //  Copy Current/PermanentAddress MAC address
   1267   //
   1268   CopyMem (&Instance->Mode.CurrentAddress, &Instance->InterfaceInfo.MacAddr, sizeof(Instance->Mode.CurrentAddress));
   1269   CopyMem (&Instance->Mode.PermanentAddress, &Instance->InterfaceInfo.MacAddr, sizeof(Instance->Mode.PermanentAddress));
   1270 
   1271   //
   1272   //  Since the fake SNP is based on a real NIC, to avoid conflict with the host
   1273   //  NIC network stack, we use a different MAC address.
   1274   //  So just change the last byte of the MAC address for the real NIC.
   1275   //
   1276   Instance->Mode.CurrentAddress.Addr[NET_ETHER_ADDR_LEN - 1]++;
   1277 
   1278   //
   1279   //  Create a fake device path for the instance
   1280   //
   1281   ZeroMem (&Node, sizeof (Node));
   1282 
   1283   Node.DevPath.Type     = MESSAGING_DEVICE_PATH;
   1284   Node.DevPath.SubType  = MSG_MAC_ADDR_DP;
   1285   SetDevicePathNodeLength (&Node.DevPath, sizeof (MAC_ADDR_DEVICE_PATH));
   1286 
   1287   CopyMem (
   1288     &Node.MacAddr.MacAddress,
   1289     &Instance->Mode.CurrentAddress,
   1290     NET_ETHER_ADDR_LEN
   1291     );
   1292 
   1293   Node.MacAddr.IfType = Instance->Mode.IfType;
   1294 
   1295   SetDevicePathEndNode (&EndNode.DevPath);
   1296 
   1297   Instance->DevicePath = AppendDevicePathNode (
   1298                            &EndNode.DevPath,
   1299                            &Node.DevPath
   1300                            );
   1301 
   1302   //
   1303   //  Create a fake device handle for the fake SNP
   1304   //
   1305   Status = gBS->InstallMultipleProtocolInterfaces (
   1306                   &Instance->DeviceHandle,
   1307                   &gEfiSimpleNetworkProtocolGuid,
   1308                   &Instance->Snp,
   1309                   &gEfiDevicePathProtocolGuid,
   1310                   Instance->DevicePath,
   1311                   NULL
   1312                   );
   1313   return Status;
   1314 }
   1315 
   1316 
   1317 /**
   1318   Close the SnpNt32 driver instance.
   1319 
   1320   @param  This                  Pointer to the SnpNt32 global data.
   1321   @param  Instance              Pointer to the instance context data.
   1322 
   1323   @retval EFI_SUCCESS           The instance is closed.
   1324 
   1325 **/
   1326 EFI_STATUS
   1327 SnpNt32CloseInstance (
   1328   IN SNPNT32_GLOBAL_DATA        *This,
   1329   IN OUT SNPNT32_INSTANCE_DATA  *Instance
   1330   )
   1331 {
   1332   ASSERT (This != NULL);
   1333   ASSERT (Instance != NULL);
   1334 
   1335   gBS->UninstallMultipleProtocolInterfaces (
   1336          Instance->DeviceHandle,
   1337          &gEfiSimpleNetworkProtocolGuid,
   1338          &Instance->Snp,
   1339          &gEfiDevicePathProtocolGuid,
   1340          Instance->DevicePath,
   1341          NULL
   1342          );
   1343 
   1344   if (Instance->DevicePath != NULL) {
   1345     gBS->FreePool (Instance->DevicePath);
   1346   }
   1347 
   1348   return EFI_SUCCESS;
   1349 }
   1350 
   1351 /**
   1352   Unloads an image.
   1353 
   1354   @param  ImageHandle           Handle that identifies the image to be unloaded.
   1355 
   1356   @retval EFI_SUCCESS           The image has been unloaded.
   1357   @return Exit code from the image's unload handler
   1358 
   1359 **/
   1360 EFI_STATUS
   1361 EFIAPI
   1362 SnpNt32Unload (
   1363   IN EFI_HANDLE  ImageHandle
   1364   )
   1365 {
   1366   EFI_STATUS            Status;
   1367   SNPNT32_GLOBAL_DATA   *This;
   1368   LIST_ENTRY            *Entry;
   1369   SNPNT32_INSTANCE_DATA *Instance;
   1370 
   1371   This    = &gSnpNt32GlobalData;
   1372 
   1373   Status  = NetLibDefaultUnload (ImageHandle);
   1374 
   1375   if (EFI_ERROR (Status)) {
   1376     return Status;
   1377   }
   1378 
   1379   while (!IsListEmpty (&This->InstanceList)) {
   1380     //
   1381     //  Walkthrough the interfaces and remove all the SNP instance
   1382     //
   1383     Entry     = This->InstanceList.ForwardLink;
   1384 
   1385     Instance  = NET_LIST_USER_STRUCT_S (Entry, SNPNT32_INSTANCE_DATA, Entry, SNP_NT32_INSTANCE_SIGNATURE);
   1386 
   1387     RemoveEntryList (Entry);
   1388 
   1389     This->CloseInstance (This, Instance);
   1390     gBS->FreePool (Instance);
   1391   }
   1392 
   1393   if (This->NtNetUtilityTable.Finalize != NULL) {
   1394     This->NtNetUtilityTable.Finalize ();
   1395   }
   1396 
   1397   This->WinNtThunk->FreeLibrary (This->NetworkLibraryHandle);
   1398 
   1399   return EFI_SUCCESS;
   1400 }
   1401 
   1402 /**
   1403   This is the declaration of an EFI image entry point. This entry point is
   1404   the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
   1405   both device drivers and bus drivers.
   1406 
   1407   @param  ImageHandle           The firmware allocated handle for the UEFI image.
   1408   @param  SystemTable           A pointer to the EFI System Table.
   1409 
   1410   @retval EFI_SUCCESS           The operation completed successfully.
   1411   @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
   1412 
   1413 **/
   1414 EFI_STATUS
   1415 InitializeSnpNt32Driver (
   1416   IN EFI_HANDLE        ImageHandle,
   1417   IN EFI_SYSTEM_TABLE  *SystemTable
   1418   )
   1419 {
   1420 
   1421   EFI_STATUS  Status;
   1422 
   1423   //
   1424   // Install the Driver Protocols
   1425   //
   1426 
   1427   Status = EfiLibInstallDriverBindingComponentName2 (
   1428              ImageHandle,
   1429              SystemTable,
   1430              &gSnpNt32DriverBinding,
   1431              ImageHandle,
   1432              &gSnpNt32DriverComponentName,
   1433              &gSnpNt32DriverComponentName2
   1434              );
   1435   if (EFI_ERROR (Status)) {
   1436     return Status;
   1437   }
   1438 
   1439   //
   1440   //  Initialize the global data
   1441   //
   1442   Status = SnpNt32InitializeGlobalData (&gSnpNt32GlobalData);
   1443   if (EFI_ERROR (Status)) {
   1444     SnpNt32Unload (ImageHandle);
   1445   }
   1446 
   1447   return Status;
   1448 }
   1449