]> git.proxmox.com Git - mirror_edk2.git/blob - NetworkPkg/ArpDxe/ArpMain.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / NetworkPkg / ArpDxe / ArpMain.c
1 /** @file
2 Implementation of EFI Address Resolution Protocol (ARP) Protocol interface functions.
3
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "ArpImpl.h"
10
11 /**
12 This function is used to assign a station address to the ARP cache for this instance
13 of the ARP driver.
14
15 Each ARP instance has one station address. The EFI_ARP_PROTOCOL driver will
16 respond to ARP requests that match this registered station address. A call to
17 this function with the ConfigData field set to NULL will reset this ARP instance.
18
19 Once a protocol type and station address have been assigned to this ARP instance,
20 all the following ARP functions will use this information. Attempting to change
21 the protocol type or station address to a configured ARP instance will result in errors.
22
23 @param This Pointer to the EFI_ARP_PROTOCOL instance.
24 @param ConfigData Pointer to the EFI_ARP_CONFIG_DATA structure.
25
26 @retval EFI_SUCCESS The new station address was successfully
27 registered.
28 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
29 This is NULL. SwAddressLength is zero when
30 ConfigData is not NULL. StationAddress is NULL
31 when ConfigData is not NULL.
32 @retval EFI_ACCESS_DENIED The SwAddressType, SwAddressLength, or
33 StationAddress is different from the one that is
34 already registered.
35 @retval EFI_OUT_OF_RESOURCES Storage for the new StationAddress could not be
36 allocated.
37
38 **/
39 EFI_STATUS
40 EFIAPI
41 ArpConfigure (
42 IN EFI_ARP_PROTOCOL *This,
43 IN EFI_ARP_CONFIG_DATA *ConfigData OPTIONAL
44 )
45 {
46 EFI_STATUS Status;
47 ARP_INSTANCE_DATA *Instance;
48 EFI_TPL OldTpl;
49
50 if (This == NULL) {
51 return EFI_INVALID_PARAMETER;
52 }
53
54 if ((ConfigData != NULL) &&
55 ((ConfigData->SwAddressLength == 0) ||
56 (ConfigData->StationAddress == NULL) ||
57 (ConfigData->SwAddressType <= 1500)))
58 {
59 return EFI_INVALID_PARAMETER;
60 }
61
62 Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
63
64 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
65
66 //
67 // Configure this instance, the ConfigData has already passed the basic checks.
68 //
69 Status = ArpConfigureInstance (Instance, ConfigData);
70
71 gBS->RestoreTPL (OldTpl);
72
73 return Status;
74 }
75
76 /**
77 This function is used to insert entries into the ARP cache.
78
79 ARP cache entries are typically inserted and updated by network protocol drivers
80 as network traffic is processed. Most ARP cache entries will time out and be
81 deleted if the network traffic stops. ARP cache entries that were inserted
82 by the Add() function may be static (will not time out) or dynamic (will time out).
83 Default ARP cache timeout values are not covered in most network protocol
84 specifications (although RFC 1122 comes pretty close) and will only be
85 discussed in general in this specification. The timeout values that are
86 used in the EFI Sample Implementation should be used only as a guideline.
87 Final product implementations of the EFI network stack should be tuned for
88 their expected network environments.
89
90 @param This Pointer to the EFI_ARP_PROTOCOL instance.
91 @param DenyFlag Set to TRUE if this entry is a deny entry. Set to
92 FALSE if this entry is a normal entry.
93 @param TargetSwAddress Pointer to a protocol address to add (or deny).
94 May be set to NULL if DenyFlag is TRUE.
95 @param TargetHwAddress Pointer to a hardware address to add (or deny).
96 May be set to NULL if DenyFlag is TRUE.
97 @param TimeoutValue Time in 100-ns units that this entry will remain
98 in the ARP cache. A value of zero means that the
99 entry is permanent. A nonzero value will override
100 the one given by Configure() if the entry to be
101 added is a dynamic entry.
102 @param Overwrite If TRUE, the matching cache entry will be
103 overwritten with the supplied parameters. If
104 FALSE, EFI_ACCESS_DENIED is returned if the
105 corresponding cache entry already exists.
106
107 @retval EFI_SUCCESS The entry has been added or updated.
108 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
109 This is NULL. DenyFlag is FALSE and
110 TargetHwAddress is NULL. DenyFlag is FALSE and
111 TargetSwAddress is NULL. TargetHwAddress is NULL
112 and TargetSwAddress is NULL. Both TargetSwAddress
113 and TargetHwAddress are not NULL when DenyFlag is
114 TRUE.
115 @retval EFI_OUT_OF_RESOURCES The new ARP cache entry could not be allocated.
116 @retval EFI_ACCESS_DENIED The ARP cache entry already exists and Overwrite
117 is not true.
118 @retval EFI_NOT_STARTED The ARP driver instance has not been configured.
119
120 **/
121 EFI_STATUS
122 EFIAPI
123 ArpAdd (
124 IN EFI_ARP_PROTOCOL *This,
125 IN BOOLEAN DenyFlag,
126 IN VOID *TargetSwAddress OPTIONAL,
127 IN VOID *TargetHwAddress OPTIONAL,
128 IN UINT32 TimeoutValue,
129 IN BOOLEAN Overwrite
130 )
131 {
132 EFI_STATUS Status;
133 ARP_INSTANCE_DATA *Instance;
134 ARP_SERVICE_DATA *ArpService;
135 ARP_CACHE_ENTRY *CacheEntry;
136 EFI_SIMPLE_NETWORK_MODE *SnpMode;
137 NET_ARP_ADDRESS MatchAddress[2];
138 EFI_TPL OldTpl;
139
140 if (This == NULL) {
141 return EFI_INVALID_PARAMETER;
142 }
143
144 if (((!DenyFlag) && ((TargetHwAddress == NULL) || (TargetSwAddress == NULL))) ||
145 (DenyFlag && (TargetHwAddress != NULL) && (TargetSwAddress != NULL)) ||
146 ((TargetHwAddress == NULL) && (TargetSwAddress == NULL)))
147 {
148 return EFI_INVALID_PARAMETER;
149 }
150
151 Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
152
153 if (!Instance->Configured) {
154 return EFI_NOT_STARTED;
155 }
156
157 Status = EFI_SUCCESS;
158 ArpService = Instance->ArpService;
159 SnpMode = &Instance->ArpService->SnpMode;
160
161 //
162 // Fill the hardware address part in the MatchAddress.
163 //
164 MatchAddress[Hardware].Type = SnpMode->IfType;
165 MatchAddress[Hardware].Length = (UINT8)SnpMode->HwAddressSize;
166 MatchAddress[Hardware].AddressPtr = TargetHwAddress;
167
168 //
169 // Fill the software address part in the MatchAddress.
170 //
171 MatchAddress[Protocol].Type = Instance->ConfigData.SwAddressType;
172 MatchAddress[Protocol].Length = Instance->ConfigData.SwAddressLength;
173 MatchAddress[Protocol].AddressPtr = TargetSwAddress;
174
175 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
176
177 //
178 // See whether the entry to add exists. Check the DeniedCacheTable first.
179 //
180 CacheEntry = ArpFindDeniedCacheEntry (
181 ArpService,
182 &MatchAddress[Protocol],
183 &MatchAddress[Hardware]
184 );
185
186 if (CacheEntry == NULL) {
187 //
188 // Check the ResolvedCacheTable
189 //
190 CacheEntry = ArpFindNextCacheEntryInTable (
191 &ArpService->ResolvedCacheTable,
192 NULL,
193 ByBoth,
194 &MatchAddress[Protocol],
195 &MatchAddress[Hardware]
196 );
197 }
198
199 if ((CacheEntry != NULL) && !Overwrite) {
200 //
201 // The entry to add exists, if not Overwrite, deny this add request.
202 //
203 Status = EFI_ACCESS_DENIED;
204 goto UNLOCK_EXIT;
205 }
206
207 if ((CacheEntry == NULL) && (TargetSwAddress != NULL)) {
208 //
209 // Check whether there are pending requests matching the entry to be added.
210 //
211 CacheEntry = ArpFindNextCacheEntryInTable (
212 &ArpService->PendingRequestTable,
213 NULL,
214 ByProtoAddress,
215 &MatchAddress[Protocol],
216 NULL
217 );
218 }
219
220 if (CacheEntry != NULL) {
221 //
222 // Remove it from the Table.
223 //
224 RemoveEntryList (&CacheEntry->List);
225 } else {
226 //
227 // It's a new entry, allocate memory for the entry.
228 //
229 CacheEntry = ArpAllocCacheEntry (Instance);
230
231 if (CacheEntry == NULL) {
232 DEBUG ((DEBUG_ERROR, "ArpAdd: Failed to allocate pool for CacheEntry.\n"));
233 Status = EFI_OUT_OF_RESOURCES;
234 goto UNLOCK_EXIT;
235 }
236 }
237
238 //
239 // Overwrite these parameters.
240 //
241 CacheEntry->DefaultDecayTime = TimeoutValue;
242 CacheEntry->DecayTime = TimeoutValue;
243
244 //
245 // Fill in the addresses.
246 //
247 ArpFillAddressInCacheEntry (
248 CacheEntry,
249 &MatchAddress[Hardware],
250 &MatchAddress[Protocol]
251 );
252
253 //
254 // Inform the user if there is any.
255 //
256 ArpAddressResolved (CacheEntry, NULL, NULL);
257
258 //
259 // Add this CacheEntry to the corresponding CacheTable.
260 //
261 if (DenyFlag) {
262 InsertHeadList (&ArpService->DeniedCacheTable, &CacheEntry->List);
263 } else {
264 InsertHeadList (&ArpService->ResolvedCacheTable, &CacheEntry->List);
265 }
266
267 UNLOCK_EXIT:
268
269 gBS->RestoreTPL (OldTpl);
270
271 return Status;
272 }
273
274 /**
275 This function searches the ARP cache for matching entries and allocates a buffer into
276 which those entries are copied.
277
278 The first part of the allocated buffer is EFI_ARP_FIND_DATA, following which
279 are protocol address pairs and hardware address pairs.
280 When finding a specific protocol address (BySwAddress is TRUE and AddressBuffer
281 is not NULL), the ARP cache timeout for the found entry is reset if Refresh is
282 set to TRUE. If the found ARP cache entry is a permanent entry, it is not
283 affected by Refresh.
284
285 @param This Pointer to the EFI_ARP_PROTOCOL instance.
286 @param BySwAddress Set to TRUE to look for matching software protocol
287 addresses. Set to FALSE to look for matching
288 hardware protocol addresses.
289 @param AddressBuffer Pointer to address buffer. Set to NULL to match
290 all addresses.
291 @param EntryLength The size of an entry in the entries buffer.
292 @param EntryCount The number of ARP cache entries that are found by
293 the specified criteria.
294 @param Entries Pointer to the buffer that will receive the ARP
295 cache entries.
296 @param Refresh Set to TRUE to refresh the timeout value of the
297 matching ARP cache entry.
298
299 @retval EFI_SUCCESS The requested ARP cache entries were copied into
300 the buffer.
301 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
302 This is NULL. Both EntryCount and EntryLength are
303 NULL, when Refresh is FALSE.
304 @retval EFI_NOT_FOUND No matching entries were found.
305 @retval EFI_NOT_STARTED The ARP driver instance has not been configured.
306
307 **/
308 EFI_STATUS
309 EFIAPI
310 ArpFind (
311 IN EFI_ARP_PROTOCOL *This,
312 IN BOOLEAN BySwAddress,
313 IN VOID *AddressBuffer OPTIONAL,
314 OUT UINT32 *EntryLength OPTIONAL,
315 OUT UINT32 *EntryCount OPTIONAL,
316 OUT EFI_ARP_FIND_DATA **Entries OPTIONAL,
317 IN BOOLEAN Refresh
318 )
319 {
320 EFI_STATUS Status;
321 ARP_INSTANCE_DATA *Instance;
322 EFI_TPL OldTpl;
323
324 if ((This == NULL) ||
325 (!Refresh && (EntryCount == NULL) && (EntryLength == NULL)) ||
326 ((Entries != NULL) && ((EntryLength == NULL) || (EntryCount == NULL))))
327 {
328 return EFI_INVALID_PARAMETER;
329 }
330
331 Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
332
333 if (!Instance->Configured) {
334 return EFI_NOT_STARTED;
335 }
336
337 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
338
339 //
340 // All the check passed, find the cache entries now.
341 //
342 Status = ArpFindCacheEntry (
343 Instance,
344 BySwAddress,
345 AddressBuffer,
346 EntryLength,
347 EntryCount,
348 Entries,
349 Refresh
350 );
351
352 gBS->RestoreTPL (OldTpl);
353
354 return Status;
355 }
356
357 /**
358 This function removes specified ARP cache entries.
359
360 @param This Pointer to the EFI_ARP_PROTOCOL instance.
361 @param BySwAddress Set to TRUE to delete matching protocol addresses.
362 Set to FALSE to delete matching hardware
363 addresses.
364 @param AddressBuffer Pointer to the address buffer that is used as a
365 key to look for the cache entry. Set to NULL to
366 delete all entries.
367
368 @retval EFI_SUCCESS The entry was removed from the ARP cache.
369 @retval EFI_INVALID_PARAMETER This is NULL.
370 @retval EFI_NOT_FOUND The specified deletion key was not found.
371 @retval EFI_NOT_STARTED The ARP driver instance has not been configured.
372
373 **/
374 EFI_STATUS
375 EFIAPI
376 ArpDelete (
377 IN EFI_ARP_PROTOCOL *This,
378 IN BOOLEAN BySwAddress,
379 IN VOID *AddressBuffer OPTIONAL
380 )
381 {
382 ARP_INSTANCE_DATA *Instance;
383 UINTN Count;
384 EFI_TPL OldTpl;
385
386 if (This == NULL) {
387 return EFI_INVALID_PARAMETER;
388 }
389
390 Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
391
392 if (!Instance->Configured) {
393 return EFI_NOT_STARTED;
394 }
395
396 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
397
398 //
399 // Delete the specified cache entries.
400 //
401 Count = ArpDeleteCacheEntry (Instance, BySwAddress, AddressBuffer, TRUE);
402
403 gBS->RestoreTPL (OldTpl);
404
405 return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS;
406 }
407
408 /**
409 This function delete all dynamic entries from the ARP cache that match the specified
410 software protocol type.
411
412 @param This Pointer to the EFI_ARP_PROTOCOL instance.
413
414 @retval EFI_SUCCESS The cache has been flushed.
415 @retval EFI_INVALID_PARAMETER This is NULL.
416 @retval EFI_NOT_FOUND There are no matching dynamic cache entries.
417 @retval EFI_NOT_STARTED The ARP driver instance has not been configured.
418
419 **/
420 EFI_STATUS
421 EFIAPI
422 ArpFlush (
423 IN EFI_ARP_PROTOCOL *This
424 )
425 {
426 ARP_INSTANCE_DATA *Instance;
427 UINTN Count;
428 EFI_TPL OldTpl;
429
430 if (This == NULL) {
431 return EFI_INVALID_PARAMETER;
432 }
433
434 Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
435
436 if (!Instance->Configured) {
437 return EFI_NOT_STARTED;
438 }
439
440 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
441
442 //
443 // Delete the dynamic entries from the cache table.
444 //
445 Count = ArpDeleteCacheEntry (Instance, FALSE, NULL, FALSE);
446
447 gBS->RestoreTPL (OldTpl);
448
449 return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS;
450 }
451
452 /**
453 This function tries to resolve the TargetSwAddress and optionally returns a
454 TargetHwAddress if it already exists in the ARP cache.
455
456 @param This Pointer to the EFI_ARP_PROTOCOL instance.
457 @param TargetSwAddress Pointer to the protocol address to resolve.
458 @param ResolvedEvent Pointer to the event that will be signaled when
459 the address is resolved or some error occurs.
460 @param TargetHwAddress Pointer to the buffer for the resolved hardware
461 address in network byte order.
462
463 @retval EFI_SUCCESS The data is copied from the ARP cache into the
464 TargetHwAddress buffer.
465 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
466 This is NULL. TargetHwAddress is NULL.
467 @retval EFI_ACCESS_DENIED The requested address is not present in the normal
468 ARP cache but is present in the deny address list.
469 Outgoing traffic to that address is forbidden.
470 @retval EFI_NOT_STARTED The ARP driver instance has not been configured.
471 @retval EFI_NOT_READY The request has been started and is not finished.
472
473 **/
474 EFI_STATUS
475 EFIAPI
476 ArpRequest (
477 IN EFI_ARP_PROTOCOL *This,
478 IN VOID *TargetSwAddress OPTIONAL,
479 IN EFI_EVENT ResolvedEvent OPTIONAL,
480 OUT VOID *TargetHwAddress
481 )
482 {
483 EFI_STATUS Status;
484 ARP_INSTANCE_DATA *Instance;
485 ARP_SERVICE_DATA *ArpService;
486 EFI_SIMPLE_NETWORK_MODE *SnpMode;
487 ARP_CACHE_ENTRY *CacheEntry;
488 NET_ARP_ADDRESS HardwareAddress;
489 NET_ARP_ADDRESS ProtocolAddress;
490 USER_REQUEST_CONTEXT *RequestContext;
491 EFI_TPL OldTpl;
492
493 if ((This == NULL) || (TargetHwAddress == NULL)) {
494 return EFI_INVALID_PARAMETER;
495 }
496
497 Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
498
499 if (!Instance->Configured) {
500 return EFI_NOT_STARTED;
501 }
502
503 Status = EFI_SUCCESS;
504 ArpService = Instance->ArpService;
505 SnpMode = &ArpService->SnpMode;
506
507 if ((TargetSwAddress == NULL) ||
508 ((Instance->ConfigData.SwAddressType == IPV4_ETHER_PROTO_TYPE) &&
509 IP4_IS_LOCAL_BROADCAST (*((UINT32 *)TargetSwAddress))))
510 {
511 //
512 // Return the hardware broadcast address.
513 //
514 CopyMem (TargetHwAddress, &SnpMode->BroadcastAddress, SnpMode->HwAddressSize);
515
516 goto SIGNAL_USER;
517 }
518
519 if ((Instance->ConfigData.SwAddressType == IPV4_ETHER_PROTO_TYPE) &&
520 IP4_IS_MULTICAST (NTOHL (*((UINT32 *)TargetSwAddress))))
521 {
522 //
523 // If the software address is an IPv4 multicast address, invoke Mnp to
524 // resolve the address.
525 //
526 Status = ArpService->Mnp->McastIpToMac (
527 ArpService->Mnp,
528 FALSE,
529 TargetSwAddress,
530 TargetHwAddress
531 );
532 goto SIGNAL_USER;
533 }
534
535 HardwareAddress.Type = SnpMode->IfType;
536 HardwareAddress.Length = (UINT8)SnpMode->HwAddressSize;
537 HardwareAddress.AddressPtr = NULL;
538
539 ProtocolAddress.Type = Instance->ConfigData.SwAddressType;
540 ProtocolAddress.Length = Instance->ConfigData.SwAddressLength;
541 ProtocolAddress.AddressPtr = TargetSwAddress;
542
543 //
544 // Initialize the TargetHwAddress to a zero address.
545 //
546 ZeroMem (TargetHwAddress, SnpMode->HwAddressSize);
547
548 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
549
550 //
551 // Check whether the software address is in the denied table.
552 //
553 CacheEntry = ArpFindDeniedCacheEntry (ArpService, &ProtocolAddress, NULL);
554 if (CacheEntry != NULL) {
555 Status = EFI_ACCESS_DENIED;
556 goto UNLOCK_EXIT;
557 }
558
559 //
560 // Check whether the software address is already resolved.
561 //
562 CacheEntry = ArpFindNextCacheEntryInTable (
563 &ArpService->ResolvedCacheTable,
564 NULL,
565 ByProtoAddress,
566 &ProtocolAddress,
567 NULL
568 );
569 if (CacheEntry != NULL) {
570 //
571 // Resolved, copy the address into the user buffer.
572 //
573 CopyMem (
574 TargetHwAddress,
575 CacheEntry->Addresses[Hardware].AddressPtr,
576 CacheEntry->Addresses[Hardware].Length
577 );
578
579 goto UNLOCK_EXIT;
580 }
581
582 if (ResolvedEvent == NULL) {
583 Status = EFI_NOT_READY;
584 goto UNLOCK_EXIT;
585 }
586
587 //
588 // Create a request context for this arp request.
589 //
590 RequestContext = AllocatePool (sizeof (USER_REQUEST_CONTEXT));
591 if (RequestContext == NULL) {
592 DEBUG ((DEBUG_ERROR, "ArpRequest: Allocate memory for RequestContext failed.\n"));
593
594 Status = EFI_OUT_OF_RESOURCES;
595 goto UNLOCK_EXIT;
596 }
597
598 RequestContext->Instance = Instance;
599 RequestContext->UserRequestEvent = ResolvedEvent;
600 RequestContext->UserHwAddrBuffer = TargetHwAddress;
601 InitializeListHead (&RequestContext->List);
602
603 //
604 // Check whether there is a same request.
605 //
606 CacheEntry = ArpFindNextCacheEntryInTable (
607 &ArpService->PendingRequestTable,
608 NULL,
609 ByProtoAddress,
610 &ProtocolAddress,
611 NULL
612 );
613 if (CacheEntry != NULL) {
614 CacheEntry->NextRetryTime = Instance->ConfigData.RetryTimeOut;
615 CacheEntry->RetryCount = Instance->ConfigData.RetryCount;
616 } else {
617 //
618 // Allocate a cache entry for this request.
619 //
620 CacheEntry = ArpAllocCacheEntry (Instance);
621 if (CacheEntry == NULL) {
622 DEBUG ((DEBUG_ERROR, "ArpRequest: Allocate memory for CacheEntry failed.\n"));
623 FreePool (RequestContext);
624
625 Status = EFI_OUT_OF_RESOURCES;
626 goto UNLOCK_EXIT;
627 }
628
629 //
630 // Fill the software address.
631 //
632 ArpFillAddressInCacheEntry (CacheEntry, &HardwareAddress, &ProtocolAddress);
633
634 //
635 // Add this entry into the PendingRequestTable.
636 //
637 InsertTailList (&ArpService->PendingRequestTable, &CacheEntry->List);
638 }
639
640 //
641 // Link this request context into the cache entry.
642 //
643 InsertHeadList (&CacheEntry->UserRequestList, &RequestContext->List);
644
645 //
646 // Send out the ARP Request frame.
647 //
648 ArpSendFrame (Instance, CacheEntry, ARP_OPCODE_REQUEST);
649 Status = EFI_NOT_READY;
650
651 UNLOCK_EXIT:
652
653 gBS->RestoreTPL (OldTpl);
654
655 SIGNAL_USER:
656
657 if ((ResolvedEvent != NULL) && (Status == EFI_SUCCESS)) {
658 gBS->SignalEvent (ResolvedEvent);
659
660 //
661 // Dispatch the DPC queued by the NotifyFunction of ResolvedEvent.
662 //
663 DispatchDpc ();
664 }
665
666 return Status;
667 }
668
669 /**
670 This function aborts the previous ARP request (identified by This, TargetSwAddress
671 and ResolvedEvent) that is issued by EFI_ARP_PROTOCOL.Request().
672
673 If the request is in the internal ARP request queue, the request is aborted
674 immediately and its ResolvedEvent is signaled. Only an asynchronous address
675 request needs to be canceled. If TargetSwAddress and ResolvedEvent are both
676 NULL, all the pending asynchronous requests that have been issued by This
677 instance will be cancelled and their corresponding events will be signaled.
678
679 @param This Pointer to the EFI_ARP_PROTOCOL instance.
680 @param TargetSwAddress Pointer to the protocol address in previous
681 request session.
682 @param ResolvedEvent Pointer to the event that is used as the
683 notification event in previous request session.
684
685 @retval EFI_SUCCESS The pending request session(s) is/are aborted and
686 corresponding event(s) is/are signaled.
687 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
688 This is NULL. TargetSwAddress is not NULL and
689 ResolvedEvent is NULL. TargetSwAddress is NULL and
690 ResolvedEvent is not NULL.
691 @retval EFI_NOT_STARTED The ARP driver instance has not been configured.
692 @retval EFI_NOT_FOUND The request is not issued by
693 EFI_ARP_PROTOCOL.Request().
694
695 **/
696 EFI_STATUS
697 EFIAPI
698 ArpCancel (
699 IN EFI_ARP_PROTOCOL *This,
700 IN VOID *TargetSwAddress OPTIONAL,
701 IN EFI_EVENT ResolvedEvent OPTIONAL
702 )
703 {
704 ARP_INSTANCE_DATA *Instance;
705 UINTN Count;
706 EFI_TPL OldTpl;
707
708 if ((This == NULL) ||
709 ((TargetSwAddress != NULL) && (ResolvedEvent == NULL)) ||
710 ((TargetSwAddress == NULL) && (ResolvedEvent != NULL)))
711 {
712 return EFI_INVALID_PARAMETER;
713 }
714
715 Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
716
717 if (!Instance->Configured) {
718 return EFI_NOT_STARTED;
719 }
720
721 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
722
723 //
724 // Cancel the specified request.
725 //
726 Count = ArpCancelRequest (Instance, TargetSwAddress, ResolvedEvent);
727
728 //
729 // Dispatch the DPCs queued by the NotifyFunction of the events signaled
730 // by ArpCancelRequest.
731 //
732 DispatchDpc ();
733
734 gBS->RestoreTPL (OldTpl);
735
736 return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS;
737 }