/** @file
  Driver Binding functions implementationfor for UefiPxeBc Driver.

  (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2007 - 2018, 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"


EFI_DRIVER_BINDING_PROTOCOL gPxeBcIp4DriverBinding = {
  PxeBcIp4DriverBindingSupported,
  PxeBcIp4DriverBindingStart,
  PxeBcIp4DriverBindingStop,
  0xa,
  NULL,
  NULL
};

EFI_DRIVER_BINDING_PROTOCOL gPxeBcIp6DriverBinding = {
  PxeBcIp6DriverBindingSupported,
  PxeBcIp6DriverBindingStart,
  PxeBcIp6DriverBindingStop,
  0xa,
  NULL,
  NULL
};

/**
  Get the Nic handle using any child handle in the IPv4 stack.

  @param[in]  ControllerHandle    Pointer to child handle over IPv4.

  @return NicHandle               The pointer to the Nic handle.

**/
EFI_HANDLE
PxeBcGetNicByIp4Children (
  IN EFI_HANDLE                 ControllerHandle
  )
{
  EFI_HANDLE                    NicHandle;

  NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiArpProtocolGuid);
  if (NicHandle == NULL) {
    NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid);
    if (NicHandle == NULL) {
      NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp4ProtocolGuid);
      if (NicHandle == NULL) {
        NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp4ProtocolGuid);
        if (NicHandle == NULL) {
          NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiMtftp4ProtocolGuid);
          if (NicHandle == NULL) {
            return NULL;
          }
        }
      }
    }
  }

  return NicHandle;
}


/**
  Get the Nic handle using any child handle in the IPv6 stack.

  @param[in]  ControllerHandle    Pointer to child handle over IPv6.

  @return NicHandle               The pointer to the Nic handle.

**/
EFI_HANDLE
PxeBcGetNicByIp6Children (
  IN EFI_HANDLE                  ControllerHandle
  )
{
  EFI_HANDLE                     NicHandle;

  NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp6ProtocolGuid);
  if (NicHandle == NULL) {
    NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp6ProtocolGuid);
    if (NicHandle == NULL) {
      NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp6ProtocolGuid);
      if (NicHandle == NULL) {
        NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiMtftp6ProtocolGuid);
        if (NicHandle == NULL) {
          return NULL;
        }
      }
    }
  }

  return NicHandle;
}


/**
  Destroy the opened instances based on IPv4.

  @param[in]  This              Pointer to the EFI_DRIVER_BINDING_PROTOCOL.
  @param[in]  Private           Pointer to PXEBC_PRIVATE_DATA.

**/
VOID
PxeBcDestroyIp4Children (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN PXEBC_PRIVATE_DATA           *Private
  )
{
  ASSERT(Private != NULL);

  if (Private->ArpChild != NULL) {
    //
    // Close Arp for PxeBc->Arp and destroy the instance.
    //
    gBS->CloseProtocol (
           Private->ArpChild,
           &gEfiArpProtocolGuid,
           This->DriverBindingHandle,
           Private->Controller
           );

    NetLibDestroyServiceChild (
      Private->Controller,
      This->DriverBindingHandle,
      &gEfiArpServiceBindingProtocolGuid,
      Private->ArpChild
      );
  }

  if (Private->Ip4Child != NULL) {
    //
    // Close Ip4 for background ICMP error message and destroy the instance.
    //
    gBS->CloseProtocol (
           Private->Ip4Child,
           &gEfiIp4ProtocolGuid,
           This->DriverBindingHandle,
           Private->Controller
           );

    NetLibDestroyServiceChild (
      Private->Controller,
      This->DriverBindingHandle,
      &gEfiIp4ServiceBindingProtocolGuid,
      Private->Ip4Child
      );
  }

  if (Private->Udp4WriteChild != NULL) {
    //
    // Close Udp4 for PxeBc->UdpWrite and destroy the instance.
    //
    gBS->CloseProtocol (
           Private->Udp4WriteChild,
           &gEfiUdp4ProtocolGuid,
           This->DriverBindingHandle,
           Private->Controller
           );

    NetLibDestroyServiceChild (
      Private->Controller,
      This->DriverBindingHandle,
      &gEfiUdp4ServiceBindingProtocolGuid,
      Private->Udp4WriteChild
      );
  }

  if (Private->Udp4ReadChild != NULL) {
    //
    // Close Udp4 for PxeBc->UdpRead and destroy the instance.
    //
    gBS->CloseProtocol (
          Private->Udp4ReadChild,
          &gEfiUdp4ProtocolGuid,
          This->DriverBindingHandle,
          Private->Controller
          );

    NetLibDestroyServiceChild (
      Private->Controller,
      This->DriverBindingHandle,
      &gEfiUdp4ServiceBindingProtocolGuid,
      Private->Udp4ReadChild
      );
  }

  if (Private->Mtftp4Child != NULL) {
    //
    // Close Mtftp4 for PxeBc->Mtftp4 and destroy the instance.
    //
    gBS->CloseProtocol (
          Private->Mtftp4Child,
          &gEfiMtftp4ProtocolGuid,
          This->DriverBindingHandle,
          Private->Controller
          );

    NetLibDestroyServiceChild (
      Private->Controller,
      This->DriverBindingHandle,
      &gEfiMtftp4ServiceBindingProtocolGuid,
      Private->Mtftp4Child
      );
  }

  if (Private->Dhcp4Child != NULL) {
    //
    // Close Dhcp4 for PxeBc->Dhcp4 and destroy the instance.
    //
    gBS->CloseProtocol (
          Private->Dhcp4Child,
          &gEfiDhcp4ProtocolGuid,
          This->DriverBindingHandle,
          Private->Controller
          );

    NetLibDestroyServiceChild (
      Private->Controller,
      This->DriverBindingHandle,
      &gEfiDhcp4ServiceBindingProtocolGuid,
      Private->Dhcp4Child
      );
  }

  if (Private->Ip4Nic != NULL) {
    //
    // Close PxeBcPrivate from the parent Nic handle and destroy the virtual handle.
    //
    gBS->CloseProtocol (
           Private->Controller,
           &gEfiCallerIdGuid,
           This->DriverBindingHandle,
           Private->Ip4Nic->Controller
           );

    gBS->UninstallMultipleProtocolInterfaces (
           Private->Ip4Nic->Controller,
           &gEfiDevicePathProtocolGuid,
           Private->Ip4Nic->DevicePath,
           &gEfiLoadFileProtocolGuid,
           &Private->Ip4Nic->LoadFile,
           &gEfiPxeBaseCodeProtocolGuid,
           &Private->PxeBc,
           NULL
           );
    FreePool (Private->Ip4Nic->DevicePath);

    if (Private->Snp != NULL) {
      //
      // Close SNP from the child virtual handle
      //
      gBS->CloseProtocol (
             Private->Ip4Nic->Controller,
             &gEfiSimpleNetworkProtocolGuid,
             This->DriverBindingHandle,
             Private->Ip4Nic->Controller
             );

      gBS->UninstallProtocolInterface (
             Private->Ip4Nic->Controller,
             &gEfiSimpleNetworkProtocolGuid,
             Private->Snp
             );
    }
    FreePool (Private->Ip4Nic);
  }

  Private->ArpChild         = NULL;
  Private->Ip4Child         = NULL;
  Private->Udp4WriteChild   = NULL;
  Private->Udp4ReadChild    = NULL;
  Private->Mtftp4Child      = NULL;
  Private->Dhcp4Child       = NULL;
  Private->Ip4Nic           = NULL;
}


