/** @file
  This implementation of EFI_PXE_BASE_CODE_PROTOCOL and EFI_LOAD_FILE_PROTOCOL.

  Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "PxeBcImpl.h"


/**
  Enables the use of the PXE Base Code Protocol functions.

  This function enables the use of the PXE Base Code Protocol functions. If the
  Started field of the EFI_PXE_BASE_CODE_MODE structure is already TRUE, then
  EFI_ALREADY_STARTED will be returned. If UseIpv6 is TRUE, then IPv6 formatted
  addresses will be used in this session. If UseIpv6 is FALSE, then IPv4 formatted
  addresses will be used in this session. If UseIpv6 is TRUE, and the Ipv6Supported
  field of the EFI_PXE_BASE_CODE_MODE structure is FALSE, then EFI_UNSUPPORTED will
  be returned. If there is not enough memory or other resources to start the PXE
  Base Code Protocol, then EFI_OUT_OF_RESOURCES will be returned. Otherwise, the
  PXE Base Code Protocol will be started.

  @param[in]  This              Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance.
  @param[in]  UseIpv6           Specifies the type of IP addresses that are to be
                                used during the session that is being started.
                                Set to TRUE for IPv6, and FALSE for IPv4.

  @retval EFI_SUCCESS           The PXE Base Code Protocol was started.
  @retval EFI_DEVICE_ERROR      The network device encountered an error during this operation.
  @retval EFI_UNSUPPORTED       UseIpv6 is TRUE, but the Ipv6Supported field of the
                                EFI_PXE_BASE_CODE_MODE structure is FALSE.
  @retval EFI_ALREADY_STARTED   The PXE Base Code Protocol is already in the started state.
  @retval EFI_INVALID_PARAMETER The This parameter is NULL or does not point to a valid
                                EFI_PXE_BASE_CODE_PROTOCOL structure.
  @retval EFI_OUT_OF_RESOURCES  Could not allocate enough memory or other resources to start the
                                PXE Base Code Protocol.

**/
EFI_STATUS
EFIAPI
EfiPxeBcStart (
  IN EFI_PXE_BASE_CODE_PROTOCOL       *This,
  IN BOOLEAN                          UseIpv6
  )
{
  PXEBC_PRIVATE_DATA      *Private;
  EFI_PXE_BASE_CODE_MODE  *Mode;
  UINTN                   Index;
  EFI_STATUS              Status;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);
  Mode    = Private->PxeBc.Mode;

  if (Mode->Started) {
    return EFI_ALREADY_STARTED;
  }

  //
  // Detect whether using IPv6 or not, and set it into mode data.
  //
  if (UseIpv6 && Mode->Ipv6Available && Mode->Ipv6Supported && Private->Ip6Nic != NULL) {
    Mode->UsingIpv6 = TRUE;
  } else if (!UseIpv6 && Private->Ip4Nic != NULL) {
    Mode->UsingIpv6 = FALSE;
  } else {
    return EFI_UNSUPPORTED;
  }

  if (Mode->UsingIpv6) {
    AsciiPrint ("\n>>Start PXE over IPv6");
    //
    // Configure udp6 instance to receive data.
    //
    Status = Private->Udp6Read->Configure (
                                  Private->Udp6Read,
                                  &Private->Udp6CfgData
                                  );
    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }

    //
    // Configure block size for TFTP as a default value to handle all link layers.
    //
    Private->BlockSize = Private->Ip6MaxPacketSize -
                           PXEBC_DEFAULT_UDP_OVERHEAD_SIZE - PXEBC_DEFAULT_TFTP_OVERHEAD_SIZE;

    //
    // PXE over IPv6 starts here, initialize the fields and list header.
    //
    Private->Ip6Policy                          = PXEBC_IP6_POLICY_MAX;
    Private->ProxyOffer.Dhcp6.Packet.Offer.Size = PXEBC_CACHED_DHCP6_PACKET_MAX_SIZE;
    Private->DhcpAck.Dhcp6.Packet.Ack.Size      = PXEBC_CACHED_DHCP6_PACKET_MAX_SIZE;
    Private->PxeReply.Dhcp6.Packet.Ack.Size     = PXEBC_CACHED_DHCP6_PACKET_MAX_SIZE;

    for (Index = 0; Index < PXEBC_OFFER_MAX_NUM; Index++) {
      Private->OfferBuffer[Index].Dhcp6.Packet.Offer.Size = PXEBC_CACHED_DHCP6_PACKET_MAX_SIZE;
    }

    //
    // Create event and set status for token to capture ICMP6 error message.
    //
    Private->Icmp6Token.Status = EFI_NOT_READY;
    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    PxeBcIcmp6ErrorUpdate,
                    Private,
                    &Private->Icmp6Token.Event
                    );
    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }

    //
    // Set Ip6 policy to Automatic to start the IP6 router discovery.
    //
    Status = PxeBcSetIp6Policy (Private);
    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }
  } else {
    AsciiPrint ("\n>>Start PXE over IPv4");
    //
    // Configure udp4 instance to receive data.
    //
    Status = Private->Udp4Read->Configure (
                                  Private->Udp4Read,
                                  &Private->Udp4CfgData
                                  );
    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }

    //
    // Configure block size for TFTP as a default value to handle all link layers.
    //
    Private->BlockSize = Private->Ip4MaxPacketSize -
                           PXEBC_DEFAULT_UDP_OVERHEAD_SIZE - PXEBC_DEFAULT_TFTP_OVERHEAD_SIZE;

    //
    // PXE over IPv4 starts here, initialize the fields.
    //
    Private->ProxyOffer.Dhcp4.Packet.Offer.Size = PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE;
    Private->DhcpAck.Dhcp4.Packet.Ack.Size      = PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE;
    Private->PxeReply.Dhcp4.Packet.Ack.Size     = PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE;

    for (Index = 0; Index < PXEBC_OFFER_MAX_NUM; Index++) {
      Private->OfferBuffer[Index].Dhcp4.Packet.Offer.Size = PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE;
    }

    PxeBcSeedDhcp4Packet (&Private->SeedPacket, Private->Udp4Read);

    //
    // Create the event for Arp cache update.
    //
    Status = gBS->CreateEvent (
                    EVT_TIMER | EVT_NOTIFY_SIGNAL,
                    TPL_CALLBACK,
                    PxeBcArpCacheUpdate,
                    Private,
                    &Private->ArpUpdateEvent
                    );
    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }

    //
    // Start a periodic timer by second to update Arp cache.
    //
    Status = gBS->SetTimer (
                    Private->ArpUpdateEvent,
                    TimerPeriodic,
                    TICKS_PER_SECOND
                    );
    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }

    //
    // Create event and set status for token to capture ICMP error message.
    //
    Private->Icmp6Token.Status = EFI_NOT_READY;
    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    PxeBcIcmpErrorUpdate,
                    Private,
                    &Private->IcmpToken.Event
                    );
    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }

    //
    //DHCP4 service allows only one of its children to be configured in
    //the active state, If the DHCP4 D.O.R.A started by IP4 auto
    //configuration and has not been completed, the Dhcp4 state machine
    //will not be in the right state for the PXE to start a new round D.O.R.A.
    //so we need to switch its policy to static.
    //
    Status = PxeBcSetIp4Policy (Private);
    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }
  }

  //
  // If PcdTftpBlockSize is set to non-zero, override the default value.
  //
  if (PcdGet64 (PcdTftpBlockSize) != 0) {
    Private->BlockSize   = (UINTN) PcdGet64 (PcdTftpBlockSize);
  }

  //
  // Create event for UdpRead/UdpWrite timeout since they are both blocking API.
  //
  Status = gBS->CreateEvent (
                  EVT_TIMER,
                  TPL_CALLBACK,
                  NULL,
                  NULL,
                  &Private->UdpTimeOutEvent
                  );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  Private->IsAddressOk = FALSE;
  Mode->Started        = TRUE;

  return EFI_SUCCESS;

ON_ERROR:
  if (Mode->UsingIpv6) {
    if (Private->Icmp6Token.Event != NULL) {
      gBS->CloseEvent (Private->Icmp6Token.Event);
      Private->Icmp6Token.Event = NULL;
    }
    Private->Udp6Read->Configure (Private->Udp6Read, NULL);
    Private->Ip6->Configure (Private->Ip6, NULL);
  } else {
    if (Private->ArpUpdateEvent != NULL) {
      gBS->CloseEvent (Private->ArpUpdateEvent);
      Private->ArpUpdateEvent = NULL;
    }
    if (Private->IcmpToken.Event != NULL) {
      gBS->CloseEvent (Private->IcmpToken.Event);
      Private->IcmpToken.Event = NULL;
    }
    Private->Udp4Read->Configure (Private->Udp4Read, NULL);
    Private->Ip4->Configure (Private->Ip4, NULL);
  }
  return Status;
}


/**
  Disable the use of the PXE Base Code Protocol functions.

  This function stops all activity on the network device. All the resources allocated
  in Start() are released, the Started field of the EFI_PXE_BASE_CODE_MODE structure is
  set to FALSE, and EFI_SUCCESS is returned. If the Started field of the EFI_PXE_BASE_CODE_MODE
  structure is already FALSE, then EFI_NOT_STARTED will be returned.

  @param[in]  This               Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance.

  @retval EFI_SUCCESS           The PXE Base Code Protocol was stopped.
  @retval EFI_NOT_STARTED       The PXE Base Code Protocol is already in the stopped state.
  @retval EFI_INVALID_PARAMETER The This parameter is NULL or does not point to a valid
                                EFI_PXE_BASE_CODE_PROTOCOL structure.
  @retval Others

**/
EFI_STATUS
EFIAPI
EfiPxeBcStop (
  IN EFI_PXE_BASE_CODE_PROTOCOL       *This
  )
{
  PXEBC_PRIVATE_DATA      *Private;
  EFI_PXE_BASE_CODE_MODE  *Mode;
  BOOLEAN                 Ipv6Supported;
  BOOLEAN                 Ipv6Available;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Private       = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);
  Mode          = Private->PxeBc.Mode;
  Ipv6Supported = Mode->Ipv6Supported;
  Ipv6Available = Mode->Ipv6Available;

  if (!Mode->Started) {
    return EFI_NOT_STARTED;
  }

  if (Mode->UsingIpv6) {
    //
    // Configure all the instances for IPv6 as NULL.
    //
    ZeroMem (&Private->Udp6CfgData.StationAddress, sizeof (EFI_IPv6_ADDRESS));
    ZeroMem (&Private->Ip6CfgData.StationAddress, sizeof (EFI_IPv6_ADDRESS));
    Private->Dhcp6->Stop (Private->Dhcp6);
    Private->Dhcp6->Configure (Private->Dhcp6, NULL);
    Private->Udp6Write->Configure (Private->Udp6Write, NULL);
    Private->Udp6Read->Groups (Private->Udp6Read, FALSE, NULL);
    Private->Udp6Read->Configure (Private->Udp6Read, NULL);
    Private->Ip6->Cancel (Private->Ip6, &Private->Icmp6Token);
    Private->Ip6->Configure (Private->Ip6, NULL);
    PxeBcUnregisterIp6Address (Private);
    if (Private->Icmp6Token.Event != NULL) {
      gBS->CloseEvent (Private->Icmp6Token.Event);
      Private->Icmp6Token.Event = NULL;
    }
    if (Private->Dhcp6Request != NULL) {
      FreePool (Private->Dhcp6Request);
      Private->Dhcp6Request = NULL;
    }
    if (Private->BootFileName != NULL) {
      FreePool (Private->BootFileName);
      Private->BootFileName = NULL;
    }
  } else {
    //
    // Configure all the instances for IPv4 as NULL.
    //
    ZeroMem (&Private->Udp4CfgData.StationAddress, sizeof (EFI_IPv4_ADDRESS));
    ZeroMem (&Private->Udp4CfgData.SubnetMask, sizeof (EFI_IPv4_ADDRESS));
    ZeroMem (&Private->Ip4CfgData.StationAddress, sizeof (EFI_IPv4_ADDRESS));
    ZeroMem (&Private->Ip4CfgData.SubnetMask, sizeof (EFI_IPv4_ADDRESS));
    Private->Dhcp4->Stop (Private->Dhcp4);
    Private->Dhcp4->Configure (Private->Dhcp4, NULL);
    Private->Udp4Write->Configure (Private->Udp4Write, NULL);
    Private->Udp4Read->Groups (Private->Udp4Read, FALSE, NULL);
    Private->Udp4Read->Configure (Private->Udp4Read, NULL);
    Private->Ip4->Cancel (Private->Ip4, &Private->IcmpToken);
    Private->Ip4->Configure (Private->Ip4, NULL);
    if (Private->ArpUpdateEvent != NULL) {
      gBS->CloseEvent (Private->ArpUpdateEvent);
      Private->ArpUpdateEvent = NULL;
    }
    if (Private->IcmpToken.Event != NULL) {
      gBS->CloseEvent (Private->IcmpToken.Event);
      Private->IcmpToken.Event = NULL;
    }
    Private->BootFileName = NULL;
  }

  gBS->CloseEvent (Private->UdpTimeOutEvent);
  Private->CurSrcPort   = 0;
  Private->BootFileSize = 0;
  Private->SolicitTimes = 0;
  Private->ElapsedTime  = 0;
  ZeroMem (&Private->StationIp, sizeof (EFI_IP_ADDRESS));
  ZeroMem (&Private->SubnetMask, sizeof (EFI_IP_ADDRESS));
  ZeroMem (&Private->GatewayIp, sizeof (EFI_IP_ADDRESS));
  ZeroMem (&Private->ServerIp, sizeof (EFI_IP_ADDRESS));

  //
  // Reset the mode data.
  //
  ZeroMem (Mode, sizeof (EFI_PXE_BASE_CODE_MODE));
  Mode->Ipv6Available = Ipv6Available;
  Mode->Ipv6Supported = Ipv6Supported;
  Mode->AutoArp       = TRUE;
  Mode->TTL           = DEFAULT_TTL;
  Mode->ToS           = DEFAULT_ToS;

  return EFI_SUCCESS;
}


