]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.c
Retire NetLibQueueDpc() and NetLibDispatchDpc() and use QueueDpc() and DispatchDpc...
[mirror_edk2.git] / MdeModulePkg / Universal / Network / UefiPxeBcDxe / PxeBcImpl.c
index bed82ae21cff71f2cd27bfa31c81bfb0b472cd57..3eeacdcc5c8065c51c56213b5a7dee9d9fb03db0 100644 (file)
@@ -1,7 +1,7 @@
 /** @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
@@ -15,7 +15,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \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
@@ -84,8 +84,6 @@ UpdateArpCache (
 \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
@@ -139,8 +137,6 @@ FindInArpCache (
 \r
   @param  Context               The PXEBC private data.\r
 \r
-  @return None.\r
-\r
 **/\r
 VOID\r
 EFIAPI\r
@@ -233,8 +229,6 @@ Resume:
   @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
@@ -246,7 +240,7 @@ IcmpErrorListenHandler (
   //\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
@@ -479,7 +473,7 @@ EfiPxeBcStop (
   // 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
@@ -502,6 +496,7 @@ EfiPxeBcStop (
 \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
@@ -560,8 +555,6 @@ EfiPxeBcDhcp (
   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
@@ -589,85 +582,62 @@ EfiPxeBcDhcp (
 \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
+  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->Configure (Dhcp4, &Dhcp4CfgData);\r
-    if (EFI_ERROR (Status)) {\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
-    //\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
+    goto ON_EXIT;\r
+  }\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
-    }\r
+  Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4Mode);\r
+  if (EFI_ERROR (Status)) {\r
+    goto ON_EXIT;\r
+  }\r
 \r
-    Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4Mode);\r
-    if (EFI_ERROR (Status)) {\r
-      break;\r
-    }\r
+  ASSERT (Dhcp4Mode.State == Dhcp4Bound);\r
 \r
-    ASSERT (Dhcp4Mode.State == Dhcp4Bound);\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 (\r
-      &Private->StationIp, \r
-      &Dhcp4Mode.ClientAddress, \r
-      sizeof (EFI_IPv4_ADDRESS)\r
-      );\r
-    CopyMem (\r
-      &Private->SubnetMask, \r
-      &Dhcp4Mode.SubnetMask, \r
-      sizeof (EFI_IPv4_ADDRESS)\r
-      );\r
-    CopyMem (\r
-      &Private->GatewayIp, \r
-      &Dhcp4Mode.RouterAddress, \r
-      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
 \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
@@ -1138,10 +1108,6 @@ EfiPxeBcMtftp (
               BufferSize\r
               );\r
 \r
-    if (!EFI_ERROR (Status)) {\r
-      Status = EFI_BUFFER_TOO_SMALL;\r
-    }\r
-\r
     break;\r
 \r
   case EFI_PXE_BASE_CODE_TFTP_READ_FILE:\r
@@ -1460,6 +1426,8 @@ CheckIpByFilter (
     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
@@ -1603,9 +1571,10 @@ TRY_AGAIN:
     RxData  = Token.Packet.RxData;\r
     Session = &RxData->UdpSession;\r
 \r
-    Matched = FALSE;\r
+    Matched = TRUE;\r
 \r
     if ((OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER) != 0) {\r
+      Matched = FALSE;\r
       //\r
       // Check UDP package by IP filter settings\r
       //\r
@@ -1782,20 +1751,20 @@ EfiPxeBcSetIpFilter (
   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
@@ -1805,6 +1774,7 @@ EfiPxeBcSetIpFilter (
   }\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
@@ -2509,16 +2479,24 @@ DiscoverBootFile (
     Packet = &Private->Dhcp4Ack;\r
   }\r
 \r
-  CopyMem (&Private->ServerIp, &Packet->Packet.Offer.Dhcp4.Header.ServerAddr, sizeof (EFI_IPv4_ADDRESS));\r
-  if (Private->ServerIp.Addr[0] == 0) {\r
-    //\r
-    // next server ip address is zero, use option 54 instead\r
-    //\r
+  //\r
+  // use option 54, if zero, use siaddr in header\r
+  //\r
+  if (Packet->Dhcp4Option[PXEBC_DHCP4_TAG_INDEX_SERVER_ID] != NULL) {\r
     CopyMem (\r
       &Private->ServerIp,\r
       Packet->Dhcp4Option[PXEBC_DHCP4_TAG_INDEX_SERVER_ID]->Data,\r
       sizeof (EFI_IPv4_ADDRESS)\r
       );\r
+  } else {\r
+    CopyMem (\r
+      &Private->ServerIp, \r
+      &Packet->Packet.Offer.Dhcp4.Header.ServerAddr, \r
+      sizeof (EFI_IPv4_ADDRESS)\r
+      );\r
+  }\r
+  if (Private->ServerIp.Addr[0] == 0) {\r
+    return EFI_DEVICE_ERROR;\r
   }\r
 \r
   ASSERT (Packet->Dhcp4Option[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] != NULL);\r
@@ -2658,10 +2636,25 @@ EfiPxeLoadFile (
 \r
     if (sizeof (UINTN) < sizeof (UINT64) && (TmpBufSize > 0xFFFFFFFF)) {\r
       Status = EFI_DEVICE_ERROR;\r
-    } else {\r
+    } else if (TmpBufSize > 0 && *BufferSize >= (UINTN) TmpBufSize && Buffer != NULL) {\r
+      *BufferSize = (UINTN) TmpBufSize;\r
+      Status = PxeBc->Mtftp (\r
+                        PxeBc,\r
+                        EFI_PXE_BASE_CODE_TFTP_READ_FILE,\r
+                        Buffer,\r
+                        FALSE,\r
+                        &TmpBufSize,\r
+                        &BlockSize,\r
+                        &Private->ServerIp,\r
+                        (UINT8 *) Private->BootFileName,\r
+                        NULL,\r
+                        FALSE\r
+                        );\r
+    } else if (TmpBufSize > 0) {\r
       *BufferSize = (UINTN) TmpBufSize;\r
+      Status      = EFI_BUFFER_TOO_SMALL;\r
     }\r
-  } else if (Buffer == NULL) {\r
+  } else if (Buffer == NULL || Private->FileSize > *BufferSize) {\r
     *BufferSize = Private->FileSize;\r
     Status      = EFI_BUFFER_TOO_SMALL;\r
   } else {\r
@@ -2744,3 +2737,5 @@ EfiPxeLoadFile (
   return Status;\r
 }\r
 \r
+EFI_LOAD_FILE_PROTOCOL  mLoadFileProtocolTemplate = { EfiPxeLoadFile };\r
+\r