/**
  Destroy the opened instances based on IPv6.

  @param[in]  This              Pointer to the EFI_DRIVER_BINDING_PROTOCOL.
  @param[in]  Private           Pointer to PXEBC_PRIVATE_DATA.

**/
VOID
PxeBcDestroyIp6Children (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN PXEBC_PRIVATE_DATA           *Private
  )
{
  ASSERT(Private != NULL);

  if (Private->Ip6Child != NULL) {
    //
    // Close Ip6 for Ip6->Ip6Config and destroy the instance.
    //
    gBS->CloseProtocol (
          Private->Ip6Child,
          &gEfiIp6ProtocolGuid,
          This->DriverBindingHandle,
          Private->Controller
          );

    NetLibDestroyServiceChild (
      Private->Controller,
      This->DriverBindingHandle,
      &gEfiIp6ServiceBindingProtocolGuid,
      Private->Ip6Child
      );
  }

  if (Private->Udp6WriteChild != NULL) {
    //
    // Close Udp6 for PxeBc->UdpWrite and destroy the instance.
    //
    gBS->CloseProtocol (
           Private->Udp6WriteChild,
           &gEfiUdp6ProtocolGuid,
           This->DriverBindingHandle,
           Private->Controller
           );
    NetLibDestroyServiceChild (
      Private->Controller,
      This->DriverBindingHandle,
      &gEfiUdp6ServiceBindingProtocolGuid,
      Private->Udp6WriteChild
      );
  }

  if (Private->Udp6ReadChild != NULL) {
    //
    // Close Udp6 for PxeBc->UdpRead and destroy the instance.
    //
    gBS->CloseProtocol (
          Private->Udp6ReadChild,
          &gEfiUdp6ProtocolGuid,
          This->DriverBindingHandle,
          Private->Controller
          );
    NetLibDestroyServiceChild (
      Private->Controller,
      This->DriverBindingHandle,
      &gEfiUdp6ServiceBindingProtocolGuid,
      Private->Udp6ReadChild
      );
  }

  if (Private->Mtftp6Child != NULL) {
    //
    // Close Mtftp6 for PxeBc->Mtftp and destroy the instance.
    //
    gBS->CloseProtocol (
          Private->Mtftp6Child,
          &gEfiMtftp6ProtocolGuid,
          This->DriverBindingHandle,
          Private->Controller
          );

    NetLibDestroyServiceChild (
      Private->Controller,
      This->DriverBindingHandle,
      &gEfiMtftp6ServiceBindingProtocolGuid,
      Private->Mtftp6Child
      );
  }

  if (Private->Dhcp6Child != NULL) {
    //
    // Close Dhcp6 for PxeBc->Dhcp and destroy the instance.
    //
    gBS->CloseProtocol (
          Private->Dhcp6Child,
          &gEfiDhcp6ProtocolGuid,
          This->DriverBindingHandle,
          Private->Controller
          );

    NetLibDestroyServiceChild (
      Private->Controller,
      This->DriverBindingHandle,
      &gEfiDhcp6ServiceBindingProtocolGuid,
      Private->Dhcp6Child
      );
  }

  if (Private->Ip6Nic != NULL) {
    //
    // Close PxeBcPrivate from the parent Nic handle and destroy the virtual handle.
    //
    gBS->CloseProtocol (
           Private->Controller,
           &gEfiCallerIdGuid,
           This->DriverBindingHandle,
           Private->Ip6Nic->Controller
           );

    gBS->UninstallMultipleProtocolInterfaces (
           Private->Ip6Nic->Controller,
           &gEfiDevicePathProtocolGuid,
           Private->Ip6Nic->DevicePath,
           &gEfiLoadFileProtocolGuid,
           &Private->Ip6Nic->LoadFile,
           &gEfiPxeBaseCodeProtocolGuid,
           &Private->PxeBc,
           NULL
           );
    FreePool (Private->Ip6Nic->DevicePath);

    if (Private->Snp != NULL) {
      //
      // Close SNP from the child virtual handle
      //
      gBS->CloseProtocol (
             Private->Ip6Nic->Controller,
             &gEfiSimpleNetworkProtocolGuid,
             This->DriverBindingHandle,
             Private->Ip6Nic->Controller
             );
      gBS->UninstallProtocolInterface (
             Private->Ip6Nic->Controller,
             &gEfiSimpleNetworkProtocolGuid,
             Private->Snp
             );
    }
    FreePool (Private->Ip6Nic);
  }

  Private->Ip6Child           = NULL;
  Private->Udp6WriteChild     = NULL;
  Private->Udp6ReadChild      = NULL;
  Private->Mtftp6Child        = NULL;
  Private->Dhcp6Child         = NULL;
  Private->Ip6Nic             = NULL;
  Private->Mode.Ipv6Available = FALSE;
}

