]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c
MdeModulePkg/Ip4Dxe: Fix the incorrect RemoveEntryList
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Ip4Dxe / Ip4Driver.c
index 4d3ccec61047c9b1ddde686a43e21ac2b38401c9..792db5c173f2ad47a5578e31407ce8279074d73e 100644 (file)
@@ -1,7 +1,9 @@
 /** @file\r
   The driver binding and service binding protocol for IP4 driver.\r
 \r
-Copyright (c) 2005 - 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2005 - 2017, Intel Corporation. All rights reserved.<BR>\r
+(C) Copyright 2015 Hewlett-Packard Development Company, L.P.<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
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -23,6 +25,30 @@ EFI_DRIVER_BINDING_PROTOCOL gIp4DriverBinding = {
   NULL\r
 };\r
 \r
+BOOLEAN  mIpSec2Installed = FALSE;\r
+\r
+/**\r
+   Callback function for IpSec2 Protocol install.\r
+\r
+   @param[in] Event           Event whose notification function is being invoked\r
+   @param[in] Context         Pointer to the notification function's context\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+IpSec2InstalledCallback (\r
+  IN EFI_EVENT  Event,\r
+  IN VOID       *Context\r
+  )\r
+{\r
+  //\r
+  // Close the event so it does not get called again.\r
+  //\r
+  gBS->CloseEvent (Event);\r
+\r
+  mIpSec2Installed = TRUE;\r
+}\r
+\r
 /**\r
   This is the declaration of an EFI image entry point. This entry point is\r
   the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including\r
@@ -45,6 +71,16 @@ Ip4DriverEntryPoint (
   IN EFI_SYSTEM_TABLE       *SystemTable\r
   )\r
 {\r
+  VOID            *Registration;\r
+\r
+  EfiCreateProtocolNotifyEvent (\r
+    &gEfiIpSec2ProtocolGuid,\r
+    TPL_CALLBACK,\r
+    IpSec2InstalledCallback,\r
+    NULL,\r
+    &Registration\r
+    );\r
+\r
   return EfiLibInstallDriverBindingComponentName2 (\r
            ImageHandle,\r
            SystemTable,\r
@@ -211,12 +247,14 @@ Ip4CreateService (
   IpSb->Timer = NULL;\r
 \r
   IpSb->ReconfigEvent = NULL;\r
+\r
+  IpSb->Reconfig = FALSE;\r
   \r
   IpSb->MediaPresent = TRUE;\r
 \r
   //\r
   // Create various resources. First create the route table, timer\r
-  // event and MNP child. IGMP, interface's initialization depend\r
+  // event, ReconfigEvent and MNP child. IGMP, interface's initialization depend\r
   // on the MNP child.\r
   //\r
   IpSb->DefaultRouteTable = Ip4CreateRouteTable ();\r
@@ -238,6 +276,17 @@ Ip4CreateService (
     goto ON_ERROR;\r
   }\r
 \r
+  Status = gBS->CreateEvent (\r
+                  EVT_NOTIFY_SIGNAL,\r
+                  TPL_NOTIFY,\r
+                  Ip4AutoReconfigCallBack,\r
+                  IpSb,\r
+                  &IpSb->ReconfigEvent\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto ON_ERROR;\r
+  }\r
+\r
   Status = NetLibCreateServiceChild (\r
              Controller,\r
              ImageHandle,\r
@@ -344,6 +393,15 @@ Ip4CleanService (
 {\r
   EFI_STATUS                Status;\r
 \r
+  IpSb->State     = IP4_SERVICE_DESTROY;\r
+\r
+  if (IpSb->Timer != NULL) {\r
+    gBS->SetTimer (IpSb->Timer, TimerCancel, 0);\r
+    gBS->CloseEvent (IpSb->Timer);\r
+\r
+    IpSb->Timer = NULL;\r
+  }\r
+\r
   if (IpSb->DefaultInterface != NULL) {\r
     Status = Ip4FreeInterface (IpSb->DefaultInterface, NULL);\r
 \r
@@ -383,19 +441,14 @@ Ip4CleanService (
     IpSb->MnpChildHandle = NULL;\r
   }\r
 \r
-  if (IpSb->Timer != NULL) {\r
-    gBS->SetTimer (IpSb->Timer, TimerCancel, 0);\r
-    gBS->CloseEvent (IpSb->Timer);\r
-\r
-    IpSb->Timer = NULL;\r
-  }\r
-\r
   if (IpSb->ReconfigEvent != NULL) {\r
     gBS->CloseEvent (IpSb->ReconfigEvent);\r
 \r
     IpSb->ReconfigEvent = NULL;\r
   }\r
 \r
+  IpSb->Reconfig = FALSE;\r
+\r
   if (IpSb->MacString != NULL) {\r
     FreePool (IpSb->MacString);\r
   }\r
@@ -471,6 +524,13 @@ Ip4DriverBindingStart (
 { \r
   EFI_STATUS                    Status;\r
   IP4_SERVICE                   *IpSb;\r
+  EFI_IP4_CONFIG2_PROTOCOL      *Ip4Cfg2;\r
+  UINTN                         Index;\r
+  IP4_CONFIG2_DATA_ITEM         *DataItem;\r
+\r
+  IpSb     = NULL;\r
+  Ip4Cfg2  = NULL;\r
+  DataItem = NULL;\r
 \r
   //\r
   // Test for the Ip4 service binding protocol\r
@@ -496,6 +556,8 @@ Ip4DriverBindingStart (
   \r
   ASSERT (IpSb != NULL);\r
 \r
+  Ip4Cfg2  = &IpSb->Ip4Config2Instance.Ip4Config2;\r
+\r
   //\r
   // Install the Ip4ServiceBinding Protocol onto ControlerHandle\r
   //\r
@@ -504,13 +566,44 @@ Ip4DriverBindingStart (
                   &gEfiIp4ServiceBindingProtocolGuid,\r
                   &IpSb->ServiceBinding,\r
                   &gEfiIp4Config2ProtocolGuid,\r
-                  &IpSb->Ip4Config2Instance.Ip4Config2,\r
+                  Ip4Cfg2,\r
                   NULL\r
                   );\r
 \r
   if (EFI_ERROR (Status)) {\r
     goto FREE_SERVICE;\r
   }\r
+\r
+  //\r
+  // Read the config data from NV variable again. \r
+  // The default data can be changed by other drivers.\r
+  //\r
+  Status = Ip4Config2ReadConfigData (IpSb->MacString, &IpSb->Ip4Config2Instance);\r
+  if (EFI_ERROR (Status)) {\r
+    goto UNINSTALL_PROTOCOL;\r
+  }\r
+  \r
+  //\r
+  // Consume the installed EFI_IP4_CONFIG2_PROTOCOL to set the default data items. \r
+  //\r
+  for (Index = Ip4Config2DataTypePolicy; Index < Ip4Config2DataTypeMaximum; Index++) {\r
+    DataItem = &IpSb->Ip4Config2Instance.DataItem[Index];\r
+    if (DataItem->Data.Ptr != NULL) {\r
+      Status = Ip4Cfg2->SetData (\r
+                          Ip4Cfg2,\r
+                          Index,\r
+                          DataItem->DataSize,\r
+                          DataItem->Data.Ptr\r
+                          );\r
+      if (EFI_ERROR(Status)) {\r
+        goto UNINSTALL_PROTOCOL;\r
+      }\r
+      \r
+      if (Index == Ip4Config2DataTypePolicy && (*(DataItem->Data.Policy) == Ip4Config2PolicyDhcp)) {\r
+        break;\r
+      } \r
+    }\r
+  }\r
  \r
   //\r
   // Ready to go: start the receiving and timer.\r
@@ -663,8 +756,6 @@ Ip4DriverBindingStop (
 \r
   } else if (IsListEmpty (&IpSb->Children)) {\r
     State           = IpSb->State;\r
-    IpSb->State     = IP4_SERVICE_DESTROY;\r
-\r
     //\r
     // OK, clean other resources then uninstall the service binding protocol.\r
     //\r
@@ -709,7 +800,7 @@ ON_ERROR:
 \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 create\r
+  @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to create\r
                                 the child\r
   @retval other                 The child handle was not created\r
 \r
@@ -831,7 +922,6 @@ Ip4ServiceBindingDestroyChild (
   IP4_PROTOCOL              *IpInstance;\r
   EFI_IP4_PROTOCOL          *Ip4;\r
   EFI_TPL                   OldTpl;\r
-  INTN                      State;\r
 \r
   if ((This == NULL) || (ChildHandle == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -869,13 +959,12 @@ Ip4ServiceBindingDestroyChild (
   // when UDP driver is being stopped, it will destroy all\r
   // the IP child it opens.\r
   //\r
-  if (IpInstance->State == IP4_STATE_DESTROY) {\r
+  if (IpInstance->InDestroy) {\r
     gBS->RestoreTPL (OldTpl);\r
     return EFI_SUCCESS;\r
   }\r
 \r
-  State             = IpInstance->State;\r
-  IpInstance->State = IP4_STATE_DESTROY;\r
+  IpInstance->InDestroy = TRUE;\r
 \r
   //\r
   // Close the Managed Network protocol.\r
@@ -918,6 +1007,7 @@ Ip4ServiceBindingDestroyChild (
                   );\r
   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
   if (EFI_ERROR (Status)) {\r
+    IpInstance->InDestroy = FALSE;\r
     goto ON_ERROR;\r
   }\r
 \r
@@ -942,7 +1032,6 @@ Ip4ServiceBindingDestroyChild (
   return EFI_SUCCESS;\r
 \r
 ON_ERROR:\r
-  IpInstance->State = State;\r
   gBS->RestoreTPL (OldTpl);\r
 \r
   return Status;\r