/**
  Attempts to complete a DHCPv4 D.O.R.A. (discover / offer / request / acknowledge) or DHCPv6
  S.A.R.R (solicit / advertise / request / reply) sequence.

  If SortOffers is TRUE, then the cached DHCP offer packets will be sorted before
  they are tried. If SortOffers is FALSE, then the cached DHCP offer packets will
  be tried in the order in which they are received. Please see the Preboot Execution
  Environment (PXE) Specification and Unified Extensible Firmware Interface (UEFI)
  Specification for additional details on the implementation of DHCP.
  If the Callback Protocol does not return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE,
  then the DHCP sequence will be stopped and EFI_ABORTED will be returned.

  @param[in]  This              Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance.
  @param[in]  SortOffers        TRUE if the offers received should be sorted. Set to FALSE to
                                try the offers in the order that they are received.

  @retval EFI_SUCCESS           Valid DHCP has completed.
  @retval EFI_NOT_STARTED       The PXE Base Code Protocol is in the stopped state.
  @retval EFI_INVALID_PARAMETER The This parameter is NULL or does not point to a valid
                                EFI_PXE_BASE_CODE_PROTOCOL structure.
  @retval EFI_DEVICE_ERROR      The network device encountered an error during this operation.
  @retval EFI_OUT_OF_RESOURCES  Could not allocate enough memory to complete the DHCP Protocol.
  @retval EFI_ABORTED           The callback function aborted the DHCP Protocol.
  @retval EFI_TIMEOUT           The DHCP Protocol timed out.
  @retval EFI_ICMP_ERROR        An ICMP error packet was received during the DHCP session.
  @retval EFI_NO_RESPONSE       Valid PXE offer was not received.

**/
EFI_STATUS
EFIAPI
EfiPxeBcDhcp (
  IN EFI_PXE_BASE_CODE_PROTOCOL       *This,
  IN BOOLEAN                          SortOffers
  )
{
  PXEBC_PRIVATE_DATA           *Private;
  EFI_PXE_BASE_CODE_MODE       *Mode;
  EFI_STATUS                   Status;
  EFI_PXE_BASE_CODE_IP_FILTER  IpFilter;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Status                  = EFI_SUCCESS;
  Private                 = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);
  Mode                    = Private->PxeBc.Mode;
  Mode->IcmpErrorReceived = FALSE;
  Private->Function       = EFI_PXE_BASE_CODE_FUNCTION_DHCP;
  Private->IsOfferSorted  = SortOffers;
  Private->SolicitTimes   = 0;
  Private->ElapsedTime    = 0;

  if (!Mode->Started) {
    return EFI_NOT_STARTED;
  }

  if (Mode->UsingIpv6) {

    //
    // Stop Udp6Read instance
    //
    Private->Udp6Read->Configure (Private->Udp6Read, NULL);

    //
    // Start S.A.R.R. process to get a IPv6 address and other boot information.
    //
    Status = PxeBcDhcp6Sarr (Private, Private->Dhcp6);
  } else {

    //
    // Stop Udp4Read instance
    //
    Private->Udp4Read->Configure (Private->Udp4Read, NULL);

    //
    // Start D.O.R.A. process to get a IPv4 address and other boot information.
    //
    Status = PxeBcDhcp4Dora (Private, Private->Dhcp4);
  }

  //
  // Reconfigure the UDP instance with the default configuration.
  //
  if (Mode->UsingIpv6) {
    Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData);
  } else {
    Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData);
  }
  //
  // Dhcp(), Discover(), and Mtftp() set the IP filter, and return with the IP
  // receive filter list emptied and the filter set to EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP.
  //
  ZeroMem(&IpFilter, sizeof (EFI_PXE_BASE_CODE_IP_FILTER));
  IpFilter.Filters = EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP;
  This->SetIpFilter (This, &IpFilter);

  return Status;
}


/**
  Attempts to complete the PXE Boot Server and/or boot image discovery sequence.

  This function attempts to complete the PXE Boot Server and/or boot image discovery
  sequence. If this sequence is completed, then EFI_SUCCESS is returned, and the
  PxeDiscoverValid, PxeDiscover, PxeReplyReceived, and PxeReply fields of the
  EFI_PXE_BASE_CODE_MODE structure are filled in. If UseBis is TRUE, then the
  PxeBisReplyReceived and PxeBisReply fields of the EFI_PXE_BASE_CODE_MODE structure
  will also be filled in. If UseBis is FALSE, then PxeBisReplyValid will be set to FALSE.
  In the structure referenced by parameter Info, the PXE Boot Server list, SrvList[],
  has two uses: It is the Boot Server IP address list used for unicast discovery
  (if the UseUCast field is TRUE), and it is the list used for Boot Server verification
  (if the MustUseList field is TRUE). Also, if the MustUseList field in that structure
  is TRUE and the AcceptAnyResponse field in the SrvList[] array is TRUE, any Boot
  Server reply of that type will be accepted. If the AcceptAnyResponse field is
  FALSE, only responses from Boot Servers with matching IP addresses will be accepted.
  This function can take at least 10 seconds to timeout and return control to the
  caller. If the Discovery sequence does not complete, then EFI_TIMEOUT will be
  returned. Please see the Preboot Execution Environment (PXE) Specification for
  additional details on the implementation of the Discovery sequence.
  If the Callback Protocol does not return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE,
  then the Discovery sequence is stopped and EFI_ABORTED will be returned.

  @param[in]  This              Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance.
  @param[in]  Type              The type of bootstrap to perform.
  @param[in]  Layer             Pointer to the boot server layer number to discover, which must be
                                PXE_BOOT_LAYER_INITIAL when a new server type is being
                                discovered.
  @param[in]  UseBis            TRUE if Boot Integrity Services are to be used. FALSE otherwise.
  @param[in]  Info              Pointer to a data structure that contains additional information
                                on the type of discovery operation that is to be performed.
                                It is optional.

  @retval EFI_SUCCESS           The Discovery sequence has been completed.
  @retval EFI_NOT_STARTED       The PXE Base Code Protocol is in the stopped state.
  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
  @retval EFI_DEVICE_ERROR      The network device encountered an error during this operation.
  @retval EFI_OUT_OF_RESOURCES  Could not allocate enough memory to complete Discovery.
  @retval EFI_ABORTED           The callback function aborted the Discovery sequence.
  @retval EFI_TIMEOUT           The Discovery sequence timed out.
  @retval EFI_ICMP_ERROR        An ICMP error packet was received during the PXE discovery
                                session.

**/
EFI_STATUS
EFIAPI
EfiPxeBcDiscover (
  IN EFI_PXE_BASE_CODE_PROTOCOL       *This,
  IN UINT16                           Type,
  IN UINT16                           *Layer,
  IN BOOLEAN                          UseBis,
  IN EFI_PXE_BASE_CODE_DISCOVER_INFO  *Info   OPTIONAL
  )
{
  PXEBC_PRIVATE_DATA              *Private;
  EFI_PXE_BASE_CODE_MODE          *Mode;
  EFI_PXE_BASE_CODE_DISCOVER_INFO DefaultInfo;
  EFI_PXE_BASE_CODE_SRVLIST       *SrvList;
  PXEBC_BOOT_SVR_ENTRY            *BootSvrEntry;
  UINT16                          Index;
  EFI_STATUS                      Status;
  EFI_PXE_BASE_CODE_IP_FILTER     IpFilter;
  EFI_PXE_BASE_CODE_DISCOVER_INFO *NewCreatedInfo;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Private                 = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);
  Mode                    = Private->PxeBc.Mode;
  Mode->IcmpErrorReceived = FALSE;
  BootSvrEntry            = NULL;
  SrvList                 = NULL;
  Status                  = EFI_DEVICE_ERROR;
  Private->Function       = EFI_PXE_BASE_CODE_FUNCTION_DISCOVER;
  NewCreatedInfo          = NULL;

  if (!Mode->Started) {
    return EFI_NOT_STARTED;
  }

  //
  // Station address should be ready before do discover.
  //
  if (!Private->IsAddressOk) {
    return EFI_INVALID_PARAMETER;
  }

  if (Mode->UsingIpv6) {

    //
    // Stop Udp6Read instance
    //
    Private->Udp6Read->Configure (Private->Udp6Read, NULL);
  } else {

    //
    // Stop Udp4Read instance
    //
    Private->Udp4Read->Configure (Private->Udp4Read, NULL);
  }

  //
  // There are 3 methods to get the information for discover.
  //
  ZeroMem (&DefaultInfo, sizeof (EFI_PXE_BASE_CODE_DISCOVER_INFO));
  if (*Layer != EFI_PXE_BASE_CODE_BOOT_LAYER_INITIAL) {
    //
    // 1. Take the previous setting as the discover info.
    //
    if (!Mode->PxeDiscoverValid ||
        !Mode->PxeReplyReceived ||
        (!Mode->PxeBisReplyReceived && UseBis)) {
      Status = EFI_INVALID_PARAMETER;
      goto ON_EXIT;
    }

    Info                         = &DefaultInfo;
    Info->IpCnt                  = 1;
    Info->UseUCast               = TRUE;
    SrvList                      = Info->SrvList;
    SrvList[0].Type              = Type;
    SrvList[0].AcceptAnyResponse = FALSE;

    CopyMem (&SrvList->IpAddr, &Private->ServerIp, sizeof (EFI_IP_ADDRESS));

  } else if (Info == NULL) {
    //
    // 2. Extract the discover information from the cached packets if unspecified.
    //
    NewCreatedInfo = &DefaultInfo;
    Status = PxeBcExtractDiscoverInfo (Private, Type, &NewCreatedInfo, &BootSvrEntry, &SrvList);
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }
    ASSERT (NewCreatedInfo != NULL);
    Info = NewCreatedInfo;
  } else {
    //
    // 3. Take the pass-in information as the discover info, and validate the server list.
    //
    SrvList = Info->SrvList;

    if (!SrvList[0].AcceptAnyResponse) {
      for (Index = 1; Index < Info->IpCnt; Index++) {
        if (SrvList[Index].AcceptAnyResponse) {
          break;
        }
      }
      if (Index != Info->IpCnt) {
        //
        // It's invalid if the first server doesn't accept any response
        // but any of the other servers does accept any response.
        //
        Status = EFI_INVALID_PARAMETER;
        goto ON_EXIT;
      }
    }
  }

  //
  // Info and BootSvrEntry/SrvList are all ready by now, so execute discover by UniCast/BroadCast/MultiCast.
  //
  if ((!Info->UseUCast && !Info->UseBCast && !Info->UseMCast) ||
      (Info->MustUseList && Info->IpCnt == 0)) {
    Status = EFI_INVALID_PARAMETER;
    goto ON_EXIT;
  }

  Private->IsDoDiscover = TRUE;

  if (Info->UseMCast) {
    //
    // Do discover by multicast.
    //
    Status = PxeBcDiscoverBootServer (
               Private,
               Type,
               Layer,
               UseBis,
               &Info->ServerMCastIp,
               Info->IpCnt,
               SrvList
               );

  } else if (Info->UseBCast) {
    //
    // Do discover by broadcast, but only valid for IPv4.
    //
    ASSERT (!Mode->UsingIpv6);
    Status = PxeBcDiscoverBootServer (
               Private,
               Type,
               Layer,
               UseBis,
               NULL,
               Info->IpCnt,
               SrvList
               );

  } else if (Info->UseUCast) {
    //
    // Do discover by unicast.
    //
    for (Index = 0; Index < Info->IpCnt; Index++) {
      if (BootSvrEntry == NULL) {
        CopyMem (&Private->ServerIp, &SrvList[Index].IpAddr, sizeof (EFI_IP_ADDRESS));
      } else {
        ASSERT (!Mode->UsingIpv6);
        ZeroMem (&Private->ServerIp, sizeof (EFI_IP_ADDRESS));
        CopyMem (&Private->ServerIp, &BootSvrEntry->IpAddr[Index], sizeof (EFI_IPv4_ADDRESS));
      }

      Status = PxeBcDiscoverBootServer (
                 Private,
                 Type,
                 Layer,
                 UseBis,
                 &Private->ServerIp,
                 Info->IpCnt,
                 SrvList
                 );
      }
  }

  if (!EFI_ERROR (Status)) {
    //
    // Parse the cached PXE reply packet, and store it into mode data if valid.
    //
    if (Mode->UsingIpv6) {
      Status = PxeBcParseDhcp6Packet (&Private->PxeReply.Dhcp6);
      if (!EFI_ERROR (Status)) {
        CopyMem (
          &Mode->PxeReply.Dhcpv6,
          &Private->PxeReply.Dhcp6.Packet.Ack.Dhcp6,
          Private->PxeReply.Dhcp6.Packet.Ack.Length
          );
        Mode->PxeReplyReceived = TRUE;
        Mode->PxeDiscoverValid = TRUE;
      }
    } else {
      Status = PxeBcParseDhcp4Packet (&Private->PxeReply.Dhcp4);
      if (!EFI_ERROR (Status)) {
        CopyMem (
          &Mode->PxeReply.Dhcpv4,
          &Private->PxeReply.Dhcp4.Packet.Ack.Dhcp4,
          Private->PxeReply.Dhcp4.Packet.Ack.Length
          );
        Mode->PxeReplyReceived = TRUE;
        Mode->PxeDiscoverValid = TRUE;
      }
    }
  }

