From ac99793b73a7856f06edcb63a23bf1518febb347 Mon Sep 17 00:00:00 2001 From: Zhang Lubo Date: Wed, 29 Jul 2015 04:10:09 +0000 Subject: NetworkPkg: Fix the issue cannot boot to UEFI Network after reset 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. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Zhang Lubo Reviewed-by: Fu Siyuan Reviewed-by: Wu Jiaxin git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18104 6f19259b-4bc3-4df7-8a09-765794883524 --- NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c | 46 ++++++++++++++++++++++++++++++++ NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.h | 16 ++++++++++- NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c | 12 +++++++++ NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c | 12 +++++++++ NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h | 2 ++ NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf | 1 + 6 files changed, 88 insertions(+), 1 deletion(-) (limited to 'NetworkPkg') diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c index c0277706f2..587566d4e0 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c @@ -1506,6 +1506,52 @@ PxeBcDhcp4Discover ( return Status; } +/** + 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; +} /** Start the D.O.R.A DHCPv4 process to acquire the IPv4 address and other PXE boot information. diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.h b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.h index 8e4e101806..248dc60d2c 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.h +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.h @@ -1,7 +1,7 @@ /** @file Functions declaration related with DHCPv4 for UefiPxeBc Driver. - Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -374,6 +374,20 @@ PxeBcDhcp4Discover ( IN EFI_PXE_BASE_CODE_SRVLIST *SrvList ); +/** + 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 + ); + /** Start the D.O.R.A DHCPv4 process to acquire the IPv4 address and other PXE boot information. diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c index c2987b8734..a6f66682f3 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c @@ -742,6 +742,18 @@ PxeBcCreateIp4Children ( Private->Ip4Nic->Private = Private; Private->Ip4Nic->Signature = PXEBC_VIRTUAL_NIC_SIGNATURE; + // + // 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; + } + // // Create a device path node for Ipv4 virtual nic, and append it. // diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c index 374b4a1667..cdcf2f0d3e 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c @@ -204,6 +204,18 @@ EfiPxeBcStart ( if (EFI_ERROR (Status)) { goto ON_ERROR; } + + // + //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_ERROR; + } } // diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h index 4aa3ce2f5b..ac7dc8781a 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -116,6 +117,7 @@ struct _PXEBC_PRIVATE_DATA { EFI_ARP_PROTOCOL *Arp; EFI_IP4_PROTOCOL *Ip4; + EFI_IP4_CONFIG2_PROTOCOL *Ip4Config2; EFI_DHCP4_PROTOCOL *Dhcp4; EFI_MTFTP4_PROTOCOL *Mtftp4; EFI_UDP4_PROTOCOL *Udp4Read; diff --git a/NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf b/NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf index ea083bf1c5..c3ca218ba3 100644 --- a/NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf +++ b/NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf @@ -79,6 +79,7 @@ gEfiArpProtocolGuid ## TO_START gEfiIp4ServiceBindingProtocolGuid ## TO_START gEfiIp4ProtocolGuid ## TO_START + gEfiIp4Config2ProtocolGuid ## TO_START gEfiIp6ServiceBindingProtocolGuid ## TO_START gEfiIp6ProtocolGuid ## TO_START gEfiIp6ConfigProtocolGuid ## TO_START -- cgit v1.2.3