Git version '3d0a49ad' commit provided a scenario to resolve the 
performance issue for IPv4, but it's not workable for IPv6. To 
avoid IPv4 and IPv6 inconsistency, we decided to revert that version 
fix.

If so, the default policy for Ip4Config2 is Ip4Config2PolicyDhcp, 
which results in all NIC ports attempting DHCP. So, this patch is 
used to changes the the default IPv4 config policy to 
Ip4Config2PolicyStatic and also defer the SetData operation after 
Ip4Config2Protocol installed. This update let the other platform 
drivers have chance to change the default config data by consume 
Ip4Config2Protocol.

Cc: Subramanian Sriram <srira...@hpe.com>
Cc: El-Haj-Mahmoud Samer <samer.el-haj-mahm...@hpe.com>
Cc: Ye Ting <ting...@intel.com>
Cc: Fu Siyuan <siyuan...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiaxin Wu <jiaxin...@intel.com>
---
 .../Universal/Network/Ip4Dxe/Ip4Config2Impl.c      | 76 +++++++++++++-----
 .../Universal/Network/Ip4Dxe/Ip4Config2Impl.h      | 36 ++++++++-
 MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c  | 57 +++++++++++++-
 MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf   |  2 +-
 MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c    | 90 ++--------------------
 5 files changed, 155 insertions(+), 106 deletions(-)

diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c 
b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c
index edbddba..1f763b6 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c
@@ -1,9 +1,9 @@
 /** @file
   The implementation of EFI IPv4 Configuration II Protocol.
 
-  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
   (C) Copyright 2015 Hewlett Packard Enterprise Development LP<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
@@ -1142,11 +1142,13 @@ Ip4Config2SetPolicy (
   if (NewPolicy >= Ip4Config2PolicyMax) {
     return EFI_INVALID_PARAMETER;
   }
 
   if (NewPolicy == Instance->Policy) {
-     return EFI_ABORTED;
+    if (NewPolicy != Ip4Config2PolicyDhcp || Instance->DhcpSuccess) {
+      return EFI_ABORTED;
+    }
   } else {
     if (NewPolicy == Ip4Config2PolicyDhcp) {
       //
       // The policy is changed from static to dhcp:
       // Clean the ManualAddress, Gateway and DnsServers, shrink the variable
@@ -1906,11 +1908,11 @@ Ip4Config2InitInstance (
 
   DataItem           = &Instance->DataItem[Ip4Config2DataTypePolicy];
   DataItem->SetData  = Ip4Config2SetPolicy;
   DataItem->Data.Ptr = &Instance->Policy;
   DataItem->DataSize = sizeof (Instance->Policy);
-  Instance->Policy   = Ip4Config2PolicyDhcp;
+  Instance->Policy   = Ip4Config2PolicyStatic;
   SET_DATA_ATTRIB (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED);
 
   DataItem           = &Instance->DataItem[Ip4Config2DataTypeManualAddress];
   DataItem->SetData  = Ip4Config2SetMaunualAddress;
   DataItem->Status   = EFI_NOT_FOUND;
@@ -1937,34 +1939,22 @@ Ip4Config2InitInstance (
 
   Instance->Configured  = TRUE;
 
   //
   // Try to read the config data from NV variable.
+  // If not found, write initialized config data into NV variable 
+  // as a default config data.
   //
   Status = Ip4Config2ReadConfigData (IpSb->MacString, Instance);
   if (Status == EFI_NOT_FOUND) {
     Status = Ip4Config2WriteConfigData (IpSb->MacString, Instance);
   }
 
   if (EFI_ERROR (Status)) {
     return Status;
   }
-
-  //
-  // Try to set the configured parameter.
-  //
-  for (Index = Ip4Config2DataTypePolicy; Index < Ip4Config2DataTypeMaximum; 
Index++) {
-    DataItem = &IpSb->Ip4Config2Instance.DataItem[Index];
-    if (DataItem->Data.Ptr != NULL) {
-      DataItem->SetData (
-                  &IpSb->Ip4Config2Instance,
-                  DataItem->DataSize,
-                  DataItem->Data.Ptr
-                  );
-    }
-  }
-
+  
   Instance->Ip4Config2.SetData              = EfiIp4Config2SetData;
   Instance->Ip4Config2.GetData              = EfiIp4Config2GetData;
   Instance->Ip4Config2.RegisterDataNotify   = EfiIp4Config2RegisterDataNotify;
   Instance->Ip4Config2.UnregisterDataNotify = 
EfiIp4Config2UnregisterDataNotify;
 
@@ -2027,5 +2017,55 @@ Ip4Config2CleanInstance (
   Ip4Config2FormUnload (Instance);
 
   RemoveEntryList (&Instance->Link);
 }
 
+/**
+  The event handle for IP4 auto reconfiguration. The original default
+  interface and route table will be removed as the default.
+
+  @param[in]  Context                The IP4 service binding instance.
+
+**/
+VOID
+EFIAPI
+Ip4AutoReconfigCallBackDpc (
+  IN VOID                   *Context
+  )
+{
+  IP4_SERVICE               *IpSb;
+
+  IpSb      = (IP4_SERVICE *) Context;
+  NET_CHECK_SIGNATURE (IpSb, IP4_SERVICE_SIGNATURE);
+
+  if (IpSb->State > IP4_SERVICE_UNSTARTED) {
+    IpSb->State = IP4_SERVICE_UNSTARTED;
+  }
+  
+  IpSb->Reconfig = TRUE;
+
+  Ip4StartAutoConfig (&IpSb->Ip4Config2Instance);
+
+  return ;
+}
+
+
+/**
+  Request Ip4AutoReconfigCallBackDpc as a DPC at TPL_CALLBACK.
+
+  @param Event     The event that is signalled.
+  @param Context   The IP4 service binding instance.
+
+**/
+VOID
+EFIAPI
+Ip4AutoReconfigCallBack (
+  IN EFI_EVENT              Event,
+  IN VOID                   *Context
+  )
+{
+  //
+  // Request Ip4AutoReconfigCallBackDpc as a DPC at TPL_CALLBACK
+  //
+  QueueDpc (TPL_CALLBACK, Ip4AutoReconfigCallBackDpc, Context);
+}
+
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.h 
b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.h
index ab72525..77bdc8d 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.h
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.h
@@ -1,9 +1,9 @@
 /** @file
   Definitions for EFI IPv4 Configuration II Protocol implementation.
 
-  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
   (C) Copyright 2015 Hewlett Packard Enterprise Development LP<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
@@ -211,10 +211,30 @@ typedef struct {
   UINT8                   Dns;
 } IP4_CONFIG2_DHCP4_OPTION;
 #pragma pack()
 
 /**
+  Read the configuration data from variable storage according to the VarName 
and
+  gEfiIp4Config2ProtocolGuid. It checks the integrity of variable data. If the
+  data is corrupted, it clears the variable data to ZERO. Othewise, it outputs 
the
+  configuration data to IP4_CONFIG2_INSTANCE.
+
+  @param[in]      VarName       The pointer to the variable name
+  @param[in, out] Instance      The pointer to the IP4 config2 instance data.
+
+  @retval EFI_NOT_FOUND         The variable can not be found or already 
corrupted.
+  @retval EFI_OUT_OF_RESOURCES  Fail to allocate resource to complete the 
operation.
+  @retval EFI_SUCCESS           The configuration data was retrieved 
successfully.
+
+**/
+EFI_STATUS
+Ip4Config2ReadConfigData (
+  IN     CHAR16               *VarName,
+  IN OUT IP4_CONFIG2_INSTANCE *Instance
+  );
+
+/**
   Start the DHCP configuration for this IP service instance.
   It will locates the EFI_IP4_CONFIG2_PROTOCOL, then start the
   DHCP configuration.
 
   @param[in]  Instance           The IP4 config2 instance to configure.
@@ -252,10 +272,24 @@ VOID
 Ip4Config2CleanInstance (
   IN OUT IP4_CONFIG2_INSTANCE  *Instance
   );
 
 /**
+  Request Ip4AutoReconfigCallBackDpc as a DPC at TPL_CALLBACK.
+
+  @param Event     The event that is signalled.
+  @param Context   The IP4 service binding instance.
+
+**/
+VOID
+EFIAPI
+Ip4AutoReconfigCallBack (
+  IN EFI_EVENT              Event,
+  IN VOID                   *Context
+  );
+
+/**
   Destroy the Dhcp4 child in IP4_CONFIG2_INSTANCE and release the resources.
 
   @param[in, out] Instance    The buffer of IP4 config2 instance to be freed.
 
   @retval EFI_SUCCESS         The child was successfully destroyed.
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c 
b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c
index 3dc4d88..e12ebe9 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c
@@ -1,9 +1,9 @@
 /** @file
   The driver binding and service binding protocol for IP4 driver.
 
-Copyright (c) 2005 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR>
 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<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
@@ -509,10 +509,17 @@ Ip4DriverBindingStart (
   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
   )
 { 
   EFI_STATUS                    Status;
   IP4_SERVICE                   *IpSb;
+  EFI_IP4_CONFIG2_PROTOCOL      *Ip4Cfg2;
+  UINTN                         Index;
+  IP4_CONFIG2_DATA_ITEM         *DataItem;
+
+  IpSb     = NULL;
+  Ip4Cfg2  = NULL;
+  DataItem = NULL;
 
   //
   // Test for the Ip4 service binding protocol
   //
   Status = gBS->OpenProtocol (
@@ -534,25 +541,54 @@ Ip4DriverBindingStart (
     return Status;
   }
   
   ASSERT (IpSb != NULL);
 
+  Ip4Cfg2  = &IpSb->Ip4Config2Instance.Ip4Config2;
+
   //
   // Install the Ip4ServiceBinding Protocol onto ControlerHandle
   //
   Status = gBS->InstallMultipleProtocolInterfaces (
                   &ControllerHandle,
                   &gEfiIp4ServiceBindingProtocolGuid,
                   &IpSb->ServiceBinding,
                   &gEfiIp4Config2ProtocolGuid,
-                  &IpSb->Ip4Config2Instance.Ip4Config2,
+                  Ip4Cfg2,
                   NULL
                   );
 
   if (EFI_ERROR (Status)) {
     goto FREE_SERVICE;
   }
+
+  //
+  // Read the config data from NV variable again. 
+  // The default data can be changed by other drivers.
+  //
+  Status = Ip4Config2ReadConfigData (IpSb->MacString, 
&IpSb->Ip4Config2Instance);
+  if (EFI_ERROR (Status)) {
+    goto UNINSTALL_PROTOCOL;
+  }
+  
+  //
+  // Consume the installed EFI_IP4_CONFIG2_PROTOCOL to set the default data 
items. 
+  //
+  for (Index = Ip4Config2DataTypePolicy; Index < Ip4Config2DataTypeMaximum; 
Index++) {
+    DataItem = &IpSb->Ip4Config2Instance.DataItem[Index];
+    if (DataItem->Data.Ptr != NULL) {
+      Status = Ip4Cfg2->SetData (
+                          Ip4Cfg2,
+                          Index,
+                          DataItem->DataSize,
+                          DataItem->Data.Ptr
+                          );
+      if (EFI_ERROR(Status)) {
+        goto UNINSTALL_PROTOCOL;
+      }
+    }
+  }
  
   //
   // Ready to go: start the receiving and timer.
   // Ip4Config2SetPolicy maybe call Ip4ReceiveFrame() to set the default 
interface's RecvRequest first after
   // Ip4Config2 instance is initialized. So, EFI_ALREADY_STARTED is the 
allowed return status.
@@ -568,10 +604,27 @@ Ip4DriverBindingStart (
   if (EFI_ERROR (Status)) {
     goto UNINSTALL_PROTOCOL;
   }
 
   //
+  // Create the ReconfigEvent to start the new configuration.
+  //
+  if (IpSb->ReconfigEvent == NULL) {
+    Status = gBS->CreateEvent (
+                    EVT_NOTIFY_SIGNAL,
+                    TPL_NOTIFY,
+                    Ip4AutoReconfigCallBack,
+                    IpSb,
+                    &IpSb->ReconfigEvent
+                    );
+
+    if (EFI_ERROR (Status)) {
+      goto UNINSTALL_PROTOCOL;
+    }
+  }
+
+  //
   // Initialize the IP4 ID
   //
   mIp4Id = (UINT16)NET_RANDOM (NetRandomInitSeed ());
 
   return Status;
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf 
b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
index f561af0..3135287 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
@@ -4,11 +4,11 @@
 #  This module produces EFI IPv4 Protocol upon EFI MNP Protocol and EFI ARP 
Protocol,
 #  to provide basic network IPv4 packet I/O services, which includes support 
for a
 #  subset of the Internet Control Message Protocol (ICMP) and may include 
support for
 #  the Internet Group Management Protocol (IGMP).
 #
-#  Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2016, 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
 #
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c 
b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c
index b9a294b..58adba7 100644
--- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c
+++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c
@@ -1,8 +1,8 @@
 /** @file
 
-Copyright (c) 2005 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2005 - 2016, 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
 
@@ -562,61 +562,10 @@ Ip4InitProtocol (
   EfiInitializeLock (&IpInstance->RecycleLock, TPL_NOTIFY);
 }
 
 
 /**
-  The event handle for IP4 auto reconfiguration. The original default
-  interface and route table will be removed as the default.
-
-  @param[in]  Context                The IP4 service binding instance.
-
-**/
-VOID
-EFIAPI
-Ip4AutoReconfigCallBackDpc (
-  IN VOID                   *Context
-  )
-{
-  IP4_SERVICE               *IpSb;
-
-  IpSb      = (IP4_SERVICE *) Context;
-  NET_CHECK_SIGNATURE (IpSb, IP4_SERVICE_SIGNATURE);
-
-  if (IpSb->State > IP4_SERVICE_UNSTARTED) {
-    IpSb->State = IP4_SERVICE_UNSTARTED;
-  }
-  
-  IpSb->Reconfig = TRUE;
-
-  Ip4StartAutoConfig (&IpSb->Ip4Config2Instance);
-
-  return ;
-}
-
-
-/**
-  Request Ip4AutoReconfigCallBackDpc as a DPC at TPL_CALLBACK.
-
-  @param Event     The event that is signalled.
-  @param Context   The IP4 service binding instance.
-
-**/
-VOID
-EFIAPI
-Ip4AutoReconfigCallBack (
-  IN EFI_EVENT              Event,
-  IN VOID                   *Context
-  )
-{
-  //
-  // Request Ip4AutoReconfigCallBackDpc as a DPC at TPL_CALLBACK
-  //
-  QueueDpc (TPL_CALLBACK, Ip4AutoReconfigCallBackDpc, Context);
-}
-
-
-/**
   Configure the IP4 child. If the child is already configured,
   change the configuration parameter. Otherwise configure it
   for the first time. The caller should validate the configuration
   before deliver them to it. It also don't do configure NULL.
 
@@ -722,36 +671,15 @@ Ip4ConfigProtocol (
     //
     Ip4AddRoute (IpInstance->RouteTable, Ip, Netmask, IP4_ALLZERO_ADDRESS);
 
   } else {
     //
-    // Use the default address. If the default configuration hasn't
-    // been started, start it.
+    // Use the default address. Check the state.
     //
     if (IpSb->State == IP4_SERVICE_UNSTARTED) {
-      //
-      // Create the ReconfigEvent to start the new configuration.
-      //
-      if (IpSb->ReconfigEvent == NULL) {
-        Status = gBS->CreateEvent (
-                        EVT_NOTIFY_SIGNAL,
-                        TPL_NOTIFY,
-                        Ip4AutoReconfigCallBack,
-                        IpSb,
-                        &IpSb->ReconfigEvent
-                        );
-
-        if (EFI_ERROR (Status)) {
-          goto ON_ERROR;
-        }
-      }
-      
-      Status = Ip4StartAutoConfig (&IpSb->Ip4Config2Instance);
-
-      if (EFI_ERROR (Status)) {
-        goto CLOSE_RECONFIG_EVENT;
-      }
+      Status = EFI_NO_MAPPING;
+      goto ON_ERROR;
     }
 
     IpIf = IpSb->DefaultInterface;
     NET_GET_REF (IpSb->DefaultInterface);
 
@@ -776,11 +704,11 @@ Ip4ConfigProtocol (
                     gIp4DriverBinding.DriverBindingHandle,
                     IpInstance->Handle,
                     EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                     );
     if (EFI_ERROR (Status)) {
-      goto CLOSE_RECONFIG_EVENT;
+      goto ON_ERROR;
     }
   }
   InsertTailList (&IpIf->IpInstances, &IpInstance->AddrLink);
 
   CopyMem (&IpInstance->ConfigData, Config, sizeof (IpInstance->ConfigData));
@@ -795,16 +723,10 @@ Ip4ConfigProtocol (
     return EFI_NO_MAPPING;
   }
 
   return EFI_SUCCESS;
 
-CLOSE_RECONFIG_EVENT:
-  if (IpSb->ReconfigEvent != NULL) {
-    gBS->CloseEvent (IpSb->ReconfigEvent);
-    IpSb->ReconfigEvent = NULL;
-  }
-
 ON_ERROR:
   Ip4FreeRouteTable (IpInstance->RouteTable);
   IpInstance->RouteTable = NULL;
   return Status;
 }
@@ -2415,11 +2337,11 @@ Ip4TimerTicking (
 
   IpSb->MediaPresent = SnpModeData.MediaPresent;
   //
   // Media transimit Unpresent to Present means new link movement is detected.
   //
-  if (!OldMediaPresent && IpSb->MediaPresent) {
+  if (!OldMediaPresent && IpSb->MediaPresent && 
(IpSb->Ip4Config2Instance.Policy == Ip4Config2PolicyDhcp)) {
     //
     // Signal the IP4 to run the dhcp configuration again. IP4 driver will free
     // old IP address related resource, such as route table and Interface, 
then 
     // initiate a DHCP round to acquire new IP, eventually 
     // create route table for new IP address.
-- 
1.9.5.msysgit.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to