ON_EXIT:

  if (NewCreatedInfo != NULL && NewCreatedInfo != &DefaultInfo) {
    FreePool (NewCreatedInfo);
  }

  if (Mode->UsingIpv6) {
    Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData);
  } else {
    Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData);
  }

  //
  // Dhcp(), Discover(), and Mtftp() set the IP filter, and return with the IP
  // receive filter list emptied and the filter set to EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP.
  //
  ZeroMem(&IpFilter, sizeof (EFI_PXE_BASE_CODE_IP_FILTER));
  IpFilter.Filters = EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP;
  This->SetIpFilter (This, &IpFilter);

  return Status;
}


/**
  Used to perform TFTP and MTFTP services.

  This function is used to perform TFTP and MTFTP services. This includes the
  TFTP operations to get the size of a file, read a directory, read a file, and
  write a file. It also includes the MTFTP operations to get the size of a file,
  read a directory, and read a file. The type of operation is specified by Operation.
  If the callback function that is invoked during the TFTP/MTFTP operation does
  not return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, then EFI_ABORTED will
  be returned.
  For read operations, the return data will be placed in the buffer specified by
  BufferPtr. If BufferSize is too small to contain the entire downloaded file,
  then EFI_BUFFER_TOO_SMALL will be returned and BufferSize will be set to zero,
  or the size of the requested file. (NOTE: the size of the requested file is only returned
  if the TFTP server supports TFTP options). If BufferSize is large enough for the
  read operation, then BufferSize will be set to the size of the downloaded file,
  and EFI_SUCCESS will be returned. Applications using the PxeBc.Mtftp() services
  should use the get-file-size operations to determine the size of the downloaded
  file prior to using the read-file operations-especially when downloading large
  (greater than 64 MB) files-instead of making two calls to the read-file operation.
  Following this recommendation will save time if the file is larger than expected
  and the TFTP server does not support TFTP option extensions. Without TFTP option
  extension support, the client must download the entire file, counting and discarding
  the received packets, to determine the file size.
  For write operations, the data to be sent is in the buffer specified by BufferPtr.
  BufferSize specifies the number of bytes to send. If the write operation completes
  successfully, then EFI_SUCCESS will be returned.
  For TFTP "get file size" operations, the size of the requested file or directory
  is returned in BufferSize, and EFI_SUCCESS will be returned. If the TFTP server
  does not support options, the file will be downloaded into a bit bucket and the
  length of the downloaded file will be returned. For MTFTP "get file size" operations,
  if the MTFTP server does not support the "get file size" option, EFI_UNSUPPORTED
  will be returned.
  This function can take up to 10 seconds to timeout and return control to the caller.
  If the TFTP sequence does not complete, EFI_TIMEOUT will be returned.
  If the Callback Protocol does not return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE,
  then the TFTP sequence is stopped and EFI_ABORTED will be returned.

  @param[in]      This          Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance.
  @param[in]      Operation     The type of operation to perform.
  @param[in, out] BufferPtr     A pointer to the data buffer.
  @param[in]      Overwrite     Only used on write file operations. TRUE if a file on a remote
                                server can be overwritten.
  @param[in, out] BufferSize    For get-file-size operations, *BufferSize returns the size of the
                                requested file.
  @param[in]      BlockSize     The requested block size to be used during a TFTP transfer.
  @param[in]      ServerIp      The TFTP / MTFTP server IP address.
  @param[in]      Filename      A Null-terminated ASCII string that specifies a directory name
                                or a file name.
  @param[in]      Info          Pointer to the MTFTP information.
  @param[in]      DontUseBuffer Set to FALSE for normal TFTP and MTFTP read file operation.

  @retval EFI_SUCCESS           The TFTP/MTFTP operation was completed.
  @retval EFI_NOT_STARTED       The PXE Base Code Protocol is in the stopped state.
  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
  @retval EFI_DEVICE_ERROR      The network device encountered an error during this operation.
  @retval EFI_BUFFER_TOO_SMALL  The buffer is not large enough to complete the read operation.
  @retval EFI_ABORTED           The callback function aborted the TFTP/MTFTP operation.
  @retval EFI_TIMEOUT           The TFTP/MTFTP operation timed out.
  @retval EFI_ICMP_ERROR        An ICMP error packet was received during the MTFTP session.
  @retval EFI_TFTP_ERROR        A TFTP error packet was received during the MTFTP session.

**/
EFI_STATUS
EFIAPI
EfiPxeBcMtftp (
  IN     EFI_PXE_BASE_CODE_PROTOCOL       *This,
  IN     EFI_PXE_BASE_CODE_TFTP_OPCODE    Operation,
  IN OUT VOID                             *BufferPtr    OPTIONAL,
  IN     BOOLEAN                          Overwrite,
  IN OUT UINT64                           *BufferSize,
  IN     UINTN                            *BlockSize    OPTIONAL,
  IN     EFI_IP_ADDRESS                   *ServerIp,
  IN     UINT8                            *Filename,
  IN     EFI_PXE_BASE_CODE_MTFTP_INFO     *Info         OPTIONAL,
  IN     BOOLEAN                          DontUseBuffer
  )
{
  PXEBC_PRIVATE_DATA              *Private;
  EFI_PXE_BASE_CODE_MODE          *Mode;
  EFI_MTFTP4_CONFIG_DATA          Mtftp4Config;
  EFI_MTFTP6_CONFIG_DATA          Mtftp6Config;
  VOID                            *Config;
  EFI_STATUS                      Status;
  EFI_PXE_BASE_CODE_IP_FILTER     IpFilter;
  UINTN                           WindowSize;

  if ((This == NULL) ||
      (Filename == NULL) ||
      (BufferSize == NULL) ||
      (ServerIp == NULL) ||
      ((BlockSize != NULL) && (*BlockSize < PXE_MTFTP_DEFAULT_BLOCK_SIZE))) {
    return EFI_INVALID_PARAMETER;
  }

  if (Operation == EFI_PXE_BASE_CODE_TFTP_READ_FILE ||
      Operation == EFI_PXE_BASE_CODE_TFTP_READ_DIRECTORY ||
      Operation == EFI_PXE_BASE_CODE_MTFTP_READ_FILE ||
      Operation == EFI_PXE_BASE_CODE_MTFTP_READ_DIRECTORY) {
    if (BufferPtr == NULL && !DontUseBuffer) {
      return EFI_INVALID_PARAMETER;
    }
  }

  Config    = NULL;
  Status    = EFI_DEVICE_ERROR;
  Private   = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);
  Mode      = Private->PxeBc.Mode;

  //
  // Get PcdPxeTftpWindowSize.
  //
  WindowSize = (UINTN) PcdGet64 (PcdPxeTftpWindowSize);

  if (Mode->UsingIpv6) {
    if (!NetIp6IsValidUnicast (&ServerIp->v6)) {
      return EFI_INVALID_PARAMETER;
    }
  } else {
    if (IP4_IS_UNSPECIFIED (NTOHL (ServerIp->Addr[0])) || IP4_IS_LOCAL_BROADCAST (NTOHL (ServerIp->Addr[0])))   {
      return EFI_INVALID_PARAMETER;
    }
  }

  if (Mode->UsingIpv6) {
    //
    // Set configuration data for Mtftp6 instance.
    //
    ZeroMem (&Mtftp6Config, sizeof (EFI_MTFTP6_CONFIG_DATA));
    Config                         = &Mtftp6Config;
    Mtftp6Config.TimeoutValue      = PXEBC_MTFTP_TIMEOUT;
    Mtftp6Config.TryCount          = PXEBC_MTFTP_RETRIES;
    CopyMem (&Mtftp6Config.StationIp, &Private->StationIp.v6, sizeof (EFI_IPv6_ADDRESS));
    CopyMem (&Mtftp6Config.ServerIp, &ServerIp->v6, sizeof (EFI_IPv6_ADDRESS));
    //
    // Stop Udp6Read instance
    //
    Private->Udp6Read->Configure (Private->Udp6Read, NULL);
  } else {
    //
    // Set configuration data for Mtftp4 instance.
    //
    ZeroMem (&Mtftp4Config, sizeof (EFI_MTFTP4_CONFIG_DATA));
    Config                         = &Mtftp4Config;
    Mtftp4Config.UseDefaultSetting = FALSE;
    Mtftp4Config.TimeoutValue      = PXEBC_MTFTP_TIMEOUT;
    Mtftp4Config.TryCount          = PXEBC_MTFTP_RETRIES;
    CopyMem (&Mtftp4Config.StationIp, &Private->StationIp.v4, sizeof (EFI_IPv4_ADDRESS));
    CopyMem (&Mtftp4Config.SubnetMask, &Private->SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS));
    CopyMem (&Mtftp4Config.GatewayIp, &Private->GatewayIp.v4, sizeof (EFI_IPv4_ADDRESS));
    CopyMem (&Mtftp4Config.ServerIp, &ServerIp->v4, sizeof (EFI_IPv4_ADDRESS));
    //
    // Stop Udp4Read instance
    //
    Private->Udp4Read->Configure (Private->Udp4Read, NULL);
  }

  Mode->TftpErrorReceived = FALSE;
  Mode->IcmpErrorReceived = FALSE;

  switch (Operation) {

  case EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE:
    //
    // Send TFTP request to get file size.
    //
    Status = PxeBcTftpGetFileSize (
               Private,
               Config,
               Filename,
               BlockSize,
               (WindowSize > 1) ? &WindowSize : NULL,
               BufferSize
               );

    break;

  case EFI_PXE_BASE_CODE_TFTP_READ_FILE:
    //
    // Send TFTP request to read file.
    //
    Status = PxeBcTftpReadFile (
               Private,
               Config,
               Filename,
               BlockSize,
               (WindowSize > 1) ? &WindowSize : NULL,
               BufferPtr,
               BufferSize,
               DontUseBuffer
               );

    break;

  case EFI_PXE_BASE_CODE_TFTP_WRITE_FILE:
    //
    // Send TFTP request to write file.
    //
    Status = PxeBcTftpWriteFile (
               Private,
               Config,
               Filename,
               Overwrite,
               BlockSize,
               BufferPtr,
               BufferSize
               );

    break;

  case EFI_PXE_BASE_CODE_TFTP_READ_DIRECTORY:
    //
    // Send TFTP request to read directory.
    //
    Status = PxeBcTftpReadDirectory (
               Private,
               Config,
               Filename,
               BlockSize,
               (WindowSize > 1) ? &WindowSize : NULL,
               BufferPtr,
               BufferSize,
               DontUseBuffer
               );

    break;

  case EFI_PXE_BASE_CODE_MTFTP_GET_FILE_SIZE:
  case EFI_PXE_BASE_CODE_MTFTP_READ_FILE:
  case EFI_PXE_BASE_CODE_MTFTP_READ_DIRECTORY:
    Status = EFI_UNSUPPORTED;

    break;

  default:
    Status = EFI_INVALID_PARAMETER;

    break;
  }

  if (Status == EFI_ICMP_ERROR) {
    Mode->IcmpErrorReceived = TRUE;
  }

  //
  // Reconfigure the UDP instance with the default configuration.
  //
  if (Mode->UsingIpv6) {
    Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData);
  } else {
    Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData);
  }
  //
  // Dhcp(), Discover(), and Mtftp() set the IP filter, and return with the IP
  // receive filter list emptied and the filter set to EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP.
  //
  ZeroMem(&IpFilter, sizeof (EFI_PXE_BASE_CODE_IP_FILTER));
  IpFilter.Filters = EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP;
  This->SetIpFilter (This, &IpFilter);

  return Status;
}


