Enable the use of UEFI HTTP boot function.\r
\r
@param[in] Private The pointer to the driver's private data.\r
+ @param[in] UsingIpv6 Specifies the type of IP addresses that are to be\r
+ used during the session that is being started.\r
+ Set to TRUE for IPv6, and FALSE for IPv4.\r
\r
@retval EFI_SUCCESS HTTP boot was successfully enabled.\r
@retval EFI_INVALID_PARAMETER Private is NULL.\r
**/\r
EFI_STATUS\r
HttpBootStart (\r
- IN HTTP_BOOT_PRIVATE_DATA *Private\r
+ IN HTTP_BOOT_PRIVATE_DATA *Private,\r
+ IN BOOLEAN UsingIpv6\r
)\r
{\r
- UINTN Index;\r
+ UINTN Index;\r
+ EFI_STATUS Status;\r
\r
if (Private == NULL) {\r
return EFI_INVALID_PARAMETER;\r
return EFI_ALREADY_STARTED;\r
}\r
\r
+ //\r
+ // Detect whether using ipv6 or not, and set it to the private data.\r
+ //\r
+ if (UsingIpv6 && Private->Ip6Nic != NULL) {\r
+ Private->UsingIpv6 = TRUE;\r
+ } else if (!UsingIpv6 && Private->Ip4Nic != NULL) {\r
+ Private->UsingIpv6 = FALSE;\r
+ } else {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ \r
+ //\r
+ // Init the content of cached DHCP offer list.\r
+ //\r
+ ZeroMem (Private->OfferBuffer, sizeof (Private->OfferBuffer));\r
if (!Private->UsingIpv6) {\r
- //\r
- // Init the content of cached DHCP offer list.\r
- //\r
- ZeroMem (Private->OfferBuffer, sizeof (Private->OfferBuffer));\r
for (Index = 0; Index < HTTP_BOOT_OFFER_MAX_NUM; Index++) {\r
Private->OfferBuffer[Index].Dhcp4.Packet.Offer.Size = HTTP_BOOT_DHCP4_PACKET_MAX_SIZE;\r
}\r
} else {\r
- ASSERT (FALSE);\r
+ for (Index = 0; Index < HTTP_BOOT_OFFER_MAX_NUM; Index++) {\r
+ Private->OfferBuffer[Index].Dhcp6.Packet.Offer.Size = HTTP_BOOT_DHCP6_PACKET_MAX_SIZE;\r
+ }\r
}\r
\r
+ if (Private->UsingIpv6) {\r
+ //\r
+ // Set Ip6 policy to Automatic to start the Ip6 router discovery.\r
+ //\r
+ Status = HttpBootSetIp6Policy (Private);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
Private->Started = TRUE;\r
\r
return EFI_SUCCESS;\r
}\r
\r
/**\r
- Attempt to complete a DHCPv4 D.O.R.A sequence to retrieve the boot resource information.\r
+ Attempt to complete a DHCPv4 D.O.R.A or DHCPv6 S.R.A.A sequence to retrieve the boot resource information.\r
\r
@param[in] Private The pointer to the driver's private data.\r
\r
Status = EFI_DEVICE_ERROR;\r
\r
if (!Private->UsingIpv6) {\r
+ //\r
+ // Start D.O.R.A process to get a IPv4 address and other boot information.\r
+ //\r
Status = HttpBootDhcp4Dora (Private);\r
} else {\r
- ASSERT (FALSE);\r
+ //\r
+ // Start S.A.R.R process to get a IPv6 address and other boot information.\r
+ //\r
+ Status = HttpBootDhcp6Sarr (Private);\r
}\r
\r
return Status;\r
Private->BootFileUriParser = NULL;\r
Private->BootFileSize = 0;\r
Private->SelectIndex = 0;\r
- Private->SelectProxyType = HttpOfferTypeMax;\r
+ Private->SelectProxyType = HttpOfferTypeMax; \r
\r
if (!Private->UsingIpv6) {\r
//\r
}\r
}\r
} else {\r
- ASSERT (FALSE);\r
+ //\r
+ // Stop and release the DHCP6 child.\r
+ //\r
+ Private->Dhcp6->Stop (Private->Dhcp6);\r
+ Private->Dhcp6->Configure (Private->Dhcp6, NULL);\r
+ \r
+ for (Index = 0; Index < HTTP_BOOT_OFFER_MAX_NUM; Index++) {\r
+ if (Private->OfferBuffer[Index].Dhcp6.UriParser) {\r
+ HttpUrlFreeParser (Private->OfferBuffer[Index].Dhcp6.UriParser);\r
+ }\r
+ }\r
}\r
\r
ZeroMem (Private->OfferBuffer, sizeof (Private->OfferBuffer));\r
)\r
{\r
HTTP_BOOT_PRIVATE_DATA *Private;\r
+ HTTP_BOOT_VIRTUAL_NIC *VirtualNic;\r
BOOLEAN MediaPresent;\r
+ BOOLEAN UsingIpv6;\r
EFI_STATUS Status;\r
\r
if (This == NULL || BufferSize == NULL) {\r
return EFI_UNSUPPORTED;\r
}\r
\r
- Private = HTTP_BOOT_PRIVATE_DATA_FROM_LOADFILE (This);\r
-\r
+ VirtualNic = HTTP_BOOT_VIRTUAL_NIC_FROM_LOADFILE (This);\r
+ Private = VirtualNic->Private;\r
+ UsingIpv6 = FALSE;\r
+ \r
//\r
// Check media status before HTTP boot start\r
//\r
return EFI_NO_MEDIA;\r
}\r
\r
+ //\r
+ // Check whether the virtual nic is using IPv6 or not.\r
+ //\r
+ if (VirtualNic == Private->Ip6Nic) {\r
+ UsingIpv6 = TRUE;\r
+ }\r
+ \r
//\r
// Initialize HTTP boot and load the boot file.\r
//\r
- Status = HttpBootStart (Private);\r
+ Status = HttpBootStart (Private, UsingIpv6);\r
+ if (Status == EFI_ALREADY_STARTED && UsingIpv6 != Private->UsingIpv6) {\r
+ //\r
+ // Http boot Driver has already been started but not on the required IP version, restart it.\r
+ //\r
+ Status = HttpBootStop (Private);\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = HttpBootStart (Private, UsingIpv6);\r
+ }\r
+ }\r
if (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED) {\r
Status = HttpBootLoadFile (Private, BufferSize, Buffer);\r
}\r
if (Status != EFI_SUCCESS && Status != EFI_BUFFER_TOO_SMALL) {\r
HttpBootStop (Private);\r
} else {\r
- //\r
- // Stop and release the DHCP4 child.\r
- //\r
- Private->Dhcp4->Stop (Private->Dhcp4);\r
- Private->Dhcp4->Configure (Private->Dhcp4, NULL);\r
+ if (!Private->UsingIpv6) {\r
+ //\r
+ // Stop and release the DHCP4 child.\r
+ //\r
+ Private->Dhcp4->Stop (Private->Dhcp4);\r
+ Private->Dhcp4->Configure (Private->Dhcp4, NULL);\r
+ } else {\r
+ //\r
+ // Stop and release the DHCP6 child.\r
+ //\r
+ Private->Dhcp6->Stop (Private->Dhcp6);\r
+ Private->Dhcp6->Configure (Private->Dhcp6, NULL);\r
+ }\r
}\r
\r
return Status;\r