/**
  Check whether UNDI protocol supports IPv6.

  @param[in]   ControllerHandle  Controller handle.
  @param[in]   Private           Pointer to PXEBC_PRIVATE_DATA.
  @param[out]  Ipv6Support       TRUE if UNDI supports IPv6.

  @retval EFI_SUCCESS            Get the result whether UNDI supports IPv6 by NII or AIP protocol successfully.
  @retval EFI_NOT_FOUND          Don't know whether UNDI supports IPv6 since NII or AIP is not available.

**/
EFI_STATUS
PxeBcCheckIpv6Support (
  IN  EFI_HANDLE                   ControllerHandle,
  IN  PXEBC_PRIVATE_DATA           *Private,
  OUT BOOLEAN                      *Ipv6Support
  )
{
  EFI_HANDLE                       Handle;
  EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;
  EFI_STATUS                       Status;
  EFI_GUID                         *InfoTypesBuffer;
  UINTN                            InfoTypeBufferCount;
  UINTN                            TypeIndex;
  BOOLEAN                          Supported;
  VOID                             *InfoBlock;
  UINTN                            InfoBlockSize;

  ASSERT (Private != NULL && Ipv6Support != NULL);

  //
  // Check whether the UNDI supports IPv6 by NII protocol.
  //
  if (Private->Nii != NULL) {
    *Ipv6Support = Private->Nii->Ipv6Supported;
    return EFI_SUCCESS;
  }

  //
  // Check whether the UNDI supports IPv6 by AIP protocol.
  //

  //
  // Get the NIC handle by SNP protocol.
  //
  Handle = NetLibGetSnpHandle (ControllerHandle, NULL);
  if (Handle == NULL) {
    return EFI_NOT_FOUND;
  }

  Aip    = NULL;
  Status = gBS->HandleProtocol (
                  Handle,
                  &gEfiAdapterInformationProtocolGuid,
                  (VOID *) &Aip
                  );
  if (EFI_ERROR (Status) || Aip == NULL) {
    return EFI_NOT_FOUND;
  }

  InfoTypesBuffer     = NULL;
  InfoTypeBufferCount = 0;
  Status = Aip->GetSupportedTypes (Aip, &InfoTypesBuffer, &InfoTypeBufferCount);
  if (EFI_ERROR (Status) || InfoTypesBuffer == NULL) {
    FreePool (InfoTypesBuffer);
    return EFI_NOT_FOUND;
  }

  Supported = FALSE;
  for (TypeIndex = 0; TypeIndex < InfoTypeBufferCount; TypeIndex++) {
    if (CompareGuid (&InfoTypesBuffer[TypeIndex], &gEfiAdapterInfoUndiIpv6SupportGuid)) {
      Supported = TRUE;
      break;
    }
  }

  FreePool (InfoTypesBuffer);
  if (!Supported) {
    return EFI_NOT_FOUND;
  }

  //
  // We now have adapter information block.
  //
  InfoBlock     = NULL;
  InfoBlockSize = 0;
  Status = Aip->GetInformation (Aip, &gEfiAdapterInfoUndiIpv6SupportGuid, &InfoBlock, &InfoBlockSize);
  if (EFI_ERROR (Status) || InfoBlock == NULL) {
    FreePool (InfoBlock);
    return EFI_NOT_FOUND;
  }

  *Ipv6Support = ((EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT *) InfoBlock)->Ipv6Support;
  FreePool (InfoBlock);
  return EFI_SUCCESS;

}