/**
  Writes a UDP packet to the network interface.

  This function writes a UDP packet specified by the (optional HeaderPtr and)
  BufferPtr parameters to the network interface. The UDP header is automatically
  built by this routine. It uses the parameters OpFlags, DestIp, DestPort, GatewayIp,
  SrcIp, and SrcPort to build this header. If the packet is successfully built and
  transmitted through the network interface, then EFI_SUCCESS will be returned.
  If a timeout occurs during the transmission of the packet, then EFI_TIMEOUT will
  be returned. If an ICMP error occurs during the transmission of the packet, then
  the IcmpErrorReceived field is set to TRUE, the IcmpError field is filled in and
  EFI_ICMP_ERROR will be returned. If the Callback Protocol does not return
  EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE, then EFI_ABORTED will be returned.

  @param[in]      This          Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance.
  @param[in]      OpFlags       The UDP operation flags.
  @param[in]      DestIp        The destination IP address.
  @param[in]      DestPort      The destination UDP port number.
  @param[in]      GatewayIp     The gateway IP address.
  @param[in]      SrcIp         The source IP address.
  @param[in, out] SrcPort       The source UDP port number.
  @param[in]      HeaderSize    An optional field which may be set to the length of a header
                                at HeaderPtr to be prefixed to the data at BufferPtr.
  @param[in]  HeaderPtr         If HeaderSize is not NULL, a pointer to a header to be
                                prefixed to the data at BufferPtr.
  @param[in]  BufferSize        A pointer to the size of the data at BufferPtr.
  @param[in]  BufferPtr         A pointer to the data to be written.

  @retval EFI_SUCCESS           The UDP Write operation completed.
  @retval EFI_NOT_STARTED       The PXE Base Code Protocol is in the stopped state.
  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
  @retval EFI_BAD_BUFFER_SIZE   The buffer is too long to be transmitted.
  @retval EFI_ABORTED           The callback function aborted the UDP Write operation.
  @retval EFI_TIMEOUT           The UDP Write operation timed out.
  @retval EFI_ICMP_ERROR        An ICMP error packet was received during the UDP write session.

**/
EFI_STATUS
EFIAPI
EfiPxeBcUdpWrite (
  IN     EFI_PXE_BASE_CODE_PROTOCOL       *This,
  IN     UINT16                           OpFlags,
  IN     EFI_IP_ADDRESS                   *DestIp,
  IN     EFI_PXE_BASE_CODE_UDP_PORT       *DestPort,
  IN     EFI_IP_ADDRESS                   *GatewayIp  OPTIONAL,
  IN     EFI_IP_ADDRESS                   *SrcIp      OPTIONAL,
  IN OUT EFI_PXE_BASE_CODE_UDP_PORT       *SrcPort    OPTIONAL,
  IN     UINTN                            *HeaderSize OPTIONAL,
  IN     VOID                             *HeaderPtr  OPTIONAL,
  IN     UINTN                            *BufferSize,
  IN     VOID                             *BufferPtr
  )
{
  PXEBC_PRIVATE_DATA        *Private;
  EFI_PXE_BASE_CODE_MODE    *Mode;
  EFI_UDP4_SESSION_DATA     Udp4Session;
  EFI_UDP6_SESSION_DATA     Udp6Session;
  EFI_STATUS                Status;
  BOOLEAN                   DoNotFragment;

  if (This == NULL || DestIp == NULL || DestPort == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);
  Mode    = Private->PxeBc.Mode;

  if ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT) != 0) {
    DoNotFragment = FALSE;
  } else {
    DoNotFragment = TRUE;
  }

  if (!Mode->UsingIpv6 && GatewayIp != NULL && Mode->SubnetMask.Addr[0] != 0 &&
      !NetIp4IsUnicast (NTOHL (GatewayIp->Addr[0]), EFI_NTOHL(Mode->SubnetMask))) {
    //
    // Gateway is provided but it's not a unicast IPv4 address, while it will be ignored for IPv6.
    //
    return EFI_INVALID_PARAMETER;
  }

  if (HeaderSize != NULL && (*HeaderSize == 0 || HeaderPtr == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (BufferSize == NULL || (*BufferSize != 0 && BufferPtr == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (!Mode->Started) {
    return EFI_NOT_STARTED;
  }

  if (!Private->IsAddressOk && SrcIp == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (Private->CurSrcPort == 0 ||
      (SrcPort != NULL && *SrcPort != Private->CurSrcPort)) {
    //
    // Reconfigure UDPv4/UDPv6 for UdpWrite if the source port changed.
    //
    if (SrcPort != NULL) {
      Private->CurSrcPort = *SrcPort;
    }
  }

  if (Mode->UsingIpv6) {
    Status = PxeBcConfigUdp6Write (
               Private->Udp6Write,
               &Private->StationIp.v6,
               &Private->CurSrcPort
               );
  } else {
    //
    // Configure the UDPv4 instance with gateway information from DHCP server as default.
    //
    Status = PxeBcConfigUdp4Write (
               Private->Udp4Write,
               &Private->StationIp.v4,
               &Private->SubnetMask.v4,
               &Private->GatewayIp.v4,
               &Private->CurSrcPort,
               DoNotFragment,
               Private->Mode.TTL,
               Private->Mode.ToS
               );
  }

  if (EFI_ERROR (Status)) {
    Private->CurSrcPort = 0;
    return EFI_INVALID_PARAMETER;
  } else if (SrcPort != NULL) {
    *SrcPort = Private->CurSrcPort;
  }

  //
  // Start a timer as timeout event for this blocking API.
  //
  gBS->SetTimer (Private->UdpTimeOutEvent, TimerRelative, PXEBC_UDP_TIMEOUT);

  if (Mode->UsingIpv6) {
    //
    // Construct UDPv6 session data.
    //
    ZeroMem (&Udp6Session, sizeof (EFI_UDP6_SESSION_DATA));
    CopyMem (&Udp6Session.DestinationAddress, DestIp, sizeof (EFI_IPv6_ADDRESS));
    Udp6Session.DestinationPort = *DestPort;
    if (SrcIp != NULL) {
      CopyMem (&Udp6Session.SourceAddress, SrcIp, sizeof (EFI_IPv6_ADDRESS));
    }
    if (SrcPort != NULL) {
      Udp6Session.SourcePort = *SrcPort;
    }

    Status = PxeBcUdp6Write (
               Private->Udp6Write,
               &Udp6Session,
               Private->UdpTimeOutEvent,
               HeaderSize,
               HeaderPtr,
               BufferSize,
               BufferPtr
               );
  } else {
    //
    // Construct UDPv4 session data.
    //
    ZeroMem (&Udp4Session, sizeof (EFI_UDP4_SESSION_DATA));
    CopyMem (&Udp4Session.DestinationAddress, DestIp, sizeof (EFI_IPv4_ADDRESS));
    Udp4Session.DestinationPort = *DestPort;
    if (SrcIp != NULL) {
      CopyMem (&Udp4Session.SourceAddress, SrcIp, sizeof (EFI_IPv4_ADDRESS));
    }
    if (SrcPort != NULL) {
      Udp4Session.SourcePort = *SrcPort;
    }
    //
    // Override the gateway information if user specified.
    //
    Status = PxeBcUdp4Write (
               Private->Udp4Write,
               &Udp4Session,
               Private->UdpTimeOutEvent,
               (EFI_IPv4_ADDRESS *) GatewayIp,
               HeaderSize,
               HeaderPtr,
               BufferSize,
               BufferPtr
               );
  }

  gBS->SetTimer (Private->UdpTimeOutEvent, TimerCancel, 0);


  //
  // Reset the UdpWrite instance.
  //
  if (Mode->UsingIpv6) {
    Private->Udp6Write->Configure (Private->Udp6Write, NULL);
  } else {
    Private->Udp4Write->Configure (Private->Udp4Write, NULL);
  }

  return Status;
}


/**
  Reads a UDP packet from the network interface.
+
  This function reads a UDP packet from a network interface. The data contents
  are returned in (the optional HeaderPtr and) BufferPtr, and the size of the
  buffer received is returned in BufferSize . If the input BufferSize is smaller
  than the UDP packet received (less optional HeaderSize), it will be set to the
  required size, and EFI_BUFFER_TOO_SMALL will be returned. In this case, the
  contents of BufferPtr are undefined, and the packet is lost. If a UDP packet is
  successfully received, then EFI_SUCCESS will be returned, and the information
  from the UDP header will be returned in DestIp, DestPort, SrcIp, and SrcPort if
  they are not NULL. Depending on the values of OpFlags and the DestIp, DestPort,
  SrcIp, and SrcPort input values, different types of UDP packet receive filtering
  will be performed. The following tables summarize these receive filter operations.

  @param[in]      This          Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance.
  @param[in]      OpFlags       The UDP operation flags.
  @param[in, out] DestIp        The destination IP address.
  @param[in, out] DestPort      The destination UDP port number.
  @param[in, out] SrcIp         The source IP address.
  @param[in, out] SrcPort       The source UDP port number.
  @param[in]      HeaderSize    An optional field which may be set to the length of a
                                header at HeaderPtr to be prefixed to the data at BufferPtr.
  @param[in]      HeaderPtr     If HeaderSize is not NULL, a pointer to a header to be
                                prefixed to the data at BufferPtr.
  @param[in, out] BufferSize    A pointer to the size of the data at BufferPtr.
  @param[in]      BufferPtr     A pointer to the data to be read.

  @retval EFI_SUCCESS           The UDP Read operation was completed.
  @retval EFI_NOT_STARTED       The PXE Base Code Protocol is in the stopped state.
  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
  @retval EFI_DEVICE_ERROR      The network device encountered an error during this operation.
  @retval EFI_BUFFER_TOO_SMALL  The packet is larger than Buffer can hold.
  @retval EFI_ABORTED           The callback function aborted the UDP Read operation.
  @retval EFI_TIMEOUT           The UDP Read operation timed out.

**/
EFI_STATUS
EFIAPI
EfiPxeBcUdpRead (
  IN     EFI_PXE_BASE_CODE_PROTOCOL   *This,
  IN     UINT16                       OpFlags,
  IN OUT EFI_IP_ADDRESS               *DestIp      OPTIONAL,
  IN OUT EFI_PXE_BASE_CODE_UDP_PORT   *DestPort    OPTIONAL,
  IN OUT EFI_IP_ADDRESS               *SrcIp       OPTIONAL,
  IN OUT EFI_PXE_BASE_CODE_UDP_PORT   *SrcPort     OPTIONAL,
  IN     UINTN                        *HeaderSize  OPTIONAL,
  IN     VOID                         *HeaderPtr   OPTIONAL,
  IN OUT UINTN                        *BufferSize,
  IN     VOID                         *BufferPtr
  )
{
  PXEBC_PRIVATE_DATA          *Private;
  EFI_PXE_BASE_CODE_MODE      *Mode;
  EFI_UDP4_COMPLETION_TOKEN   Udp4Token;
  EFI_UDP6_COMPLETION_TOKEN   Udp6Token;
  EFI_UDP4_RECEIVE_DATA       *Udp4Rx;
  EFI_UDP6_RECEIVE_DATA       *Udp6Rx;
  EFI_STATUS                  Status;
  BOOLEAN                     IsDone;
  BOOLEAN                     IsMatched;
  UINTN                       CopiedLen;
  UINTN                       HeaderLen;
  UINTN                       HeaderCopiedLen;
  UINTN                       BufferCopiedLen;
  UINT32                      FragmentLength;
  UINTN                       FragmentIndex;
  UINT8                       *FragmentBuffer;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Private   = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);
  Mode      = Private->PxeBc.Mode;
  IsDone    = FALSE;
  IsMatched = FALSE;
  Udp4Rx    = NULL;
  Udp6Rx    = NULL;

  if (((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT) == 0 && DestPort == NULL) ||
      ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP) == 0 && SrcIp == NULL) ||
      ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT) == 0 && SrcPort == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((HeaderSize != NULL && *HeaderSize == 0) || (HeaderSize != NULL && HeaderPtr == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((BufferSize == NULL) || (BufferPtr == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (!Mode->Started) {
    return EFI_NOT_STARTED;
  }

  ZeroMem (&Udp6Token, sizeof (EFI_UDP6_COMPLETION_TOKEN));
  ZeroMem (&Udp4Token, sizeof (EFI_UDP4_COMPLETION_TOKEN));

  if (Mode->UsingIpv6) {
    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    PxeBcCommonNotify,
                    &IsDone,
                    &Udp6Token.Event
                    );
    if (EFI_ERROR (Status)) {
      return EFI_OUT_OF_RESOURCES;
    }
  } else {
    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    PxeBcCommonNotify,
                    &IsDone,
                    &Udp4Token.Event
                    );
    if (EFI_ERROR (Status)) {
      return EFI_OUT_OF_RESOURCES;
    }
  }

  //
  // Start a timer as timeout event for this blocking API.
  //
  gBS->SetTimer (Private->UdpTimeOutEvent, TimerRelative, PXEBC_UDP_TIMEOUT);
  Mode->IcmpErrorReceived = FALSE;

  //
  // Read packet by Udp4Read/Udp6Read until matched or timeout.
  //
  while (!IsMatched && !EFI_ERROR (Status)) {
    if (Mode->UsingIpv6) {
      Status = PxeBcUdp6Read (
                 Private->Udp6Read,
                 &Udp6Token,
                 Mode,
                 Private->UdpTimeOutEvent,
                 OpFlags,
                 &IsDone,
                 &IsMatched,
                 DestIp,
                 DestPort,
                 SrcIp,
                 SrcPort
                 );
    } else {
      Status = PxeBcUdp4Read (
                 Private->Udp4Read,
                 &Udp4Token,
                 Mode,
                 Private->UdpTimeOutEvent,
                 OpFlags,
                 &IsDone,
                 &IsMatched,
                 DestIp,
                 DestPort,
                 SrcIp,
                 SrcPort
                 );
    }
  }

  if (Status == EFI_ICMP_ERROR ||
      Status == EFI_NETWORK_UNREACHABLE ||
      Status == EFI_HOST_UNREACHABLE ||
      Status == EFI_PROTOCOL_UNREACHABLE ||
      Status == EFI_PORT_UNREACHABLE) {
    //
    // Get different return status for icmp error from Udp, refers to UEFI spec.
    //
    Mode->IcmpErrorReceived = TRUE;
  }
  gBS->SetTimer (Private->UdpTimeOutEvent, TimerCancel, 0);

  if (IsMatched) {
    //
    // Copy the received packet to user if matched by filter.
    //
    if (Mode->UsingIpv6) {
      Udp6Rx = Udp6Token.Packet.RxData;
      ASSERT (Udp6Rx != NULL);

      HeaderLen = 0;
      if (HeaderSize != NULL) {
        HeaderLen = MIN (*HeaderSize, Udp6Rx->DataLength);
      }

      if (Udp6Rx->DataLength - HeaderLen > *BufferSize) {
        Status = EFI_BUFFER_TOO_SMALL;
      } else {
        if (HeaderSize != NULL) {
          *HeaderSize = HeaderLen;
        }
        *BufferSize = Udp6Rx->DataLength - HeaderLen;

        HeaderCopiedLen = 0;
        BufferCopiedLen = 0;
        for (FragmentIndex = 0; FragmentIndex < Udp6Rx->FragmentCount; FragmentIndex++) {
          FragmentLength = Udp6Rx->FragmentTable[FragmentIndex].FragmentLength;
          FragmentBuffer = Udp6Rx->FragmentTable[FragmentIndex].FragmentBuffer;
          if (HeaderCopiedLen + FragmentLength < HeaderLen) {
            //
            // Copy the header part of received data.
            //
            CopyMem ((UINT8 *) HeaderPtr + HeaderCopiedLen, FragmentBuffer, FragmentLength);
            HeaderCopiedLen += FragmentLength;
          } else if (HeaderCopiedLen < HeaderLen) {
            //
            // Copy the header part of received data.
            //
            CopiedLen = HeaderLen - HeaderCopiedLen;
            CopyMem ((UINT8 *) HeaderPtr + HeaderCopiedLen, FragmentBuffer, CopiedLen);
            HeaderCopiedLen += CopiedLen;

            //
            // Copy the other part of received data.
            //
            CopyMem ((UINT8 *) BufferPtr + BufferCopiedLen, FragmentBuffer + CopiedLen, FragmentLength - CopiedLen);
            BufferCopiedLen += (FragmentLength - CopiedLen);
          } else {
            //
            // Copy the other part of received data.
            //
            CopyMem ((UINT8 *) BufferPtr + BufferCopiedLen, FragmentBuffer, FragmentLength);
            BufferCopiedLen += FragmentLength;
          }
        }
      }
      //
      // Recycle the receiving buffer after copy to user.
      //
      gBS->SignalEvent (Udp6Rx->RecycleSignal);
    } else {
      Udp4Rx = Udp4Token.Packet.RxData;
      ASSERT (Udp4Rx != NULL);

      HeaderLen = 0;
      if (HeaderSize != NULL) {
        HeaderLen = MIN (*HeaderSize, Udp4Rx->DataLength);
      }

      if (Udp4Rx->DataLength - HeaderLen > *BufferSize) {
        Status = EFI_BUFFER_TOO_SMALL;
      } else {
        if (HeaderSize != NULL) {
          *HeaderSize = HeaderLen;
        }
        *BufferSize = Udp4Rx->DataLength - HeaderLen;

        HeaderCopiedLen = 0;
        BufferCopiedLen = 0;
        for (FragmentIndex = 0; FragmentIndex < Udp4Rx->FragmentCount; FragmentIndex++) {
          FragmentLength = Udp4Rx->FragmentTable[FragmentIndex].FragmentLength;
          FragmentBuffer = Udp4Rx->FragmentTable[FragmentIndex].FragmentBuffer;
          if (HeaderCopiedLen + FragmentLength < HeaderLen) {
            //
            // Copy the header part of received data.
            //
            CopyMem ((UINT8 *) HeaderPtr + HeaderCopiedLen, FragmentBuffer, FragmentLength);
            HeaderCopiedLen += FragmentLength;
          } else if (HeaderCopiedLen < HeaderLen) {
            //
            // Copy the header part of received data.
            //
            CopiedLen = HeaderLen - HeaderCopiedLen;
            CopyMem ((UINT8 *) HeaderPtr + HeaderCopiedLen, FragmentBuffer, CopiedLen);
            HeaderCopiedLen += CopiedLen;

            //
            // Copy the other part of received data.
            //
            CopyMem ((UINT8 *) BufferPtr + BufferCopiedLen, FragmentBuffer + CopiedLen, FragmentLength - CopiedLen);
            BufferCopiedLen += (FragmentLength - CopiedLen);
          } else {
            //
            // Copy the other part of received data.
            //
            CopyMem ((UINT8 *) BufferPtr + BufferCopiedLen, FragmentBuffer, FragmentLength);
            BufferCopiedLen += FragmentLength;
          }
        }
      }
      //
      // Recycle the receiving buffer after copy to user.
      //
      gBS->SignalEvent (Udp4Rx->RecycleSignal);
    }
  }

  if (Mode->UsingIpv6) {
    Private->Udp6Read->Cancel (Private->Udp6Read, &Udp6Token);
    gBS->CloseEvent (Udp6Token.Event);
  } else {
    Private->Udp4Read->Cancel (Private->Udp4Read, &Udp4Token);
    gBS->CloseEvent (Udp4Token.Event);
  }

  return Status;
}


/**
  Updates the IP receive filters of a network device and enables software filtering.

  The NewFilter field is used to modify the network device's current IP receive
  filter settings and to enable a software filter. This function updates the IpFilter
  field of the EFI_PXE_BASE_CODE_MODE structure with the contents of NewIpFilter.
  The software filter is used when the USE_FILTER in OpFlags is set to UdpRead().
  The current hardware filter remains in effect no matter what the settings of OpFlags.
  This is so that the meaning of ANY_DEST_IP set in OpFlags to UdpRead() is from those
  packets whose reception is enabled in hardware-physical NIC address (unicast),
  broadcast address, logical address or addresses (multicast), or all (promiscuous).
  UdpRead() does not modify the IP filter settings.
  Dhcp(), Discover(), and Mtftp() set the IP filter, and return with the IP receive
  filter list emptied and the filter set to EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP.
  If an application or driver wishes to preserve the IP receive filter settings,
  it will have to preserve the IP receive filter settings before these calls, and
  use SetIpFilter() to restore them after the calls. If incompatible filtering is
  requested (for example, PROMISCUOUS with anything else), or if the device does not
  support a requested filter setting and it cannot be accommodated in software
  (for example, PROMISCUOUS not supported), EFI_INVALID_PARAMETER will be returned.
  The IPlist field is used to enable IPs other than the StationIP. They may be
  multicast or unicast. If IPcnt is set as well as EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP,
  then both the StationIP and the IPs from the IPlist will be used.

  @param[in]  This              Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance.
  @param[in]  NewFilter         Pointer to the new set of IP receive filters.

  @retval EFI_SUCCESS           The IP receive filter settings were updated.
  @retval EFI_NOT_STARTED       The PXE Base Code Protocol is in the stopped state.
  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

**/
EFI_STATUS
EFIAPI
EfiPxeBcSetIpFilter (
  IN EFI_PXE_BASE_CODE_PROTOCOL       *This,
  IN EFI_PXE_BASE_CODE_IP_FILTER      *NewFilter
  )
{
  EFI_STATUS                Status;
  PXEBC_PRIVATE_DATA        *Private;
  EFI_PXE_BASE_CODE_MODE    *Mode;
  EFI_UDP4_CONFIG_DATA      *Udp4Cfg;
  EFI_UDP6_CONFIG_DATA      *Udp6Cfg;
  UINTN                     Index;
  BOOLEAN                   NeedPromiscuous;
  BOOLEAN                   AcceptPromiscuous;
  BOOLEAN                   AcceptBroadcast;
  BOOLEAN                   MultiCastUpdate;

  if (This == NULL || NewFilter == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Private         = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);
  Mode            = Private->PxeBc.Mode;
  Status          = EFI_SUCCESS;
  NeedPromiscuous = FALSE;

  if (!Mode->Started) {
    return EFI_NOT_STARTED;
  }

  for (Index = 0; Index < NewFilter->IpCnt; Index++) {
    ASSERT (Index < EFI_PXE_BASE_CODE_MAX_IPCNT);
    if (!Mode->UsingIpv6 &&
        IP4_IS_LOCAL_BROADCAST (EFI_IP4 (NewFilter->IpList[Index].v4))) {
      //
      // IPv4 broadcast address should not be in IP filter.
      //
      return EFI_INVALID_PARAMETER;
    }
    if (Mode->UsingIpv6) {
      if ((NewFilter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP) != 0 &&
          NetIp6IsValidUnicast (&NewFilter->IpList[Index].v6)) {
        NeedPromiscuous = TRUE;
      }
    } else if ((EFI_NTOHL(Mode->StationIp) != 0) &&
               (EFI_NTOHL(Mode->SubnetMask) != 0) &&
               IP4_NET_EQUAL(EFI_NTOHL(Mode->StationIp), EFI_NTOHL(NewFilter->IpList[Index].v4), EFI_NTOHL(Mode->SubnetMask.v4)) &&
               NetIp4IsUnicast (EFI_IP4 (NewFilter->IpList[Index].v4), EFI_NTOHL(Mode->SubnetMask)) &&
               ((NewFilter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP) != 0)) {
      NeedPromiscuous = TRUE;
    }
  }

  AcceptPromiscuous = FALSE;
  AcceptBroadcast   = FALSE;
  MultiCastUpdate   = FALSE;

  if (NeedPromiscuous ||
      (NewFilter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS) != 0 ||
      (NewFilter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST) != 0) {
    //
    // Configure UDPv4/UDPv6 as promiscuous mode to receive all packets.
    //
    AcceptPromiscuous = TRUE;
  } else if ((NewFilter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST) != 0) {
    //
    // Configure UDPv4 to receive all broadcast packets.
    //
    AcceptBroadcast  = TRUE;
  }

  //
  // In multicast condition when Promiscuous FALSE and IpCnt no-zero.
  // Here check if there is any update of the multicast ip address. If yes,
  // we need leave the old multicast group (by Config UDP instance to NULL),
  // and join the new multicast group.
  //
  if (!AcceptPromiscuous) {
    if ((NewFilter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP) != 0) {
      if (Mode->IpFilter.IpCnt != NewFilter->IpCnt) {
        MultiCastUpdate = TRUE;
      } else if (CompareMem (Mode->IpFilter.IpList, NewFilter->IpList, NewFilter->IpCnt * sizeof (EFI_IP_ADDRESS)) != 0 ) {
        MultiCastUpdate = TRUE;
      }
    }
  }

  if (!Mode->UsingIpv6) {
    //
    // Check whether we need reconfigure the UDP4 instance.
    //
    Udp4Cfg = &Private->Udp4CfgData;
    if ((AcceptPromiscuous != Udp4Cfg->AcceptPromiscuous)   ||
        (AcceptBroadcast != Udp4Cfg->AcceptBroadcast)     || MultiCastUpdate) {
      //
      // Clear the UDP4 instance configuration, all joined groups will be left
      // during the operation.
      //
      Private->Udp4Read->Configure (Private->Udp4Read, NULL);

      //
      // Configure the UDP instance with the new configuration.
      //
      Udp4Cfg->AcceptPromiscuous = AcceptPromiscuous;
      Udp4Cfg->AcceptBroadcast   = AcceptBroadcast;
      Status = Private->Udp4Read->Configure (Private->Udp4Read, Udp4Cfg);
      if (EFI_ERROR (Status)) {
        return Status;
      }

      //
      // In not Promiscuous mode, need to join the new multicast group.
      //
      if (!AcceptPromiscuous) {
        for (Index = 0; Index < NewFilter->IpCnt; ++Index) {
          if (IP4_IS_MULTICAST (EFI_NTOHL (NewFilter->IpList[Index].v4))) {
            //
            // Join the multicast group.
            //
            Status = Private->Udp4Read->Groups (Private->Udp4Read, TRUE, &NewFilter->IpList[Index].v4);
            if (EFI_ERROR (Status)) {
              return Status;
            }
          }
        }
      }
    }
  } else {
    //
    // Check whether we need reconfigure the UDP6 instance.
    //
    Udp6Cfg = &Private->Udp6CfgData;
    if ((AcceptPromiscuous != Udp6Cfg->AcceptPromiscuous) || MultiCastUpdate) {
      //
      // Clear the UDP6 instance configuration, all joined groups will be left
      // during the operation.
      //
      Private->Udp6Read->Configure (Private->Udp6Read, NULL);

      //
      // Configure the UDP instance with the new configuration.
      //
      Udp6Cfg->AcceptPromiscuous = AcceptPromiscuous;
      Status = Private->Udp6Read->Configure (Private->Udp6Read, Udp6Cfg);
      if (EFI_ERROR (Status)) {
        return Status;
      }

      //
      // In not Promiscuous mode, need to join the new multicast group.
      //
      if (!AcceptPromiscuous) {
        for (Index = 0; Index < NewFilter->IpCnt; ++Index) {
          if (IP6_IS_MULTICAST (&NewFilter->IpList[Index].v6)) {
            //
            // Join the multicast group.
            //
            Status = Private->Udp6Read->Groups (Private->Udp6Read, TRUE, &NewFilter->IpList[Index].v6);
            if (EFI_ERROR (Status)) {
              return Status;
            }
          }
        }
      }
    }
  }

  //
  // Save the new IP filter into mode data.
  //
  CopyMem (&Mode->IpFilter, NewFilter, sizeof (Mode->IpFilter));

  return Status;
}


/**
  Uses the ARP protocol to resolve a MAC address. It is not supported for IPv6.

  This function uses the ARP protocol to resolve a MAC address. The IP address specified
  by IpAddr is used to resolve a MAC address. If the ARP protocol succeeds in resolving
  the specified address, then the ArpCacheEntries and ArpCache fields of the mode data
  are updated, and EFI_SUCCESS is returned. If MacAddr is not NULL, the resolved
  MAC address is placed there as well.  If the PXE Base Code protocol is in the
  stopped state, then EFI_NOT_STARTED is returned. If the ARP protocol encounters
  a timeout condition while attempting to resolve an address, then EFI_TIMEOUT is
  returned. If the Callback Protocol does not return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE,
  then EFI_ABORTED is returned.

  @param[in]  This              Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance.
  @param[in]  IpAddr            Pointer to the IP address that is used to resolve a MAC address.
  @param[in]  MacAddr           If not NULL, a pointer to the MAC address that was resolved with the
                                ARP protocol.

  @retval EFI_SUCCESS           The IP or MAC address was resolved.
  @retval EFI_NOT_STARTED       The PXE Base Code Protocol is in the stopped state.
  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
  @retval EFI_DEVICE_ERROR      The network device encountered an error during this operation.
  @retval EFI_ICMP_ERROR        An error occur with the ICMP packet message.

**/
EFI_STATUS
EFIAPI
EfiPxeBcArp (
  IN EFI_PXE_BASE_CODE_PROTOCOL       *This,
  IN EFI_IP_ADDRESS                   *IpAddr,
  IN EFI_MAC_ADDRESS                  *MacAddr OPTIONAL
  )
{
  PXEBC_PRIVATE_DATA      *Private;
  EFI_PXE_BASE_CODE_MODE  *Mode;
  EFI_EVENT               ResolvedEvent;
  EFI_STATUS              Status;
  EFI_MAC_ADDRESS         TempMac;
  EFI_MAC_ADDRESS         ZeroMac;
  BOOLEAN                 IsResolved;

  if (This == NULL || IpAddr == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Private       = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);
  Mode          = Private->PxeBc.Mode;
  ResolvedEvent = NULL;
  Status        = EFI_SUCCESS;
  IsResolved    = FALSE;

  if (!Mode->Started) {
    return EFI_NOT_STARTED;
  }

  if (Mode->UsingIpv6) {
    return EFI_UNSUPPORTED;
  }

  //
  // Station address should be ready before do arp.
  //
  if (!Private->IsAddressOk) {
    return EFI_INVALID_PARAMETER;
  }

  Mode->IcmpErrorReceived = FALSE;
  ZeroMem (&TempMac, sizeof (EFI_MAC_ADDRESS));
  ZeroMem (&ZeroMac, sizeof (EFI_MAC_ADDRESS));

  if (!Mode->AutoArp) {
    //
    // If AutoArp is FALSE, only search in the current Arp cache.
    //
    PxeBcArpCacheUpdate (NULL, Private);
    if (!PxeBcCheckArpCache (Mode, &IpAddr->v4, &TempMac)) {
      Status = EFI_DEVICE_ERROR;
      goto ON_EXIT;
    }
  } else {
    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    PxeBcCommonNotify,
                    &IsResolved,
                    &ResolvedEvent
                    );
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }

    //
    // If AutoArp is TRUE, try to send Arp request on initiative.
    //
    Status = Private->Arp->Request (Private->Arp, &IpAddr->v4, ResolvedEvent, &TempMac);
    if (EFI_ERROR (Status) && Status != EFI_NOT_READY) {
      goto ON_EXIT;
    }

    while (!IsResolved) {
      if (CompareMem (&TempMac, &ZeroMac, sizeof (EFI_MAC_ADDRESS)) != 0) {
        break;
      }
    }
    if (CompareMem (&TempMac, &ZeroMac, sizeof (EFI_MAC_ADDRESS)) != 0) {
      Status = EFI_SUCCESS;
    } else {
      Status = EFI_TIMEOUT;
    }
  }

  //
  // Copy the Mac address to user if needed.
  //
  if (MacAddr != NULL && !EFI_ERROR (Status)) {
    CopyMem (MacAddr, &TempMac, sizeof (EFI_MAC_ADDRESS));
  }

ON_EXIT:
  if (ResolvedEvent != NULL) {
    gBS->CloseEvent (ResolvedEvent);
  }
  return Status;
}


/**
  Updates the parameters that affect the operation of the PXE Base Code Protocol.

  This function sets parameters that affect the operation of the PXE Base Code Protocol.
  The parameter specified by NewAutoArp is used to control the generation of ARP
  protocol packets. If NewAutoArp is TRUE, then ARP Protocol packets will be generated
  as required by the PXE Base Code Protocol. If NewAutoArp is FALSE, then no ARP
  Protocol packets will be generated. In this case, the only mappings that are
  available are those stored in the ArpCache of the EFI_PXE_BASE_CODE_MODE structure.
  If there are not enough mappings in the ArpCache to perform a PXE Base Code Protocol
  service, then the service will fail. This function updates the AutoArp field of
  the EFI_PXE_BASE_CODE_MODE structure to NewAutoArp.
  The SetParameters() call must be invoked after a Callback Protocol is installed
  to enable the use of callbacks.

  @param[in]  This              Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance.
  @param[in]  NewAutoArp        If not NULL, a pointer to a value that specifies whether to replace the
                                current value of AutoARP.
  @param[in]  NewSendGUID       If not NULL, a pointer to a value that specifies whether to replace the
                                current value of SendGUID.
  @param[in]  NewTTL            If not NULL, a pointer to be used in place of the current value of TTL,
                                the "time to live" field of the IP header.
  @param[in]  NewToS            If not NULL, a pointer to be used in place of the current value of ToS,
                                the "type of service" field of the IP header.
  @param[in]  NewMakeCallback   If not NULL, a pointer to a value that specifies whether to replace the
                                current value of the MakeCallback field of the Mode structure.

  @retval EFI_SUCCESS           The new parameters values were updated.
  @retval EFI_NOT_STARTED       The PXE Base Code Protocol is in the stopped state.
  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

**/
EFI_STATUS
EFIAPI
EfiPxeBcSetParameters (
  IN EFI_PXE_BASE_CODE_PROTOCOL       *This,
  IN BOOLEAN                          *NewAutoArp         OPTIONAL,
  IN BOOLEAN                          *NewSendGUID        OPTIONAL,
  IN UINT8                            *NewTTL             OPTIONAL,
  IN UINT8                            *NewToS             OPTIONAL,
  IN BOOLEAN                          *NewMakeCallback    OPTIONAL
  )
{
  PXEBC_PRIVATE_DATA      *Private;
  EFI_PXE_BASE_CODE_MODE  *Mode;
  EFI_GUID                SystemGuid;
  EFI_STATUS              Status;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);
  Mode    = Private->PxeBc.Mode;

  if (!Mode->Started) {
    return EFI_NOT_STARTED;
  }

  if (NewMakeCallback != NULL) {
    if (*NewMakeCallback) {
      //
      // Update the previous PxeBcCallback protocol.
      //
      Status = gBS->HandleProtocol (
                      Mode->UsingIpv6 ? Private->Ip6Nic->Controller : Private->Ip4Nic->Controller,
                      &gEfiPxeBaseCodeCallbackProtocolGuid,
                      (VOID **) &Private->PxeBcCallback
                      );

      if (EFI_ERROR (Status) || (Private->PxeBcCallback->Callback == NULL)) {
        return EFI_INVALID_PARAMETER;
      }
    } else {
      Private->PxeBcCallback = NULL;
    }
    Mode->MakeCallbacks = *NewMakeCallback;
  }

  if (NewSendGUID != NULL) {
    if (*NewSendGUID && EFI_ERROR (NetLibGetSystemGuid (&SystemGuid))) {
      DEBUG ((EFI_D_WARN, "PXE: Failed to read system GUID from the smbios table!\n"));
      return EFI_INVALID_PARAMETER;
    }
    Mode->SendGUID = *NewSendGUID;
  }

  if (NewAutoArp != NULL) {
    Mode->AutoArp = *NewAutoArp;
  }

  if (NewTTL != NULL) {
    Mode->TTL = *NewTTL;
  }

  if (NewToS != NULL) {
    Mode->ToS = *NewToS;
  }

  return EFI_SUCCESS;
}


