]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/UefiPxeBcDxe/PxeBcDriver.c
Add IPV6 support from UNDI
[mirror_edk2.git] / NetworkPkg / UefiPxeBcDxe / PxeBcDriver.c
index 92fd1f19df64bc9ebbf972a58dcc96adb7a5b306..c2987b8734a8986cbba9e0e776ca08842fa919ab 100644 (file)
@@ -2,7 +2,7 @@
   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 - 2015, 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
@@ -442,6 +442,103 @@ PxeBcDestroyIp6Children (
   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
@@ -1057,7 +1154,18 @@ PxeBcCreateIp6Children (
   // 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