/** @file\r
Interface routines for PxeBc.\r
\r
-Copyright (c) 2007 - 2008, Intel Corporation.<BR>\r
+Copyright (c) 2007 - 2009, Intel Corporation.<BR>\r
All rights reserved. This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
\r
#include "PxeBcImpl.h"\r
\r
-EFI_LOAD_FILE_PROTOCOL mLoadFileProtocolTemplate = { EfiPxeLoadFile };\r
+UINT32 mPxeDhcpTimeout[4] = { 4, 8, 16, 32 };\r
\r
/**\r
Get and record the arp cache.\r
\r
@param Event Pointer to EFI_PXE_BC_PROTOCOL\r
@param Context Context of the timer event\r
- \r
- @return None.\r
\r
**/\r
VOID\r
\r
@param Context The PXEBC private data.\r
\r
- @return None.\r
-\r
**/\r
VOID\r
EFIAPI\r
@param Event The event signaled.\r
@param Context The context passed in by the event notifier.\r
\r
- @return None.\r
-\r
**/\r
VOID\r
EFIAPI\r
//\r
// Request IpIoListenHandlerDpc as a DPC at TPL_CALLBACK\r
//\r
- NetLibQueueDpc (TPL_CALLBACK, IcmpErrorListenHandlerDpc, Context);\r
+ QueueDpc (TPL_CALLBACK, IcmpErrorListenHandlerDpc, Context);\r
}\r
\r
/** \r
// Dispatch the DPCs queued by the NotifyFunction of the canceled rx token's\r
// events.\r
//\r
- NetLibDispatchDpc ();\r
+ DispatchDpc ();\r
\r
Private->Ip4->Configure (Private->Ip4, NULL);\r
\r
\r
Private->CurrentUdpSrcPort = 0;\r
Private->Udp4Write->Configure (Private->Udp4Write, NULL);\r
+ Private->Udp4Read->Groups (Private->Udp4Read, FALSE, NULL);\r
Private->Udp4Read->Configure (Private->Udp4Read, NULL);\r
\r
Private->Dhcp4->Stop (Private->Dhcp4);\r
EFI_DHCP4_MODE_DATA Dhcp4Mode;\r
EFI_DHCP4_PACKET_OPTION *OptList[PXEBC_DHCP4_MAX_OPTION_NUM];\r
UINT32 OptCount;\r
- UINT32 DiscoverTimeout;\r
- UINTN Index;\r
EFI_STATUS Status;\r
EFI_ARP_CONFIG_DATA ArpConfigData;\r
\r
\r
//\r
// Set the DHCP4 config data.\r
+ // The four discovery timeouts are 4, 8, 16, 32 seconds respectively.\r
//\r
ZeroMem (&Dhcp4CfgData, sizeof (EFI_DHCP4_CONFIG_DATA));\r
Dhcp4CfgData.OptionCount = OptCount;\r
Dhcp4CfgData.OptionList = OptList;\r
Dhcp4CfgData.Dhcp4Callback = PxeBcDhcpCallBack;\r
Dhcp4CfgData.CallbackContext = Private;\r
- Dhcp4CfgData.DiscoverTryCount = 1;\r
- Dhcp4CfgData.DiscoverTimeout = &DiscoverTimeout;\r
+ Dhcp4CfgData.DiscoverTryCount = 4;\r
+ Dhcp4CfgData.DiscoverTimeout = mPxeDhcpTimeout;\r
\r
- for (Index = 0; Index < PXEBC_DHCP4_DISCOVER_RETRIES; Index++) {\r
- //\r
- // The four discovery timeouts are 4, 8, 16, 32 seconds respectively.\r
- //\r
- DiscoverTimeout = (PXEBC_DHCP4_DISCOVER_INIT_TIMEOUT << Index);\r
-\r
- Status = Dhcp4->Configure (Dhcp4, &Dhcp4CfgData);\r
- if (EFI_ERROR (Status)) {\r
- break;\r
- }\r
- //\r
- // Zero those arrays to record the varies numbers of DHCP OFFERS.\r
- //\r
- Private->GotProxyOffer = FALSE;\r
- Private->NumOffers = 0;\r
- Private->BootpIndex = 0;\r
- ZeroMem (Private->ServerCount, sizeof (Private->ServerCount));\r
- ZeroMem (Private->ProxyIndex, sizeof (Private->ProxyIndex));\r
+ Status = Dhcp4->Configure (Dhcp4, &Dhcp4CfgData);\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+ \r
+ //\r
+ // Zero those arrays to record the varies numbers of DHCP OFFERS.\r
+ //\r
+ Private->GotProxyOffer = FALSE;\r
+ Private->NumOffers = 0;\r
+ Private->BootpIndex = 0;\r
+ ZeroMem (Private->ServerCount, sizeof (Private->ServerCount));\r
+ ZeroMem (Private->ProxyIndex, sizeof (Private->ProxyIndex));\r
\r
- Status = Dhcp4->Start (Dhcp4, NULL);\r
- if (EFI_ERROR (Status)) {\r
- if (Status == EFI_TIMEOUT) {\r
- //\r
- // If no response is received or all received offers don't match\r
- // the PXE boot requirements, EFI_TIMEOUT will be returned.\r
- //\r
- continue;\r
- }\r
- if (Status == EFI_ICMP_ERROR) {\r
- Mode->IcmpErrorReceived = TRUE;\r
- }\r
- //\r
- // Other error status means the DHCP really fails.\r
- //\r
- break;\r
+ Status = Dhcp4->Start (Dhcp4, NULL);\r
+ if (EFI_ERROR (Status)) {\r
+ if (Status == EFI_ICMP_ERROR) {\r
+ Mode->IcmpErrorReceived = TRUE;\r
}\r
+ goto ON_EXIT;\r
+ }\r
\r
- Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4Mode);\r
- if (EFI_ERROR (Status)) {\r
- break;\r
- }\r
+ Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4Mode);\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
\r
- ASSERT (Dhcp4Mode.State == Dhcp4Bound);\r
+ ASSERT (Dhcp4Mode.State == Dhcp4Bound);\r
\r
- CopyMem (&Private->StationIp, &Dhcp4Mode.ClientAddress, sizeof (EFI_IPv4_ADDRESS));\r
- CopyMem (&Private->SubnetMask, &Dhcp4Mode.SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
- CopyMem (&Private->GatewayIp, &Dhcp4Mode.RouterAddress, sizeof (EFI_IPv4_ADDRESS));\r
+ CopyMem (&Private->StationIp, &Dhcp4Mode.ClientAddress, sizeof (EFI_IPv4_ADDRESS));\r
+ CopyMem (&Private->SubnetMask, &Dhcp4Mode.SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
+ CopyMem (&Private->GatewayIp, &Dhcp4Mode.RouterAddress, sizeof (EFI_IPv4_ADDRESS));\r
\r
- CopyMem (&Mode->StationIp, &Private->StationIp, sizeof (EFI_IPv4_ADDRESS));\r
- CopyMem (&Mode->SubnetMask, &Private->SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
+ CopyMem (&Mode->StationIp, &Private->StationIp, sizeof (EFI_IPv4_ADDRESS));\r
+ CopyMem (&Mode->SubnetMask, &Private->SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
\r
- //\r
- // Check the selected offer to see whether BINL is required, if no or BINL is\r
- // finished, set the various Mode members.\r
- //\r
- Status = PxeBcCheckSelectedOffer (Private);\r
- if (!EFI_ERROR (Status)) {\r
- break;\r
- }\r
+ //\r
+ // Check the selected offer to see whether BINL is required, if no or BINL is\r
+ // finished, set the various Mode members.\r
+ //\r
+ Status = PxeBcCheckSelectedOffer (Private);\r
+ if (!EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
}\r
\r
+ON_EXIT:\r
if (EFI_ERROR (Status)) {\r
Dhcp4->Stop (Dhcp4);\r
Dhcp4->Configure (Dhcp4, NULL);\r
return TRUE;\r
}\r
\r
+ ASSERT (PxeBcMode->IpFilter.IpCnt < EFI_PXE_BASE_CODE_MAX_IPCNT);\r
+\r
for (Index = 0; Index < PxeBcMode->IpFilter.IpCnt; Index++) {\r
CopyMem (\r
&Ip4Address, \r
BOOLEAN PromiscuousNeed;\r
\r
if (This == NULL) {\r
- DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL.\n"));\r
+ DEBUG ((EFI_D_ERROR, "This == NULL.\n"));\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);\r
Mode = Private->PxeBc.Mode;\r
\r
- if (Private == NULL) {\r
- DEBUG ((EFI_D_ERROR, "PXEBC_PRIVATE_DATA poiner == NULL.\n"));\r
+ if (NewFilter == NULL) {\r
+ DEBUG ((EFI_D_ERROR, "NewFilter == NULL.\n"));\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- if (NewFilter == NULL) {\r
- DEBUG ((EFI_D_ERROR, "IP Filter *NewFilter == NULL.\n"));\r
+ if (NewFilter->IpCnt > EFI_PXE_BASE_CODE_MAX_IPCNT) {\r
+ DEBUG ((EFI_D_ERROR, "NewFilter->IpCnt > %d.\n", EFI_PXE_BASE_CODE_MAX_IPCNT));\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
}\r
\r
PromiscuousNeed = FALSE;\r
+\r
for (Index = 0; Index < NewFilter->IpCnt; ++Index) {\r
if (IP4_IS_LOCAL_BROADCAST (EFI_IP4 (NewFilter->IpList[Index].v4))) {\r
//\r
}\r
\r
//\r
- // use option 54, if zero, use siaddr in header\r
+ // Use siaddr(next server) in DHCPOFFER packet header, if zero, use option 54(server identifier)\r
+ // in DHCPOFFER packet.\r
+ // (It does not comply with PXE Spec, Ver2.1)\r
//\r
- if (Packet->Dhcp4Option[PXEBC_DHCP4_TAG_INDEX_SERVER_ID] != NULL) {\r
+ if (EFI_IP4_EQUAL (&Packet->Packet.Offer.Dhcp4.Header.ServerAddr, &mZeroIp4Addr)) {\r
CopyMem (\r
&Private->ServerIp,\r
Packet->Dhcp4Option[PXEBC_DHCP4_TAG_INDEX_SERVER_ID]->Data,\r
\r
if (sizeof (UINTN) < sizeof (UINT64) && (TmpBufSize > 0xFFFFFFFF)) {\r
Status = EFI_DEVICE_ERROR;\r
- } else if (*BufferSize >= (UINTN) TmpBufSize && Buffer != NULL) {\r
+ } else if (TmpBufSize > 0 && *BufferSize >= (UINTN) TmpBufSize && Buffer != NULL) {\r
*BufferSize = (UINTN) TmpBufSize;\r
Status = PxeBc->Mtftp (\r
PxeBc,\r
NULL,\r
FALSE\r
);\r
- } else {\r
+ } else if (TmpBufSize > 0) {\r
*BufferSize = (UINTN) TmpBufSize;\r
Status = EFI_BUFFER_TOO_SMALL;\r
}\r
return Status;\r
}\r
\r
+EFI_LOAD_FILE_PROTOCOL mLoadFileProtocolTemplate = { EfiPxeLoadFile };\r
+\r