/**
  Updates the station IP address and/or subnet mask values of a network device.

  This function updates the station IP address and/or subnet mask values of a network
  device. The NewStationIp field is used to modify the network device's current IP address.
  If NewStationIP is NULL, then the current IP address will not be modified. Otherwise,
  this function updates the StationIp field of the EFI_PXE_BASE_CODE_MODE structure
  with NewStationIp. The NewSubnetMask field is used to modify the network device's current subnet
  mask. If NewSubnetMask is NULL, then the current subnet mask will not be modified.
  Otherwise, this function updates the SubnetMask field of the EFI_PXE_BASE_CODE_MODE
  structure with NewSubnetMask.

  @param[in]  This              Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance.
  @param[in]  NewStationIp      Pointer to the new IP address to be used by the network device.
  @param[in]  NewSubnetMask     Pointer to the new subnet mask to be used by the network device.

  @retval EFI_SUCCESS           The new station IP address and/or subnet mask were updated.
  @retval EFI_NOT_STARTED       The PXE Base Code Protocol is in the stopped state.
  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.

**/
EFI_STATUS
EFIAPI
EfiPxeBcSetStationIP (
  IN EFI_PXE_BASE_CODE_PROTOCOL       *This,
  IN EFI_IP_ADDRESS                   *NewStationIp    OPTIONAL,
  IN EFI_IP_ADDRESS                   *NewSubnetMask   OPTIONAL
  )
{
  EFI_STATUS              Status;
  PXEBC_PRIVATE_DATA      *Private;
  EFI_PXE_BASE_CODE_MODE  *Mode;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (NewStationIp != NULL && !NetIp6IsValidUnicast (&NewStationIp->v6)) {
    return EFI_INVALID_PARAMETER;
  }

  Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);
  Mode    = Private->PxeBc.Mode;
  Status  = EFI_SUCCESS;

  if (!Mode->UsingIpv6 &&
      NewSubnetMask != NULL &&
      !IP4_IS_VALID_NETMASK (NTOHL (NewSubnetMask->Addr[0]))) {
    return EFI_INVALID_PARAMETER;
  }

  if (!Mode->UsingIpv6 && NewStationIp != NULL) {
    if (IP4_IS_UNSPECIFIED(NTOHL (NewStationIp->Addr[0])) ||
        IP4_IS_LOCAL_BROADCAST(NTOHL (NewStationIp->Addr[0])) ||
        (NewSubnetMask != NULL && NewSubnetMask->Addr[0] != 0 && !NetIp4IsUnicast (NTOHL (NewStationIp->Addr[0]), NTOHL (NewSubnetMask->Addr[0])))) {
      return EFI_INVALID_PARAMETER;
    }
  }

  if (!Mode->Started) {
    return EFI_NOT_STARTED;
  }

  if (Mode->UsingIpv6 && NewStationIp != NULL) {
    //
    // Set the IPv6 address by Ip6Config protocol.
    //
    Status = PxeBcRegisterIp6Address (Private, &NewStationIp->v6);
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }
  }

  if (NewStationIp != NULL) {
    CopyMem (&Mode->StationIp, NewStationIp, sizeof (EFI_IP_ADDRESS));
    CopyMem (&Private->StationIp, NewStationIp, sizeof (EFI_IP_ADDRESS));
  }

  if (!Mode->UsingIpv6 && NewSubnetMask != NULL) {
    CopyMem (&Mode->SubnetMask, NewSubnetMask, sizeof (EFI_IP_ADDRESS));
    CopyMem (&Private->SubnetMask ,NewSubnetMask, sizeof (EFI_IP_ADDRESS));
  }

  Status = PxeBcFlushStationIp (Private, NewStationIp, NewSubnetMask);
  if (!EFI_ERROR (Status)) {
    Private->IsAddressOk = TRUE;
  }

