]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/ArpDxe/ArpMain.c
Roll back the DEBUG mask change which cause SerialIo read_conf test item failure.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / ArpDxe / ArpMain.c
index eb1b082a21c0b2b9f39eb5976f0e1c83a348bd40..ac76fcd6324917747c2778b8ad80a39e4f754e59 100644 (file)
@@ -1,21 +1,15 @@
 /** @file\r
-\r
-Copyright (c) 2006, Intel Corporation\r
+  Implementation of EFI Address Resolution Protocol (ARP) Protocol interface functions.\r
+  \r
+Copyright (c) 2006, 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
+which accompanies this distribution.  The full text of the license may be found at<BR>\r
 http://opensource.org/licenses/bsd-license.php\r
 \r
 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
-Module Name:\r
-\r
-  ArpMain.c\r
-\r
-Abstract:\r
-\r
-\r
 **/\r
 \r
 #include "ArpImpl.h"\r
@@ -23,8 +17,15 @@ Abstract:
 \r
 /**\r
   This function is used to assign a station address to the ARP cache for this instance\r
-  of the ARP driver. A call to this function with the ConfigData field set to NULL\r
-  will reset this ARP instance.\r
+  of the ARP driver.\r
+  \r
+  Each ARP instance has one station address. The EFI_ARP_PROTOCOL driver will \r
+  respond to ARP requests that match this registered station address. A call to \r
+  this function with the ConfigData field set to NULL will reset this ARP instance.\r
+  \r
+  Once a protocol type and station address have been assigned to this ARP instance, \r
+  all the following ARP functions will use this information. Attempting to change \r
+  the protocol type or station address to a configured ARP instance will result in errors.\r
 \r
   @param  This                   Pointer to the EFI_ARP_PROTOCOL instance.\r
   @param  ConfigData             Pointer to the EFI_ARP_CONFIG_DATA structure.\r
@@ -51,6 +52,7 @@ ArpConfigure (
 {\r
   EFI_STATUS         Status;\r
   ARP_INSTANCE_DATA  *Instance;\r
+  EFI_TPL            OldTpl;\r
 \r
   if (This == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -65,16 +67,14 @@ ArpConfigure (
 \r
   Instance = ARP_INSTANCE_DATA_FROM_THIS (This);\r
 \r
-  if (EFI_ERROR (NET_TRYLOCK (&Instance->ArpService->Lock))) {\r
-    return EFI_ACCESS_DENIED;\r
-  }\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
   //\r
   // Configure this instance, the ConfigData has already passed the basic checks.\r
   //\r
   Status = ArpConfigureInstance (Instance, ConfigData);\r
 \r
-  NET_UNLOCK (&Instance->ArpService->Lock);\r
+  gBS->RestoreTPL (OldTpl);\r
 \r
   return Status;\r
 }\r
@@ -83,6 +83,17 @@ ArpConfigure (
 /**\r
   This function is used to insert entries into the ARP cache.\r
 \r
+  ARP cache entries are typically inserted and updated by network protocol drivers \r
+  as network traffic is processed. Most ARP cache entries will time out and be \r
+  deleted if the network traffic stops. ARP cache entries that were inserted \r
+  by the Add() function may be static (will not time out) or dynamic (will time out).\r
+  Default ARP cache timeout values are not covered in most network protocol \r
+  specifications (although RFC 1122 comes pretty close) and will only be \r
+  discussed in general in this specification. The timeout values that are \r
+  used in the EFI Sample Implementation should be used only as a guideline. \r
+  Final product implementations of the EFI network stack should be tuned for \r
+  their expected network environments.\r
+  \r
   @param  This                   Pointer to the EFI_ARP_PROTOCOL instance.\r
   @param  DenyFlag               Set to TRUE if this entry is a deny entry. Set to\r
                                  FALSE if this  entry is a normal entry.\r
@@ -131,6 +142,7 @@ ArpAdd (
   ARP_CACHE_ENTRY          *CacheEntry;\r
   EFI_SIMPLE_NETWORK_MODE  *SnpMode;\r
   NET_ARP_ADDRESS          MatchAddress[2];\r
+  EFI_TPL                  OldTpl;\r
 \r
   if (This == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -166,9 +178,7 @@ ArpAdd (
   MatchAddress[Protocol].Length     = Instance->ConfigData.SwAddressLength;\r
   MatchAddress[Protocol].AddressPtr = TargetSwAddress;\r
 \r
-  if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) {\r
-    return EFI_ACCESS_DENIED;\r
-  }\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
   //\r
   // See whether the entry to add exists. Check the DeinedCacheTable first.\r
@@ -217,7 +227,7 @@ ArpAdd (
     //\r
     // Remove it from the Table.\r
     //\r
-    NetListRemoveEntry (&CacheEntry->List);\r
+    RemoveEntryList (&CacheEntry->List);\r
   } else {\r
     //\r
     // It's a new entry, allocate memory for the entry.\r
@@ -225,7 +235,7 @@ ArpAdd (
     CacheEntry = ArpAllocCacheEntry (Instance);\r
 \r
     if (CacheEntry == NULL) {\r
-      ARP_DEBUG_ERROR (("ArpAdd: Failed to allocate pool for CacheEntry.\n"));\r
+      DEBUG ((EFI_D_ERROR, "ArpAdd: Failed to allocate pool for CacheEntry.\n"));\r
       Status = EFI_OUT_OF_RESOURCES;\r
       goto UNLOCK_EXIT;\r
     }\r
@@ -255,14 +265,14 @@ ArpAdd (
   // Add this CacheEntry to the corresponding CacheTable.\r
   //\r
   if (DenyFlag) {\r
-    NetListInsertHead (&ArpService->DeniedCacheTable, &CacheEntry->List);\r
+    InsertHeadList (&ArpService->DeniedCacheTable, &CacheEntry->List);\r
   } else {\r
-    NetListInsertHead (&ArpService->ResolvedCacheTable, &CacheEntry->List);\r
+    InsertHeadList (&ArpService->ResolvedCacheTable, &CacheEntry->List);\r
   }\r
 \r
 UNLOCK_EXIT:\r
 \r
-  NET_UNLOCK (&ArpService->Lock);\r
+  gBS->RestoreTPL (OldTpl);\r
 \r
   return Status;\r
 }\r
@@ -271,7 +281,14 @@ UNLOCK_EXIT:
 /**\r
   This function searches the ARP cache for matching entries and allocates a buffer into\r
   which those entries are copied.\r
-\r
+  \r
+  The first part of the allocated buffer is EFI_ARP_FIND_DATA, following which \r
+  are protocol address pairs and hardware address pairs.\r
+  When finding a specific protocol address (BySwAddress is TRUE and AddressBuffer \r
+  is not NULL), the ARP cache timeout for the found entry is reset if Refresh is \r
+  set to TRUE. If the found ARP cache entry is a permanent entry, it is not \r
+  affected by Refresh.\r
+  \r
   @param  This                   Pointer to the EFI_ARP_PROTOCOL instance.\r
   @param  BySwAddress            Set to TRUE to look for matching software protocol\r
                                  addresses. Set to FALSE to look for matching\r
@@ -309,7 +326,7 @@ ArpFind (
 {\r
   EFI_STATUS         Status;\r
   ARP_INSTANCE_DATA  *Instance;\r
-  ARP_SERVICE_DATA   *ArpService;\r
+  EFI_TPL            OldTpl;\r
 \r
   if ((This == NULL) ||\r
     (!Refresh && (EntryCount == NULL) && (EntryLength == NULL)) ||\r
@@ -318,15 +335,12 @@ ArpFind (
   }\r
 \r
   Instance   = ARP_INSTANCE_DATA_FROM_THIS (This);\r
-  ArpService = Instance->ArpService;\r
 \r
   if (!Instance->Configured) {\r
     return EFI_NOT_STARTED;\r
   }\r
 \r
-  if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) {\r
-    return EFI_ACCESS_DENIED;\r
-  }\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
   //\r
   // All the check passed, find the cache entries now.\r
@@ -341,7 +355,7 @@ ArpFind (
              Refresh\r
              );\r
 \r
-  NET_UNLOCK (&ArpService->Lock);\r
+  gBS->RestoreTPL (OldTpl);\r
 \r
   return Status;\r
 }\r
@@ -373,8 +387,8 @@ ArpDelete (
   )\r
 {\r
   ARP_INSTANCE_DATA  *Instance;\r
-  ARP_SERVICE_DATA   *ArpService;\r
   UINTN              Count;\r
+  EFI_TPL            OldTpl;\r
 \r
   if (This == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -386,18 +400,14 @@ ArpDelete (
     return EFI_NOT_STARTED;\r
   }\r
 \r
-  ArpService = Instance->ArpService;\r
-\r
-  if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) {\r
-    return EFI_ACCESS_DENIED;\r
-  }\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
   //\r
   // Delete the specified cache entries.\r
   //\r
   Count = ArpDeleteCacheEntry (Instance, BySwAddress, AddressBuffer, TRUE);\r
 \r
-  NET_UNLOCK (&ArpService->Lock);\r
+  gBS->RestoreTPL (OldTpl);\r
 \r
   return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS;\r
 }\r
@@ -422,8 +432,8 @@ ArpFlush (
   )\r
 {\r
   ARP_INSTANCE_DATA  *Instance;\r
-  ARP_SERVICE_DATA   *ArpService;\r
   UINTN              Count;\r
+  EFI_TPL            OldTpl;\r
 \r
   if (This == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -435,18 +445,14 @@ ArpFlush (
     return EFI_NOT_STARTED;\r
   }\r
 \r
-  ArpService = Instance->ArpService;\r
-\r
-  if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) {\r
-    return EFI_ACCESS_DENIED;\r
-  }\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
   //\r
   // Delete the dynamic entries from the cache table.\r
   //\r
   Count = ArpDeleteCacheEntry (Instance, FALSE, NULL, FALSE);\r
 \r
-  NET_UNLOCK (&ArpService->Lock);\r
+  gBS->RestoreTPL (OldTpl);\r
 \r
   return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS;\r
 }\r
@@ -491,6 +497,7 @@ ArpRequest (
   NET_ARP_ADDRESS          HardwareAddress;\r
   NET_ARP_ADDRESS          ProtocolAddress;\r
   USER_REQUEST_CONTEXT     *RequestContext;\r
+  EFI_TPL                  OldTpl;\r
 \r
   if ((This == NULL) || (TargetHwAddress == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -507,17 +514,17 @@ ArpRequest (
   SnpMode    = &ArpService->SnpMode;\r
 \r
   if ((TargetSwAddress == NULL) ||\r
-    ((Instance->ConfigData.SwAddressType == IPv4_ETHER_PROTO_TYPE) &&\r
+    ((Instance->ConfigData.SwAddressType == IPV4_ETHER_PROTO_TYPE) &&\r
     IP4_IS_LOCAL_BROADCAST (*((UINT32 *)TargetSwAddress)))) {\r
     //\r
     // Return the hardware broadcast address.\r
     //\r
-    NetCopyMem (TargetHwAddress, &SnpMode->BroadcastAddress, SnpMode->HwAddressSize);\r
+    CopyMem (TargetHwAddress, &SnpMode->BroadcastAddress, SnpMode->HwAddressSize);\r
 \r
     goto SIGNAL_USER;\r
   }\r
 \r
-  if ((Instance->ConfigData.SwAddressType == IPv4_ETHER_PROTO_TYPE) &&\r
+  if ((Instance->ConfigData.SwAddressType == IPV4_ETHER_PROTO_TYPE) &&\r
     IP4_IS_MULTICAST (NTOHL (*((UINT32 *)TargetSwAddress)))) {\r
     //\r
     // If the software address is an IPv4 multicast address, invoke Mnp to\r
@@ -543,11 +550,9 @@ ArpRequest (
   //\r
   // Initialize the TargetHwAddrss to a zero address.\r
   //\r
-  NetZeroMem (TargetHwAddress, SnpMode->HwAddressSize);\r
+  ZeroMem (TargetHwAddress, SnpMode->HwAddressSize);\r
 \r
-  if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) {\r
-    return EFI_ACCESS_DENIED;\r
-  }\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
   //\r
   // Check whether the software address is in the denied table.\r
@@ -572,7 +577,7 @@ ArpRequest (
     //\r
     // Resolved, copy the address into the user buffer.\r
     //\r
-    NetCopyMem (\r
+    CopyMem (\r
       TargetHwAddress,\r
       CacheEntry->Addresses[Hardware].AddressPtr,\r
       CacheEntry->Addresses[Hardware].Length\r
@@ -589,9 +594,9 @@ ArpRequest (
   //\r
   // Create a request context for this arp request.\r
   //\r
-  RequestContext = NetAllocatePool (sizeof(USER_REQUEST_CONTEXT));\r
+  RequestContext = AllocatePool (sizeof(USER_REQUEST_CONTEXT));\r
   if (RequestContext == NULL) {\r
-    ARP_DEBUG_ERROR (("ArpRequest: Allocate memory for RequestContext failed.\n"));\r
+    DEBUG ((EFI_D_ERROR, "ArpRequest: Allocate memory for RequestContext failed.\n"));\r
 \r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto UNLOCK_EXIT;\r
@@ -600,7 +605,7 @@ ArpRequest (
   RequestContext->Instance         = Instance;\r
   RequestContext->UserRequestEvent = ResolvedEvent;\r
   RequestContext->UserHwAddrBuffer = TargetHwAddress;\r
-  NetListInit (&RequestContext->List);\r
+  InitializeListHead (&RequestContext->List);\r
 \r
   //\r
   // Check whether there is a same request.\r
@@ -622,8 +627,8 @@ ArpRequest (
     //\r
     CacheEntry = ArpAllocCacheEntry (Instance);\r
     if (CacheEntry == NULL) {\r
-      ARP_DEBUG_ERROR (("ArpRequest: Allocate memory for CacheEntry failed.\n"));\r
-      NetFreePool (RequestContext);\r
+      DEBUG ((EFI_D_ERROR, "ArpRequest: Allocate memory for CacheEntry failed.\n"));\r
+      gBS->FreePool (RequestContext);\r
 \r
       Status = EFI_OUT_OF_RESOURCES;\r
       goto UNLOCK_EXIT;\r
@@ -637,13 +642,13 @@ ArpRequest (
     //\r
     // Add this entry into the PendingRequestTable.\r
     //\r
-    NetListInsertTail (&ArpService->PendingRequestTable, &CacheEntry->List);\r
+    InsertTailList (&ArpService->PendingRequestTable, &CacheEntry->List);\r
   }\r
 \r
   //\r
   // Link this request context into the cache entry.\r
   //\r
-  NetListInsertHead (&CacheEntry->UserRequestList, &RequestContext->List);\r
+  InsertHeadList (&CacheEntry->UserRequestList, &RequestContext->List);\r
 \r
   //\r
   // Send out the ARP Request frame.\r
@@ -653,12 +658,17 @@ ArpRequest (
 \r
 UNLOCK_EXIT:\r
 \r
-  NET_UNLOCK (&ArpService->Lock);\r
+  gBS->RestoreTPL (OldTpl);\r
 \r
 SIGNAL_USER:\r
 \r
   if ((ResolvedEvent != NULL) && (Status == EFI_SUCCESS)) {\r
     gBS->SignalEvent (ResolvedEvent);\r
+\r
+    //\r
+    // Dispatch the DPC queued by the NotifyFunction of ResolvedEvent.\r
+    //\r
+    NetLibDispatchDpc ();\r
   }\r
 \r
   return Status;\r
@@ -668,7 +678,13 @@ SIGNAL_USER:
 /**\r
   This function aborts the previous ARP request (identified by This,  TargetSwAddress\r
   and ResolvedEvent) that is issued by EFI_ARP_PROTOCOL.Request().\r
-\r
+  \r
+  If the request is in the internal ARP request queue, the request is aborted \r
+  immediately and its ResolvedEvent is signaled. Only an asynchronous address \r
+  request needs to be canceled. If TargeSwAddress and ResolveEvent are both \r
+  NULL, all the pending asynchronous requests that have been issued by This \r
+  instance will be cancelled and their corresponding events will be signaled.\r
+  \r
   @param  This                   Pointer to the EFI_ARP_PROTOCOL instance.\r
   @param  TargetSwAddress        Pointer to the protocol address in previous\r
                                  request session.\r
@@ -695,8 +711,8 @@ ArpCancel (
   )\r
 {\r
   ARP_INSTANCE_DATA  *Instance;\r
-  ARP_SERVICE_DATA   *ArpService;\r
   UINTN              Count;\r
+  EFI_TPL            OldTpl;\r
 \r
   if ((This == NULL) ||\r
     ((TargetSwAddress != NULL) && (ResolvedEvent == NULL)) ||\r
@@ -710,18 +726,20 @@ ArpCancel (
     return EFI_NOT_STARTED;\r
   }\r
 \r
-  ArpService = Instance->ArpService;\r
-\r
-  if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) {\r
-    return EFI_ACCESS_DENIED;\r
-  }\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
   //\r
   // Cancel the specified request.\r
   //\r
   Count = ArpCancelRequest (Instance, TargetSwAddress, ResolvedEvent);\r
 \r
-  NET_UNLOCK (&ArpService->Lock);\r
+  //\r
+  // Dispatch the DPCs queued by the NotifyFunction of the events signaled\r
+  // by ArpCancleRequest.\r
+  //\r
+  NetLibDispatchDpc ();\r
+\r
+  gBS->RestoreTPL (OldTpl);\r
 \r
   return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS;\r
 }\r