/** @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
\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
{\r
EFI_STATUS Status;\r
ARP_INSTANCE_DATA *Instance;\r
+ EFI_TPL OldTpl;\r
\r
if (This == NULL) {\r
return EFI_INVALID_PARAMETER;\r
\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
/**\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
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
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
//\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
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
// 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
/**\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
{\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
}\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
Refresh\r
);\r
\r
- NET_UNLOCK (&ArpService->Lock);\r
+ gBS->RestoreTPL (OldTpl);\r
\r
return Status;\r
}\r
)\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
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
)\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
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
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
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
//\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
//\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
//\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
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
//\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
//\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
\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
+ DispatchDpc ();\r
}\r
\r
return Status;\r
/**\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
)\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
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
+ DispatchDpc ();\r
+\r
+ gBS->RestoreTPL (OldTpl);\r
\r
return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS;\r
}\r