/**
  Create the opened instances based on IPv4.

  @param[in]  This              Pointer to EFI_DRIVER_BINDING_PROTOCOL.
  @param[in]  ControllerHandle  Handle of the child to destroy.
  @param[in]  Private Handle    Pointer to PXEBC_PRIVATE_DATA.

  @retval EFI_SUCCESS           The instances based on IPv4 were all created successfully.
  @retval Others                An unexpected error occurred.

**/
EFI_STATUS
PxeBcCreateIp4Children (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN PXEBC_PRIVATE_DATA           *Private
  )
{
  EFI_STATUS                      Status;
  IPv4_DEVICE_PATH                Ip4Node;
  EFI_PXE_BASE_CODE_MODE          *Mode;
  EFI_UDP4_CONFIG_DATA            *Udp4CfgData;
  EFI_IP4_CONFIG_DATA             *Ip4CfgData;
  EFI_IP4_MODE_DATA               Ip4ModeData;
  PXEBC_PRIVATE_PROTOCOL          *Id;
  EFI_SIMPLE_NETWORK_PROTOCOL     *Snp;

  if (Private->Ip4Nic != NULL) {
    //
    // Already created before.
    //
    return EFI_SUCCESS;
  }

  //
  // Create Dhcp4 child and open Dhcp4 protocol for PxeBc->Dhcp.
  //
  Status = NetLibCreateServiceChild (
             ControllerHandle,
             This->DriverBindingHandle,
             &gEfiDhcp4ServiceBindingProtocolGuid,
             &Private->Dhcp4Child
             );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  Status = gBS->OpenProtocol (
                  Private->Dhcp4Child,
                  &gEfiDhcp4ProtocolGuid,
                  (VOID **) &Private->Dhcp4,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Create Mtftp4 child and open Mtftp4 protocol for PxeBc->Mtftp.
  //
  Status = NetLibCreateServiceChild (
             ControllerHandle,
             This->DriverBindingHandle,
             &gEfiMtftp4ServiceBindingProtocolGuid,
             &Private->Mtftp4Child
             );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  Status = gBS->OpenProtocol (
                  Private->Mtftp4Child,
                  &gEfiMtftp4ProtocolGuid,
                  (VOID **) &Private->Mtftp4,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Create Udp4 child and open Udp4 protocol for PxeBc->UdpRead.
  //
  Status = NetLibCreateServiceChild (
             ControllerHandle,
             This->DriverBindingHandle,
             &gEfiUdp4ServiceBindingProtocolGuid,
             &Private->Udp4ReadChild
             );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  Status = gBS->OpenProtocol (
                  Private->Udp4ReadChild,
                  &gEfiUdp4ProtocolGuid,
                  (VOID **) &Private->Udp4Read,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Create Udp4 child and open Udp4 protocol for PxeBc->UdpWrite.
  //
  Status = NetLibCreateServiceChild (
             ControllerHandle,
             This->DriverBindingHandle,
             &gEfiUdp4ServiceBindingProtocolGuid,
             &Private->Udp4WriteChild
             );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  Status = gBS->OpenProtocol (
                  Private->Udp4WriteChild,
                  &gEfiUdp4ProtocolGuid,
                  (VOID **) &Private->Udp4Write,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Create Arp child and open Arp protocol for PxeBc->Arp.
  //
  Status = NetLibCreateServiceChild (
             ControllerHandle,
             This->DriverBindingHandle,
             &gEfiArpServiceBindingProtocolGuid,
             &Private->ArpChild
             );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  Status = gBS->OpenProtocol (
                  Private->ArpChild,
                  &gEfiArpProtocolGuid,
                  (VOID **) &Private->Arp,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Create Ip4 child and open Ip4 protocol for background ICMP packets.
  //
  Status = NetLibCreateServiceChild (
             ControllerHandle,
             This->DriverBindingHandle,
             &gEfiIp4ServiceBindingProtocolGuid,
             &Private->Ip4Child
             );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  Status = gBS->OpenProtocol (
                  Private->Ip4Child,
                  &gEfiIp4ProtocolGuid,
                  (VOID **) &Private->Ip4,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Get max packet size from Ip4 to calculate block size for Tftp later.
  //
  Status = Private->Ip4->GetModeData (Private->Ip4, &Ip4ModeData, NULL, NULL);
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  Private->Ip4MaxPacketSize = Ip4ModeData.MaxPacketSize;

  Private->Ip4Nic = AllocateZeroPool (sizeof (PXEBC_VIRTUAL_NIC));
  if (Private->Ip4Nic == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Private->Ip4Nic->Private   = Private;
  Private->Ip4Nic->Signature = PXEBC_VIRTUAL_NIC_SIGNATURE;

   //
  // Locate Ip4->Ip4Config2 and store it for set IPv4 Policy.
  //
  Status = gBS->HandleProtocol (
                  ControllerHandle,
                  &gEfiIp4Config2ProtocolGuid,
                  (VOID **) &Private->Ip4Config2
                  );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Create a device path node for Ipv4 virtual nic, and append it.
  //
  ZeroMem (&Ip4Node, sizeof (IPv4_DEVICE_PATH));
  Ip4Node.Header.Type     = MESSAGING_DEVICE_PATH;
  Ip4Node.Header.SubType  = MSG_IPv4_DP;
  Ip4Node.StaticIpAddress = FALSE;

  SetDevicePathNodeLength (&Ip4Node.Header, sizeof (Ip4Node));

  Private->Ip4Nic->DevicePath = AppendDevicePathNode (Private->DevicePath, &Ip4Node.Header);

  if (Private->Ip4Nic->DevicePath == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_ERROR;
  }

  CopyMem (
    &Private->Ip4Nic->LoadFile,
    &gLoadFileProtocolTemplate,
    sizeof (EFI_LOAD_FILE_PROTOCOL)
    );

  //
  // Create a new handle for IPv4 virtual nic,
  // and install PxeBaseCode, LoadFile and DevicePath protocols.
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Private->Ip4Nic->Controller,
                  &gEfiDevicePathProtocolGuid,
                  Private->Ip4Nic->DevicePath,
                  &gEfiLoadFileProtocolGuid,
                  &Private->Ip4Nic->LoadFile,
                  &gEfiPxeBaseCodeProtocolGuid,
                  &Private->PxeBc,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  if (Private->Snp != NULL) {
    //
    // Install SNP protocol on purpose is for some OS loader backward
    // compatibility consideration.
    //
    Status = gBS->InstallProtocolInterface (
                    &Private->Ip4Nic->Controller,
                    &gEfiSimpleNetworkProtocolGuid,
                    EFI_NATIVE_INTERFACE,
                    Private->Snp
                    );
    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }

    //
    // Open SNP on the child handle BY_DRIVER|EXCLUSIVE. It will prevent any additionally
    // layering to perform the experiment.
    //
    Status = gBS->OpenProtocol (
                    Private->Ip4Nic->Controller,
                    &gEfiSimpleNetworkProtocolGuid,
                    (VOID **) &Snp,
                    This->DriverBindingHandle,
                    Private->Ip4Nic->Controller,
                    EFI_OPEN_PROTOCOL_BY_DRIVER|EFI_OPEN_PROTOCOL_EXCLUSIVE
                    );
    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }
  }

  //
  // Open PxeBaseCodePrivate protocol by child to setup a parent-child relationship between
  // real NIC handle and the virtual IPv4 NIC handle.
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiCallerIdGuid,
                  (VOID **) &Id,
                  This->DriverBindingHandle,
                  Private->Ip4Nic->Controller,
                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                  );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Set default configure data for Udp4Read and Ip4 instance.
  //
  Mode                            = Private->PxeBc.Mode;
  Udp4CfgData                     = &Private->Udp4CfgData;
  Ip4CfgData                      = &Private->Ip4CfgData;

  Udp4CfgData->AcceptBroadcast    = FALSE;
  Udp4CfgData->AcceptAnyPort      = TRUE;
  Udp4CfgData->AllowDuplicatePort = TRUE;
  Udp4CfgData->TypeOfService      = Mode->ToS;
  Udp4CfgData->TimeToLive         = Mode->TTL;
  Udp4CfgData->ReceiveTimeout     = PXEBC_DEFAULT_LIFETIME;
  Udp4CfgData->TransmitTimeout    = PXEBC_DEFAULT_LIFETIME;

  Ip4CfgData->AcceptIcmpErrors    = TRUE;
  Ip4CfgData->DefaultProtocol     = EFI_IP_PROTO_ICMP;
  Ip4CfgData->TypeOfService       = Mode->ToS;
  Ip4CfgData->TimeToLive          = Mode->TTL;
  Ip4CfgData->ReceiveTimeout      = PXEBC_DEFAULT_LIFETIME;
  Ip4CfgData->TransmitTimeout     = PXEBC_DEFAULT_LIFETIME;

  return EFI_SUCCESS;

ON_ERROR:
  PxeBcDestroyIp4Children (This, Private);
  return Status;
}


/**
  Create the opened instances based on IPv6.

  @param[in]  This              Pointer to EFI_DRIVER_BINDING_PROTOCOL.
  @param[in]  ControllerHandle  Handle of the child to destroy.
  @param[in]  Private Handle    Pointer to PXEBC_PRIVATE_DATA.

  @retval EFI_SUCCESS           The instances based on IPv6 were all created successfully.
  @retval Others                An unexpected error occurred.

**/
EFI_STATUS
PxeBcCreateIp6Children (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN PXEBC_PRIVATE_DATA           *Private
  )
{
  EFI_STATUS                      Status;
  IPv6_DEVICE_PATH                Ip6Node;
  EFI_UDP6_CONFIG_DATA            *Udp6CfgData;
  EFI_IP6_CONFIG_DATA             *Ip6CfgData;
  EFI_IP6_MODE_DATA               Ip6ModeData;
  PXEBC_PRIVATE_PROTOCOL          *Id;
  EFI_SIMPLE_NETWORK_PROTOCOL     *Snp;
  UINTN                           Index;

  if (Private->Ip6Nic != NULL) {
    //
    // Already created before.
    //
    return EFI_SUCCESS;
  }

  Private->Ip6Nic = AllocateZeroPool (sizeof (PXEBC_VIRTUAL_NIC));

  if (Private->Ip6Nic == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Private->Ip6Nic->Private   = Private;
  Private->Ip6Nic->Signature = PXEBC_VIRTUAL_NIC_SIGNATURE;

  //
  // Create Dhcp6 child and open Dhcp6 protocol for PxeBc->Dhcp.
  //
  Status = NetLibCreateServiceChild (
             ControllerHandle,
             This->DriverBindingHandle,
             &gEfiDhcp6ServiceBindingProtocolGuid,
             &Private->Dhcp6Child
             );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  Status = gBS->OpenProtocol (
                  Private->Dhcp6Child,
                  &gEfiDhcp6ProtocolGuid,
                  (VOID **) &Private->Dhcp6,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Generate a random IAID for the Dhcp6 assigned address.
  //
  Private->IaId = NET_RANDOM (NetRandomInitSeed ());
  if (Private->Snp != NULL) {
    for (Index = 0; Index < Private->Snp->Mode->HwAddressSize; Index++) {
      Private->IaId |= (Private->Snp->Mode->CurrentAddress.Addr[Index] << ((Index << 3) & 31));
    }
  }

  //
  // Create Mtftp6 child and open Mtftp6 protocol for PxeBc->Mtftp.
  //
  Status = NetLibCreateServiceChild (
             ControllerHandle,
             This->DriverBindingHandle,
             &gEfiMtftp6ServiceBindingProtocolGuid,
             &Private->Mtftp6Child
             );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  Status = gBS->OpenProtocol (
                  Private->Mtftp6Child,
                  &gEfiMtftp6ProtocolGuid,
                  (VOID **) &Private->Mtftp6,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Create Udp6 child and open Udp6 protocol for PxeBc->UdpRead.
  //
  Status = NetLibCreateServiceChild (
             ControllerHandle,
             This->DriverBindingHandle,
             &gEfiUdp6ServiceBindingProtocolGuid,
             &Private->Udp6ReadChild
             );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  Status = gBS->OpenProtocol (
                  Private->Udp6ReadChild,
                  &gEfiUdp6ProtocolGuid,
                  (VOID **) &Private->Udp6Read,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Create Udp6 child and open Udp6 protocol for PxeBc->UdpWrite.
  //
  Status = NetLibCreateServiceChild (
             ControllerHandle,
             This->DriverBindingHandle,
             &gEfiUdp6ServiceBindingProtocolGuid,
             &Private->Udp6WriteChild
             );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  Status = gBS->OpenProtocol (
                  Private->Udp6WriteChild,
                  &gEfiUdp6ProtocolGuid,
                  (VOID **) &Private->Udp6Write,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Create Ip6 child and open Ip6 protocol for background ICMP6 packets.
  //
  Status = NetLibCreateServiceChild (
             ControllerHandle,
             This->DriverBindingHandle,
             &gEfiIp6ServiceBindingProtocolGuid,
             &Private->Ip6Child
             );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  Status = gBS->OpenProtocol (
                  Private->Ip6Child,
                  &gEfiIp6ProtocolGuid,
                  (VOID **) &Private->Ip6,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Get max packet size from Ip6 to calculate block size for Tftp later.
  //
  Status = Private->Ip6->GetModeData (Private->Ip6, &Ip6ModeData, NULL, NULL);
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  Private->Ip6MaxPacketSize = Ip6ModeData.MaxPacketSize;

  if (Ip6ModeData.AddressList != NULL) {
    FreePool (Ip6ModeData.AddressList);
  }

  if (Ip6ModeData.GroupTable != NULL) {
    FreePool (Ip6ModeData.GroupTable);
  }

  if (Ip6ModeData.RouteTable != NULL) {
    FreePool (Ip6ModeData.RouteTable);
  }

  if (Ip6ModeData.NeighborCache != NULL) {
    FreePool (Ip6ModeData.NeighborCache);
  }

  if (Ip6ModeData.PrefixTable != NULL) {
    FreePool (Ip6ModeData.PrefixTable);
  }

  if (Ip6ModeData.IcmpTypeList != NULL) {
    FreePool (Ip6ModeData.IcmpTypeList);
  }

  //
  // Locate Ip6->Ip6Config and store it for set IPv6 address.
  //
  Status = gBS->HandleProtocol (
                  ControllerHandle,
                  &gEfiIp6ConfigProtocolGuid,
                  (VOID **) &Private->Ip6Cfg
                  );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Create a device path node for Ipv6 virtual nic, and append it.
  //
  ZeroMem (&Ip6Node, sizeof (IPv6_DEVICE_PATH));
  Ip6Node.Header.Type     = MESSAGING_DEVICE_PATH;
  Ip6Node.Header.SubType  = MSG_IPv6_DP;
  Ip6Node.PrefixLength    = IP6_PREFIX_LENGTH;

  SetDevicePathNodeLength (&Ip6Node.Header, sizeof (Ip6Node));

  Private->Ip6Nic->DevicePath = AppendDevicePathNode (Private->DevicePath, &Ip6Node.Header);

  if (Private->Ip6Nic->DevicePath == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_ERROR;
  }

  CopyMem (
    &Private->Ip6Nic->LoadFile,
    &gLoadFileProtocolTemplate,
    sizeof (EFI_LOAD_FILE_PROTOCOL)
    );

  //
  // Create a new handle for IPv6 virtual nic,
  // and install PxeBaseCode, LoadFile and DevicePath protocols.
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Private->Ip6Nic->Controller,
                  &gEfiDevicePathProtocolGuid,
                  Private->Ip6Nic->DevicePath,
                  &gEfiLoadFileProtocolGuid,
                  &Private->Ip6Nic->LoadFile,
                  &gEfiPxeBaseCodeProtocolGuid,
                  &Private->PxeBc,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  if (Private->Snp != NULL) {
    //
    // Install SNP protocol on purpose is for some OS loader backward
    // compatibility consideration.
    //
    Status = gBS->InstallProtocolInterface (
                    &Private->Ip6Nic->Controller,
                    &gEfiSimpleNetworkProtocolGuid,
                    EFI_NATIVE_INTERFACE,
                    Private->Snp
                    );
    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }

    //
    // Open SNP on the child handle BY_DRIVER|EXCLUSIVE. It will prevent any additionally
    // layering to perform the experiment.
    //
    Status = gBS->OpenProtocol (
                    Private->Ip6Nic->Controller,
                    &gEfiSimpleNetworkProtocolGuid,
                    (VOID **) &Snp,
                    This->DriverBindingHandle,
                    Private->Ip6Nic->Controller,
                    EFI_OPEN_PROTOCOL_BY_DRIVER|EFI_OPEN_PROTOCOL_EXCLUSIVE
                    );
    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }
  }

  //
  // Open PxeBaseCodePrivate protocol by child to setup a parent-child relationship between
  // real NIC handle and the virtual IPv6 NIC handle.
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiCallerIdGuid,
                  (VOID **) &Id,
                  This->DriverBindingHandle,
                  Private->Ip6Nic->Controller,
                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                  );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Set IPv6 avaiable flag and set default configure data for
  // Udp6Read and Ip6 instance.
  //
  Status = PxeBcCheckIpv6Support (ControllerHandle, Private, &Private->Mode.Ipv6Available);
  if (EFI_ERROR (Status)) {
    //
    // Fail to get the data whether UNDI supports IPv6. Set default value.
    //
    Private->Mode.Ipv6Available   = TRUE;
  }

  if (!Private->Mode.Ipv6Available) {
    goto ON_ERROR;
  }

  Udp6CfgData                     = &Private->Udp6CfgData;
  Ip6CfgData                      = &Private->Ip6CfgData;

  Udp6CfgData->AcceptAnyPort      = TRUE;
  Udp6CfgData->AllowDuplicatePort = TRUE;
  Udp6CfgData->HopLimit           = PXEBC_DEFAULT_HOPLIMIT;
  Udp6CfgData->ReceiveTimeout     = PXEBC_DEFAULT_LIFETIME;
  Udp6CfgData->TransmitTimeout    = PXEBC_DEFAULT_LIFETIME;

  Ip6CfgData->AcceptIcmpErrors    = TRUE;
  Ip6CfgData->DefaultProtocol     = IP6_ICMP;
  Ip6CfgData->HopLimit            = PXEBC_DEFAULT_HOPLIMIT;
  Ip6CfgData->ReceiveTimeout      = PXEBC_DEFAULT_LIFETIME;
  Ip6CfgData->TransmitTimeout     = PXEBC_DEFAULT_LIFETIME;

  return EFI_SUCCESS;

ON_ERROR:
  PxeBcDestroyIp6Children (This, Private);
  return Status;
}


/**
  The entry point for UefiPxeBc driver that installs the driver
  binding and component name protocol on its image.

  @param[in]  ImageHandle          The Image handle of the driver.
  @param[in]  SystemTable          The system table.

  @return EFI_SUCCESS
  @return Others

**/
EFI_STATUS
EFIAPI
PxeBcDriverEntryPoint (
  IN EFI_HANDLE             ImageHandle,
  IN EFI_SYSTEM_TABLE       *SystemTable
  )
{
  EFI_STATUS  Status;

  Status = EfiLibInstallDriverBindingComponentName2 (
             ImageHandle,
             SystemTable,
             &gPxeBcIp4DriverBinding,
             ImageHandle,
             &gPxeBcComponentName,
             &gPxeBcComponentName2
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = EfiLibInstallDriverBindingComponentName2 (
             ImageHandle,
             SystemTable,
             &gPxeBcIp6DriverBinding,
             NULL,
             &gPxeBcComponentName,
             &gPxeBcComponentName2
             );
  if (EFI_ERROR (Status)) {
    gBS->UninstallMultipleProtocolInterfaces (
           ImageHandle,
           &gEfiDriverBindingProtocolGuid,
           &gPxeBcIp4DriverBinding,
           &gEfiComponentName2ProtocolGuid,
           &gPxeBcComponentName2,
           &gEfiComponentNameProtocolGuid,
           &gPxeBcComponentName,
           NULL
           );
  }

  return Status;
}

/**
  Test to see if this driver supports ControllerHandle. This is the worker function for
  PxeBcIp4(6)DriverBindingSupported.

  @param[in]  This                The pointer to the driver binding protocol.
  @param[in]  ControllerHandle    The handle of device to be tested.
  @param[in]  RemainingDevicePath Optional parameter used to pick a specific child
                                  device to be started.
  @param[in]  IpVersion           IP_VERSION_4 or IP_VERSION_6.

  @retval EFI_SUCCESS         This driver supports this device.
  @retval EFI_UNSUPPORTED     This driver does not support this device.

**/
EFI_STATUS
EFIAPI
PxeBcSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL,
  IN UINT8                        IpVersion
  )
{
  EFI_STATUS                      Status;
  EFI_GUID                        *DhcpServiceBindingGuid;
  EFI_GUID                        *MtftpServiceBindingGuid;

  if (IpVersion == IP_VERSION_4) {
    DhcpServiceBindingGuid  = &gEfiDhcp4ServiceBindingProtocolGuid;
    MtftpServiceBindingGuid = &gEfiMtftp4ServiceBindingProtocolGuid;
  } else {
    DhcpServiceBindingGuid  = &gEfiDhcp6ServiceBindingProtocolGuid;
    MtftpServiceBindingGuid = &gEfiMtftp6ServiceBindingProtocolGuid;
  }

  //
  // Try to open the Mtftp and Dhcp protocol to test whether IP stack is ready.
  //
  Status = gBS->OpenProtocol (
                     ControllerHandle,
                     DhcpServiceBindingGuid,
                     NULL,
                     This->DriverBindingHandle,
                     ControllerHandle,
                     EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                     );
  if (!EFI_ERROR (Status)) {
    Status = gBS->OpenProtocol (
                       ControllerHandle,
                       MtftpServiceBindingGuid,
                       NULL,
                       This->DriverBindingHandle,
                       ControllerHandle,
                       EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                       );
  }

  //
  // It's unsupported case if IP stack are not ready.
  //
  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  return EFI_SUCCESS;
}

/**
  Start this driver on ControllerHandle. This is the worker function for
  PxeBcIp4(6)DriverBindingStart.

  @param[in]  This                 The pointer to the driver binding protocol.
  @param[in]  ControllerHandle     The handle of device to be started.
  @param[in]  RemainingDevicePath  Optional parameter used to pick a specific child
                                   device to be started.
  @param[in]  IpVersion            IP_VERSION_4 or IP_VERSION_6.


  @retval EFI_SUCCESS          This driver is installed to ControllerHandle.
  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle.
  @retval other                This driver does not support this device.

**/
EFI_STATUS
EFIAPI
PxeBcStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL,
  IN UINT8                        IpVersion
  )
{
  PXEBC_PRIVATE_DATA              *Private;
  EFI_STATUS                      Status;
  PXEBC_PRIVATE_PROTOCOL          *Id;
  BOOLEAN                         FirstStart;

  FirstStart = FALSE;
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiCallerIdGuid,
                  (VOID **) &Id,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (!EFI_ERROR (Status)) {
    //
    // Skip the initialization if the driver has been started already.
    //
    Private = PXEBC_PRIVATE_DATA_FROM_ID (Id);
  } else {
    FirstStart = TRUE;
    //
    // If the driver has not been started yet, it should do initialization.
    //
    Private = AllocateZeroPool (sizeof (PXEBC_PRIVATE_DATA));
    if (Private == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    CopyMem (
      &Private->PxeBc,
      &gPxeBcProtocolTemplate,
      sizeof (EFI_PXE_BASE_CODE_PROTOCOL)
      );

    Private->Signature          = PXEBC_PRIVATE_DATA_SIGNATURE;
    Private->Controller         = ControllerHandle;
    Private->Image              = This->ImageHandle;
    Private->PxeBc.Mode         = &Private->Mode;
    Private->Mode.Ipv6Supported = TRUE;
    Private->Mode.AutoArp       = TRUE;
    Private->Mode.TTL           = DEFAULT_TTL;
    Private->Mode.ToS           = DEFAULT_ToS;

    //
    // Open device path to prepare for appending virtual NIC node.
    //
    Status = gBS->OpenProtocol (
                    ControllerHandle,
                    &gEfiDevicePathProtocolGuid,
                    (VOID **) &Private->DevicePath,
                    This->DriverBindingHandle,
                    ControllerHandle,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );

    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }

    //
    // Get the NII interface if it exists, it's not required.
    //
    Status = gBS->OpenProtocol (
                    ControllerHandle,
                    &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
                    (VOID **) &Private->Nii,
                    This->DriverBindingHandle,
                    ControllerHandle,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      Private->Nii = NULL;
    }

    //
    // Install PxeBaseCodePrivate protocol onto the real NIC handler.
    // PxeBaseCodePrivate protocol is only used to keep the relationship between
    // NIC handle and virtual child handles.
    // gEfiCallerIdGuid will be used as its protocol guid.
    //
    Status = gBS->InstallProtocolInterface (
                    &ControllerHandle,
                    &gEfiCallerIdGuid,
                    EFI_NATIVE_INTERFACE,
                    &Private->Id
                    );
    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }

    //
    // Try to locate SNP protocol.
    //
    NetLibGetSnpHandle(ControllerHandle, &Private->Snp);
  }

  if (IpVersion == IP_VERSION_4) {
    //
    // Try to create virtual NIC handle for IPv4.
    //
    Status = PxeBcCreateIp4Children (This, ControllerHandle, Private);
  } else {
    //
    // Try to create virtual NIC handle for IPv6.
    //
    Status = PxeBcCreateIp6Children (This, ControllerHandle, Private);
  }
  if (EFI_ERROR (Status)) {
    //
    // Failed to start PXE driver if IPv4 and IPv6 stack are both not available.
    //
    Status = EFI_DEVICE_ERROR;
    goto ON_ERROR;
  }

  return EFI_SUCCESS;

ON_ERROR:
  if (FirstStart) {
    gBS->UninstallProtocolInterface (
           ControllerHandle,
           &gEfiCallerIdGuid,
           &Private->Id
           );
  }

  if (IpVersion == IP_VERSION_4) {
    PxeBcDestroyIp4Children (This, Private);
  } else {
    PxeBcDestroyIp6Children (This, Private);
  }

  if (FirstStart && Private != NULL) {
    FreePool (Private);
  }

  return Status;
}


/**
  Stop this driver on ControllerHandle. This is the worker function for
  PxeBcIp4(6)DriverBindingStop.

  @param[in]  This              Protocol instance pointer.
  @param[in]  ControllerHandle  Handle of device to stop driver on.
  @param[in]  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
                                children is zero stop the entire bus driver.
  @param[in]  ChildHandleBuffer List of Child Handles to Stop.
  @param[in]  IpVersion         IP_VERSION_4 or IP_VERSION_6.

  @retval EFI_SUCCESS           This driver was removed ControllerHandle.
  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.
  @retval Others                This driver was not removed from this device

**/
EFI_STATUS
EFIAPI
PxeBcStop (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN UINTN                        NumberOfChildren,
  IN EFI_HANDLE                   *ChildHandleBuffer,
  IN UINT8                        IpVersion
  )
{
  PXEBC_PRIVATE_DATA              *Private;
  PXEBC_VIRTUAL_NIC               *VirtualNic;
  EFI_LOAD_FILE_PROTOCOL          *LoadFile;
  EFI_STATUS                      Status;
  EFI_HANDLE                      NicHandle;
  PXEBC_PRIVATE_PROTOCOL          *Id;

  Private    = NULL;
  NicHandle  = NULL;
  VirtualNic = NULL;
  LoadFile   = NULL;
  Id         = NULL;

  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiLoadFileProtocolGuid,
                  (VOID **) &LoadFile,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    //
    // Get the Nic handle by any pass-over service child handle.
    //
    if (IpVersion == IP_VERSION_4) {
      NicHandle = PxeBcGetNicByIp4Children (ControllerHandle);
    } else {
      NicHandle = PxeBcGetNicByIp6Children (ControllerHandle);
    }
    if (NicHandle == NULL) {
      return EFI_SUCCESS;
    }

    //
    // Try to retrieve the private data by PxeBcPrivate protocol.
    //
    Status = gBS->OpenProtocol (
                    NicHandle,
                    &gEfiCallerIdGuid,
                    (VOID **) &Id,
                    This->DriverBindingHandle,
                    ControllerHandle,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }
    Private = PXEBC_PRIVATE_DATA_FROM_ID (Id);

  } else {
    //
    // It's a virtual handle with LoadFileProtocol.
    //
    Status = gBS->OpenProtocol (
                    ControllerHandle,
                    &gEfiLoadFileProtocolGuid,
                    (VOID **) &LoadFile,
                    This->DriverBindingHandle,
                    ControllerHandle,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    VirtualNic = PXEBC_VIRTUAL_NIC_FROM_LOADFILE (LoadFile);
    Private    = VirtualNic->Private;
    NicHandle  = Private->Controller;
  }

  //
  // Stop functionality of PXE Base Code protocol
  //
  Status = Private->PxeBc.Stop (&Private->PxeBc);
  if (Status != EFI_SUCCESS && Status != EFI_NOT_STARTED) {
    return Status;
  }


  if (Private->Ip4Nic != NULL && IpVersion == IP_VERSION_4) {
    PxeBcDestroyIp4Children (This, Private);
  }

  if (Private->Ip6Nic != NULL && IpVersion == IP_VERSION_6) {
    PxeBcDestroyIp6Children (This, Private);
  }

  if (Private->Ip4Nic == NULL && Private->Ip6Nic == NULL) {
    gBS->UninstallProtocolInterface (
           NicHandle,
           &gEfiCallerIdGuid,
           &Private->Id
           );
    FreePool (Private);
  }

  return EFI_SUCCESS;
}

/**
  Test to see if this driver supports ControllerHandle. This service
  is called by the EFI boot service ConnectController(). In
  order to make drivers as small as possible, there are a few calling
  restrictions for this service. ConnectController() must
  follow these calling restrictions. If any other agent wishes to call
  Supported() it must also follow these calling restrictions.

  @param[in]  This                The pointer to the driver binding protocol.
  @param[in]  ControllerHandle    The handle of device to be tested.
  @param[in]  RemainingDevicePath Optional parameter used to pick a specific child
                                  device to be started.

  @retval EFI_SUCCESS         This driver supports this device.
  @retval EFI_UNSUPPORTED     This driver does not support this device.

**/
EFI_STATUS
EFIAPI
PxeBcIp4DriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  return PxeBcSupported (
           This,
           ControllerHandle,
           RemainingDevicePath,
           IP_VERSION_4
           );
}

/**
  Start this driver on ControllerHandle. This service is called by the
  EFI boot service ConnectController(). In order to make
  drivers as small as possible, there are a few calling restrictions for
  this service. ConnectController() must follow these
  calling restrictions. If any other agent wishes to call Start() it
  must also follow these calling restrictions.

  @param[in]  This                 The pointer to the driver binding protocol.
  @param[in]  ControllerHandle     The handle of device to be started.
  @param[in]  RemainingDevicePath  Optional parameter used to pick a specific child
                                   device to be started.

  @retval EFI_SUCCESS          This driver is installed to ControllerHandle.
  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle.
  @retval other                This driver does not support this device.

**/
EFI_STATUS
EFIAPI
PxeBcIp4DriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  return PxeBcStart (
           This,
           ControllerHandle,
           RemainingDevicePath,
           IP_VERSION_4
           );
}

/**
  Stop this driver on ControllerHandle. This service is called by the
  EFI boot service DisconnectController(). In order to
  make drivers as small as possible, there are a few calling
  restrictions for this service. DisconnectController()
  must follow these calling restrictions. If any other agent wishes
  to call Stop() it must also follow these calling restrictions.

  @param[in]  This              Protocol instance pointer.
  @param[in]  ControllerHandle  Handle of device to stop driver on
  @param[in]  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
                                children is zero stop the entire bus driver.
  @param[in]  ChildHandleBuffer List of Child Handles to Stop.

  @retval EFI_SUCCESS           This driver is removed ControllerHandle
  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.
  @retval Others                This driver was not removed from this device.

**/
EFI_STATUS
EFIAPI
PxeBcIp4DriverBindingStop (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN UINTN                        NumberOfChildren,
  IN EFI_HANDLE                   *ChildHandleBuffer
  )
{
  return PxeBcStop (
           This,
           ControllerHandle,
           NumberOfChildren,
           ChildHandleBuffer,
           IP_VERSION_4
           );
}

/**
  Test to see if this driver supports ControllerHandle. This service
  is called by the EFI boot service ConnectController(). In
  order to make drivers as small as possible, there are a few calling
  restrictions for this service. ConnectController() must
  follow these calling restrictions. If any other agent wishes to call
  Supported() it must also follow these calling restrictions.

  @param[in]  This                The pointer to the driver binding protocol.
  @param[in]  ControllerHandle    The handle of device to be tested.
  @param[in]  RemainingDevicePath Optional parameter use to pick a specific child
                                  device to be started.

  @retval EFI_SUCCESS         This driver supports this device.
  @retval EFI_UNSUPPORTED     This driver does not support this device.

**/
EFI_STATUS
EFIAPI
PxeBcIp6DriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  return PxeBcSupported (
           This,
           ControllerHandle,
           RemainingDevicePath,
           IP_VERSION_6
           );
}

/**
  Start this driver on ControllerHandle. This service is called by the
  EFI boot service ConnectController(). In order to make
  drivers as small as possible, there are a few calling restrictions for
  this service. ConnectController() must follow these
  calling restrictions. If any other agent wishes to call Start() it
  must also follow these calling restrictions.

  @param[in]  This                 The pointer to the driver binding protocol.
  @param[in]  ControllerHandle     The handle of device to be started.
  @param[in]  RemainingDevicePath  Optional parameter used to pick a specific child
                                   device to be started.

  @retval EFI_SUCCESS          This driver is installed to ControllerHandle.
  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle.
  @retval other                This driver does not support this device.

**/
EFI_STATUS
EFIAPI
PxeBcIp6DriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  return PxeBcStart (
           This,
           ControllerHandle,
           RemainingDevicePath,
           IP_VERSION_6
           );
}

/**
  Stop this driver on ControllerHandle. This service is called by the
  EFI boot service DisconnectController(). In order to
  make drivers as small as possible, there are a few calling
  restrictions for this service. DisconnectController()
  must follow these calling restrictions. If any other agent wishes
  to call Stop() it must also follow these calling restrictions.

  @param[in]  This              Protocol instance pointer.
  @param[in]  ControllerHandle  Handle of device to stop driver on
  @param[in]  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
                                children is zero stop the entire bus driver.
  @param[in]  ChildHandleBuffer List of Child Handles to Stop.

  @retval EFI_SUCCESS           This driver is removed ControllerHandle
  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.
  @retval Others                This driver was not removed from this device.

**/
EFI_STATUS
EFIAPI
PxeBcIp6DriverBindingStop (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN UINTN                        NumberOfChildren,
  IN EFI_HANDLE                   *ChildHandleBuffer
  )
{
  return PxeBcStop (
           This,
           ControllerHandle,
           NumberOfChildren,
           ChildHandleBuffer,
           IP_VERSION_6
           );
}
