]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.c
Fix GCC build fail issue for MdeModulePkg and NetworkPkg.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / MnpDxe / MnpDriver.c
index 1c02e73f68f5bceb5b24e26fef7669d635c3c038..2ddcec8962bf8399ffa0e67a376426656c18f102 100644 (file)
@@ -1,26 +1,21 @@
 /** @file\r
+  Implementation of driver entry point and driver binding protocol.\r
 \r
-Copyright (c) 2005 - 2008, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
+Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions\r
+of the BSD License which accompanies this distribution.  The full\r
+text of the license may be found at<BR>\r
 http://opensource.org/licenses/bsd-license.php\r
 \r
 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
-Module Name:\r
-\r
-  MnpDriver.c\r
-\r
-Abstract:\r
-\r
-\r
 **/\r
 \r
 #include "MnpDriver.h"\r
 #include "MnpImpl.h"\r
-\r
+#include "MnpVlan.h"\r
 \r
 EFI_DRIVER_BINDING_PROTOCOL gMnpDriverBinding = {\r
   MnpDriverBindingSupported,\r
@@ -31,46 +26,81 @@ EFI_DRIVER_BINDING_PROTOCOL gMnpDriverBinding = {
   NULL\r
 };\r
 \r
+/**\r
+  Callback function which provided by user to remove one node in NetDestroyLinkList process.\r
+  \r
+  @param[in]    Entry           The entry to be removed.\r
+  @param[in]    Context         Pointer to the callback context corresponds to the Context in NetDestroyLinkList.\r
+\r
+  @retval EFI_SUCCESS           The entry has been removed successfully.\r
+  @retval Others                Fail to remove the entry.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MnpDestroyServiceDataEntry (\r
+  IN LIST_ENTRY         *Entry,\r
+  IN VOID               *Context\r
+  )\r
+{\r
+  MNP_SERVICE_DATA              *MnpServiceData;\r
+  \r
+  MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);\r
+  return MnpDestroyServiceData (MnpServiceData);\r
+}\r
 \r
 /**\r
-  Test to see if this driver supports ControllerHandle.\r
+  Callback function which provided by user to remove one node in NetDestroyLinkList process.\r
+  \r
+  @param[in]    Entry           The entry to be removed.\r
+  @param[in]    Context         Pointer to the callback context corresponds to the Context in NetDestroyLinkList.\r
+\r
+  @retval EFI_SUCCESS           The entry has been removed successfully.\r
+  @retval Others                Fail to remove the entry.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+MnpDestroyServiceChildEntry (\r
+  IN LIST_ENTRY         *Entry,\r
+  IN VOID               *Context\r
+  )\r
+{\r
+  MNP_SERVICE_DATA              *MnpServiceData;\r
 \r
-  @param  This                   Protocol instance pointer.\r
-  @param  ControllerHandle       Handle of device to test.\r
-  @param  RemainingDevicePath    Optional parameter use to pick a specific child\r
-                                 device to start.\r
+  MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);\r
+  return MnpDestroyServiceChild (MnpServiceData);\r
+}\r
 \r
-  @retval EFI_SUCCES             This driver supports this device.\r
-  @retval EFI_ALREADY_STARTED    This driver is already running on this device.\r
-  @retval other                  This driver does not support this device.\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                 Protocol instance pointer.\r
+  @param[in]  ControllerHandle     Handle of device to test.\r
+  @param[in]  RemainingDevicePath  Optional parameter use to pick a specific\r
+                                   child device to start.\r
+\r
+  @retval EFI_SUCCESS              This driver supports this device.\r
+  @retval EFI_ALREADY_STARTED      This driver is already running on this device.\r
+  @retval Others                   This driver does not support this device.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 MnpDriverBindingSupported (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
-  IN EFI_HANDLE                   ControllerHandle,\r
-  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL\r
+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,\r
+  IN EFI_HANDLE                      ControllerHandle,\r
+  IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath OPTIONAL\r
   )\r
 {\r
   EFI_STATUS                   Status;\r
   EFI_SIMPLE_NETWORK_PROTOCOL  *Snp;\r
 \r
-  //\r
-  // Test to see if MNP is already installed.\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  ControllerHandle,\r
-                  &gEfiManagedNetworkServiceBindingProtocolGuid,\r
-                  NULL,\r
-                  This->DriverBindingHandle,\r
-                  ControllerHandle,\r
-                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
-                  );\r
-  if (!EFI_ERROR (Status)) {\r
-    return EFI_ALREADY_STARTED;\r
-  }\r
-\r
   //\r
   // Test to open the Simple Network protocol BY_DRIVER.\r
   //\r
@@ -82,7 +112,6 @@ MnpDriverBindingSupported (
                   ControllerHandle,\r
                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
                   );\r
-\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
@@ -102,109 +131,202 @@ MnpDriverBindingSupported (
 \r
 \r
 /**\r
-  Start this driver on ControllerHandle.\r
-\r
-  @param  This                   Protocol instance pointer.\r
-  @param  ControllerHandle       Handle of device to bind driver to.\r
-  @param  RemainingDevicePath    Optional parameter use to pick a specific child\r
-                                 device to start.\r
-\r
-  @retval EFI_SUCCES             This driver is added to ControllerHandle.\r
-  @retval EFI_ALREADY_STARTED    This driver is already running on\r
-                                 ControllerHandle.\r
-  @retval other                  This driver does not support this device.\r
+  Start this driver on ControllerHandle. This service is called by the\r
+  EFI boot service ConnectController(). In order to make drivers as small\r
+  as possible, there are a few calling restrictions for this service.\r
+  ConnectController() must follow these calling restrictions. If any other\r
+  agent wishes to call Start() it must also follow these calling restrictions.\r
+\r
+  @param[in]       This                 Protocol instance pointer.\r
+  @param[in]       ControllerHandle     Handle of device to bind driver to.\r
+  @param[in]       RemainingDevicePath  Optional parameter use to pick a specific\r
+                                        child device to start.\r
+\r
+  @retval EFI_SUCCESS           This driver is added to ControllerHandle.\r
+  @retval EFI_ALREADY_STARTED   This driver is already running on ControllerHandle.\r
+  @retval EFI_OUT_OF_RESOURCES  Failed to allocate memory for Mnp Service Data.\r
+  @retval Others                This driver does not support this device.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 MnpDriverBindingStart (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
-  IN EFI_HANDLE                   ControllerHandle,\r
-  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL\r
+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,\r
+  IN EFI_HANDLE                      ControllerHandle,\r
+  IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath OPTIONAL\r
   )\r
 {\r
   EFI_STATUS        Status;\r
   MNP_SERVICE_DATA  *MnpServiceData;\r
-  BOOLEAN           MnpInitialized;\r
+  MNP_DEVICE_DATA   *MnpDeviceData;\r
+  LIST_ENTRY        *Entry;\r
+  VLAN_TCI          *VlanVariable;\r
+  UINTN             NumberOfVlan;\r
+  UINTN             Index;\r
 \r
-  MnpInitialized  = FALSE;\r
+  VlanVariable = NULL;\r
 \r
-  MnpServiceData  = AllocateZeroPool (sizeof (MNP_SERVICE_DATA));\r
-  if (MnpServiceData == NULL) {\r
-    DEBUG ((EFI_D_ERROR, "MnpDriverBindingStart(): Failed to allocate the Mnp Service Data.\n"));\r
+  //\r
+  // Initialize the Mnp Device Data\r
+  //\r
+  MnpDeviceData = AllocateZeroPool (sizeof (MNP_DEVICE_DATA));\r
+  if (MnpDeviceData == NULL) {\r
+    DEBUG ((EFI_D_ERROR, "MnpDriverBindingStart(): Failed to allocate the Mnp Device Data.\n"));\r
 \r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  //\r
-  // Initialize the Mnp Service Data.\r
-  //\r
-  Status = MnpInitializeServiceData (MnpServiceData, This->DriverBindingHandle, ControllerHandle);\r
+  Status = MnpInitializeDeviceData (MnpDeviceData, This->DriverBindingHandle, ControllerHandle);\r
   if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "MnpDriverBindingStart: MnpInitializeDeviceData failed, %r.\n", Status));\r
 \r
-    DEBUG ((EFI_D_ERROR, "MnpDriverBindingStart: MnpInitializeServiceData failed, %r.\n",Status));\r
-    goto ErrorExit;\r
+    FreePool (MnpDeviceData);\r
+    return Status;\r
   }\r
 \r
-  MnpInitialized = TRUE;\r
+  //\r
+  // Check whether NIC driver has already produced VlanConfig protocol\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiVlanConfigProtocolGuid,\r
+                  NULL,\r
+                  This->DriverBindingHandle,\r
+                  ControllerHandle,\r
+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+                  );\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // NIC hardware already implement VLAN,\r
+    // no need to provide software VLAN implementation in MNP driver\r
+    //\r
+    MnpDeviceData->NumberOfVlan = 0;\r
+    ZeroMem (&MnpDeviceData->VlanConfig, sizeof (EFI_VLAN_CONFIG_PROTOCOL));\r
+    MnpServiceData = MnpCreateServiceData (MnpDeviceData, 0, 0);\r
+    Status = (MnpServiceData != NULL) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;\r
+    goto Exit;\r
+  }\r
 \r
   //\r
-  // Install the MNP Service Binding Protocol.\r
+  // Install VLAN Config Protocol\r
   //\r
   Status = gBS->InstallMultipleProtocolInterfaces (\r
                   &ControllerHandle,\r
-                  &gEfiManagedNetworkServiceBindingProtocolGuid,\r
-                  &MnpServiceData->ServiceBinding,\r
+                  &gEfiVlanConfigProtocolGuid,\r
+                  &MnpDeviceData->VlanConfig,\r
                   NULL\r
                   );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Exit;\r
+  }\r
 \r
-ErrorExit:\r
+  //\r
+  // Get current VLAN configuration from EFI Variable\r
+  //\r
+  NumberOfVlan = 0;\r
+  Status = MnpGetVlanVariable (MnpDeviceData, &NumberOfVlan, &VlanVariable);\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // No VLAN is set, create a default MNP service data for untagged frame\r
+    //\r
+    MnpDeviceData->NumberOfVlan = 0;\r
+    MnpServiceData = MnpCreateServiceData (MnpDeviceData, 0, 0);\r
+    Status = (MnpServiceData != NULL) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;\r
+    goto Exit;\r
+  }\r
+\r
+  //\r
+  // Create MNP service data for each VLAN\r
+  //\r
+  MnpDeviceData->NumberOfVlan = NumberOfVlan;\r
+  for (Index = 0; Index < NumberOfVlan; Index++) {\r
+    MnpServiceData = MnpCreateServiceData (\r
+                       MnpDeviceData,\r
+                       VlanVariable[Index].Bits.Vid,\r
+                       (UINT8) VlanVariable[Index].Bits.Priority\r
+                       );\r
+\r
+    if (MnpServiceData == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+\r
+      goto Exit;\r
+    }\r
+  }\r
+\r
+Exit:\r
+  if (VlanVariable != NULL) {\r
+    FreePool (VlanVariable);\r
+  }\r
 \r
   if (EFI_ERROR (Status)) {\r
+    //\r
+    // Destroy all MNP service data\r
+    //\r
+    while (!IsListEmpty (&MnpDeviceData->ServiceList)) {\r
+      Entry = GetFirstNode (&MnpDeviceData->ServiceList);\r
+      MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);\r
+      MnpDestroyServiceData (MnpServiceData);\r
+    }\r
 \r
-    if (MnpInitialized) {\r
-      //\r
-      // Flush the Mnp Service Data.\r
-      //\r
-      MnpFlushServiceData (MnpServiceData);\r
+    //\r
+    // Uninstall the VLAN Config Protocol if any\r
+    //\r
+    if (MnpDeviceData->VlanConfig.Set != NULL) {\r
+      gBS->UninstallMultipleProtocolInterfaces (\r
+             MnpDeviceData->ControllerHandle,\r
+             &gEfiVlanConfigProtocolGuid,\r
+             &MnpDeviceData->VlanConfig,\r
+             NULL\r
+             );\r
     }\r
 \r
-    gBS->FreePool (MnpServiceData);\r
+    //\r
+    // Destroy Mnp Device Data\r
+    //\r
+    MnpDestroyDeviceData (MnpDeviceData, This->DriverBindingHandle);\r
+    FreePool (MnpDeviceData);\r
   }\r
 \r
   return Status;\r
 }\r
 \r
-\r
 /**\r
-  Stop this driver on ControllerHandle.\r
-\r
-  @param  This                   Protocol instance pointer.\r
-  @param  ControllerHandle       Handle of device to stop driver on.\r
-  @param  NumberOfChildren       Number of Handles in ChildHandleBuffer. If number\r
-                                 of children is zero stop the entire bus driver.\r
-  @param  ChildHandleBuffer      List of Child Handles to Stop.\r
-\r
-  @retval EFI_SUCCES             This driver is removed ControllerHandle.\r
-  @retval other                  This driver was not removed from this device.\r
+  Stop this driver on ControllerHandle. This service is called by the\r
+  EFI boot service DisconnectController(). In order to make drivers as\r
+  small as possible, there are a few calling restrictions for this service.\r
+  DisconnectController() must follow these calling restrictions. If any other\r
+  agent wishes 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\r
+                                 number of children is zero stop the entire\r
+                                 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       The device could not be stopped due to a device error.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 MnpDriverBindingStop (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
-  IN EFI_HANDLE                   ControllerHandle,\r
-  IN UINTN                        NumberOfChildren,\r
-  IN EFI_HANDLE                   *ChildHandleBuffer\r
+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,\r
+  IN EFI_HANDLE                      ControllerHandle,\r
+  IN UINTN                           NumberOfChildren,\r
+  IN EFI_HANDLE                      *ChildHandleBuffer OPTIONAL\r
   )\r
 {\r
   EFI_STATUS                    Status;\r
   EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;\r
+  EFI_VLAN_CONFIG_PROTOCOL      *VlanConfig;\r
+  MNP_DEVICE_DATA               *MnpDeviceData;\r
   MNP_SERVICE_DATA              *MnpServiceData;\r
-  MNP_INSTANCE_DATA             *Instance;\r
+  LIST_ENTRY                    *List;\r
+  UINTN                         ListLength;\r
 \r
   //\r
-  // Retrieve the MNP service binding protocol from the ControllerHandle.\r
+  // Try to retrieve MNP service binding protocol from the ControllerHandle\r
   //\r
   Status = gBS->OpenProtocol (\r
                   ControllerHandle,\r
@@ -215,95 +337,116 @@ MnpDriverBindingStop (
                   EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
                   );\r
   if (EFI_ERROR (Status)) {\r
+    //\r
+    // Retrieve VLAN Config Protocol from the ControllerHandle\r
+    //\r
+    Status = gBS->OpenProtocol (\r
+                    ControllerHandle,\r
+                    &gEfiVlanConfigProtocolGuid,\r
+                    (VOID **) &VlanConfig,\r
+                    This->DriverBindingHandle,\r
+                    ControllerHandle,\r
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "MnpDriverBindingStop: try to stop unknown Controller.\n"));\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
 \r
-    DEBUG (\r
-      (EFI_D_ERROR,\r
-      "MnpDriverBindingStop: Locate MNP Service Binding Protocol failed, %r.\n",\r
-      Status)\r
-      );\r
-    return EFI_DEVICE_ERROR;\r
+    MnpDeviceData = MNP_DEVICE_DATA_FROM_THIS (VlanConfig);\r
+  } else {\r
+    MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (ServiceBinding);\r
+    MnpDeviceData = MnpServiceData->MnpDeviceData;\r
   }\r
 \r
-  MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (ServiceBinding);\r
-\r
   if (NumberOfChildren == 0) {\r
     //\r
-    // Uninstall the MNP Service Binding Protocol.\r
+    // Destroy all MNP service data\r
     //\r
-    gBS->UninstallMultipleProtocolInterfaces (\r
-           ControllerHandle,\r
-           &gEfiManagedNetworkServiceBindingProtocolGuid,\r
-           ServiceBinding,\r
-           NULL\r
-           );\r
+    List = &MnpDeviceData->ServiceList;\r
+    Status = NetDestroyLinkList (\r
+               List,\r
+               MnpDestroyServiceDataEntry,\r
+               NULL,\r
+               &ListLength\r
+               );\r
+    if (EFI_ERROR (Status) || ListLength !=0) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
 \r
     //\r
-    // Close the openned Snp protocol.\r
+    // Uninstall the VLAN Config Protocol if any\r
     //\r
-    gBS->CloseProtocol (\r
-           ControllerHandle,\r
-           &gEfiSimpleNetworkProtocolGuid,\r
-           This->DriverBindingHandle,\r
-           ControllerHandle\r
-           );\r
+    if (MnpDeviceData->VlanConfig.Set != NULL) {\r
+      gBS->UninstallMultipleProtocolInterfaces (\r
+             MnpDeviceData->ControllerHandle,\r
+             &gEfiVlanConfigProtocolGuid,\r
+             &MnpDeviceData->VlanConfig,\r
+             NULL\r
+             );\r
+    }\r
 \r
     //\r
-    // Flush the Mnp service data.\r
+    // Destroy Mnp Device Data\r
     //\r
-    MnpFlushServiceData (MnpServiceData);\r
+    MnpDestroyDeviceData (MnpDeviceData, This->DriverBindingHandle);\r
+    FreePool (MnpDeviceData);\r
 \r
-    gBS->FreePool (MnpServiceData);\r
-  } else {\r
-    while (!IsListEmpty (&MnpServiceData->ChildrenList)) {\r
-      //\r
-      // Don't use NetListRemoveHead here, the remove opreration will be done\r
-      // in ServiceBindingDestroyChild.\r
-      //\r
-      Instance = NET_LIST_HEAD (\r
-                   &MnpServiceData->ChildrenList,\r
-                   MNP_INSTANCE_DATA,\r
-                   InstEntry\r
-                   );\r
-\r
-      ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);\r
+    if (gMnpControllerNameTable != NULL) {\r
+      FreeUnicodeStringTable (gMnpControllerNameTable);\r
+      gMnpControllerNameTable = NULL;\r
     }\r
+    return EFI_SUCCESS;\r
   }\r
 \r
-  return Status;\r
+  //\r
+  // Stop all MNP child\r
+  //\r
+  List = &MnpDeviceData->ServiceList;\r
+  Status = NetDestroyLinkList (\r
+             List,\r
+             MnpDestroyServiceChildEntry,\r
+             NULL,\r
+             &ListLength\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 \r
 /**\r
   Creates a child handle with a set of I/O services.\r
 \r
-  @param  This                   Protocol instance pointer.\r
-  @param  ChildHandle            Pointer to the handle of the child to create. If\r
-                                 it is NULL, then a new handle is created. If it is\r
-                                 not NULL, then the I/O services are  added to the\r
-                                 existing child handle.\r
+  @param[in]       This              Protocol instance pointer.\r
+  @param[in, out]  ChildHandle       Pointer to the handle of the child to create. If\r
+                                     it is NULL, then a new handle is created. If\r
+                                     it is not NULL, then the I/O services are added\r
+                                     to the existing child handle.\r
 \r
-  @retval EFI_SUCCES             The child handle was created with the I/O\r
-                                 services.\r
-  @retval EFI_OUT_OF_RESOURCES   There are not enough resources availabe to create\r
-                                 the child.\r
-  @retval other                  The child handle was not created.\r
+  @retval EFI_SUCCES                 The protocol was added to ChildHandle.\r
+  @retval EFI_INVALID_PARAMETER      ChildHandle is NULL.\r
+  @retval EFI_OUT_OF_RESOURCES       There are not enough resources availabe to\r
+                                     create the child.\r
+  @retval Others                     The child handle was not created.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 MnpServiceBindingCreateChild (\r
-  IN EFI_SERVICE_BINDING_PROTOCOL  *This,\r
-  IN EFI_HANDLE                    *ChildHandle\r
+  IN     EFI_SERVICE_BINDING_PROTOCOL    *This,\r
+  IN OUT EFI_HANDLE                      *ChildHandle\r
   )\r
 {\r
   EFI_STATUS         Status;\r
   MNP_SERVICE_DATA   *MnpServiceData;\r
   MNP_INSTANCE_DATA  *Instance;\r
-  VOID               *Snp;\r
+  VOID               *MnpSb;\r
   EFI_TPL            OldTpl;\r
 \r
   if ((This == NULL) || (ChildHandle == NULL)) {\r
-\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -314,8 +457,8 @@ MnpServiceBindingCreateChild (
   //\r
   Instance = AllocateZeroPool (sizeof (MNP_INSTANCE_DATA));\r
   if (Instance == NULL) {\r
-\r
     DEBUG ((EFI_D_ERROR, "MnpServiceBindingCreateChild: Faild to allocate memory for the new instance.\n"));\r
+\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
@@ -331,12 +474,12 @@ MnpServiceBindingCreateChild (
                   NULL\r
                   );\r
   if (EFI_ERROR (Status)) {\r
-\r
     DEBUG (\r
       (EFI_D_ERROR,\r
       "MnpServiceBindingCreateChild: Failed to install the MNP protocol, %r.\n",\r
       Status)\r
       );\r
+\r
     goto ErrorExit;\r
   }\r
 \r
@@ -346,9 +489,9 @@ MnpServiceBindingCreateChild (
   Instance->Handle = *ChildHandle;\r
 \r
   Status = gBS->OpenProtocol (\r
-                  MnpServiceData->ControllerHandle,\r
-                  &gEfiSimpleNetworkProtocolGuid,\r
-                  (VOID **) &Snp,\r
+                  MnpServiceData->ServiceHandle,\r
+                  &gEfiManagedNetworkServiceBindingProtocolGuid,\r
+                  (VOID **) &MnpSb,\r
                   gMnpDriverBinding.DriverBindingHandle,\r
                   Instance->Handle,\r
                   EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
@@ -374,13 +517,14 @@ ErrorExit:
     if (Instance->Handle != NULL) {\r
 \r
       gBS->UninstallMultipleProtocolInterfaces (\r
+            Instance->Handle,\r
             &gEfiManagedNetworkProtocolGuid,\r
             &Instance->ManagedNetwork,\r
             NULL\r
             );\r
     }\r
 \r
-    gBS->FreePool (Instance);\r
+    FreePool (Instance);\r
   }\r
 \r
   return Status;\r
@@ -390,24 +534,29 @@ ErrorExit:
 /**\r
   Destroys a child handle with a set of I/O services.\r
 \r
-  @param  This                   Protocol instance pointer.\r
-  @param  ChildHandle            Handle of the child to destroy.\r
+  The DestroyChild() function does the opposite of CreateChild(). It removes a\r
+  protocol that was installed by CreateChild() from ChildHandle. If the removed\r
+  protocol is the last protocol on ChildHandle, then ChildHandle is destroyed.\r
 \r
-  @retval EFI_SUCCES             The I/O services were removed from the child\r
-                                 handle.\r
-  @retval EFI_UNSUPPORTED        The child handle does not support the I/O services\r
-                                  that are being removed.\r
-  @retval EFI_INVALID_PARAMETER  Child handle is not a valid EFI Handle.\r
-  @retval EFI_ACCESS_DENIED      The child handle could not be destroyed because\r
-                                 its  I/O services are being used.\r
-  @retval other                  The child handle was not destroyed.\r
+  @param[in]  This               Pointer to the EFI_SERVICE_BINDING_PROTOCOL\r
+                                 instance.\r
+  @param[in]  ChildHandle        Handle of the child to destroy.\r
+\r
+  @retval EFI_SUCCES             The protocol was removed from ChildHandle.\r
+  @retval EFI_UNSUPPORTED        ChildHandle does not support the protocol that\r
+                                 is being removed.\r
+  @retval EFI_INVALID_PARAMETER  ChildHandle is NULL.\r
+  @retval EFI_ACCESS_DENIED      The protocol could not be removed from the\r
+                                 ChildHandle because its services are being\r
+                                 used.\r
+  @retval Others                 The child handle was not destroyed.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 MnpServiceBindingDestroyChild (\r
-  IN EFI_SERVICE_BINDING_PROTOCOL  *This,\r
-  IN EFI_HANDLE                    ChildHandle\r
+  IN EFI_SERVICE_BINDING_PROTOCOL    *This,\r
+  IN EFI_HANDLE                      ChildHandle\r
   )\r
 {\r
   EFI_STATUS                    Status;\r
@@ -417,7 +566,6 @@ MnpServiceBindingDestroyChild (
   EFI_TPL                       OldTpl;\r
 \r
   if ((This == NULL) || (ChildHandle == NULL)) {\r
-\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -435,7 +583,6 @@ MnpServiceBindingDestroyChild (
                   EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
                   );\r
   if (EFI_ERROR (Status)) {\r
-\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
@@ -448,7 +595,6 @@ MnpServiceBindingDestroyChild (
   // will only excecute once.\r
   //\r
   if (Instance->Destroyed) {\r
-\r
     return EFI_SUCCESS;\r
   }\r
 \r
@@ -458,9 +604,9 @@ MnpServiceBindingDestroyChild (
   // Close the Simple Network protocol.\r
   //\r
   gBS->CloseProtocol (\r
-         MnpServiceData->ControllerHandle,\r
-         &gEfiSimpleNetworkProtocolGuid,\r
-         gMnpDriverBinding.DriverBindingHandle,\r
+         MnpServiceData->ServiceHandle,\r
+         &gEfiManagedNetworkServiceBindingProtocolGuid,\r
+         MnpServiceData->MnpDeviceData->ImageHandle,\r
          ChildHandle\r
          );\r
 \r
@@ -474,7 +620,6 @@ MnpServiceBindingDestroyChild (
                   NULL\r
                   );\r
   if (EFI_ERROR (Status)) {\r
-\r
     DEBUG (\r
       (EFI_D_ERROR,\r
       "MnpServiceBindingDestroyChild: Failed to uninstall the ManagedNetwork protocol, %r.\n",\r
@@ -510,36 +655,29 @@ MnpServiceBindingDestroyChild (
 \r
   gBS->RestoreTPL (OldTpl);\r
 \r
-  gBS->FreePool (Instance);\r
+  FreePool (Instance);\r
 \r
   return Status;\r
 }\r
 \r
+/**\r
+  The entry point for Mnp driver which installs the driver binding and component\r
+  name protocol on its ImageHandle.\r
+\r
+  @param[in]  ImageHandle  The image handle of the driver.\r
+  @param[in]  SystemTable  The system table.\r
+\r
+  @retval EFI_SUCCES       The driver binding and component name protocols are\r
+                           successfully installed.\r
+  @retval Others           Other errors as indicated.\r
 \r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 MnpDriverEntryPoint (\r
-  IN EFI_HANDLE        ImageHandle,\r
-  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  IN EFI_HANDLE          ImageHandle,\r
+  IN EFI_SYSTEM_TABLE    *SystemTable\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  The entry point for Mnp driver which installs the driver binding and component name\r
-  protocol on its ImageHandle.\r
-\r
-Arguments:\r
-\r
-  ImageHandle - The image handle of the driver.\r
-  SystemTable - The system table.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS - If the driver binding and component name protocols are successfully\r
-                installed, otherwise if failed.\r
-\r
---*/\r
 {\r
   return EfiLibInstallDriverBindingComponentName2 (\r
            ImageHandle,\r