]> git.proxmox.com Git - mirror_edk2.git/blob - NetworkPkg/ArpDxe/ArpDriver.c
NetworkPkg: Move Network library and drivers from MdeModulePkg to NetworkPkg
[mirror_edk2.git] / NetworkPkg / ArpDxe / ArpDriver.c
1 /** @file
2 ARP driver 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 "ArpDriver.h"
10 #include "ArpImpl.h"
11
12 EFI_DRIVER_BINDING_PROTOCOL gArpDriverBinding = {
13 ArpDriverBindingSupported,
14 ArpDriverBindingStart,
15 ArpDriverBindingStop,
16 0xa,
17 NULL,
18 NULL
19 };
20
21
22 /**
23 Create and initialize the arp service context data.
24
25 @param[in] ImageHandle The image handle representing the loaded driver
26 image.
27 @param[in] ControllerHandle The controller handle the driver binds to.
28 @param[in, out] ArpService Pointer to the buffer containing the arp service
29 context data.
30
31 @retval EFI_SUCCESS The arp service context is initialized.
32
33 @retval EFI_UNSUPPORTED The underlayer Snp mode type is not ethernet.
34 Failed to initialize the service context.
35 @retval other Failed to initialize the arp service context.
36
37 **/
38 EFI_STATUS
39 ArpCreateService (
40 IN EFI_HANDLE ImageHandle,
41 IN EFI_HANDLE ControllerHandle,
42 IN OUT ARP_SERVICE_DATA *ArpService
43 )
44 {
45 EFI_STATUS Status;
46
47 ASSERT (ArpService != NULL);
48
49 ArpService->Signature = ARP_SERVICE_DATA_SIGNATURE;
50
51 //
52 // Init the lists.
53 //
54 InitializeListHead (&ArpService->ChildrenList);
55 InitializeListHead (&ArpService->PendingRequestTable);
56 InitializeListHead (&ArpService->DeniedCacheTable);
57 InitializeListHead (&ArpService->ResolvedCacheTable);
58
59 //
60 // Init the servicebinding protocol members.
61 //
62 ArpService->ServiceBinding.CreateChild = ArpServiceBindingCreateChild;
63 ArpService->ServiceBinding.DestroyChild = ArpServiceBindingDestroyChild;
64
65 //
66 // Save the handles.
67 //
68 ArpService->ImageHandle = ImageHandle;
69 ArpService->ControllerHandle = ControllerHandle;
70
71 //
72 // Create a MNP child instance.
73 //
74 Status = NetLibCreateServiceChild (
75 ControllerHandle,
76 ImageHandle,
77 &gEfiManagedNetworkServiceBindingProtocolGuid,
78 &ArpService->MnpChildHandle
79 );
80 if (EFI_ERROR (Status)) {
81 return Status;
82 }
83
84 //
85 // Open the MNP protocol.
86 //
87 Status = gBS->OpenProtocol (
88 ArpService->MnpChildHandle,
89 &gEfiManagedNetworkProtocolGuid,
90 (VOID **)&ArpService->Mnp,
91 ImageHandle,
92 ControllerHandle,
93 EFI_OPEN_PROTOCOL_BY_DRIVER
94 );
95 if (EFI_ERROR (Status)) {
96 goto ERROR_EXIT;
97 }
98
99 //
100 // Get the underlayer Snp mode data.
101 //
102 Status = ArpService->Mnp->GetModeData (ArpService->Mnp, NULL, &ArpService->SnpMode);
103 if ((Status != EFI_NOT_STARTED) && EFI_ERROR (Status)) {
104 goto ERROR_EXIT;
105 }
106
107 if (ArpService->SnpMode.IfType != NET_IFTYPE_ETHERNET) {
108 //
109 // Only support the ethernet.
110 //
111 Status = EFI_UNSUPPORTED;
112 goto ERROR_EXIT;
113 }
114
115 //
116 // Set the Mnp config parameters.
117 //
118 ArpService->MnpConfigData.ReceivedQueueTimeoutValue = 0;
119 ArpService->MnpConfigData.TransmitQueueTimeoutValue = 0;
120 ArpService->MnpConfigData.ProtocolTypeFilter = ARP_ETHER_PROTO_TYPE;
121 ArpService->MnpConfigData.EnableUnicastReceive = TRUE;
122 ArpService->MnpConfigData.EnableMulticastReceive = FALSE;
123 ArpService->MnpConfigData.EnableBroadcastReceive = TRUE;
124 ArpService->MnpConfigData.EnablePromiscuousReceive = FALSE;
125 ArpService->MnpConfigData.FlushQueuesOnReset = TRUE;
126 ArpService->MnpConfigData.EnableReceiveTimestamps = FALSE;
127 ArpService->MnpConfigData.DisableBackgroundPolling = FALSE;
128
129 //
130 // Configure the Mnp child.
131 //
132 Status = ArpService->Mnp->Configure (ArpService->Mnp, &ArpService->MnpConfigData);
133 if (EFI_ERROR (Status)) {
134 goto ERROR_EXIT;
135 }
136
137 //
138 // Create the event used in the RxToken.
139 //
140 Status = gBS->CreateEvent (
141 EVT_NOTIFY_SIGNAL,
142 TPL_NOTIFY,
143 ArpOnFrameRcvd,
144 ArpService,
145 &ArpService->RxToken.Event
146 );
147 if (EFI_ERROR (Status)) {
148 goto ERROR_EXIT;
149 }
150
151 //
152 // Create the Arp heartbeat timer.
153 //
154 Status = gBS->CreateEvent (
155 EVT_NOTIFY_SIGNAL | EVT_TIMER,
156 TPL_CALLBACK,
157 ArpTimerHandler,
158 ArpService,
159 &ArpService->PeriodicTimer
160 );
161 if (EFI_ERROR (Status)) {
162 goto ERROR_EXIT;
163 }
164
165 //
166 // Start the heartbeat timer.
167 //
168 Status = gBS->SetTimer (
169 ArpService->PeriodicTimer,
170 TimerPeriodic,
171 ARP_PERIODIC_TIMER_INTERVAL
172 );
173
174 ERROR_EXIT:
175
176 return Status;
177 }
178
179
180 /**
181 Clean the arp service context data.
182
183 @param[in, out] ArpService Pointer to the buffer containing the arp service
184 context data.
185
186 @return None.
187
188 **/
189 VOID
190 ArpCleanService (
191 IN OUT ARP_SERVICE_DATA *ArpService
192 )
193 {
194 NET_CHECK_SIGNATURE (ArpService, ARP_SERVICE_DATA_SIGNATURE);
195
196 if (ArpService->PeriodicTimer != NULL) {
197 //
198 // Cancle and close the PeriodicTimer.
199 //
200 gBS->SetTimer (ArpService->PeriodicTimer, TimerCancel, 0);
201 gBS->CloseEvent (ArpService->PeriodicTimer);
202 }
203
204 if (ArpService->RxToken.Event != NULL) {
205 //
206 // Cancle the RxToken and close the event in the RxToken.
207 //
208 ArpService->Mnp->Cancel (ArpService->Mnp, NULL);
209 gBS->CloseEvent (ArpService->RxToken.Event);
210 }
211
212 if (ArpService->Mnp != NULL) {
213 //
214 // Reset the Mnp child and close the Mnp protocol.
215 //
216 ArpService->Mnp->Configure (ArpService->Mnp, NULL);
217 gBS->CloseProtocol (
218 ArpService->MnpChildHandle,
219 &gEfiManagedNetworkProtocolGuid,
220 ArpService->ImageHandle,
221 ArpService->ControllerHandle
222 );
223 }
224
225 if (ArpService->MnpChildHandle != NULL) {
226 //
227 // Destroy the mnp child.
228 //
229 NetLibDestroyServiceChild(
230 ArpService->ControllerHandle,
231 ArpService->ImageHandle,
232 &gEfiManagedNetworkServiceBindingProtocolGuid,
233 ArpService->MnpChildHandle
234 );
235 }
236 }
237
238 /**
239 Callback function which provided by user to remove one node in NetDestroyLinkList process.
240
241 @param[in] Entry The entry to be removed.
242 @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
243
244 @retval EFI_SUCCESS The entry has been removed successfully.
245 @retval Others Fail to remove the entry.
246
247 **/
248 EFI_STATUS
249 EFIAPI
250 ArpDestroyChildEntryInHandleBuffer (
251 IN LIST_ENTRY *Entry,
252 IN VOID *Context
253 )
254 {
255 ARP_INSTANCE_DATA *Instance;
256 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
257
258 if (Entry == NULL || Context == NULL) {
259 return EFI_INVALID_PARAMETER;
260 }
261
262 Instance = NET_LIST_USER_STRUCT_S (Entry, ARP_INSTANCE_DATA, List, ARP_INSTANCE_DATA_SIGNATURE);
263 ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *) Context;
264
265 return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
266 }
267
268 /**
269 Tests to see if this driver supports a given controller.
270
271 If a child device is provided, it further tests to see if this driver supports
272 creating a handle for the specified child device.
273
274 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
275 @param[in] ControllerHandle The handle of the controller to test. This handle
276 must support a protocol interface that supplies
277 an I/O abstraction to the driver.
278 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path.
279 This parameter is ignored by device drivers,
280 and is optional for bus drivers.
281
282 @retval EFI_SUCCESS The device specified by ControllerHandle and
283 RemainingDevicePath is supported by the driver
284 specified by This.
285 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
286 RemainingDevicePath is already being managed
287 by the driver specified by This.
288 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
289 RemainingDevicePath is already being managed by
290 a different driver or an application that
291 requires exclusive acces. Currently not implemented.
292 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
293 RemainingDevicePath is not supported by the
294 driver specified by This.
295
296 **/
297 EFI_STATUS
298 EFIAPI
299 ArpDriverBindingSupported (
300 IN EFI_DRIVER_BINDING_PROTOCOL *This,
301 IN EFI_HANDLE ControllerHandle,
302 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
303 )
304 {
305 EFI_STATUS Status;
306
307 //
308 // Test to see if Arp SB is already installed.
309 //
310 Status = gBS->OpenProtocol (
311 ControllerHandle,
312 &gEfiArpServiceBindingProtocolGuid,
313 NULL,
314 This->DriverBindingHandle,
315 ControllerHandle,
316 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
317 );
318 if (Status == EFI_SUCCESS) {
319 return EFI_ALREADY_STARTED;
320 }
321
322 //
323 // Test to see if MNP SB is installed.
324 //
325 Status = gBS->OpenProtocol (
326 ControllerHandle,
327 &gEfiManagedNetworkServiceBindingProtocolGuid,
328 NULL,
329 This->DriverBindingHandle,
330 ControllerHandle,
331 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
332 );
333
334 return Status;
335 }
336
337
338 /**
339 Start this driver on ControllerHandle.
340
341 The Start() function is designed to be invoked from the EFI boot service ConnectController().
342 As a result, much of the error checking on the parameters to Start() has been
343 moved into this common boot service. It is legal to call Start() from other locations,
344 but the following calling restrictions must be followed or the system behavior
345 will not be deterministic.
346 1. ControllerHandle must be a valid EFI_HANDLE.
347 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally
348 aligned EFI_DEVICE_PATH_PROTOCOL.
349 3. Prior to calling Start(), the Supported() function for the driver specified
350 by This must have been called with the same calling parameters, and Supported()
351 must have returned EFI_SUCCESS.
352
353 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
354 @param[in] ControllerHandle The handle of the controller to start. This handle
355 must support a protocol interface that supplies
356 an I/O abstraction to the driver.
357 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path.
358 This parameter is ignored by device drivers,
359 and is optional for bus drivers.
360
361 @retval EFI_SUCCESS The device was started.
362 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.
363 Currently not implemented.
364 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of
365 resources.
366 @retval Others The driver failded to start the device.
367
368 **/
369 EFI_STATUS
370 EFIAPI
371 ArpDriverBindingStart (
372 IN EFI_DRIVER_BINDING_PROTOCOL *This,
373 IN EFI_HANDLE ControllerHandle,
374 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
375 )
376 {
377 EFI_STATUS Status;
378 ARP_SERVICE_DATA *ArpService;
379
380 //
381 // Allocate a zero pool for ArpService.
382 //
383 ArpService = AllocateZeroPool (sizeof(ARP_SERVICE_DATA));
384 if (ArpService == NULL) {
385 return EFI_OUT_OF_RESOURCES;
386 }
387
388 //
389 // Initialize the arp service context data.
390 //
391 Status = ArpCreateService (This->DriverBindingHandle, ControllerHandle, ArpService);
392 if (EFI_ERROR (Status)) {
393 goto ERROR;
394 }
395
396 //
397 // Install the ARP service binding protocol.
398 //
399 Status = gBS->InstallMultipleProtocolInterfaces (
400 &ControllerHandle,
401 &gEfiArpServiceBindingProtocolGuid,
402 &ArpService->ServiceBinding,
403 NULL
404 );
405 if (EFI_ERROR (Status)) {
406 goto ERROR;
407 }
408
409 //
410 // OK, start to receive arp packets from Mnp.
411 //
412 Status = ArpService->Mnp->Receive (ArpService->Mnp, &ArpService->RxToken);
413 if (EFI_ERROR (Status)) {
414 goto ERROR;
415 }
416
417 return Status;
418
419 ERROR:
420
421 //
422 // On error, clean the arp service context data, and free the memory allocated.
423 //
424 ArpCleanService (ArpService);
425 FreePool (ArpService);
426
427 return Status;
428 }
429
430
431 /**
432 Stop this driver on ControllerHandle.
433
434 Release the control of this controller and remove the IScsi functions. The Stop()
435 function is designed to be invoked from the EFI boot service DisconnectController().
436 As a result, much of the error checking on the parameters to Stop() has been moved
437 into this common boot service. It is legal to call Stop() from other locations,
438 but the following calling restrictions must be followed or the system behavior
439 will not be deterministic.
440 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
441 same driver's Start() function.
442 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
443 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
444 Start() function, and the Start() function must have called OpenProtocol() on
445 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
446
447 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
448 @param[in] ControllerHandle A handle to the device being stopped. The handle must
449 support a bus specific I/O protocol for the driver
450 to use to stop the device.
451 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
452 Not used.
453 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
454 if NumberOfChildren is 0.Not used.
455
456 @retval EFI_SUCCESS The device was stopped.
457 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
458
459 **/
460 EFI_STATUS
461 EFIAPI
462 ArpDriverBindingStop (
463 IN EFI_DRIVER_BINDING_PROTOCOL *This,
464 IN EFI_HANDLE ControllerHandle,
465 IN UINTN NumberOfChildren,
466 IN EFI_HANDLE *ChildHandleBuffer
467 )
468 {
469 EFI_STATUS Status;
470 EFI_HANDLE NicHandle;
471 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
472 ARP_SERVICE_DATA *ArpService;
473 LIST_ENTRY *List;
474
475 //
476 // Get the NicHandle which the arp servicebinding is installed on.
477 //
478 NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
479 if (NicHandle == NULL) {
480 return EFI_SUCCESS;
481 }
482
483 //
484 // Try to get the arp servicebinding protocol on the NicHandle.
485 //
486 Status = gBS->OpenProtocol (
487 NicHandle,
488 &gEfiArpServiceBindingProtocolGuid,
489 (VOID **)&ServiceBinding,
490 This->DriverBindingHandle,
491 ControllerHandle,
492 EFI_OPEN_PROTOCOL_GET_PROTOCOL
493 );
494 if (EFI_ERROR (Status)) {
495 DEBUG ((EFI_D_ERROR, "ArpDriverBindingStop: Open ArpSb failed, %r.\n", Status));
496 return EFI_DEVICE_ERROR;
497 }
498
499 ArpService = ARP_SERVICE_DATA_FROM_THIS (ServiceBinding);
500
501 if (NumberOfChildren != 0) {
502 //
503 // NumberOfChildren is not zero, destroy all the ARP children instances.
504 //
505 List = &ArpService->ChildrenList;
506 Status = NetDestroyLinkList (
507 List,
508 ArpDestroyChildEntryInHandleBuffer,
509 ServiceBinding,
510 NULL
511 );
512 ASSERT (IsListEmpty (&ArpService->PendingRequestTable));
513 ASSERT (IsListEmpty (&ArpService->DeniedCacheTable));
514 ASSERT (IsListEmpty (&ArpService->ResolvedCacheTable));
515 } else if (IsListEmpty (&ArpService->ChildrenList)) {
516 //
517 // Uninstall the ARP ServiceBinding protocol.
518 //
519 gBS->UninstallMultipleProtocolInterfaces (
520 NicHandle,
521 &gEfiArpServiceBindingProtocolGuid,
522 &ArpService->ServiceBinding,
523 NULL
524 );
525
526 //
527 // Clean the arp servicebinding context data and free the memory allocated.
528 //
529 ArpCleanService (ArpService);
530
531 FreePool (ArpService);
532 }
533
534 return EFI_SUCCESS;
535 }
536
537 /**
538 Creates a child handle and installs a protocol.
539
540 The CreateChild() function installs a protocol on ChildHandle.
541 If ChildHandle is a pointer to NULL, then a new handle is created and returned
542 in ChildHandle. If ChildHandle is not a pointer to NULL, then the protocol
543 installs on the existing ChildHandle.
544
545 @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
546 @param ChildHandle Pointer to the handle of the child to create. If it is NULL,
547 then a new handle is created. If it is a pointer to an existing
548 UEFI handle, then the protocol is added to the existing UEFI handle.
549
550 @retval EFI_SUCCES The protocol was added to ChildHandle.
551 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
552 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
553 the child
554 @retval other The child handle was not created
555
556 **/
557 EFI_STATUS
558 EFIAPI
559 ArpServiceBindingCreateChild (
560 IN EFI_SERVICE_BINDING_PROTOCOL *This,
561 IN EFI_HANDLE *ChildHandle
562 )
563 {
564 EFI_STATUS Status;
565 ARP_SERVICE_DATA *ArpService;
566 ARP_INSTANCE_DATA *Instance;
567 VOID *Mnp;
568 EFI_TPL OldTpl;
569
570 if ((This == NULL) || (ChildHandle == NULL)) {
571 return EFI_INVALID_PARAMETER;
572 }
573
574 ArpService = ARP_SERVICE_DATA_FROM_THIS (This);
575
576 //
577 // Allocate memory for the instance context data.
578 //
579 Instance = AllocateZeroPool (sizeof(ARP_INSTANCE_DATA));
580 if (Instance == NULL) {
581 DEBUG ((EFI_D_ERROR, "ArpSBCreateChild: Failed to allocate memory for Instance.\n"));
582
583 return EFI_OUT_OF_RESOURCES;
584 }
585
586 //
587 // Init the instance context data.
588 //
589 ArpInitInstance (ArpService, Instance);
590
591 //
592 // Install the ARP protocol onto the ChildHandle.
593 //
594 Status = gBS->InstallMultipleProtocolInterfaces (
595 ChildHandle,
596 &gEfiArpProtocolGuid,
597 (VOID *)&Instance->ArpProto,
598 NULL
599 );
600 if (EFI_ERROR (Status)) {
601 DEBUG ((EFI_D_ERROR, "ArpSBCreateChild: faild to install ARP protocol, %r.\n", Status));
602
603 FreePool (Instance);
604 return Status;
605 }
606
607 //
608 // Save the ChildHandle.
609 //
610 Instance->Handle = *ChildHandle;
611
612 //
613 // Open the Managed Network protocol BY_CHILD.
614 //
615 Status = gBS->OpenProtocol (
616 ArpService->MnpChildHandle,
617 &gEfiManagedNetworkProtocolGuid,
618 (VOID **) &Mnp,
619 gArpDriverBinding.DriverBindingHandle,
620 Instance->Handle,
621 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
622 );
623 if (EFI_ERROR (Status)) {
624 goto ERROR;
625 }
626
627 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
628
629 //
630 // Insert the instance into children list managed by the arp service context data.
631 //
632 InsertTailList (&ArpService->ChildrenList, &Instance->List);
633 ArpService->ChildrenNumber++;
634
635 gBS->RestoreTPL (OldTpl);
636
637 ERROR:
638
639 if (EFI_ERROR (Status)) {
640
641 gBS->CloseProtocol (
642 ArpService->MnpChildHandle,
643 &gEfiManagedNetworkProtocolGuid,
644 gArpDriverBinding.DriverBindingHandle,
645 Instance->Handle
646 );
647
648 gBS->UninstallMultipleProtocolInterfaces (
649 Instance->Handle,
650 &gEfiArpProtocolGuid,
651 &Instance->ArpProto,
652 NULL
653 );
654
655 //
656 // Free the allocated memory.
657 //
658 FreePool (Instance);
659 }
660
661 return Status;
662 }
663
664
665 /**
666 Destroys a child handle with a protocol installed on it.
667
668 The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
669 that was installed by CreateChild() from ChildHandle. If the removed protocol is the
670 last protocol on ChildHandle, then ChildHandle is destroyed.
671
672 @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
673 @param ChildHandle Handle of the child to destroy
674
675 @retval EFI_SUCCES The protocol was removed from ChildHandle.
676 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is
677 being removed.
678 @retval EFI_INVALID_PARAMETER Child handle is NULL.
679 @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
680 because its services are being used.
681 @retval other The child handle was not destroyed
682
683 **/
684 EFI_STATUS
685 EFIAPI
686 ArpServiceBindingDestroyChild (
687 IN EFI_SERVICE_BINDING_PROTOCOL *This,
688 IN EFI_HANDLE ChildHandle
689 )
690 {
691 EFI_STATUS Status;
692 ARP_SERVICE_DATA *ArpService;
693 ARP_INSTANCE_DATA *Instance;
694 EFI_ARP_PROTOCOL *Arp;
695 EFI_TPL OldTpl;
696
697 if ((This == NULL) || (ChildHandle == NULL)) {
698 return EFI_INVALID_PARAMETER;
699 }
700
701 ArpService = ARP_SERVICE_DATA_FROM_THIS (This);
702
703 //
704 // Get the arp protocol.
705 //
706 Status = gBS->OpenProtocol (
707 ChildHandle,
708 &gEfiArpProtocolGuid,
709 (VOID **)&Arp,
710 ArpService->ImageHandle,
711 ChildHandle,
712 EFI_OPEN_PROTOCOL_GET_PROTOCOL
713 );
714 if (EFI_ERROR (Status)) {
715 return EFI_UNSUPPORTED;
716 }
717
718 Instance = ARP_INSTANCE_DATA_FROM_THIS (Arp);
719
720 if (Instance->InDestroy) {
721 return EFI_SUCCESS;
722 }
723
724 //
725 // Use the InDestroy as a flag to avoid re-entrance.
726 //
727 Instance->InDestroy = TRUE;
728
729 //
730 // Close the Managed Network protocol.
731 //
732 gBS->CloseProtocol (
733 ArpService->MnpChildHandle,
734 &gEfiManagedNetworkProtocolGuid,
735 gArpDriverBinding.DriverBindingHandle,
736 ChildHandle
737 );
738
739 //
740 // Uninstall the ARP protocol.
741 //
742 Status = gBS->UninstallMultipleProtocolInterfaces (
743 ChildHandle,
744 &gEfiArpProtocolGuid,
745 &Instance->ArpProto,
746 NULL
747 );
748 if (EFI_ERROR (Status)) {
749 DEBUG ((EFI_D_ERROR, "ArpSBDestroyChild: Failed to uninstall the arp protocol, %r.\n",
750 Status));
751
752 Instance->InDestroy = FALSE;
753 return Status;
754 }
755
756 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
757
758 if (Instance->Configured) {
759 //
760 // Delete the related cache entry.
761 //
762 ArpDeleteCacheEntry (Instance, FALSE, NULL, TRUE);
763
764 //
765 // Reset the instance configuration.
766 //
767 ArpConfigureInstance (Instance, NULL);
768 }
769
770 //
771 // Remove this instance from the ChildrenList.
772 //
773 RemoveEntryList (&Instance->List);
774 ArpService->ChildrenNumber--;
775
776 gBS->RestoreTPL (OldTpl);
777
778 FreePool (Instance);
779
780 return Status;
781 }
782
783 /**
784 The entry point for Arp driver which installs the driver binding and component name
785 protocol on its ImageHandle.
786
787 @param[in] ImageHandle The image handle of the driver.
788 @param[in] SystemTable The system table.
789
790 @retval EFI_SUCCESS if the driver binding and component name protocols
791 are successfully
792 @retval Others Failed to install the protocols.
793
794 **/
795 EFI_STATUS
796 EFIAPI
797 ArpDriverEntryPoint (
798 IN EFI_HANDLE ImageHandle,
799 IN EFI_SYSTEM_TABLE *SystemTable
800 )
801 {
802 return EfiLibInstallDriverBindingComponentName2 (
803 ImageHandle,
804 SystemTable,
805 &gArpDriverBinding,
806 ImageHandle,
807 &gArpComponentName,
808 &gArpComponentName2
809 );
810 }
811