Driver Binding functions implementationfor for UefiPxeBc Driver.\r
\r
(C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>\r
- Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<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
- http://opensource.org/licenses/bsd-license.php.\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
&Private->PxeBc,\r
NULL\r
);\r
+ FreePool (Private->Ip4Nic->DevicePath);\r
\r
- if (Private->Snp != NULL) { \r
+ if (Private->Snp != NULL) {\r
//\r
// Close SNP from the child virtual handle\r
//\r
This->DriverBindingHandle,\r
Private->Ip4Nic->Controller\r
);\r
- \r
+\r
gBS->UninstallProtocolInterface (\r
Private->Ip4Nic->Controller,\r
&gEfiSimpleNetworkProtocolGuid,\r
&Private->PxeBc,\r
NULL\r
);\r
+ FreePool (Private->Ip6Nic->DevicePath);\r
+\r
if (Private->Snp != NULL) {\r
//\r
// Close SNP from the child virtual handle\r
Private->Mode.Ipv6Available = FALSE;\r
}\r
\r
+/**\r
+ Check whether UNDI protocol supports IPv6.\r
+\r
+ @param[in] ControllerHandle Controller handle.\r
+ @param[in] Private Pointer to PXEBC_PRIVATE_DATA.\r
+ @param[out] Ipv6Support TRUE if UNDI supports IPv6.\r
+\r
+ @retval EFI_SUCCESS Get the result whether UNDI supports IPv6 by NII or AIP protocol successfully.\r
+ @retval EFI_NOT_FOUND Don't know whether UNDI supports IPv6 since NII or AIP is not available.\r
+\r
+**/\r
+EFI_STATUS\r
+PxeBcCheckIpv6Support (\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN PXEBC_PRIVATE_DATA *Private,\r
+ OUT BOOLEAN *Ipv6Support\r
+ )\r
+{\r
+ EFI_HANDLE Handle;\r
+ EFI_ADAPTER_INFORMATION_PROTOCOL *Aip;\r
+ EFI_STATUS Status;\r
+ EFI_GUID *InfoTypesBuffer;\r
+ UINTN InfoTypeBufferCount;\r
+ UINTN TypeIndex;\r
+ BOOLEAN Supported;\r
+ VOID *InfoBlock;\r
+ UINTN InfoBlockSize;\r
+\r
+ ASSERT (Private != NULL && Ipv6Support != NULL);\r
+\r
+ //\r
+ // Check whether the UNDI supports IPv6 by NII protocol.\r
+ //\r
+ if (Private->Nii != NULL) {\r
+ *Ipv6Support = Private->Nii->Ipv6Supported;\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Check whether the UNDI supports IPv6 by AIP protocol.\r
+ //\r
+\r
+ //\r
+ // Get the NIC handle by SNP protocol.\r
+ //\r
+ Handle = NetLibGetSnpHandle (ControllerHandle, NULL);\r
+ if (Handle == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ Aip = NULL;\r
+ Status = gBS->HandleProtocol (\r
+ Handle,\r
+ &gEfiAdapterInformationProtocolGuid,\r
+ (VOID *) &Aip\r
+ );\r
+ if (EFI_ERROR (Status) || Aip == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ InfoTypesBuffer = NULL;\r
+ InfoTypeBufferCount = 0;\r
+ Status = Aip->GetSupportedTypes (Aip, &InfoTypesBuffer, &InfoTypeBufferCount);\r
+ if (EFI_ERROR (Status) || InfoTypesBuffer == NULL) {\r
+ FreePool (InfoTypesBuffer);\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ Supported = FALSE;\r
+ for (TypeIndex = 0; TypeIndex < InfoTypeBufferCount; TypeIndex++) {\r
+ if (CompareGuid (&InfoTypesBuffer[TypeIndex], &gEfiAdapterInfoUndiIpv6SupportGuid)) {\r
+ Supported = TRUE;\r
+ break;\r
+ }\r
+ }\r
+\r
+ FreePool (InfoTypesBuffer);\r
+ if (!Supported) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ //\r
+ // We now have adapter information block.\r
+ //\r
+ InfoBlock = NULL;\r
+ InfoBlockSize = 0;\r
+ Status = Aip->GetInformation (Aip, &gEfiAdapterInfoUndiIpv6SupportGuid, &InfoBlock, &InfoBlockSize);\r
+ if (EFI_ERROR (Status) || InfoBlock == NULL) {\r
+ FreePool (InfoBlock);\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ *Ipv6Support = ((EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT *) InfoBlock)->Ipv6Support;\r
+ FreePool (InfoBlock);\r
+ return EFI_SUCCESS;\r
+\r
+}\r
\r
/**\r
Create the opened instances based on IPv4.\r
Private->Ip4Nic->Private = Private;\r
Private->Ip4Nic->Signature = PXEBC_VIRTUAL_NIC_SIGNATURE;\r
\r
+ //\r
+ // Locate Ip4->Ip4Config2 and store it for set IPv4 Policy.\r
+ //\r
+ Status = gBS->HandleProtocol (\r
+ ControllerHandle,\r
+ &gEfiIp4Config2ProtocolGuid,\r
+ (VOID **) &Private->Ip4Config2\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
+\r
//\r
// Create a device path node for Ipv4 virtual nic, and append it.\r
//\r
}\r
\r
//\r
- // Open SNP on the child handle BY_DRIVER. It will prevent any additionally \r
+ // Open SNP on the child handle BY_DRIVER|EXCLUSIVE. It will prevent any additionally\r
// layering to perform the experiment.\r
//\r
Status = gBS->OpenProtocol (\r
(VOID **) &Snp,\r
This->DriverBindingHandle,\r
Private->Ip4Nic->Controller,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER|EFI_OPEN_PROTOCOL_EXCLUSIVE\r
);\r
if (EFI_ERROR (Status)) {\r
goto ON_ERROR;\r
if (Private->Snp != NULL) {\r
for (Index = 0; Index < Private->Snp->Mode->HwAddressSize; Index++) {\r
Private->IaId |= (Private->Snp->Mode->CurrentAddress.Addr[Index] << ((Index << 3) & 31));\r
- } \r
+ }\r
}\r
\r
//\r
\r
Private->Ip6MaxPacketSize = Ip6ModeData.MaxPacketSize;\r
\r
+ if (Ip6ModeData.AddressList != NULL) {\r
+ FreePool (Ip6ModeData.AddressList);\r
+ }\r
+\r
+ if (Ip6ModeData.GroupTable != NULL) {\r
+ FreePool (Ip6ModeData.GroupTable);\r
+ }\r
+\r
+ if (Ip6ModeData.RouteTable != NULL) {\r
+ FreePool (Ip6ModeData.RouteTable);\r
+ }\r
+\r
+ if (Ip6ModeData.NeighborCache != NULL) {\r
+ FreePool (Ip6ModeData.NeighborCache);\r
+ }\r
+\r
+ if (Ip6ModeData.PrefixTable != NULL) {\r
+ FreePool (Ip6ModeData.PrefixTable);\r
+ }\r
+\r
+ if (Ip6ModeData.IcmpTypeList != NULL) {\r
+ FreePool (Ip6ModeData.IcmpTypeList);\r
+ }\r
+\r
//\r
// Locate Ip6->Ip6Config and store it for set IPv6 address.\r
//\r
if (EFI_ERROR (Status)) {\r
goto ON_ERROR;\r
}\r
- \r
+\r
if (Private->Snp != NULL) {\r
//\r
// Install SNP protocol on purpose is for some OS loader backward\r
}\r
\r
//\r
- // Open SNP on the child handle BY_DRIVER. It will prevent any additionally \r
+ // Open SNP on the child handle BY_DRIVER|EXCLUSIVE. It will prevent any additionally\r
// layering to perform the experiment.\r
//\r
Status = gBS->OpenProtocol (\r
(VOID **) &Snp,\r
This->DriverBindingHandle,\r
Private->Ip6Nic->Controller,\r
- EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER|EFI_OPEN_PROTOCOL_EXCLUSIVE\r
);\r
if (EFI_ERROR (Status)) {\r
goto ON_ERROR;\r
// Set IPv6 avaiable flag and set default configure data for\r
// Udp6Read and Ip6 instance.\r
//\r
- Private->Mode.Ipv6Available = TRUE;\r
+ Status = PxeBcCheckIpv6Support (ControllerHandle, Private, &Private->Mode.Ipv6Available);\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Fail to get the data whether UNDI supports IPv6. Set default value.\r
+ //\r
+ Private->Mode.Ipv6Available = TRUE;\r
+ }\r
+\r
+ if (!Private->Mode.Ipv6Available) {\r
+ goto ON_ERROR;\r
+ }\r
+\r
Udp6CfgData = &Private->Udp6CfgData;\r
Ip6CfgData = &Private->Ip6CfgData;\r
\r
&gPxeBcComponentName2\r
);\r
if (EFI_ERROR (Status)) {\r
- gBS->UninstallMultipleProtocolInterfaces (\r
- ImageHandle,\r
- &gEfiDriverBindingProtocolGuid,\r
- &gPxeBcIp4DriverBinding,\r
- &gEfiComponentName2ProtocolGuid,\r
- &gPxeBcComponentName2,\r
- &gEfiComponentNameProtocolGuid,\r
- &gPxeBcComponentName,\r
- NULL\r
- );\r
+ EfiLibUninstallDriverBindingComponentName2 (\r
+ &gPxeBcIp4DriverBinding,\r
+ &gPxeBcComponentName,\r
+ &gPxeBcComponentName2\r
+ );\r
}\r
\r
return Status;\r
@param[in] RemainingDevicePath Optional parameter used to pick a specific child\r
device to be started.\r
@param[in] IpVersion IP_VERSION_4 or IP_VERSION_6.\r
- \r
+\r
@retval EFI_SUCCESS This driver supports this device.\r
@retval EFI_UNSUPPORTED This driver does not support this device.\r
\r
EFI_STATUS Status;\r
EFI_GUID *DhcpServiceBindingGuid;\r
EFI_GUID *MtftpServiceBindingGuid;\r
- \r
+\r
if (IpVersion == IP_VERSION_4) {\r
DhcpServiceBindingGuid = &gEfiDhcp4ServiceBindingProtocolGuid;\r
MtftpServiceBindingGuid = &gEfiMtftp4ServiceBindingProtocolGuid;\r
\r
//\r
// Install PxeBaseCodePrivate protocol onto the real NIC handler.\r
- // PxeBaseCodePrivate protocol is only used to keep the relationship between \r
+ // PxeBaseCodePrivate protocol is only used to keep the relationship between\r
// NIC handle and virtual child handles.\r
// gEfiCallerIdGuid will be used as its protocol guid.\r
//\r
//\r
// Try to locate SNP protocol.\r
//\r
- NetLibGetSnpHandle(ControllerHandle, &Private->Snp); \r
+ NetLibGetSnpHandle(ControllerHandle, &Private->Snp);\r
}\r
\r
if (IpVersion == IP_VERSION_4) {\r