4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
12 EFI_DRIVER_BINDING_PROTOCOL gArpDriverBinding
= {
13 ArpDriverBindingSupported
,
14 ArpDriverBindingStart
,
22 Create and initialize the arp service context data.
24 @param[in] ImageHandle The image handle representing the loaded driver
26 @param[in] ControllerHandle The controller handle the driver binds to.
27 @param[in, out] ArpService Pointer to the buffer containing the arp service
30 @retval EFI_SUCCESS The arp service context is initialized.
32 @retval EFI_UNSUPPORTED The underlayer Snp mode type is not ethernet.
33 Failed to initialize the service context.
34 @retval other Failed to initialize the arp service context.
39 IN EFI_HANDLE ImageHandle
,
40 IN EFI_HANDLE ControllerHandle
,
41 IN OUT ARP_SERVICE_DATA
*ArpService
46 ASSERT (ArpService
!= NULL
);
48 ArpService
->Signature
= ARP_SERVICE_DATA_SIGNATURE
;
53 InitializeListHead (&ArpService
->ChildrenList
);
54 InitializeListHead (&ArpService
->PendingRequestTable
);
55 InitializeListHead (&ArpService
->DeniedCacheTable
);
56 InitializeListHead (&ArpService
->ResolvedCacheTable
);
59 // Init the servicebinding protocol members.
61 ArpService
->ServiceBinding
.CreateChild
= ArpServiceBindingCreateChild
;
62 ArpService
->ServiceBinding
.DestroyChild
= ArpServiceBindingDestroyChild
;
67 ArpService
->ImageHandle
= ImageHandle
;
68 ArpService
->ControllerHandle
= ControllerHandle
;
71 // Create a MNP child instance.
73 Status
= NetLibCreateServiceChild (
76 &gEfiManagedNetworkServiceBindingProtocolGuid
,
77 &ArpService
->MnpChildHandle
79 if (EFI_ERROR (Status
)) {
84 // Open the MNP protocol.
86 Status
= gBS
->OpenProtocol (
87 ArpService
->MnpChildHandle
,
88 &gEfiManagedNetworkProtocolGuid
,
89 (VOID
**)&ArpService
->Mnp
,
92 EFI_OPEN_PROTOCOL_BY_DRIVER
94 if (EFI_ERROR (Status
)) {
99 // Get the underlayer Snp mode data.
101 Status
= ArpService
->Mnp
->GetModeData (ArpService
->Mnp
, NULL
, &ArpService
->SnpMode
);
102 if ((Status
!= EFI_NOT_STARTED
) && EFI_ERROR (Status
)) {
106 if (ArpService
->SnpMode
.IfType
!= NET_IFTYPE_ETHERNET
) {
108 // Only support the ethernet.
110 Status
= EFI_UNSUPPORTED
;
115 // Set the Mnp config parameters.
117 ArpService
->MnpConfigData
.ReceivedQueueTimeoutValue
= 0;
118 ArpService
->MnpConfigData
.TransmitQueueTimeoutValue
= 0;
119 ArpService
->MnpConfigData
.ProtocolTypeFilter
= ARP_ETHER_PROTO_TYPE
;
120 ArpService
->MnpConfigData
.EnableUnicastReceive
= TRUE
;
121 ArpService
->MnpConfigData
.EnableMulticastReceive
= FALSE
;
122 ArpService
->MnpConfigData
.EnableBroadcastReceive
= TRUE
;
123 ArpService
->MnpConfigData
.EnablePromiscuousReceive
= FALSE
;
124 ArpService
->MnpConfigData
.FlushQueuesOnReset
= TRUE
;
125 ArpService
->MnpConfigData
.EnableReceiveTimestamps
= FALSE
;
126 ArpService
->MnpConfigData
.DisableBackgroundPolling
= FALSE
;
129 // Configure the Mnp child.
131 Status
= ArpService
->Mnp
->Configure (ArpService
->Mnp
, &ArpService
->MnpConfigData
);
132 if (EFI_ERROR (Status
)) {
137 // Create the event used in the RxToken.
139 Status
= gBS
->CreateEvent (
144 &ArpService
->RxToken
.Event
146 if (EFI_ERROR (Status
)) {
151 // Create the Arp heartbeat timer.
153 Status
= gBS
->CreateEvent (
154 EVT_NOTIFY_SIGNAL
| EVT_TIMER
,
158 &ArpService
->PeriodicTimer
160 if (EFI_ERROR (Status
)) {
165 // Start the heartbeat timer.
167 Status
= gBS
->SetTimer (
168 ArpService
->PeriodicTimer
,
170 ARP_PERIODIC_TIMER_INTERVAL
179 Clean the arp service context data.
181 @param[in, out] ArpService Pointer to the buffer containing the arp service
189 IN OUT ARP_SERVICE_DATA
*ArpService
192 NET_CHECK_SIGNATURE (ArpService
, ARP_SERVICE_DATA_SIGNATURE
);
194 if (ArpService
->PeriodicTimer
!= NULL
) {
196 // Cancel and close the PeriodicTimer.
198 gBS
->SetTimer (ArpService
->PeriodicTimer
, TimerCancel
, 0);
199 gBS
->CloseEvent (ArpService
->PeriodicTimer
);
202 if (ArpService
->RxToken
.Event
!= NULL
) {
204 // Cancel the RxToken and close the event in the RxToken.
206 ArpService
->Mnp
->Cancel (ArpService
->Mnp
, NULL
);
207 gBS
->CloseEvent (ArpService
->RxToken
.Event
);
210 if (ArpService
->Mnp
!= NULL
) {
212 // Reset the Mnp child and close the Mnp protocol.
214 ArpService
->Mnp
->Configure (ArpService
->Mnp
, NULL
);
216 ArpService
->MnpChildHandle
,
217 &gEfiManagedNetworkProtocolGuid
,
218 ArpService
->ImageHandle
,
219 ArpService
->ControllerHandle
223 if (ArpService
->MnpChildHandle
!= NULL
) {
225 // Destroy the mnp child.
227 NetLibDestroyServiceChild (
228 ArpService
->ControllerHandle
,
229 ArpService
->ImageHandle
,
230 &gEfiManagedNetworkServiceBindingProtocolGuid
,
231 ArpService
->MnpChildHandle
237 Callback function which provided by user to remove one node in NetDestroyLinkList process.
239 @param[in] Entry The entry to be removed.
240 @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
242 @retval EFI_SUCCESS The entry has been removed successfully.
243 @retval Others Fail to remove the entry.
248 ArpDestroyChildEntryInHandleBuffer (
249 IN LIST_ENTRY
*Entry
,
253 ARP_INSTANCE_DATA
*Instance
;
254 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
256 if ((Entry
== NULL
) || (Context
== NULL
)) {
257 return EFI_INVALID_PARAMETER
;
260 Instance
= NET_LIST_USER_STRUCT_S (Entry
, ARP_INSTANCE_DATA
, List
, ARP_INSTANCE_DATA_SIGNATURE
);
261 ServiceBinding
= (EFI_SERVICE_BINDING_PROTOCOL
*)Context
;
263 return ServiceBinding
->DestroyChild (ServiceBinding
, Instance
->Handle
);
267 Tests to see if this driver supports a given controller.
269 If a child device is provided, it further tests to see if this driver supports
270 creating a handle for the specified child device.
272 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
273 @param[in] ControllerHandle The handle of the controller to test. This handle
274 must support a protocol interface that supplies
275 an I/O abstraction to the driver.
276 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path.
277 This parameter is ignored by device drivers,
278 and is optional for bus drivers.
280 @retval EFI_SUCCESS The device specified by ControllerHandle and
281 RemainingDevicePath is supported by the driver
283 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
284 RemainingDevicePath is already being managed
285 by the driver specified by This.
286 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
287 RemainingDevicePath is already being managed by
288 a different driver or an application that
289 requires exclusive access. Currently not implemented.
290 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
291 RemainingDevicePath is not supported by the
292 driver specified by This.
297 ArpDriverBindingSupported (
298 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
299 IN EFI_HANDLE ControllerHandle
,
300 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
306 // Test to see if Arp SB is already installed.
308 Status
= gBS
->OpenProtocol (
310 &gEfiArpServiceBindingProtocolGuid
,
312 This
->DriverBindingHandle
,
314 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
316 if (Status
== EFI_SUCCESS
) {
317 return EFI_ALREADY_STARTED
;
321 // Test to see if MNP SB is installed.
323 Status
= gBS
->OpenProtocol (
325 &gEfiManagedNetworkServiceBindingProtocolGuid
,
327 This
->DriverBindingHandle
,
329 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
336 Start this driver on ControllerHandle.
338 The Start() function is designed to be invoked from the EFI boot service ConnectController().
339 As a result, much of the error checking on the parameters to Start() has been
340 moved into this common boot service. It is legal to call Start() from other locations,
341 but the following calling restrictions must be followed or the system behavior
342 will not be deterministic.
343 1. ControllerHandle must be a valid EFI_HANDLE.
344 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally
345 aligned EFI_DEVICE_PATH_PROTOCOL.
346 3. Prior to calling Start(), the Supported() function for the driver specified
347 by This must have been called with the same calling parameters, and Supported()
348 must have returned EFI_SUCCESS.
350 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
351 @param[in] ControllerHandle The handle of the controller to start. This handle
352 must support a protocol interface that supplies
353 an I/O abstraction to the driver.
354 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path.
355 This parameter is ignored by device drivers,
356 and is optional for bus drivers.
358 @retval EFI_SUCCESS The device was started.
359 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.
360 Currently not implemented.
361 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of
363 @retval Others The driver failed to start the device.
368 ArpDriverBindingStart (
369 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
370 IN EFI_HANDLE ControllerHandle
,
371 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
375 ARP_SERVICE_DATA
*ArpService
;
378 // Allocate a zero pool for ArpService.
380 ArpService
= AllocateZeroPool (sizeof (ARP_SERVICE_DATA
));
381 if (ArpService
== NULL
) {
382 return EFI_OUT_OF_RESOURCES
;
386 // Initialize the arp service context data.
388 Status
= ArpCreateService (This
->DriverBindingHandle
, ControllerHandle
, ArpService
);
389 if (EFI_ERROR (Status
)) {
394 // Install the ARP service binding protocol.
396 Status
= gBS
->InstallMultipleProtocolInterfaces (
398 &gEfiArpServiceBindingProtocolGuid
,
399 &ArpService
->ServiceBinding
,
402 if (EFI_ERROR (Status
)) {
407 // OK, start to receive arp packets from Mnp.
409 Status
= ArpService
->Mnp
->Receive (ArpService
->Mnp
, &ArpService
->RxToken
);
410 if (EFI_ERROR (Status
)) {
419 // On error, clean the arp service context data, and free the memory allocated.
421 ArpCleanService (ArpService
);
422 FreePool (ArpService
);
428 Stop this driver on ControllerHandle.
430 Release the control of this controller and remove the IScsi functions. The Stop()
431 function is designed to be invoked from the EFI boot service DisconnectController().
432 As a result, much of the error checking on the parameters to Stop() has been moved
433 into this common boot service. It is legal to call Stop() from other locations,
434 but the following calling restrictions must be followed or the system behavior
435 will not be deterministic.
436 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
437 same driver's Start() function.
438 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
439 EFI_HANDLE. In addition, all of these handles must have been created in this driver's
440 Start() function, and the Start() function must have called OpenProtocol() on
441 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
443 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
444 @param[in] ControllerHandle A handle to the device being stopped. The handle must
445 support a bus specific I/O protocol for the driver
446 to use to stop the device.
447 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
449 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
450 if NumberOfChildren is 0.Not used.
452 @retval EFI_SUCCESS The device was stopped.
453 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
458 ArpDriverBindingStop (
459 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
460 IN EFI_HANDLE ControllerHandle
,
461 IN UINTN NumberOfChildren
,
462 IN EFI_HANDLE
*ChildHandleBuffer
466 EFI_HANDLE NicHandle
;
467 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
468 ARP_SERVICE_DATA
*ArpService
;
472 // Get the NicHandle which the arp servicebinding is installed on.
474 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiManagedNetworkProtocolGuid
);
475 if (NicHandle
== NULL
) {
480 // Try to get the arp servicebinding protocol on the NicHandle.
482 Status
= gBS
->OpenProtocol (
484 &gEfiArpServiceBindingProtocolGuid
,
485 (VOID
**)&ServiceBinding
,
486 This
->DriverBindingHandle
,
488 EFI_OPEN_PROTOCOL_GET_PROTOCOL
490 if (EFI_ERROR (Status
)) {
491 DEBUG ((DEBUG_ERROR
, "ArpDriverBindingStop: Open ArpSb failed, %r.\n", Status
));
492 return EFI_DEVICE_ERROR
;
495 ArpService
= ARP_SERVICE_DATA_FROM_THIS (ServiceBinding
);
497 if (NumberOfChildren
!= 0) {
499 // NumberOfChildren is not zero, destroy all the ARP children instances.
501 List
= &ArpService
->ChildrenList
;
502 Status
= NetDestroyLinkList (
504 ArpDestroyChildEntryInHandleBuffer
,
508 ASSERT (IsListEmpty (&ArpService
->PendingRequestTable
));
509 ASSERT (IsListEmpty (&ArpService
->DeniedCacheTable
));
510 ASSERT (IsListEmpty (&ArpService
->ResolvedCacheTable
));
511 } else if (IsListEmpty (&ArpService
->ChildrenList
)) {
513 // Uninstall the ARP ServiceBinding protocol.
515 gBS
->UninstallMultipleProtocolInterfaces (
517 &gEfiArpServiceBindingProtocolGuid
,
518 &ArpService
->ServiceBinding
,
523 // Clean the arp servicebinding context data and free the memory allocated.
525 ArpCleanService (ArpService
);
527 FreePool (ArpService
);
534 Creates a child handle and installs a protocol.
536 The CreateChild() function installs a protocol on ChildHandle.
537 If ChildHandle is a pointer to NULL, then a new handle is created and returned
538 in ChildHandle. If ChildHandle is not a pointer to NULL, then the protocol
539 installs on the existing ChildHandle.
541 @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
542 @param ChildHandle Pointer to the handle of the child to create. If it is NULL,
543 then a new handle is created. If it is a pointer to an existing
544 UEFI handle, then the protocol is added to the existing UEFI handle.
546 @retval EFI_SUCCESS The protocol was added to ChildHandle.
547 @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
548 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
550 @retval other The child handle was not created
555 ArpServiceBindingCreateChild (
556 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
557 IN EFI_HANDLE
*ChildHandle
561 ARP_SERVICE_DATA
*ArpService
;
562 ARP_INSTANCE_DATA
*Instance
;
566 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
567 return EFI_INVALID_PARAMETER
;
570 ArpService
= ARP_SERVICE_DATA_FROM_THIS (This
);
573 // Allocate memory for the instance context data.
575 Instance
= AllocateZeroPool (sizeof (ARP_INSTANCE_DATA
));
576 if (Instance
== NULL
) {
577 DEBUG ((DEBUG_ERROR
, "ArpSBCreateChild: Failed to allocate memory for Instance.\n"));
579 return EFI_OUT_OF_RESOURCES
;
583 // Init the instance context data.
585 ArpInitInstance (ArpService
, Instance
);
588 // Install the ARP protocol onto the ChildHandle.
590 Status
= gBS
->InstallMultipleProtocolInterfaces (
592 &gEfiArpProtocolGuid
,
593 (VOID
*)&Instance
->ArpProto
,
596 if (EFI_ERROR (Status
)) {
597 DEBUG ((DEBUG_ERROR
, "ArpSBCreateChild: failed to install ARP protocol, %r.\n", Status
));
604 // Save the ChildHandle.
606 Instance
->Handle
= *ChildHandle
;
609 // Open the Managed Network protocol BY_CHILD.
611 Status
= gBS
->OpenProtocol (
612 ArpService
->MnpChildHandle
,
613 &gEfiManagedNetworkProtocolGuid
,
615 gArpDriverBinding
.DriverBindingHandle
,
617 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
619 if (EFI_ERROR (Status
)) {
623 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
626 // Insert the instance into children list managed by the arp service context data.
628 InsertTailList (&ArpService
->ChildrenList
, &Instance
->List
);
629 ArpService
->ChildrenNumber
++;
631 gBS
->RestoreTPL (OldTpl
);
635 if (EFI_ERROR (Status
)) {
637 ArpService
->MnpChildHandle
,
638 &gEfiManagedNetworkProtocolGuid
,
639 gArpDriverBinding
.DriverBindingHandle
,
643 gBS
->UninstallMultipleProtocolInterfaces (
645 &gEfiArpProtocolGuid
,
651 // Free the allocated memory.
660 Destroys a child handle with a protocol installed on it.
662 The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
663 that was installed by CreateChild() from ChildHandle. If the removed protocol is the
664 last protocol on ChildHandle, then ChildHandle is destroyed.
666 @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
667 @param ChildHandle Handle of the child to destroy
669 @retval EFI_SUCCESS The protocol was removed from ChildHandle.
670 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is
672 @retval EFI_INVALID_PARAMETER Child handle is NULL.
673 @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
674 because its services are being used.
675 @retval other The child handle was not destroyed
680 ArpServiceBindingDestroyChild (
681 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
682 IN EFI_HANDLE ChildHandle
686 ARP_SERVICE_DATA
*ArpService
;
687 ARP_INSTANCE_DATA
*Instance
;
688 EFI_ARP_PROTOCOL
*Arp
;
691 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
692 return EFI_INVALID_PARAMETER
;
695 ArpService
= ARP_SERVICE_DATA_FROM_THIS (This
);
698 // Get the arp protocol.
700 Status
= gBS
->OpenProtocol (
702 &gEfiArpProtocolGuid
,
704 ArpService
->ImageHandle
,
706 EFI_OPEN_PROTOCOL_GET_PROTOCOL
708 if (EFI_ERROR (Status
)) {
709 return EFI_UNSUPPORTED
;
712 Instance
= ARP_INSTANCE_DATA_FROM_THIS (Arp
);
714 if (Instance
->InDestroy
) {
719 // Use the InDestroy as a flag to avoid re-entrance.
721 Instance
->InDestroy
= TRUE
;
724 // Close the Managed Network protocol.
727 ArpService
->MnpChildHandle
,
728 &gEfiManagedNetworkProtocolGuid
,
729 gArpDriverBinding
.DriverBindingHandle
,
734 // Uninstall the ARP protocol.
736 Status
= gBS
->UninstallMultipleProtocolInterfaces (
738 &gEfiArpProtocolGuid
,
742 if (EFI_ERROR (Status
)) {
745 "ArpSBDestroyChild: Failed to uninstall the arp protocol, %r.\n",
749 Instance
->InDestroy
= FALSE
;
753 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
755 if (Instance
->Configured
) {
757 // Delete the related cache entry.
759 ArpDeleteCacheEntry (Instance
, FALSE
, NULL
, TRUE
);
762 // Reset the instance configuration.
764 ArpConfigureInstance (Instance
, NULL
);
768 // Remove this instance from the ChildrenList.
770 RemoveEntryList (&Instance
->List
);
771 ArpService
->ChildrenNumber
--;
773 gBS
->RestoreTPL (OldTpl
);
781 The entry point for Arp driver which installs the driver binding and component name
782 protocol on its ImageHandle.
784 @param[in] ImageHandle The image handle of the driver.
785 @param[in] SystemTable The system table.
787 @retval EFI_SUCCESS if the driver binding and component name protocols
789 @retval Others Failed to install the protocols.
794 ArpDriverEntryPoint (
795 IN EFI_HANDLE ImageHandle
,
796 IN EFI_SYSTEM_TABLE
*SystemTable
799 return EfiLibInstallDriverBindingComponentName2 (