ON_EXIT:
  return Status;
}


/**
  Updates the contents of the cached DHCP and Discover packets.

  The pointers to the new packets are used to update the contents of the cached
  packets in the EFI_PXE_BASE_CODE_MODE structure.

  @param[in]  This                   Pointer to the EFI_PXE_BASE_CODE_PROTOCOL instance.
  @param[in]  NewDhcpDiscoverValid   Pointer to a value that will replace the current
                                     DhcpDiscoverValid field.
  @param[in]  NewDhcpAckReceived     Pointer to a value that will replace the current
                                     DhcpAckReceived field.
  @param[in]  NewProxyOfferReceived  Pointer to a value that will replace the current
                                     ProxyOfferReceived field.
  @param[in]  NewPxeDiscoverValid    Pointer to a value that will replace the current
                                     ProxyOfferReceived field.
  @param[in]  NewPxeReplyReceived    Pointer to a value that will replace the current
                                     PxeReplyReceived field.
  @param[in]  NewPxeBisReplyReceived Pointer to a value that will replace the current
                                     PxeBisReplyReceived field.
  @param[in]  NewDhcpDiscover        Pointer to the new cached DHCP Discover packet contents.
  @param[in]  NewDhcpAck             Pointer to the new cached DHCP Ack packet contents.
  @param[in]  NewProxyOffer          Pointer to the new cached Proxy Offer packet contents.
  @param[in]  NewPxeDiscover         Pointer to the new cached PXE Discover packet contents.
  @param[in]  NewPxeReply            Pointer to the new cached PXE Reply packet contents.
  @param[in]  NewPxeBisReply         Pointer to the new cached PXE BIS Reply packet contents.

  @retval EFI_SUCCESS            The cached packet contents were updated.
  @retval EFI_NOT_STARTED        The PXE Base Code Protocol is in the stopped state.
  @retval EFI_INVALID_PARAMETER  This is NULL or does not point to a valid
                                 EFI_PXE_BASE_CODE_PROTOCOL structure.

**/
EFI_STATUS
EFIAPI
EfiPxeBcSetPackets (
  IN EFI_PXE_BASE_CODE_PROTOCOL       *This,
  IN BOOLEAN                          *NewDhcpDiscoverValid      OPTIONAL,
  IN BOOLEAN                          *NewDhcpAckReceived        OPTIONAL,
  IN BOOLEAN                          *NewProxyOfferReceived     OPTIONAL,
  IN BOOLEAN                          *NewPxeDiscoverValid       OPTIONAL,
  IN BOOLEAN                          *NewPxeReplyReceived       OPTIONAL,
  IN BOOLEAN                          *NewPxeBisReplyReceived    OPTIONAL,
  IN EFI_PXE_BASE_CODE_PACKET         *NewDhcpDiscover           OPTIONAL,
  IN EFI_PXE_BASE_CODE_PACKET         *NewDhcpAck                OPTIONAL,
  IN EFI_PXE_BASE_CODE_PACKET         *NewProxyOffer             OPTIONAL,
  IN EFI_PXE_BASE_CODE_PACKET         *NewPxeDiscover            OPTIONAL,
  IN EFI_PXE_BASE_CODE_PACKET         *NewPxeReply               OPTIONAL,
  IN EFI_PXE_BASE_CODE_PACKET         *NewPxeBisReply            OPTIONAL
  )
{
  PXEBC_PRIVATE_DATA      *Private;
  EFI_PXE_BASE_CODE_MODE  *Mode;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);
  Mode    = Private->PxeBc.Mode;

  if (!Mode->Started) {
    return EFI_NOT_STARTED;
  }

  if (NewDhcpDiscoverValid != NULL) {
    Mode->DhcpDiscoverValid = *NewDhcpDiscoverValid;
  }

  if (NewDhcpAckReceived != NULL) {
    Mode->DhcpAckReceived = *NewDhcpAckReceived;
  }

  if (NewProxyOfferReceived != NULL) {
    Mode->ProxyOfferReceived = *NewProxyOfferReceived;
  }

  if (NewPxeDiscoverValid != NULL) {
    Mode->PxeDiscoverValid = *NewPxeDiscoverValid;
  }

  if (NewPxeReplyReceived != NULL) {
    Mode->PxeReplyReceived = *NewPxeReplyReceived;
  }

  if (NewPxeBisReplyReceived != NULL) {
    Mode->PxeBisReplyReceived = *NewPxeBisReplyReceived;
  }

  if (NewDhcpDiscover != NULL) {
    CopyMem (&Mode->DhcpDiscover, NewDhcpDiscover, sizeof (EFI_PXE_BASE_CODE_PACKET));
  }

  if (NewDhcpAck != NULL) {
    CopyMem (&Mode->DhcpAck, NewDhcpAck, sizeof (EFI_PXE_BASE_CODE_PACKET));
  }

  if (NewProxyOffer != NULL) {
    CopyMem (&Mode->ProxyOffer, NewProxyOffer, sizeof (EFI_PXE_BASE_CODE_PACKET));
  }

  if (NewPxeDiscover != NULL) {
    CopyMem (&Mode->PxeDiscover, NewPxeDiscover, sizeof (EFI_PXE_BASE_CODE_PACKET));
  }

  if (NewPxeReply != NULL) {
    CopyMem (&Mode->PxeReply, NewPxeReply, sizeof (EFI_PXE_BASE_CODE_PACKET));
  }

  if (NewPxeBisReply != NULL) {
    CopyMem (&Mode->PxeBisReply, NewPxeBisReply, sizeof (EFI_PXE_BASE_CODE_PACKET));
  }

  return EFI_SUCCESS;
}

