+/**\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