]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c
Refine code to make it more safely.
[mirror_edk2.git] / NetworkPkg / UefiPxeBcDxe / PxeBcDriver.c
index f78525546a1e0b87180a2639bb16eaa9c3e5940d..8ee831f521a5324c3c07d4d02e944ca2702b908b 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Driver Binding functions implementationfor for UefiPxeBc Driver.\r
 \r
 /** @file\r
   Driver Binding functions implementationfor for UefiPxeBc Driver.\r
 \r
-  Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
 #include "PxeBcImpl.h"\r
 \r
 \r
 #include "PxeBcImpl.h"\r
 \r
 \r
-EFI_DRIVER_BINDING_PROTOCOL gPxeBcDriverBinding = {\r
-  PxeBcDriverBindingSupported,\r
-  PxeBcDriverBindingStart,\r
-  PxeBcDriverBindingStop,\r
+EFI_DRIVER_BINDING_PROTOCOL gPxeBcIp4DriverBinding = {\r
+  PxeBcIp4DriverBindingSupported,\r
+  PxeBcIp4DriverBindingStart,\r
+  PxeBcIp4DriverBindingStop,\r
   0xa,\r
   NULL,\r
   NULL\r
 };\r
 \r
   0xa,\r
   NULL,\r
   NULL\r
 };\r
 \r
+EFI_DRIVER_BINDING_PROTOCOL gPxeBcIp6DriverBinding = {\r
+  PxeBcIp6DriverBindingSupported,\r
+  PxeBcIp6DriverBindingStart,\r
+  PxeBcIp6DriverBindingStop,\r
+  0xa,\r
+  NULL,\r
+  NULL\r
+};\r
 \r
 /**\r
   Get the Nic handle using any child handle in the IPv4 stack.\r
 \r
 /**\r
   Get the Nic handle using any child handle in the IPv4 stack.\r
@@ -226,11 +234,11 @@ PxeBcDestroyIp4Children (
 \r
   if (Private->Ip4Nic != NULL) {\r
     //\r
 \r
   if (Private->Ip4Nic != NULL) {\r
     //\r
-    // Close PxeBc from the parent Nic handle and destroy the virtual handle.\r
+    // Close PxeBcPrivate from the parent Nic handle and destroy the virtual handle.\r
     //\r
     gBS->CloseProtocol (\r
            Private->Controller,\r
     //\r
     gBS->CloseProtocol (\r
            Private->Controller,\r
-           &gEfiPxeBaseCodeProtocolGuid,\r
+           &gEfiCallerIdGuid,\r
            This->DriverBindingHandle,\r
            Private->Ip4Nic->Controller\r
            );\r
            This->DriverBindingHandle,\r
            Private->Ip4Nic->Controller\r
            );\r
@@ -241,8 +249,28 @@ PxeBcDestroyIp4Children (
            Private->Ip4Nic->DevicePath,\r
            &gEfiLoadFileProtocolGuid,\r
            &Private->Ip4Nic->LoadFile,\r
            Private->Ip4Nic->DevicePath,\r
            &gEfiLoadFileProtocolGuid,\r
            &Private->Ip4Nic->LoadFile,\r
+           &gEfiPxeBaseCodeProtocolGuid,\r
+           &Private->PxeBc,\r
            NULL\r
            );\r
            NULL\r
            );\r
+\r
+    if (Private->Snp != NULL) { \r
+      //\r
+      // Close SNP from the child virtual handle\r
+      //\r
+      gBS->CloseProtocol (\r
+             Private->Ip4Nic->Controller,\r
+             &gEfiSimpleNetworkProtocolGuid,\r
+             This->DriverBindingHandle,\r
+             Private->Ip4Nic->Controller\r
+             );\r
+             \r
+      gBS->UninstallProtocolInterface (\r
+             Private->Ip4Nic->Controller,\r
+             &gEfiSimpleNetworkProtocolGuid,\r
+             Private->Snp\r
+             );\r
+    }\r
     FreePool (Private->Ip4Nic);\r
   }\r
 \r
     FreePool (Private->Ip4Nic);\r
   }\r
 \r
@@ -366,22 +394,41 @@ PxeBcDestroyIp6Children (
 \r
   if (Private->Ip6Nic != NULL) {\r
     //\r
 \r
   if (Private->Ip6Nic != NULL) {\r
     //\r
-    // Close PxeBc from the parent Nic handle and destroy the virtual handle.\r
+    // Close PxeBcPrivate from the parent Nic handle and destroy the virtual handle.\r
     //\r
     gBS->CloseProtocol (\r
            Private->Controller,\r
     //\r
     gBS->CloseProtocol (\r
            Private->Controller,\r
-           &gEfiPxeBaseCodeProtocolGuid,\r
+           &gEfiCallerIdGuid,\r
            This->DriverBindingHandle,\r
            Private->Ip6Nic->Controller\r
            );\r
            This->DriverBindingHandle,\r
            Private->Ip6Nic->Controller\r
            );\r
+\r
     gBS->UninstallMultipleProtocolInterfaces (\r
            Private->Ip6Nic->Controller,\r
            &gEfiDevicePathProtocolGuid,\r
            Private->Ip6Nic->DevicePath,\r
            &gEfiLoadFileProtocolGuid,\r
            &Private->Ip6Nic->LoadFile,\r
     gBS->UninstallMultipleProtocolInterfaces (\r
            Private->Ip6Nic->Controller,\r
            &gEfiDevicePathProtocolGuid,\r
            Private->Ip6Nic->DevicePath,\r
            &gEfiLoadFileProtocolGuid,\r
            &Private->Ip6Nic->LoadFile,\r
+           &gEfiPxeBaseCodeProtocolGuid,\r
+           &Private->PxeBc,\r
            NULL\r
            );\r
            NULL\r
            );\r
+    if (Private->Snp != NULL) {\r
+      //\r
+      // Close SNP from the child virtual handle\r
+      //\r
+      gBS->CloseProtocol (\r
+             Private->Ip6Nic->Controller,\r
+             &gEfiSimpleNetworkProtocolGuid,\r
+             This->DriverBindingHandle,\r
+             Private->Ip6Nic->Controller\r
+             );\r
+      gBS->UninstallProtocolInterface (\r
+             Private->Ip6Nic->Controller,\r
+             &gEfiSimpleNetworkProtocolGuid,\r
+             Private->Snp\r
+             );\r
+    }\r
     FreePool (Private->Ip6Nic);\r
   }\r
 \r
     FreePool (Private->Ip6Nic);\r
   }\r
 \r
@@ -415,11 +462,12 @@ PxeBcCreateIp4Children (
 {\r
   EFI_STATUS                      Status;\r
   IPv4_DEVICE_PATH                Ip4Node;\r
 {\r
   EFI_STATUS                      Status;\r
   IPv4_DEVICE_PATH                Ip4Node;\r
-  EFI_PXE_BASE_CODE_PROTOCOL      *PxeBc;\r
   EFI_PXE_BASE_CODE_MODE          *Mode;\r
   EFI_UDP4_CONFIG_DATA            *Udp4CfgData;\r
   EFI_IP4_CONFIG_DATA             *Ip4CfgData;\r
   EFI_IP4_MODE_DATA               Ip4ModeData;\r
   EFI_PXE_BASE_CODE_MODE          *Mode;\r
   EFI_UDP4_CONFIG_DATA            *Udp4CfgData;\r
   EFI_IP4_CONFIG_DATA             *Ip4CfgData;\r
   EFI_IP4_MODE_DATA               Ip4ModeData;\r
+  PXEBC_PRIVATE_PROTOCOL          *Id;\r
+  EFI_SIMPLE_NETWORK_PROTOCOL     *Snp;\r
 \r
   if (Private->Ip4Nic != NULL) {\r
     //\r
 \r
   if (Private->Ip4Nic != NULL) {\r
     //\r
@@ -629,20 +677,54 @@ PxeBcCreateIp4Children (
                   Private->Ip4Nic->DevicePath,\r
                   &gEfiLoadFileProtocolGuid,\r
                   &Private->Ip4Nic->LoadFile,\r
                   Private->Ip4Nic->DevicePath,\r
                   &gEfiLoadFileProtocolGuid,\r
                   &Private->Ip4Nic->LoadFile,\r
+                  &gEfiPxeBaseCodeProtocolGuid,\r
+                  &Private->PxeBc,\r
                   NULL\r
                   );\r
   if (EFI_ERROR (Status)) {\r
     goto ON_ERROR;\r
   }\r
 \r
                   NULL\r
                   );\r
   if (EFI_ERROR (Status)) {\r
     goto ON_ERROR;\r
   }\r
 \r
+  if (Private->Snp != NULL) {\r
+    //\r
+    // Install SNP protocol on purpose is for some OS loader backward\r
+    // compatibility consideration.\r
+    //\r
+    Status = gBS->InstallProtocolInterface (\r
+                    &Private->Ip4Nic->Controller,\r
+                    &gEfiSimpleNetworkProtocolGuid,\r
+                    EFI_NATIVE_INTERFACE,\r
+                    Private->Snp\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      goto ON_ERROR;\r
+    }\r
+\r
+    //\r
+    // Open SNP on the child handle BY_DRIVER. It will prevent any additionally \r
+    // layering to perform the experiment.\r
+    //\r
+    Status = gBS->OpenProtocol (\r
+                    Private->Ip4Nic->Controller,\r
+                    &gEfiSimpleNetworkProtocolGuid,\r
+                    (VOID **) &Snp,\r
+                    This->DriverBindingHandle,\r
+                    Private->Ip4Nic->Controller,\r
+                    EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      goto ON_ERROR;\r
+    }\r
+  }\r
+\r
   //\r
   //\r
-  // Open PxeBaseCode protocol by child to setup a parent-child relationship between\r
+  // Open PxeBaseCodePrivate protocol by child to setup a parent-child relationship between\r
   // real NIC handle and the virtual IPv4 NIC handle.\r
   //\r
   Status = gBS->OpenProtocol (\r
                   ControllerHandle,\r
   // real NIC handle and the virtual IPv4 NIC handle.\r
   //\r
   Status = gBS->OpenProtocol (\r
                   ControllerHandle,\r
-                  &gEfiPxeBaseCodeProtocolGuid,\r
-                  (VOID **) &PxeBc,\r
+                  &gEfiCallerIdGuid,\r
+                  (VOID **) &Id,\r
                   This->DriverBindingHandle,\r
                   Private->Ip4Nic->Controller,\r
                   EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
                   This->DriverBindingHandle,\r
                   Private->Ip4Nic->Controller,\r
                   EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
@@ -654,11 +736,11 @@ PxeBcCreateIp4Children (
   //\r
   // Set default configure data for Udp4Read and Ip4 instance.\r
   //\r
   //\r
   // Set default configure data for Udp4Read and Ip4 instance.\r
   //\r
-  Mode                            = PxeBc->Mode;\r
+  Mode                            = Private->PxeBc.Mode;\r
   Udp4CfgData                     = &Private->Udp4CfgData;\r
   Ip4CfgData                      = &Private->Ip4CfgData;\r
 \r
   Udp4CfgData                     = &Private->Udp4CfgData;\r
   Ip4CfgData                      = &Private->Ip4CfgData;\r
 \r
-  Udp4CfgData->AcceptBroadcast    = TRUE;\r
+  Udp4CfgData->AcceptBroadcast    = FALSE;\r
   Udp4CfgData->AcceptAnyPort      = TRUE;\r
   Udp4CfgData->AllowDuplicatePort = TRUE;\r
   Udp4CfgData->TypeOfService      = Mode->ToS;\r
   Udp4CfgData->AcceptAnyPort      = TRUE;\r
   Udp4CfgData->AllowDuplicatePort = TRUE;\r
   Udp4CfgData->TypeOfService      = Mode->ToS;\r
@@ -701,10 +783,12 @@ PxeBcCreateIp6Children (
 {\r
   EFI_STATUS                      Status;\r
   IPv6_DEVICE_PATH                Ip6Node;\r
 {\r
   EFI_STATUS                      Status;\r
   IPv6_DEVICE_PATH                Ip6Node;\r
-  EFI_PXE_BASE_CODE_PROTOCOL      *PxeBc;\r
   EFI_UDP6_CONFIG_DATA            *Udp6CfgData;\r
   EFI_IP6_CONFIG_DATA             *Ip6CfgData;\r
   EFI_IP6_MODE_DATA               Ip6ModeData;\r
   EFI_UDP6_CONFIG_DATA            *Udp6CfgData;\r
   EFI_IP6_CONFIG_DATA             *Ip6CfgData;\r
   EFI_IP6_MODE_DATA               Ip6ModeData;\r
+  PXEBC_PRIVATE_PROTOCOL          *Id;\r
+  EFI_SIMPLE_NETWORK_PROTOCOL     *Snp;\r
+  UINTN                           Index;\r
 \r
   if (Private->Ip6Nic != NULL) {\r
     //\r
 \r
   if (Private->Ip6Nic != NULL) {\r
     //\r
@@ -747,6 +831,16 @@ PxeBcCreateIp6Children (
     goto ON_ERROR;\r
   }\r
 \r
     goto ON_ERROR;\r
   }\r
 \r
+  //\r
+  // Generate a random IAID for the Dhcp6 assigned address.\r
+  //\r
+  Private->IaId = NET_RANDOM (NetRandomInitSeed ());\r
+  if (Private->Snp != NULL) {\r
+    for (Index = 0; Index < Private->Snp->Mode->HwAddressSize; Index++) {\r
+      Private->IaId |= (Private->Snp->Mode->CurrentAddress.Addr[Index] << ((Index << 3) & 31));\r
+    }  \r
+  }\r
+\r
   //\r
   // Create Mtftp6 child and open Mtftp6 protocol for PxeBc->Mtftp.\r
   //\r
   //\r
   // Create Mtftp6 child and open Mtftp6 protocol for PxeBc->Mtftp.\r
   //\r
@@ -875,7 +969,7 @@ PxeBcCreateIp6Children (
   ZeroMem (&Ip6Node, sizeof (IPv6_DEVICE_PATH));\r
   Ip6Node.Header.Type     = MESSAGING_DEVICE_PATH;\r
   Ip6Node.Header.SubType  = MSG_IPv6_DP;\r
   ZeroMem (&Ip6Node, sizeof (IPv6_DEVICE_PATH));\r
   Ip6Node.Header.Type     = MESSAGING_DEVICE_PATH;\r
   Ip6Node.Header.SubType  = MSG_IPv6_DP;\r
-  Ip6Node.StaticIpAddress = FALSE;\r
+  Ip6Node.PrefixLength    = IP6_PREFIX_LENGTH;\r
 \r
   SetDevicePathNodeLength (&Ip6Node.Header, sizeof (Ip6Node));\r
 \r
 \r
   SetDevicePathNodeLength (&Ip6Node.Header, sizeof (Ip6Node));\r
 \r
@@ -902,20 +996,54 @@ PxeBcCreateIp6Children (
                   Private->Ip6Nic->DevicePath,\r
                   &gEfiLoadFileProtocolGuid,\r
                   &Private->Ip6Nic->LoadFile,\r
                   Private->Ip6Nic->DevicePath,\r
                   &gEfiLoadFileProtocolGuid,\r
                   &Private->Ip6Nic->LoadFile,\r
+                  &gEfiPxeBaseCodeProtocolGuid,\r
+                  &Private->PxeBc,\r
                   NULL\r
                   );\r
   if (EFI_ERROR (Status)) {\r
     goto ON_ERROR;\r
   }\r
                   NULL\r
                   );\r
   if (EFI_ERROR (Status)) {\r
     goto ON_ERROR;\r
   }\r
+  \r
+  if (Private->Snp != NULL) {\r
+    //\r
+    // Install SNP protocol on purpose is for some OS loader backward\r
+    // compatibility consideration.\r
+    //\r
+    Status = gBS->InstallProtocolInterface (\r
+                    &Private->Ip6Nic->Controller,\r
+                    &gEfiSimpleNetworkProtocolGuid,\r
+                    EFI_NATIVE_INTERFACE,\r
+                    Private->Snp\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      goto ON_ERROR;\r
+    }\r
+\r
+    //\r
+    // Open SNP on the child handle BY_DRIVER. It will prevent any additionally \r
+    // layering to perform the experiment.\r
+    //\r
+    Status = gBS->OpenProtocol (\r
+                    Private->Ip6Nic->Controller,\r
+                    &gEfiSimpleNetworkProtocolGuid,\r
+                    (VOID **) &Snp,\r
+                    This->DriverBindingHandle,\r
+                    Private->Ip6Nic->Controller,\r
+                    EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      goto ON_ERROR;\r
+    }\r
+  }\r
 \r
   //\r
 \r
   //\r
-  // Open PxeBaseCode protocol by child to setup a parent-child relationship between\r
+  // Open PxeBaseCodePrivate protocol by child to setup a parent-child relationship between\r
   // real NIC handle and the virtual IPv6 NIC handle.\r
   //\r
   Status = gBS->OpenProtocol (\r
                   ControllerHandle,\r
   // real NIC handle and the virtual IPv6 NIC handle.\r
   //\r
   Status = gBS->OpenProtocol (\r
                   ControllerHandle,\r
-                  &gEfiPxeBaseCodeProtocolGuid,\r
-                  (VOID **) &PxeBc,\r
+                  &gEfiCallerIdGuid,\r
+                  (VOID **) &Id,\r
                   This->DriverBindingHandle,\r
                   Private->Ip6Nic->Controller,\r
                   EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
                   This->DriverBindingHandle,\r
                   Private->Ip6Nic->Controller,\r
                   EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
@@ -970,82 +1098,94 @@ PxeBcDriverEntryPoint (
   IN EFI_SYSTEM_TABLE       *SystemTable\r
   )\r
 {\r
   IN EFI_SYSTEM_TABLE       *SystemTable\r
   )\r
 {\r
-  return EfiLibInstallDriverBindingComponentName2 (\r
-           ImageHandle,\r
-           SystemTable,\r
-           &gPxeBcDriverBinding,\r
+  EFI_STATUS  Status;\r
+\r
+  Status = EfiLibInstallDriverBindingComponentName2 (\r
+             ImageHandle,\r
+             SystemTable,\r
+             &gPxeBcIp4DriverBinding,\r
+             ImageHandle,\r
+             &gPxeBcComponentName,\r
+             &gPxeBcComponentName2\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = EfiLibInstallDriverBindingComponentName2 (\r
+             ImageHandle,\r
+             SystemTable,\r
+             &gPxeBcIp6DriverBinding,\r
+             NULL,\r
+             &gPxeBcComponentName,\r
+             &gPxeBcComponentName2\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    gBS->UninstallMultipleProtocolInterfaces (\r
            ImageHandle,\r
            ImageHandle,\r
+           &gEfiDriverBindingProtocolGuid,\r
+           &gPxeBcIp4DriverBinding,\r
+           &gEfiComponentName2ProtocolGuid,\r
+           &gPxeBcComponentName2,\r
+           &gEfiComponentNameProtocolGuid,\r
            &gPxeBcComponentName,\r
            &gPxeBcComponentName,\r
-           &gPxeBcComponentName2\r
+           NULL\r
            );\r
            );\r
-}\r
+  }\r
 \r
 \r
+  return Status;\r
+}\r
 \r
 /**\r
 \r
 /**\r
-  Test to see if this driver supports ControllerHandle. This service\r
-  is called by the EFI boot service ConnectController(). In\r
-  order to make drivers as small as possible, there are a few calling\r
-  restrictions for this service. ConnectController() must\r
-  follow these calling restrictions. If any other agent wishes to call\r
-  Supported() it must also follow these calling restrictions.\r
+  Test to see if this driver supports ControllerHandle. This is the worker function for\r
+  PxeBcIp4(6)DriverBindingSupported.\r
 \r
   @param[in]  This                The pointer to the driver binding protocol.\r
   @param[in]  ControllerHandle    The handle of device to be tested.\r
   @param[in]  RemainingDevicePath Optional parameter used to pick a specific child\r
                                   device to be started.\r
 \r
   @param[in]  This                The pointer to the driver binding protocol.\r
   @param[in]  ControllerHandle    The handle of device to be tested.\r
   @param[in]  RemainingDevicePath Optional parameter used to pick a specific child\r
                                   device to be started.\r
-\r
+  @param[in]  IpVersion           IP_VERSION_4 or IP_VERSION_6.\r
+  \r
   @retval EFI_SUCCESS         This driver supports this device.\r
   @retval EFI_UNSUPPORTED     This driver does not support this device.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
   @retval EFI_SUCCESS         This driver supports this device.\r
   @retval EFI_UNSUPPORTED     This driver does not support this device.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-PxeBcDriverBindingSupported (\r
+PxeBcSupported (\r
   IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
   IN EFI_HANDLE                   ControllerHandle,\r
   IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
   IN EFI_HANDLE                   ControllerHandle,\r
-  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL,\r
+  IN UINT8                        IpVersion\r
   )\r
 {\r
   )\r
 {\r
-  EFI_STATUS                      Ip4Status;\r
-  EFI_STATUS                      Ip6Status;\r
-\r
-  //\r
-  // Try to open the Mtftp4 and Dhcp4 protocol to test whether IPv4 stack is ready.\r
-  //\r
-  Ip4Status = gBS->OpenProtocol (\r
-                     ControllerHandle,\r
-                     &gEfiDhcp4ServiceBindingProtocolGuid,\r
-                     NULL,\r
-                     This->DriverBindingHandle,\r
-                     ControllerHandle,\r
-                     EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
-                     );\r
-  if (!EFI_ERROR (Ip4Status)) {\r
-    Ip4Status = gBS->OpenProtocol (\r
-                       ControllerHandle,\r
-                       &gEfiMtftp4ServiceBindingProtocolGuid,\r
-                       NULL,\r
-                       This->DriverBindingHandle,\r
-                       ControllerHandle,\r
-                       EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
-                       );\r
+  EFI_STATUS                      Status;\r
+  EFI_GUID                        *DhcpServiceBindingGuid;\r
+  EFI_GUID                        *MtftpServiceBindingGuid;\r
+  \r
+  if (IpVersion == IP_VERSION_4) {\r
+    DhcpServiceBindingGuid  = &gEfiDhcp4ServiceBindingProtocolGuid;\r
+    MtftpServiceBindingGuid = &gEfiMtftp4ServiceBindingProtocolGuid;\r
+  } else {\r
+    DhcpServiceBindingGuid  = &gEfiDhcp6ServiceBindingProtocolGuid;\r
+    MtftpServiceBindingGuid = &gEfiMtftp6ServiceBindingProtocolGuid;\r
   }\r
 \r
   //\r
   }\r
 \r
   //\r
-  // Try to open the Mtftp6 and Dhcp6 protocol to test whether IPv4 stack is ready.\r
+  // Try to open the Mtftp and Dhcp protocol to test whether IP stack is ready.\r
   //\r
   //\r
-  Ip6Status = gBS->OpenProtocol (\r
+  Status = gBS->OpenProtocol (\r
                      ControllerHandle,\r
                      ControllerHandle,\r
-                     &gEfiDhcp6ServiceBindingProtocolGuid,\r
+                     DhcpServiceBindingGuid,\r
                      NULL,\r
                      This->DriverBindingHandle,\r
                      ControllerHandle,\r
                      EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
                      );\r
                      NULL,\r
                      This->DriverBindingHandle,\r
                      ControllerHandle,\r
                      EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
                      );\r
-  if (!EFI_ERROR (Ip6Status)) {\r
-    Ip6Status = gBS->OpenProtocol (\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = gBS->OpenProtocol (\r
                        ControllerHandle,\r
                        ControllerHandle,\r
-                       &gEfiMtftp6ServiceBindingProtocolGuid,\r
+                       MtftpServiceBindingGuid,\r
                        NULL,\r
                        This->DriverBindingHandle,\r
                        ControllerHandle,\r
                        NULL,\r
                        This->DriverBindingHandle,\r
                        ControllerHandle,\r
@@ -1054,28 +1194,25 @@ PxeBcDriverBindingSupported (
   }\r
 \r
   //\r
   }\r
 \r
   //\r
-  // It's unsupported case if both stack are not ready.\r
+  // It's unsupported case if IP stack are not ready.\r
   //\r
   //\r
-  if (EFI_ERROR (Ip4Status) && EFI_ERROR (Ip6Status)) {\r
+  if (EFI_ERROR (Status)) {\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
 /**\r
-  Start this driver on ControllerHandle. This service is called by the\r
-  EFI boot service ConnectController(). In order to make\r
-  drivers as small as possible, there are a few calling restrictions for\r
-  this service. ConnectController() must follow these\r
-  calling restrictions. If any other agent wishes to call Start() it\r
-  must also follow these calling restrictions.\r
+  Start this driver on ControllerHandle. This is the worker function for\r
+  PxeBcIp4(6)DriverBindingStart.\r
 \r
   @param[in]  This                 The pointer to the driver binding protocol.\r
   @param[in]  ControllerHandle     The handle of device to be started.\r
   @param[in]  RemainingDevicePath  Optional parameter used to pick a specific child\r
                                    device to be started.\r
 \r
   @param[in]  This                 The pointer to the driver binding protocol.\r
   @param[in]  ControllerHandle     The handle of device to be started.\r
   @param[in]  RemainingDevicePath  Optional parameter used to pick a specific child\r
                                    device to be started.\r
+  @param[in]  IpVersion            IP_VERSION_4 or IP_VERSION_6.\r
+\r
 \r
   @retval EFI_SUCCESS          This driver is installed to ControllerHandle.\r
   @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle.\r
 \r
   @retval EFI_SUCCESS          This driver is installed to ControllerHandle.\r
   @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle.\r
@@ -1084,22 +1221,23 @@ PxeBcDriverBindingSupported (
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-PxeBcDriverBindingStart (\r
+PxeBcStart (\r
   IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
   IN EFI_HANDLE                   ControllerHandle,\r
   IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
   IN EFI_HANDLE                   ControllerHandle,\r
-  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL,\r
+  IN UINT8                        IpVersion\r
   )\r
 {\r
   PXEBC_PRIVATE_DATA              *Private;\r
   )\r
 {\r
   PXEBC_PRIVATE_DATA              *Private;\r
-  EFI_PXE_BASE_CODE_PROTOCOL      *PxeBc;\r
   EFI_STATUS                      Status;\r
   EFI_STATUS                      Status;\r
-  EFI_STATUS                      Ip4Status;\r
-  EFI_STATUS                      Ip6Status;\r
+  PXEBC_PRIVATE_PROTOCOL          *Id;\r
+  BOOLEAN                         FirstStart;\r
 \r
 \r
+  FirstStart = FALSE;\r
   Status = gBS->OpenProtocol (\r
                   ControllerHandle,\r
   Status = gBS->OpenProtocol (\r
                   ControllerHandle,\r
-                  &gEfiPxeBaseCodeProtocolGuid,\r
-                  (VOID **) &PxeBc,\r
+                  &gEfiCallerIdGuid,\r
+                  (VOID **) &Id,\r
                   This->DriverBindingHandle,\r
                   ControllerHandle,\r
                   EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
                   This->DriverBindingHandle,\r
                   ControllerHandle,\r
                   EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
@@ -1108,8 +1246,9 @@ PxeBcDriverBindingStart (
     //\r
     // Skip the initialization if the driver has been started already.\r
     //\r
     //\r
     // Skip the initialization if the driver has been started already.\r
     //\r
-    Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (PxeBc);\r
+    Private = PXEBC_PRIVATE_DATA_FROM_ID (Id);\r
   } else {\r
   } else {\r
+    FirstStart = TRUE;\r
     //\r
     // If the driver has not been started yet, it should do initialization.\r
     //\r
     //\r
     // If the driver has not been started yet, it should do initialization.\r
     //\r
@@ -1165,30 +1304,39 @@ PxeBcDriverBindingStart (
     }\r
 \r
     //\r
     }\r
 \r
     //\r
-    // Install PxeBaseCode protocol onto the real NIC handler.\r
+    // Install PxeBaseCodePrivate protocol onto the real NIC handler.\r
+    // PxeBaseCodePrivate protocol is only used to keep the relationship between \r
+    // NIC handle and virtual child handles.\r
+    // gEfiCallerIdGuid will be used as its protocol guid.\r
     //\r
     Status = gBS->InstallProtocolInterface (\r
                     &ControllerHandle,\r
     //\r
     Status = gBS->InstallProtocolInterface (\r
                     &ControllerHandle,\r
-                    &gEfiPxeBaseCodeProtocolGuid,\r
+                    &gEfiCallerIdGuid,\r
                     EFI_NATIVE_INTERFACE,\r
                     EFI_NATIVE_INTERFACE,\r
-                    &Private->PxeBc\r
+                    &Private->Id\r
                     );\r
     if (EFI_ERROR (Status)) {\r
       goto ON_ERROR;\r
     }\r
                     );\r
     if (EFI_ERROR (Status)) {\r
       goto ON_ERROR;\r
     }\r
-  }\r
-\r
-  //\r
-  // Try to create virtual NIC handle for IPv4.\r
-  //\r
-  Ip4Status = PxeBcCreateIp4Children (This, ControllerHandle, Private);\r
 \r
 \r
-  //\r
-  // Try to create virtual NIC handle for IPv6.\r
-  //\r
-  Ip6Status = PxeBcCreateIp6Children (This, ControllerHandle, Private);\r
+    //\r
+    // Try to locate SNP protocol.\r
+    //\r
+    NetLibGetSnpHandle(ControllerHandle, &Private->Snp);    \r
+  }\r
 \r
 \r
-  if (EFI_ERROR (Ip4Status) && EFI_ERROR (Ip6Status)) {\r
+  if (IpVersion == IP_VERSION_4) {\r
+    //\r
+    // Try to create virtual NIC handle for IPv4.\r
+    //\r
+    Status = PxeBcCreateIp4Children (This, ControllerHandle, Private);\r
+  } else {\r
+    //\r
+    // Try to create virtual NIC handle for IPv6.\r
+    //\r
+    Status = PxeBcCreateIp6Children (This, ControllerHandle, Private);\r
+  }\r
+  if (EFI_ERROR (Status)) {\r
     //\r
     // Failed to start PXE driver if IPv4 and IPv6 stack are both not available.\r
     //\r
     //\r
     // Failed to start PXE driver if IPv4 and IPv6 stack are both not available.\r
     //\r
@@ -1199,32 +1347,38 @@ PxeBcDriverBindingStart (
   return EFI_SUCCESS;\r
 \r
 ON_ERROR:\r
   return EFI_SUCCESS;\r
 \r
 ON_ERROR:\r
-  gBS->UninstallProtocolInterface (\r
-         ControllerHandle,\r
-         &gEfiPxeBaseCodeProtocolGuid,\r
-         &Private->PxeBc\r
-         );\r
-  PxeBcDestroyIp4Children (This, Private);\r
-  PxeBcDestroyIp6Children (This, Private);\r
-  FreePool (Private);\r
+  if (FirstStart) {\r
+    gBS->UninstallProtocolInterface (\r
+           ControllerHandle,\r
+           &gEfiCallerIdGuid,\r
+           &Private->Id\r
+           );\r
+  }\r
+\r
+  if (IpVersion == IP_VERSION_4) {\r
+    PxeBcDestroyIp4Children (This, Private);\r
+  } else {\r
+    PxeBcDestroyIp6Children (This, Private);\r
+  }\r
+\r
+  if (FirstStart && Private != NULL) {\r
+    FreePool (Private);\r
+  }\r
 \r
   return Status;\r
 }\r
 \r
 \r
 /**\r
 \r
   return Status;\r
 }\r
 \r
 \r
 /**\r
-  Stop this driver on ControllerHandle. This service is called by the\r
-  EFI boot service DisconnectController(). In order to\r
-  make drivers as small as possible, there are a few calling\r
-  restrictions for this service. DisconnectController()\r
-  must follow these calling restrictions. If any other agent wishes\r
-  to call Stop() it must also follow these calling restrictions.\r
+  Stop this driver on ControllerHandle. This is the worker function for\r
+  PxeBcIp4(6)DriverBindingStop.\r
 \r
   @param[in]  This              Protocol instance pointer.\r
   @param[in]  ControllerHandle  Handle of device to stop driver on.\r
   @param[in]  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of\r
                                 children is zero stop the entire bus driver.\r
   @param[in]  ChildHandleBuffer List of Child Handles to Stop.\r
 \r
   @param[in]  This              Protocol instance pointer.\r
   @param[in]  ControllerHandle  Handle of device to stop driver on.\r
   @param[in]  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of\r
                                 children is zero stop the entire bus driver.\r
   @param[in]  ChildHandleBuffer List of Child Handles to Stop.\r
+  @param[in]  IpVersion         IP_VERSION_4 or IP_VERSION_6.\r
 \r
   @retval EFI_SUCCESS           This driver was removed ControllerHandle.\r
   @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.\r
 \r
   @retval EFI_SUCCESS           This driver was removed ControllerHandle.\r
   @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.\r
@@ -1233,26 +1387,27 @@ ON_ERROR:
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-PxeBcDriverBindingStop (\r
+PxeBcStop (\r
   IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
   IN EFI_HANDLE                   ControllerHandle,\r
   IN UINTN                        NumberOfChildren,\r
   IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
   IN EFI_HANDLE                   ControllerHandle,\r
   IN UINTN                        NumberOfChildren,\r
-  IN EFI_HANDLE                   *ChildHandleBuffer\r
+  IN EFI_HANDLE                   *ChildHandleBuffer,\r
+  IN UINT8                        IpVersion\r
   )\r
 {\r
   PXEBC_PRIVATE_DATA              *Private;\r
   PXEBC_VIRTUAL_NIC               *VirtualNic;\r
   )\r
 {\r
   PXEBC_PRIVATE_DATA              *Private;\r
   PXEBC_VIRTUAL_NIC               *VirtualNic;\r
-  EFI_PXE_BASE_CODE_PROTOCOL      *PxeBc;\r
   EFI_LOAD_FILE_PROTOCOL          *LoadFile;\r
   EFI_STATUS                      Status;\r
   EFI_HANDLE                      NicHandle;\r
   BOOLEAN                         IsIpv6;\r
   EFI_LOAD_FILE_PROTOCOL          *LoadFile;\r
   EFI_STATUS                      Status;\r
   EFI_HANDLE                      NicHandle;\r
   BOOLEAN                         IsIpv6;\r
+  PXEBC_PRIVATE_PROTOCOL          *Id;\r
 \r
   Private    = NULL;\r
   NicHandle  = NULL;\r
   VirtualNic = NULL;\r
   LoadFile   = NULL;\r
 \r
   Private    = NULL;\r
   NicHandle  = NULL;\r
   VirtualNic = NULL;\r
   LoadFile   = NULL;\r
-  PxeBc      = NULL;\r
+  Id         = NULL;\r
   IsIpv6     = FALSE;\r
 \r
   Status = gBS->OpenProtocol (\r
   IsIpv6     = FALSE;\r
 \r
   Status = gBS->OpenProtocol (\r
@@ -1267,23 +1422,22 @@ PxeBcDriverBindingStop (
     //\r
     // Get the Nic handle by any pass-over service child handle.\r
     //\r
     //\r
     // Get the Nic handle by any pass-over service child handle.\r
     //\r
-    NicHandle = PxeBcGetNicByIp4Children (ControllerHandle);\r
-    if (NicHandle == NULL) {\r
+    if (IpVersion == IP_VERSION_4) {\r
+      NicHandle = PxeBcGetNicByIp4Children (ControllerHandle);\r
+    } else {\r
       NicHandle = PxeBcGetNicByIp6Children (ControllerHandle);\r
       NicHandle = PxeBcGetNicByIp6Children (ControllerHandle);\r
-      if (NicHandle == NULL) {\r
-        return EFI_DEVICE_ERROR;\r
-      } else {\r
-        IsIpv6 = TRUE;\r
-      }\r
+    }\r
+    if (NicHandle == NULL) {\r
+      return EFI_SUCCESS;\r
     }\r
 \r
     //\r
     }\r
 \r
     //\r
-    // Try to retrieve the private data by PxeBc protocol.\r
+    // Try to retrieve the private data by PxeBcPrivate protocol.\r
     //\r
     Status = gBS->OpenProtocol (\r
                     NicHandle,\r
     //\r
     Status = gBS->OpenProtocol (\r
                     NicHandle,\r
-                    &gEfiPxeBaseCodeProtocolGuid,\r
-                    (VOID **) &PxeBc,\r
+                    &gEfiCallerIdGuid,\r
+                    (VOID **) &Id,\r
                     This->DriverBindingHandle,\r
                     ControllerHandle,\r
                     EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
                     This->DriverBindingHandle,\r
                     ControllerHandle,\r
                     EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
@@ -1291,7 +1445,7 @@ PxeBcDriverBindingStop (
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
-    Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (PxeBc);\r
+    Private = PXEBC_PRIVATE_DATA_FROM_ID (Id);\r
 \r
   } else {\r
     //\r
 \r
   } else {\r
     //\r
@@ -1312,28 +1466,241 @@ PxeBcDriverBindingStop (
     VirtualNic = PXEBC_VIRTUAL_NIC_FROM_LOADFILE (LoadFile);\r
     Private    = VirtualNic->Private;\r
     NicHandle  = Private->Controller;\r
     VirtualNic = PXEBC_VIRTUAL_NIC_FROM_LOADFILE (LoadFile);\r
     Private    = VirtualNic->Private;\r
     NicHandle  = Private->Controller;\r
+  }\r
 \r
 \r
-    if (Private->Ip6Nic == VirtualNic) {\r
-      IsIpv6   = TRUE;\r
-    }\r
+  //\r
+  // Stop functionality of PXE Base Code protocol\r
+  //\r
+  Status = Private->PxeBc.Stop (&Private->PxeBc);\r
+  if (Status != EFI_SUCCESS && Status != EFI_NOT_STARTED) {\r
+    return Status;\r
   }\r
 \r
   }\r
 \r
-  if (Private->Ip4Nic != NULL && !IsIpv6) {\r
+\r
+  if (Private->Ip4Nic != NULL && IpVersion == IP_VERSION_4) {\r
     PxeBcDestroyIp4Children (This, Private);\r
   }\r
 \r
     PxeBcDestroyIp4Children (This, Private);\r
   }\r
 \r
-  if (Private->Ip6Nic != NULL && IsIpv6) {\r
+  if (Private->Ip6Nic != NULL && IpVersion == IP_VERSION_6) {\r
     PxeBcDestroyIp6Children (This, Private);\r
   }\r
 \r
   if (Private->Ip4Nic == NULL && Private->Ip6Nic == NULL) {\r
     gBS->UninstallProtocolInterface (\r
            NicHandle,\r
     PxeBcDestroyIp6Children (This, Private);\r
   }\r
 \r
   if (Private->Ip4Nic == NULL && Private->Ip6Nic == NULL) {\r
     gBS->UninstallProtocolInterface (\r
            NicHandle,\r
-           &gEfiPxeBaseCodeProtocolGuid,\r
-           &Private->PxeBc\r
+           &gEfiCallerIdGuid,\r
+           &Private->Id\r
            );\r
     FreePool (Private);\r
   }\r
 \r
   return EFI_SUCCESS;\r
 }\r
            );\r
     FreePool (Private);\r
   }\r
 \r
   return EFI_SUCCESS;\r
 }\r
+\r
+/**\r
+  Test to see if this driver supports ControllerHandle. This service\r
+  is called by the EFI boot service ConnectController(). In\r
+  order to make drivers as small as possible, there are a few calling\r
+  restrictions for this service. ConnectController() must\r
+  follow these calling restrictions. If any other agent wishes to call\r
+  Supported() it must also follow these calling restrictions.\r
+\r
+  @param[in]  This                The pointer to the driver binding protocol.\r
+  @param[in]  ControllerHandle    The handle of device to be tested.\r
+  @param[in]  RemainingDevicePath Optional parameter used to pick a specific child\r
+                                  device to be started.\r
+\r
+  @retval EFI_SUCCESS         This driver supports this device.\r
+  @retval EFI_UNSUPPORTED     This driver does not support this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PxeBcIp4DriverBindingSupported (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   ControllerHandle,\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL\r
+  )\r
+{\r
+  return PxeBcSupported (\r
+           This,\r
+           ControllerHandle,\r
+           RemainingDevicePath,\r
+           IP_VERSION_4\r
+           );\r
+}\r
+\r
+/**\r
+  Start this driver on ControllerHandle. This service is called by the\r
+  EFI boot service ConnectController(). In order to make\r
+  drivers as small as possible, there are a few calling restrictions for\r
+  this service. ConnectController() must follow these\r
+  calling restrictions. If any other agent wishes to call Start() it\r
+  must also follow these calling restrictions.\r
+\r
+  @param[in]  This                 The pointer to the driver binding protocol.\r
+  @param[in]  ControllerHandle     The handle of device to be started.\r
+  @param[in]  RemainingDevicePath  Optional parameter used to pick a specific child\r
+                                   device to be started.\r
+\r
+  @retval EFI_SUCCESS          This driver is installed to ControllerHandle.\r
+  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle.\r
+  @retval other                This driver does not support this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PxeBcIp4DriverBindingStart (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   ControllerHandle,\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL\r
+  )\r
+{\r
+  return PxeBcStart (\r
+           This,\r
+           ControllerHandle,\r
+           RemainingDevicePath,\r
+           IP_VERSION_4\r
+           );\r
+}\r
+\r
+/**\r
+  Stop this driver on ControllerHandle. This service is called by the\r
+  EFI boot service DisconnectController(). In order to\r
+  make drivers as small as possible, there are a few calling\r
+  restrictions for this service. DisconnectController()\r
+  must follow these calling restrictions. If any other agent wishes\r
+  to call Stop() it must also follow these calling restrictions.\r
+\r
+  @param[in]  This              Protocol instance pointer.\r
+  @param[in]  ControllerHandle  Handle of device to stop driver on\r
+  @param[in]  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of\r
+                                children is zero stop the entire bus driver.\r
+  @param[in]  ChildHandleBuffer List of Child Handles to Stop.\r
+\r
+  @retval EFI_SUCCESS           This driver is removed ControllerHandle\r
+  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.\r
+  @retval Others                This driver was not removed from this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PxeBcIp4DriverBindingStop (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   ControllerHandle,\r
+  IN UINTN                        NumberOfChildren,\r
+  IN EFI_HANDLE                   *ChildHandleBuffer\r
+  )\r
+{\r
+  return PxeBcStop (\r
+           This,\r
+           ControllerHandle,\r
+           NumberOfChildren,\r
+           ChildHandleBuffer,\r
+           IP_VERSION_4\r
+           );\r
+}\r
+\r
+/**\r
+  Test to see if this driver supports ControllerHandle. This service\r
+  is called by the EFI boot service ConnectController(). In\r
+  order to make drivers as small as possible, there are a few calling\r
+  restrictions for this service. ConnectController() must\r
+  follow these calling restrictions. If any other agent wishes to call\r
+  Supported() it must also follow these calling restrictions.\r
+\r
+  @param[in]  This                The pointer to the driver binding protocol.\r
+  @param[in]  ControllerHandle    The handle of device to be tested.\r
+  @param[in]  RemainingDevicePath Optional parameter use to pick a specific child\r
+                                  device to be started.\r
+\r
+  @retval EFI_SUCCESS         This driver supports this device.\r
+  @retval EFI_UNSUPPORTED     This driver does not support this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PxeBcIp6DriverBindingSupported (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   ControllerHandle,\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL\r
+  )\r
+{\r
+  return PxeBcSupported (\r
+           This,\r
+           ControllerHandle,\r
+           RemainingDevicePath,\r
+           IP_VERSION_6\r
+           );\r
+}\r
+\r
+/**\r
+  Start this driver on ControllerHandle. This service is called by the\r
+  EFI boot service ConnectController(). In order to make\r
+  drivers as small as possible, there are a few calling restrictions for\r
+  this service. ConnectController() must follow these\r
+  calling restrictions. If any other agent wishes to call Start() it\r
+  must also follow these calling restrictions.\r
+\r
+  @param[in]  This                 The pointer to the driver binding protocol.\r
+  @param[in]  ControllerHandle     The handle of device to be started.\r
+  @param[in]  RemainingDevicePath  Optional parameter used to pick a specific child\r
+                                   device to be started.\r
+\r
+  @retval EFI_SUCCESS          This driver is installed to ControllerHandle.\r
+  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle.\r
+  @retval other                This driver does not support this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PxeBcIp6DriverBindingStart (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   ControllerHandle,\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL\r
+  )\r
+{\r
+  return PxeBcStart (\r
+           This,\r
+           ControllerHandle,\r
+           RemainingDevicePath,\r
+           IP_VERSION_6\r
+           );\r
+}\r
+\r
+/**\r
+  Stop this driver on ControllerHandle. This service is called by the\r
+  EFI boot service DisconnectController(). In order to\r
+  make drivers as small as possible, there are a few calling\r
+  restrictions for this service. DisconnectController()\r
+  must follow these calling restrictions. If any other agent wishes\r
+  to call Stop() it must also follow these calling restrictions.\r
+\r
+  @param[in]  This              Protocol instance pointer.\r
+  @param[in]  ControllerHandle  Handle of device to stop driver on\r
+  @param[in]  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of\r
+                                children is zero stop the entire bus driver.\r
+  @param[in]  ChildHandleBuffer List of Child Handles to Stop.\r
+\r
+  @retval EFI_SUCCESS           This driver is removed ControllerHandle\r
+  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.\r
+  @retval Others                This driver was not removed from this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PxeBcIp6DriverBindingStop (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   ControllerHandle,\r
+  IN UINTN                        NumberOfChildren,\r
+  IN EFI_HANDLE                   *ChildHandleBuffer\r
+  )\r
+{\r
+  return PxeBcStop (\r
+           This,\r
+           ControllerHandle,\r
+           NumberOfChildren,\r
+           ChildHandleBuffer,\r
+           IP_VERSION_6\r
+           );\r
+}\r