DHCP4 service allows only one of its children to be configured
in the active state,If the DHCP4 D.O.R.A started by IP4 auto
configuration and has not been completed, the Dhcp4 state machine
will not be in the right state for the PXE to start a new round D.O.R.A.
so we need to switch it's policy to static.

Cc: Fu Siyuan<siyuan...@intel.com>
Cc: Ye Ting<ting...@intel.com>
CC: Wu Jiaxin <jiaxin...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Zhang Lubo <lubo.zh...@intel.com>
---
 .../Universal/Network/UefiPxeBcDxe/PxeBcDhcp.c     | 47 ++++++++++++++++++++++
 .../Universal/Network/UefiPxeBcDxe/PxeBcDhcp.h     | 13 ++++++
 .../Universal/Network/UefiPxeBcDxe/PxeBcDriver.c   | 11 +++++
 .../Universal/Network/UefiPxeBcDxe/PxeBcImpl.c     | 11 +++++
 .../Universal/Network/UefiPxeBcDxe/PxeBcImpl.h     |  2 +
 .../Network/UefiPxeBcDxe/UefiPxeBcDxe.inf          |  1 +
 6 files changed, 85 insertions(+)

diff --git a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDhcp.c 
b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDhcp.c
index 1293f67..85155b1 100644
--- a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDhcp.c
+++ b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDhcp.c
@@ -645,10 +645,57 @@ PxeBcCacheDhcpOffer (
   // Count the accepted offers.
   //
   Private->NumOffers++;
 }
 