EFI_PXE_BASE_CODE_PROTOCOL  gPxeBcProtocolTemplate = {
  EFI_PXE_BASE_CODE_PROTOCOL_REVISION,
  EfiPxeBcStart,
  EfiPxeBcStop,
  EfiPxeBcDhcp,
  EfiPxeBcDiscover,
  EfiPxeBcMtftp,
  EfiPxeBcUdpWrite,
  EfiPxeBcUdpRead,
  EfiPxeBcSetIpFilter,
  EfiPxeBcArp,
  EfiPxeBcSetParameters,
  EfiPxeBcSetStationIP,
  EfiPxeBcSetPackets,
  NULL
};


/**
  Callback function that is invoked when the PXE Base Code Protocol is about to transmit, has
  received, or is waiting to receive a packet.

  This function is invoked when the PXE Base Code Protocol is about to transmit, has received,
  or is waiting to receive a packet. Parameters Function and Received specify the type of event.
  Parameters PacketLen and Packet specify the packet that generated the event. If these fields
  are zero and NULL respectively, then this is a status update callback. If the operation specified
  by Function is to continue, then CALLBACK_STATUS_CONTINUE should be returned. If the operation
  specified by Function should be aborted, then CALLBACK_STATUS_ABORT should be returned. Due to
  the polling nature of UEFI device drivers, a callback function should not execute for more than 5 ms.
  The SetParameters() function must be called after a Callback Protocol is installed to enable the
  use of callbacks.

  @param[in]  This              Pointer to the EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL instance.
  @param[in]  Function          The PXE Base Code Protocol function that is waiting for an event.
  @param[in]  Received          TRUE if the callback is being invoked due to a receive event. FALSE if
                                the callback is being invoked due to a transmit event.
  @param[in]  PacketLength      The length, in bytes, of Packet. This field will have a value of zero if
                                this is a wait for receive event.
  @param[in]  PacketPtr         If Received is TRUE, a pointer to the packet that was just received;
                                otherwise a pointer to the packet that is about to be transmitted.

  @retval EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE If Function specifies a continue operation.
  @retval EFI_PXE_BASE_CODE_CALLBACK_STATUS_ABORT    If Function specifies an abort operation.

**/
EFI_PXE_BASE_CODE_CALLBACK_STATUS
EFIAPI
EfiPxeLoadFileCallback (
  IN EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL  *This,
  IN EFI_PXE_BASE_CODE_FUNCTION           Function,
  IN BOOLEAN                              Received,
  IN UINT32                               PacketLength,
  IN EFI_PXE_BASE_CODE_PACKET             *PacketPtr     OPTIONAL
  )
{
  EFI_INPUT_KEY       Key;
  EFI_STATUS          Status;

  //
  // Catch Ctrl-C or ESC to abort.
  //
  Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);

  if (!EFI_ERROR (Status)) {

    if (Key.ScanCode == SCAN_ESC || Key.UnicodeChar == (0x1F & 'c')) {

      return EFI_PXE_BASE_CODE_CALLBACK_STATUS_ABORT;
    }
  }
  //
  // No print if receive packet
  //
  if (Received) {
    return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE;
  }
  //
  // Print only for three functions
  //
  switch (Function) {

  case EFI_PXE_BASE_CODE_FUNCTION_MTFTP:
    //
    // Print only for open MTFTP packets, not every MTFTP packets
    //
    if (PacketLength != 0 && PacketPtr != NULL) {
      if (PacketPtr->Raw[0x1C] != 0x00 || PacketPtr->Raw[0x1D] != 0x01) {
        return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE;
      }
    }
    break;

  case EFI_PXE_BASE_CODE_FUNCTION_DHCP:
  case EFI_PXE_BASE_CODE_FUNCTION_DISCOVER:
    break;

  default:
    return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE;
  }

  if (PacketLength != 0 && PacketPtr != NULL) {
    //
    // Print '.' when transmit a packet
    //
    AsciiPrint (".");
  }

  return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE;
}

EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL gPxeBcCallBackTemplate = {
  EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL_REVISION,
  EfiPxeLoadFileCallback
};


/**
  Causes the driver to load a specified file.

  @param[in]      This                Protocol instance pointer.
  @param[in]      FilePath            The device specific path of the file to load.
  @param[in]      BootPolicy          If TRUE, indicates that the request originates from the
                                      boot manager is attempting to load FilePath as a boot
                                      selection. If FALSE, then FilePath must match an exact file
                                      to be loaded.
  @param[in, out] BufferSize          On input the size of Buffer in bytes. On output with a return
                                      code of EFI_SUCCESS, the amount of data transferred to
                                      Buffer. On output with a return code of EFI_BUFFER_TOO_SMALL,
                                      the size of Buffer required to retrieve the requested file.
  @param[in]      Buffer              The memory buffer to transfer the file to. IF Buffer is NULL,
                                      then no the size of the requested file is returned in
                                      BufferSize.

  @retval EFI_SUCCESS                 The file was loaded.
  @retval EFI_UNSUPPORTED             The device does not support the provided BootPolicy.
  @retval EFI_INVALID_PARAMETER       FilePath is not a valid device path, or
                                      BufferSize is NULL.
  @retval EFI_NO_MEDIA                No medium was present to load the file.
  @retval EFI_DEVICE_ERROR            The file was not loaded due to a device error.
  @retval EFI_NO_RESPONSE             The remote system did not respond.
  @retval EFI_NOT_FOUND               The file was not found.
  @retval EFI_ABORTED                 The file load process was manually cancelled.

**/
EFI_STATUS
EFIAPI
EfiPxeLoadFile (
  IN     EFI_LOAD_FILE_PROTOCOL           *This,
  IN     EFI_DEVICE_PATH_PROTOCOL         *FilePath,
  IN     BOOLEAN                          BootPolicy,
  IN OUT UINTN                            *BufferSize,
  IN     VOID                             *Buffer       OPTIONAL
  )
{
  PXEBC_PRIVATE_DATA          *Private;
  PXEBC_VIRTUAL_NIC           *VirtualNic;
  EFI_PXE_BASE_CODE_PROTOCOL  *PxeBc;
  BOOLEAN                     UsingIpv6;
  EFI_STATUS                  Status;
  EFI_STATUS                  MediaStatus;

  if (This == NULL || BufferSize == NULL || FilePath == NULL || !IsDevicePathEnd (FilePath)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Only support BootPolicy
  //
  if (!BootPolicy) {
    return EFI_UNSUPPORTED;
  }

  VirtualNic = PXEBC_VIRTUAL_NIC_FROM_LOADFILE (This);
  Private    = VirtualNic->Private;
  PxeBc      = &Private->PxeBc;
  UsingIpv6  = FALSE;
  Status     = EFI_DEVICE_ERROR;

  //
  // Check media status before PXE start
  //
  MediaStatus = EFI_SUCCESS;
  NetLibDetectMediaWaitTimeout (Private->Controller, PXEBC_CHECK_MEDIA_WAITING_TIME, &MediaStatus);
  if (MediaStatus != EFI_SUCCESS) {
    return EFI_NO_MEDIA;
  }

  //
  // Check whether the virtual nic is using IPv6 or not.
  //
  if (VirtualNic == Private->Ip6Nic) {
    UsingIpv6 = TRUE;
  }

  //
  // Start Pxe Base Code to initialize PXE boot.
  //
  Status = PxeBc->Start (PxeBc, UsingIpv6);
  if (Status == EFI_ALREADY_STARTED && UsingIpv6 != PxeBc->Mode->UsingIpv6) {
    //
    // PxeBc protocol has already been started but not on the required IP version, restart it.
    //
    Status = PxeBc->Stop (PxeBc);
    if (!EFI_ERROR (Status)) {
      Status = PxeBc->Start (PxeBc, UsingIpv6);
    }
  }
  if (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED) {
    Status = PxeBcLoadBootFile (Private, BufferSize, Buffer);
  }

  if (Status != EFI_SUCCESS &&
      Status != EFI_UNSUPPORTED &&
      Status != EFI_BUFFER_TOO_SMALL) {
    //
    // There are three cases, which needn't stop pxebc here.
    //   1. success to download file.
    //   2. success to get file size.
    //   3. unsupported.
    //
    PxeBc->Stop (PxeBc);
  } else {
    //
    // The DHCP4 can have only one configured child instance so we need to stop
    // reset the DHCP4 child before we return. Otherwise these programs which
    // also need to use DHCP4 will be impacted.
    //
    if (!PxeBc->Mode->UsingIpv6) {
      Private->Dhcp4->Stop (Private->Dhcp4);
      Private->Dhcp4->Configure (Private->Dhcp4, NULL);
    }
  }

  return Status;
}

EFI_LOAD_FILE_PROTOCOL  gLoadFileProtocolTemplate = { EfiPxeLoadFile };

