/** @file
  This implementation of EFI_PXE_BASE_CODE_PROTOCOL and EFI_LOAD_FILE_PROTOCOL.

  Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>

  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php.

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#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 = (UINTN) (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_DHCP6_PACKET_MAX_SIZE;
    Private->DhcpAck.Dhcp6.Packet.Ack.Size      = PXEBC_DHCP6_PACKET_MAX_SIZE;
    Private->PxeReply.Dhcp6.Packet.Ack.Size     = PXEBC_DHCP6_PACKET_MAX_SIZE;

    for (Index = 0; Index < PXEBC_OFFER_MAX_NUM; Index++) {
      Private->OfferBuffer[Index].Dhcp6.Packet.Offer.Size = PXEBC_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 = (UINTN) (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_DHCP4_PACKET_MAX_SIZE;
    Private->DhcpAck.Dhcp4.Packet.Ack.Size      = PXEBC_DHCP4_PACKET_MAX_SIZE;
    Private->PxeReply.Dhcp4.Packet.Ack.Size     = PXEBC_DHCP4_PACKET_MAX_SIZE;

    for (Index = 0; Index < PXEBC_OFFER_MAX_NUM; Index++) {
      Private->OfferBuffer[Index].Dhcp4.Packet.Offer.Size = PXEBC_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 it's 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 accecpt 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;


  if ((This == NULL) ||
      (Filename == NULL) ||
      (BufferSize == NULL) ||
      (ServerIp == NULL) ||
      ((BufferPtr == NULL) && DontUseBuffer) ||
      ((BlockSize != NULL) && (*BlockSize < PXE_MTFTP_DEFAULT_BLOCK_SIZE)) ||
      (!NetIp4IsUnicast (NTOHL (ServerIp->Addr[0]), 0) && !NetIp6IsValidUnicast (&ServerIp->v6))) {
    return EFI_INVALID_PARAMETER;
  }

  Config    = NULL;
  Status    = EFI_DEVICE_ERROR;
  Private   = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);
  Mode      = Private->PxeBc.Mode;

  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,
               BufferSize
               );

    break;

  case EFI_PXE_BASE_CODE_TFTP_READ_FILE:
    //
    // Send TFTP request to read file.
    //
    Status = PxeBcTftpReadFile (
               Private,
               Config,
               Filename,
               BlockSize,
               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,
               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 && !NetIp4IsUnicast (NTOHL (GatewayIp->Addr[0]), 0)) {
    //
    // 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
               );
  }

  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 rececived 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 ((NewFilter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP) != 0 &&
        (NetIp4IsUnicast (EFI_IP4 (NewFilter->IpList[Index].v4), 0) ||
         NetIp6IsValidUnicast (&NewFilter->IpList[Index].v6))) {
      //
      // If EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP is set and IPv4/IPv6 address
      // is in IpList, promiscuous mode is needed.
      //
      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 mutilcast 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 mutilcast 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 (
                      Private->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))) {
      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;
  EFI_ARP_CONFIG_DATA     ArpConfigData;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (NewStationIp != NULL &&
      (!NetIp4IsUnicast (NTOHL (NewStationIp->Addr[0]), 0) &&
       !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->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;
    }
  } else if (!Mode->UsingIpv6 && NewStationIp != NULL) {
    //
    // Configure the corresponding ARP with the IPv4 address.
    //
    ZeroMem (&ArpConfigData, sizeof (EFI_ARP_CONFIG_DATA));

    ArpConfigData.SwAddressType   = 0x0800;
    ArpConfigData.SwAddressLength = (UINT8) sizeof (EFI_IPv4_ADDRESS);
    ArpConfigData.StationAddress  = &NewStationIp->v4;

    Private->Arp->Configure (Private->Arp, NULL);
    Private->Arp->Configure (Private->Arp, &ArpConfigData);

    if (NewSubnetMask != NULL) {
      Mode->RouteTableEntries                = 1;
      Mode->RouteTable[0].IpAddr.Addr[0]     = NewStationIp->Addr[0] & NewSubnetMask->Addr[0];
      Mode->RouteTable[0].SubnetMask.Addr[0] = NewSubnetMask->Addr[0];
      Mode->RouteTable[0].GwAddr.Addr[0]     = 0;
    }

    Private->IsAddressOk = TRUE;
  }

  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);
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;
  BOOLEAN                     MediaPresent;

  if (FilePath == NULL || !IsDevicePathEnd (FilePath)) {
    return EFI_INVALID_PARAMETER;
  }
  
  VirtualNic = PXEBC_VIRTUAL_NIC_FROM_LOADFILE (This);
  Private    = VirtualNic->Private;
  PxeBc      = &Private->PxeBc;
  UsingIpv6  = FALSE;
  Status     = EFI_DEVICE_ERROR;

  if (This == NULL || BufferSize == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Only support BootPolicy
  //
  if (!BootPolicy) {
    return EFI_UNSUPPORTED;
  }

  //
  // Check media status before PXE start
  //
  MediaPresent = TRUE;
  NetLibDetectMedia (Private->Controller, &MediaPresent);
  if (!MediaPresent) {
    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 };

