]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/Dhcp6Dxe/Dhcp6Impl.c
BaseTools/GenFw: Disable support for R_X86_64_32S
[mirror_edk2.git] / NetworkPkg / Dhcp6Dxe / Dhcp6Impl.c
index 3e73976ddb6a1fda2a9ede6d09f389b3d2530b0d..9ace833b98f7a922e6dc27990ee61bfc69029f23 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   This EFI_DHCP6_PROTOCOL interface implementation.\r
 \r
-  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2009 - 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
@@ -76,6 +76,7 @@ EfiDhcp6Start (
   EFI_TPL                      OldTpl;\r
   DHCP6_INSTANCE               *Instance;\r
   DHCP6_SERVICE                *Service;\r
+  EFI_STATUS                   MediaStatus;\r
 \r
   if (This == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -101,13 +102,18 @@ EfiDhcp6Start (
   }\r
 \r
   OldTpl           = gBS->RaiseTPL (TPL_CALLBACK);\r
-  Instance->UdpSts = EFI_ALREADY_STARTED;\r
 \r
   //\r
-  // Need to clear initial time to make sure that elapsed-time\r
-  // is set to 0 for first Solicit.\r
+  // Check Media Satus.\r
   //\r
-  Instance->StartTime = 0;\r
+  MediaStatus = EFI_SUCCESS;\r
+  NetLibDetectMediaWaitTimeout (Service->Controller, DHCP_CHECK_MEDIA_WAITING_TIME, &MediaStatus);\r
+  if (MediaStatus != EFI_SUCCESS) {\r
+    Status = EFI_NO_MEDIA;\r
+    goto ON_ERROR;\r
+  }\r
+\r
+  Instance->UdpSts = EFI_ALREADY_STARTED;\r
 \r
   //\r
   // Send the solicit message to start S.A.R.R process.\r
@@ -200,13 +206,13 @@ EfiDhcp6Stop (
   ASSERT (Instance->IaCb.Ia != NULL);\r
 \r
   //\r
-  // The instance has already been stopped.\r
+  // No valid REPLY message received yet, cleanup this instance directly.\r
   //\r
   if (Instance->IaCb.Ia->State == Dhcp6Init ||\r
       Instance->IaCb.Ia->State == Dhcp6Selecting ||\r
       Instance->IaCb.Ia->State == Dhcp6Requesting\r
       ) {\r
-    return Status;\r
+    goto ON_EXIT;\r
   }\r
 \r
   //\r
@@ -215,9 +221,11 @@ EfiDhcp6Stop (
   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
   Instance->UdpSts = EFI_ALREADY_STARTED;\r
-  Dhcp6SendReleaseMsg (Instance, Instance->IaCb.Ia);\r
-\r
+  Status = Dhcp6SendReleaseMsg (Instance, Instance->IaCb.Ia);\r
   gBS->RestoreTPL (OldTpl);\r
+  if (EFI_ERROR (Status)) {\r
+    goto ON_EXIT;\r
+  }\r
 \r
   //\r
   // Poll udp out of the net tpl if synchoronus call.\r
@@ -230,6 +238,7 @@ EfiDhcp6Stop (
     Status = Instance->UdpSts;\r
   }\r
 \r
+ON_EXIT:\r
   //\r
   // Clean up the session data for the released Ia.\r
   //\r
@@ -604,11 +613,12 @@ EfiDhcp6InfoRequest (
   )\r
 {\r
   EFI_STATUS                   Status;\r
-  EFI_TPL                      OldTpl;\r
   DHCP6_INSTANCE               *Instance;\r
   DHCP6_SERVICE                *Service;\r
-  DHCP6_INF_CB                 *InfCb;\r
   UINTN                        Index;\r
+  EFI_EVENT                    Timer;\r
+  EFI_STATUS                   TimerStatus;\r
+  UINTN                        GetMappingTimeOut;\r
 \r
   if (This == NULL || OptionRequest == NULL || Retransmission == NULL || ReplyCallback == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -633,57 +643,63 @@ EfiDhcp6InfoRequest (
   Instance = DHCP6_INSTANCE_FROM_THIS (This);\r
   Service  = Instance->Service;\r
 \r
-  OldTpl           = gBS->RaiseTPL (TPL_CALLBACK);\r
-  Instance->UdpSts = EFI_ALREADY_STARTED;\r
-\r
-  //\r
-  // Create and initialize the control block for the info-request.\r
-  //\r
-  InfCb = AllocateZeroPool (sizeof(DHCP6_INF_CB));\r
-\r
-  if (InfCb == NULL) {\r
-    gBS->RestoreTPL (OldTpl);\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  InfCb->ReplyCallback   = ReplyCallback;\r
-  InfCb->CallbackContext = CallbackContext;\r
-  InfCb->TimeoutEvent    = TimeoutEvent;\r
-\r
-  InsertTailList (&Instance->InfList, &InfCb->Link);\r
-\r
-  //\r
-  // Send the info-request message to start exchange process.\r
-  //\r
-  Status = Dhcp6SendInfoRequestMsg (\r
+  Status = Dhcp6StartInfoRequest (\r
              Instance,\r
-             InfCb,\r
              SendClientId,\r
              OptionRequest,\r
              OptionCount,\r
              OptionList,\r
-             Retransmission\r
+             Retransmission,\r
+             TimeoutEvent,\r
+             ReplyCallback,\r
+             CallbackContext\r
              );\r
+  if (Status == EFI_NO_MAPPING) {\r
+    //\r
+    // The link local address is not ready, wait for some time and restart\r
+    // the DHCP6 information request process.\r
+    //\r
+    Status = Dhcp6GetMappingTimeOut(Service->Ip6Cfg, &GetMappingTimeOut);\r
+    if (EFI_ERROR(Status)) {\r
+      return Status;\r
+    }\r
 \r
-  if (EFI_ERROR (Status)) {\r
-    goto ON_ERROR;\r
-  }\r
+    Status = gBS->CreateEvent (EVT_TIMER, TPL_CALLBACK, NULL, NULL, &Timer);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
 \r
-  //\r
-  // Register receive callback for the stateless exchange process.\r
-  //\r
-  Status = UdpIoRecvDatagram(\r
-             Service->UdpIo,\r
-             Dhcp6ReceivePacket,\r
-             Service,\r
-             0\r
-             );\r
+    //\r
+    // Start the timer, wait for link local address DAD to finish.\r
+    //\r
+    Status = gBS->SetTimer (Timer, TimerRelative, GetMappingTimeOut);\r
+    if (EFI_ERROR (Status)) {\r
+      gBS->CloseEvent (Timer);\r
+      return Status;\r
+    }\r
 \r
-  if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {\r
-    goto ON_ERROR;\r
-  }\r
+    do {\r
+      TimerStatus = gBS->CheckEvent (Timer);\r
+      if (!EFI_ERROR (TimerStatus)) {\r
+        Status = Dhcp6StartInfoRequest (\r
+                   Instance,\r
+                   SendClientId,\r
+                   OptionRequest,\r
+                   OptionCount,\r
+                   OptionList,\r
+                   Retransmission,\r
+                   TimeoutEvent,\r
+                   ReplyCallback,\r
+                   CallbackContext\r
+                   );\r
+      }\r
+    } while (TimerStatus == EFI_NOT_READY);\r
 \r
-  gBS->RestoreTPL (OldTpl);\r
+    gBS->CloseEvent (Timer);\r
+  }\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
   //\r
   // Poll udp out of the net tpl if synchoronus call.\r
@@ -697,14 +713,6 @@ EfiDhcp6InfoRequest (
   }\r
 \r
   return EFI_SUCCESS;\r
-\r
-ON_ERROR:\r
-\r
-  RemoveEntryList (&InfCb->Link);\r
-  FreePool (InfCb);\r
-  gBS->RestoreTPL (OldTpl);\r
-\r
-  return Status;\r
 }\r
 \r
 \r