X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=NetworkPkg%2FUefiPxeBcDxe%2FPxeBcDriver.c;h=3c1d400d502ca63a08d07cbb96f90c6198498658;hp=92fd1f19df64bc9ebbf972a58dcc96adb7a5b306;hb=ecf98fbcf858b9cb09ff0ac1c2a09c0111b4026b;hpb=8f586b85c3f617ba802e663b4b3b303e06140863 diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c index 92fd1f19df..3c1d400d50 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c @@ -2,15 +2,9 @@ Driver Binding functions implementationfor for UefiPxeBc Driver. (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
- Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.
+ Copyright (c) 2007 - 2018, 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 - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -254,8 +248,9 @@ PxeBcDestroyIp4Children ( &Private->PxeBc, NULL ); + FreePool (Private->Ip4Nic->DevicePath); - if (Private->Snp != NULL) { + if (Private->Snp != NULL) { // // Close SNP from the child virtual handle // @@ -265,7 +260,7 @@ PxeBcDestroyIp4Children ( This->DriverBindingHandle, Private->Ip4Nic->Controller ); - + gBS->UninstallProtocolInterface ( Private->Ip4Nic->Controller, &gEfiSimpleNetworkProtocolGuid, @@ -414,6 +409,8 @@ PxeBcDestroyIp6Children ( &Private->PxeBc, NULL ); + FreePool (Private->Ip6Nic->DevicePath); + if (Private->Snp != NULL) { // // Close SNP from the child virtual handle @@ -442,6 +439,103 @@ PxeBcDestroyIp6Children ( Private->Mode.Ipv6Available = FALSE; } +/** + Check whether UNDI protocol supports IPv6. + + @param[in] ControllerHandle Controller handle. + @param[in] Private Pointer to PXEBC_PRIVATE_DATA. + @param[out] Ipv6Support TRUE if UNDI supports IPv6. + + @retval EFI_SUCCESS Get the result whether UNDI supports IPv6 by NII or AIP protocol successfully. + @retval EFI_NOT_FOUND Don't know whether UNDI supports IPv6 since NII or AIP is not available. + +**/ +EFI_STATUS +PxeBcCheckIpv6Support ( + IN EFI_HANDLE ControllerHandle, + IN PXEBC_PRIVATE_DATA *Private, + OUT BOOLEAN *Ipv6Support + ) +{ + EFI_HANDLE Handle; + EFI_ADAPTER_INFORMATION_PROTOCOL *Aip; + EFI_STATUS Status; + EFI_GUID *InfoTypesBuffer; + UINTN InfoTypeBufferCount; + UINTN TypeIndex; + BOOLEAN Supported; + VOID *InfoBlock; + UINTN InfoBlockSize; + + ASSERT (Private != NULL && Ipv6Support != NULL); + + // + // Check whether the UNDI supports IPv6 by NII protocol. + // + if (Private->Nii != NULL) { + *Ipv6Support = Private->Nii->Ipv6Supported; + return EFI_SUCCESS; + } + + // + // Check whether the UNDI supports IPv6 by AIP protocol. + // + + // + // Get the NIC handle by SNP protocol. + // + Handle = NetLibGetSnpHandle (ControllerHandle, NULL); + if (Handle == NULL) { + return EFI_NOT_FOUND; + } + + Aip = NULL; + Status = gBS->HandleProtocol ( + Handle, + &gEfiAdapterInformationProtocolGuid, + (VOID *) &Aip + ); + if (EFI_ERROR (Status) || Aip == NULL) { + return EFI_NOT_FOUND; + } + + InfoTypesBuffer = NULL; + InfoTypeBufferCount = 0; + Status = Aip->GetSupportedTypes (Aip, &InfoTypesBuffer, &InfoTypeBufferCount); + if (EFI_ERROR (Status) || InfoTypesBuffer == NULL) { + FreePool (InfoTypesBuffer); + return EFI_NOT_FOUND; + } + + Supported = FALSE; + for (TypeIndex = 0; TypeIndex < InfoTypeBufferCount; TypeIndex++) { + if (CompareGuid (&InfoTypesBuffer[TypeIndex], &gEfiAdapterInfoUndiIpv6SupportGuid)) { + Supported = TRUE; + break; + } + } + + FreePool (InfoTypesBuffer); + if (!Supported) { + return EFI_NOT_FOUND; + } + + // + // We now have adapter information block. + // + InfoBlock = NULL; + InfoBlockSize = 0; + Status = Aip->GetInformation (Aip, &gEfiAdapterInfoUndiIpv6SupportGuid, &InfoBlock, &InfoBlockSize); + if (EFI_ERROR (Status) || InfoBlock == NULL) { + FreePool (InfoBlock); + return EFI_NOT_FOUND; + } + + *Ipv6Support = ((EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT *) InfoBlock)->Ipv6Support; + FreePool (InfoBlock); + return EFI_SUCCESS; + +} /** Create the opened instances based on IPv4. @@ -645,6 +739,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. // @@ -702,7 +808,7 @@ PxeBcCreateIp4Children ( } // - // Open SNP on the child handle BY_DRIVER. It will prevent any additionally + // Open SNP on the child handle BY_DRIVER|EXCLUSIVE. It will prevent any additionally // layering to perform the experiment. // Status = gBS->OpenProtocol ( @@ -711,7 +817,7 @@ PxeBcCreateIp4Children ( (VOID **) &Snp, This->DriverBindingHandle, Private->Ip4Nic->Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER + EFI_OPEN_PROTOCOL_BY_DRIVER|EFI_OPEN_PROTOCOL_EXCLUSIVE ); if (EFI_ERROR (Status)) { goto ON_ERROR; @@ -839,7 +945,7 @@ PxeBcCreateIp6Children ( if (Private->Snp != NULL) { for (Index = 0; Index < Private->Snp->Mode->HwAddressSize; Index++) { Private->IaId |= (Private->Snp->Mode->CurrentAddress.Addr[Index] << ((Index << 3) & 31)); - } + } } // @@ -952,6 +1058,30 @@ PxeBcCreateIp6Children ( Private->Ip6MaxPacketSize = Ip6ModeData.MaxPacketSize; + if (Ip6ModeData.AddressList != NULL) { + FreePool (Ip6ModeData.AddressList); + } + + if (Ip6ModeData.GroupTable != NULL) { + FreePool (Ip6ModeData.GroupTable); + } + + if (Ip6ModeData.RouteTable != NULL) { + FreePool (Ip6ModeData.RouteTable); + } + + if (Ip6ModeData.NeighborCache != NULL) { + FreePool (Ip6ModeData.NeighborCache); + } + + if (Ip6ModeData.PrefixTable != NULL) { + FreePool (Ip6ModeData.PrefixTable); + } + + if (Ip6ModeData.IcmpTypeList != NULL) { + FreePool (Ip6ModeData.IcmpTypeList); + } + // // Locate Ip6->Ip6Config and store it for set IPv6 address. // @@ -1004,7 +1134,7 @@ PxeBcCreateIp6Children ( if (EFI_ERROR (Status)) { goto ON_ERROR; } - + if (Private->Snp != NULL) { // // Install SNP protocol on purpose is for some OS loader backward @@ -1021,7 +1151,7 @@ PxeBcCreateIp6Children ( } // - // Open SNP on the child handle BY_DRIVER. It will prevent any additionally + // Open SNP on the child handle BY_DRIVER|EXCLUSIVE. It will prevent any additionally // layering to perform the experiment. // Status = gBS->OpenProtocol ( @@ -1030,7 +1160,7 @@ PxeBcCreateIp6Children ( (VOID **) &Snp, This->DriverBindingHandle, Private->Ip6Nic->Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER + EFI_OPEN_PROTOCOL_BY_DRIVER|EFI_OPEN_PROTOCOL_EXCLUSIVE ); if (EFI_ERROR (Status)) { goto ON_ERROR; @@ -1057,7 +1187,18 @@ PxeBcCreateIp6Children ( // Set IPv6 avaiable flag and set default configure data for // Udp6Read and Ip6 instance. // - Private->Mode.Ipv6Available = TRUE; + Status = PxeBcCheckIpv6Support (ControllerHandle, Private, &Private->Mode.Ipv6Available); + if (EFI_ERROR (Status)) { + // + // Fail to get the data whether UNDI supports IPv6. Set default value. + // + Private->Mode.Ipv6Available = TRUE; + } + + if (!Private->Mode.Ipv6Available) { + goto ON_ERROR; + } + Udp6CfgData = &Private->Udp6CfgData; Ip6CfgData = &Private->Ip6CfgData; @@ -1122,16 +1263,11 @@ PxeBcDriverEntryPoint ( &gPxeBcComponentName2 ); if (EFI_ERROR (Status)) { - gBS->UninstallMultipleProtocolInterfaces ( - ImageHandle, - &gEfiDriverBindingProtocolGuid, - &gPxeBcIp4DriverBinding, - &gEfiComponentName2ProtocolGuid, - &gPxeBcComponentName2, - &gEfiComponentNameProtocolGuid, - &gPxeBcComponentName, - NULL - ); + EfiLibUninstallDriverBindingComponentName2 ( + &gPxeBcIp4DriverBinding, + &gPxeBcComponentName, + &gPxeBcComponentName2 + ); } return Status; @@ -1146,7 +1282,7 @@ PxeBcDriverEntryPoint ( @param[in] RemainingDevicePath Optional parameter used to pick a specific child device to be started. @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6. - + @retval EFI_SUCCESS This driver supports this device. @retval EFI_UNSUPPORTED This driver does not support this device. @@ -1163,7 +1299,7 @@ PxeBcSupported ( EFI_STATUS Status; EFI_GUID *DhcpServiceBindingGuid; EFI_GUID *MtftpServiceBindingGuid; - + if (IpVersion == IP_VERSION_4) { DhcpServiceBindingGuid = &gEfiDhcp4ServiceBindingProtocolGuid; MtftpServiceBindingGuid = &gEfiMtftp4ServiceBindingProtocolGuid; @@ -1306,7 +1442,7 @@ PxeBcStart ( // // Install PxeBaseCodePrivate protocol onto the real NIC handler. - // PxeBaseCodePrivate protocol is only used to keep the relationship between + // PxeBaseCodePrivate protocol is only used to keep the relationship between // NIC handle and virtual child handles. // gEfiCallerIdGuid will be used as its protocol guid. // @@ -1323,7 +1459,7 @@ PxeBcStart ( // // Try to locate SNP protocol. // - NetLibGetSnpHandle(ControllerHandle, &Private->Snp); + NetLibGetSnpHandle(ControllerHandle, &Private->Snp); } if (IpVersion == IP_VERSION_4) {