/** @file\r
This EFI_DHCP6_PROTOCOL interface implementation.\r
\r
- Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2009 - 2017, 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
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
}\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
\r
Instance->UdpSts = EFI_ALREADY_STARTED;\r
Status = Dhcp6SendReleaseMsg (Instance, Instance->IaCb.Ia);\r
+ gBS->RestoreTPL (OldTpl);\r
if (EFI_ERROR (Status)) {\r
goto ON_EXIT;\r
}\r
\r
- gBS->RestoreTPL (OldTpl);\r
-\r
//\r
// Poll udp out of the net tpl if synchoronus call.\r
//\r
)\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
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
+ 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->CloseEvent (Timer);\r
+ }\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
}\r
-\r
- gBS->RestoreTPL (OldTpl);\r
\r
//\r
// Poll udp out of the net tpl if synchoronus call.\r
}\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