+/**
+  Switch the Ip4 policy to static.
+
+  @param[in]  Private             The pointer to PXEBC_PRIVATE_DATA.
+
+  @retval     EFI_SUCCESS         The policy is already configured to static.
+  @retval     Others              Other error as indicated..
+
+**/
+EFI_STATUS
+PxeBcSetIp4Policy (   
+  IN PXEBC_PRIVATE_DATA            *Private
+  )
+{
+  EFI_STATUS                   Status;
+  EFI_IP4_CONFIG2_PROTOCOL     *Ip4Config2;
+  EFI_IP4_CONFIG2_POLICY       Policy;
+  UINTN                        DataSize;
+
+  Ip4Config2 = Private->Ip4Config2;
+  DataSize = sizeof (EFI_IP4_CONFIG2_POLICY);
+  Status = Ip4Config2->GetData (
+                       Ip4Config2,
+                       Ip4Config2DataTypePolicy,
+                       &DataSize,
+                       &Policy
+                       );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  
+  if (Policy != Ip4Config2PolicyStatic) {
+    Policy = Ip4Config2PolicyStatic;
+    Status= Ip4Config2->SetData (
+                          Ip4Config2,
+                          Ip4Config2DataTypePolicy,
+                          sizeof (EFI_IP4_CONFIG2_POLICY),
+                          &Policy
+                          );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    } 
+  }
+
+  return  EFI_SUCCESS;
+}
+
 
 /**
   Select the specified proxy offer, such as BINL, DHCP_ONLY and so on.
   If the proxy does not exist, try offers with bootfile.
 
diff --git a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDhcp.h 
b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDhcp.h
index b56d10d..32a64df 100644
--- a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDhcp.h
+++ b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDhcp.h
@@ -378,10 +378,23 @@ PxeBcDhcpCallBack (
   IN EFI_DHCP4_EVENT                   Dhcp4Event,
   IN EFI_DHCP4_PACKET                  * Packet OPTIONAL,
   OUT EFI_DHCP4_PACKET                 **NewPacket OPTIONAL
   );
 
+/**
+  Switch the Ip4 policy to static.
+
+  @param[in]  Private             The pointer to PXEBC_PRIVATE_DATA.
+
+  @retval     EFI_SUCCESS         The policy is already configured to static.
+  @retval     Others              Other error as indicated..
+
+**/
+EFI_STATUS
+PxeBcSetIp4Policy (   
+  IN PXEBC_PRIVATE_DATA            *Private
+  );
 
 /**
   Discover the boot of service and initialize the vendor option if exists.
 
   @param  Private               Pointer to PxeBc private data.
diff --git a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDriver.c 
b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDriver.c
index 3c2437e..1b7577a 100644
--- a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDriver.c
+++ b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDriver.c
@@ -373,10 +373,21 @@ PxeBcDriverBindingStart (
                   NULL
                   );
   if (EFI_ERROR (Status)) {
     goto ON_ERROR;
   }
+  //
+  // Locate Ip4->Ip4Config2 and store it for set IPv4 Policy.
+  //
+  Status = gBS->HandleProtocol (
+                  ControllerHandle,
+                  &gEfiIp4Config2ProtocolGuid,
+                  (VOID **) &Private->Ip4Config2
+                  );
+  if (EFI_ERROR (Status)) {
+    goto ON_ERROR;
+  }
 
   return EFI_SUCCESS;
 
 ON_ERROR:
 
diff --git a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.c 
b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.c
index 0c54f46..991a7be 100644
--- a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.c
+++ b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.c
@@ -408,10 +408,21 @@ EfiPxeBcStart (
                   );
   if (EFI_ERROR (Status)) {
     goto ON_EXIT;
   }
 
+  //
+  //DHCP4 service allows only one of its children to be configured in 
+  //the active state,If the DHCP4 D.O.R.A started by IP4 auto 
+  //configuration and has not been completed, the Dhcp4 state machine 
+  //will not be in the right state for the PXE to start a new round D.O.R.A. 
+  //so we need to switch it's policy to static.
+  //
+  Status = PxeBcSetIp4Policy (Private);
+  if (EFI_ERROR (Status)) {
+    goto ON_EXIT;
+  }
+  
   Status = Private->Ip4->Configure (Private->Ip4, &Private->Ip4ConfigData);
   if (EFI_ERROR (Status)) {
     goto ON_EXIT;
   }
 
diff --git a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.h 
b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.h
index 97703cb..7be0d67 100644
--- a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.h
+++ b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.h
@@ -28,10 +28,11 @@ typedef struct _PXEBC_PRIVATE_DATA  PXEBC_PRIVATE_DATA;
 #include <Protocol/LoadFile.h>
 #include <Protocol/NetworkInterfaceIdentifier.h>
 #include <Protocol/PxeBaseCodeCallBack.h>
 #include <Protocol/Arp.h>
 #include <Protocol/Ip4.h>
+#include <Protocol/Ip4Config2.h>
 
 #include <Library/DebugLib.h>
 #include <Library/BaseMemoryLib.h>
 #include <Library/MemoryAllocationLib.h>
 #include <Library/UefiDriverEntryPoint.h>
@@ -73,10 +74,11 @@ struct _PXEBC_PRIVATE_DATA {
   EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL       LoadFileCallback;
   EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL       *PxeBcCallback;
   EFI_ARP_PROTOCOL                          *Arp;
   EFI_DHCP4_PROTOCOL                        *Dhcp4;
   EFI_IP4_PROTOCOL                          *Ip4;
+  EFI_IP4_CONFIG2_PROTOCOL                  *Ip4Config2;
   EFI_IP4_CONFIG_DATA                       Ip4ConfigData;
   EFI_MTFTP4_PROTOCOL                       *Mtftp4;
   EFI_UDP4_PROTOCOL                         *Udp4Read;
   EFI_UDP4_PROTOCOL                         *Udp4Write;
   UINT16                                    CurrentUdpSrcPort;
diff --git a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf 
b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
index a126563..3dbe151 100644
--- a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
+++ b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
@@ -82,10 +82,11 @@
   gEfiUdp4ProtocolGuid                             ## TO_START
   gEfiDhcp4ServiceBindingProtocolGuid              ## TO_START
   gEfiDhcp4ProtocolGuid                            ## TO_START
   gEfiIp4ServiceBindingProtocolGuid                ## TO_START
   gEfiIp4ProtocolGuid                              ## TO_START
+  gEfiIp4Config2ProtocolGuid                       ## TO_START
 
 [Pcd]  
   gEfiMdeModulePkgTokenSpaceGuid.PcdTftpBlockSize  ## SOMETIMES_CONSUMES  
 
 [UserExtensions.TianoCore."ExtraFiles"]
-- 
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