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
,
23 Create and initialize the arp service context data.
25 @param[in] ImageHandle The image handle representing the loaded driver
27 @param[in] ControllerHandle The controller handle the driver binds to.
28 @param[in, out] ArpService Pointer to the buffer containing the arp service
31 @retval EFI_SUCCESS The arp service context is initialized.
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.
40 IN EFI_HANDLE ImageHandle
,
41 IN EFI_HANDLE ControllerHandle
,
42 IN OUT ARP_SERVICE_DATA
*ArpService
47 ASSERT (ArpService
!= NULL
);
49 ArpService
->Signature
= ARP_SERVICE_DATA_SIGNATURE
;
54 InitializeListHead (&ArpService
->ChildrenList
);
55 InitializeListHead (&ArpService
->PendingRequestTable
);
56 InitializeListHead (&ArpService
->DeniedCacheTable
);
57 InitializeListHead (&ArpService
->ResolvedCacheTable
);
60 // Init the servicebinding protocol members.
62 ArpService
->ServiceBinding
.CreateChild
= ArpServiceBindingCreateChild
;
63 ArpService
->ServiceBinding
.DestroyChild
= ArpServiceBindingDestroyChild
;
68 ArpService
->ImageHandle
= ImageHandle
;
69 ArpService
->ControllerHandle
= ControllerHandle
;
72 // Create a MNP child instance.
74 Status
= NetLibCreateServiceChild (
77 &gEfiManagedNetworkServiceBindingProtocolGuid
,
78 &ArpService
->MnpChildHandle
80 if (EFI_ERROR (Status
)) {
85 // Open the MNP protocol.
87 Status
= gBS
->OpenProtocol (
88 ArpService
->MnpChildHandle
,
89 &gEfiManagedNetworkProtocolGuid
,
90 (VOID
**)&ArpService
->Mnp
,
93 EFI_OPEN_PROTOCOL_BY_DRIVER
95 if (EFI_ERROR (Status
)) {
100 // Get the underlayer Snp mode data.
102 Status
= ArpService
->Mnp
->GetModeData (ArpService
->Mnp
, NULL
, &ArpService
->SnpMode
);
103 if ((Status
!= EFI_NOT_STARTED
) && EFI_ERROR (Status
)) {
107 if (ArpService
->SnpMode
.IfType
!= NET_IFTYPE_ETHERNET
) {
109 // Only support the ethernet.
111 Status
= EFI_UNSUPPORTED
;
116 // Set the Mnp config parameters.
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
;
130 // Configure the Mnp child.
132 Status
= ArpService
->Mnp
->Configure (ArpService
->Mnp
, &ArpService
->MnpConfigData
);
133 if (EFI_ERROR (Status
)) {
138 // Create the event used in the RxToken.
140 Status
= gBS
->CreateEvent (
145 &ArpService
->RxToken
.Event
147 if (EFI_ERROR (Status
)) {
152 // Create the Arp heartbeat timer.
154 Status
= gBS
->CreateEvent (
155 EVT_NOTIFY_SIGNAL
| EVT_TIMER
,
159 &ArpService
->PeriodicTimer
161 if (EFI_ERROR (Status
)) {
166 // Start the heartbeat timer.
168 Status
= gBS
->SetTimer (
169 ArpService
->PeriodicTimer
,
171 ARP_PERIODIC_TIMER_INTERVAL
181 Clean the arp service context data.
183 @param[in, out] ArpService Pointer to the buffer containing the arp service
191 IN OUT ARP_SERVICE_DATA
*ArpService
194 NET_CHECK_SIGNATURE (ArpService
, ARP_SERVICE_DATA_SIGNATURE
);
196 if (ArpService
->PeriodicTimer
!= NULL
) {
198 // Cancle and close the PeriodicTimer.
200 gBS
->SetTimer (ArpService
->PeriodicTimer
, TimerCancel
, 0);
201 gBS
->CloseEvent (ArpService
->PeriodicTimer
);
204 if (ArpService
->RxToken
.Event
!= NULL
) {
206 // Cancle the RxToken and close the event in the RxToken.
208 ArpService
->Mnp
->Cancel (ArpService
->Mnp
, NULL
);
209 gBS
->CloseEvent (ArpService
->RxToken
.Event
);
212 if (ArpService
->Mnp
!= NULL
) {
214 // Reset the Mnp child and close the Mnp protocol.
216 ArpService
->Mnp
->Configure (ArpService
->Mnp
, NULL
);
218 ArpService
->MnpChildHandle
,
219 &gEfiManagedNetworkProtocolGuid
,
220 ArpService
->ImageHandle
,
221 ArpService
->ControllerHandle
225 if (ArpService
->MnpChildHandle
!= NULL
) {
227 // Destroy the mnp child.
229 NetLibDestroyServiceChild(
230 ArpService
->ControllerHandle
,
231 ArpService
->ImageHandle
,
232 &gEfiManagedNetworkServiceBindingProtocolGuid
,
233 ArpService
->MnpChildHandle
239 Callback function which provided by user to remove one node in NetDestroyLinkList process.
241 @param[in] Entry The entry to be removed.
242 @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
244 @retval EFI_SUCCESS The entry has been removed successfully.
245 @retval Others Fail to remove the entry.
250 ArpDestroyChildEntryInHandleBuffer (
251 IN LIST_ENTRY
*Entry
,
255 ARP_INSTANCE_DATA
*Instance
;
256 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
258 if (Entry
== NULL
|| Context
== NULL
) {
259 return EFI_INVALID_PARAMETER
;
262 Instance
= NET_LIST_USER_STRUCT_S (Entry
, ARP_INSTANCE_DATA
, List
, ARP_INSTANCE_DATA_SIGNATURE
);
263 ServiceBinding
= (EFI_SERVICE_BINDING_PROTOCOL
*) Context
;
265 return ServiceBinding
->DestroyChild (ServiceBinding
, Instance
->Handle
);
269 Tests to see if this driver supports a given controller.
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.
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.
282 @retval EFI_SUCCESS The device specified by ControllerHandle and
283 RemainingDevicePath is supported by the driver
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.
299 ArpDriverBindingSupported (
300 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
301 IN EFI_HANDLE ControllerHandle
,
302 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
308 // Test to see if Arp SB is already installed.
310 Status
= gBS
->OpenProtocol (
312 &gEfiArpServiceBindingProtocolGuid
,
314 This
->DriverBindingHandle
,
316 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
318 if (Status
== EFI_SUCCESS
) {
319 return EFI_ALREADY_STARTED
;
323 // Test to see if MNP SB is installed.
325 Status
= gBS
->OpenProtocol (
327 &gEfiManagedNetworkServiceBindingProtocolGuid
,
329 This
->DriverBindingHandle
,
331 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
339 Start this driver on ControllerHandle.
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.
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.
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
366 @retval Others The driver failded to start the device.
371 ArpDriverBindingStart (
372 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
373 IN EFI_HANDLE ControllerHandle
,
374 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
378 ARP_SERVICE_DATA
*ArpService
;
381 // Allocate a zero pool for ArpService.
383 ArpService
= AllocateZeroPool (sizeof(ARP_SERVICE_DATA
));
384 if (ArpService
== NULL
) {
385 return EFI_OUT_OF_RESOURCES
;
389 // Initialize the arp service context data.
391 Status
= ArpCreateService (This
->DriverBindingHandle
, ControllerHandle
, ArpService
);
392 if (EFI_ERROR (Status
)) {
397 // Install the ARP service binding protocol.
399 Status
= gBS
->InstallMultipleProtocolInterfaces (
401 &gEfiArpServiceBindingProtocolGuid
,
402 &ArpService
->ServiceBinding
,
405 if (EFI_ERROR (Status
)) {
410 // OK, start to receive arp packets from Mnp.
412 Status
= ArpService
->Mnp
->Receive (ArpService
->Mnp
, &ArpService
->RxToken
);
413 if (EFI_ERROR (Status
)) {
422 // On error, clean the arp service context data, and free the memory allocated.
424 ArpCleanService (ArpService
);
425 FreePool (ArpService
);
432 Stop this driver on ControllerHandle.
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.
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.
453 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
454 if NumberOfChildren is 0.Not used.
456 @retval EFI_SUCCESS The device was stopped.
457 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
462 ArpDriverBindingStop (
463 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
464 IN EFI_HANDLE ControllerHandle
,
465 IN UINTN NumberOfChildren
,
466 IN EFI_HANDLE
*ChildHandleBuffer
470 EFI_HANDLE NicHandle
;
471 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
472 ARP_SERVICE_DATA
*ArpService
;
476 // Get the NicHandle which the arp servicebinding is installed on.
478 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiManagedNetworkProtocolGuid
);
479 if (NicHandle
== NULL
) {
484 // Try to get the arp servicebinding protocol on the NicHandle.
486 Status
= gBS
->OpenProtocol (
488 &gEfiArpServiceBindingProtocolGuid
,
489 (VOID
**)&ServiceBinding
,
490 This
->DriverBindingHandle
,
492 EFI_OPEN_PROTOCOL_GET_PROTOCOL
494 if (EFI_ERROR (Status
)) {
495 DEBUG ((EFI_D_ERROR
, "ArpDriverBindingStop: Open ArpSb failed, %r.\n", Status
));
496 return EFI_DEVICE_ERROR
;
499 ArpService
= ARP_SERVICE_DATA_FROM_THIS (ServiceBinding
);
501 if (NumberOfChildren
!= 0) {
503 // NumberOfChildren is not zero, destroy all the ARP children instances.
505 List
= &ArpService
->ChildrenList
;
506 Status
= NetDestroyLinkList (
508 ArpDestroyChildEntryInHandleBuffer
,
512 ASSERT (IsListEmpty (&ArpService
->PendingRequestTable
));
513 ASSERT (IsListEmpty (&ArpService
->DeniedCacheTable
));
514 ASSERT (IsListEmpty (&ArpService
->ResolvedCacheTable
));
515 } else if (IsListEmpty (&ArpService
->ChildrenList
)) {
517 // Uninstall the ARP ServiceBinding protocol.
519 gBS
->UninstallMultipleProtocolInterfaces (
521 &gEfiArpServiceBindingProtocolGuid
,
522 &ArpService
->ServiceBinding
,
527 // Clean the arp servicebinding context data and free the memory allocated.
529 ArpCleanService (ArpService
);
531 FreePool (ArpService
);
538 Creates a child handle and installs a protocol.
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.
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.
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
554 @retval other The child handle was not created
559 ArpServiceBindingCreateChild (
560 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
561 IN EFI_HANDLE
*ChildHandle
565 ARP_SERVICE_DATA
*ArpService
;
566 ARP_INSTANCE_DATA
*Instance
;
570 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
571 return EFI_INVALID_PARAMETER
;
574 ArpService
= ARP_SERVICE_DATA_FROM_THIS (This
);
577 // Allocate memory for the instance context data.
579 Instance
= AllocateZeroPool (sizeof(ARP_INSTANCE_DATA
));
580 if (Instance
== NULL
) {
581 DEBUG ((EFI_D_ERROR
, "ArpSBCreateChild: Failed to allocate memory for Instance.\n"));
583 return EFI_OUT_OF_RESOURCES
;
587 // Init the instance context data.
589 ArpInitInstance (ArpService
, Instance
);
592 // Install the ARP protocol onto the ChildHandle.
594 Status
= gBS
->InstallMultipleProtocolInterfaces (
596 &gEfiArpProtocolGuid
,
597 (VOID
*)&Instance
->ArpProto
,
600 if (EFI_ERROR (Status
)) {
601 DEBUG ((EFI_D_ERROR
, "ArpSBCreateChild: faild to install ARP protocol, %r.\n", Status
));
608 // Save the ChildHandle.
610 Instance
->Handle
= *ChildHandle
;
613 // Open the Managed Network protocol BY_CHILD.
615 Status
= gBS
->OpenProtocol (
616 ArpService
->MnpChildHandle
,
617 &gEfiManagedNetworkProtocolGuid
,
619 gArpDriverBinding
.DriverBindingHandle
,
621 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
623 if (EFI_ERROR (Status
)) {
627 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
630 // Insert the instance into children list managed by the arp service context data.
632 InsertTailList (&ArpService
->ChildrenList
, &Instance
->List
);
633 ArpService
->ChildrenNumber
++;
635 gBS
->RestoreTPL (OldTpl
);
639 if (EFI_ERROR (Status
)) {
642 ArpService
->MnpChildHandle
,
643 &gEfiManagedNetworkProtocolGuid
,
644 gArpDriverBinding
.DriverBindingHandle
,
648 gBS
->UninstallMultipleProtocolInterfaces (
650 &gEfiArpProtocolGuid
,
656 // Free the allocated memory.
666 Destroys a child handle with a protocol installed on it.
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.
672 @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
673 @param ChildHandle Handle of the child to destroy
675 @retval EFI_SUCCES The protocol was removed from ChildHandle.
676 @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is
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
686 ArpServiceBindingDestroyChild (
687 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
688 IN EFI_HANDLE ChildHandle
692 ARP_SERVICE_DATA
*ArpService
;
693 ARP_INSTANCE_DATA
*Instance
;
694 EFI_ARP_PROTOCOL
*Arp
;
697 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
698 return EFI_INVALID_PARAMETER
;
701 ArpService
= ARP_SERVICE_DATA_FROM_THIS (This
);
704 // Get the arp protocol.
706 Status
= gBS
->OpenProtocol (
708 &gEfiArpProtocolGuid
,
710 ArpService
->ImageHandle
,
712 EFI_OPEN_PROTOCOL_GET_PROTOCOL
714 if (EFI_ERROR (Status
)) {
715 return EFI_UNSUPPORTED
;
718 Instance
= ARP_INSTANCE_DATA_FROM_THIS (Arp
);
720 if (Instance
->InDestroy
) {
725 // Use the InDestroy as a flag to avoid re-entrance.
727 Instance
->InDestroy
= TRUE
;
730 // Close the Managed Network protocol.
733 ArpService
->MnpChildHandle
,
734 &gEfiManagedNetworkProtocolGuid
,
735 gArpDriverBinding
.DriverBindingHandle
,
740 // Uninstall the ARP protocol.
742 Status
= gBS
->UninstallMultipleProtocolInterfaces (
744 &gEfiArpProtocolGuid
,
748 if (EFI_ERROR (Status
)) {
749 DEBUG ((EFI_D_ERROR
, "ArpSBDestroyChild: Failed to uninstall the arp protocol, %r.\n",
752 Instance
->InDestroy
= FALSE
;
756 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
758 if (Instance
->Configured
) {
760 // Delete the related cache entry.
762 ArpDeleteCacheEntry (Instance
, FALSE
, NULL
, TRUE
);
765 // Reset the instance configuration.
767 ArpConfigureInstance (Instance
, NULL
);
771 // Remove this instance from the ChildrenList.
773 RemoveEntryList (&Instance
->List
);
774 ArpService
->ChildrenNumber
--;
776 gBS
->RestoreTPL (OldTpl
);
784 The entry point for Arp driver which installs the driver binding and component name
785 protocol on its ImageHandle.
787 @param[in] ImageHandle The image handle of the driver.
788 @param[in] SystemTable The system table.
790 @retval EFI_SUCCESS if the driver binding and component name protocols
792 @retval Others Failed to install the protocols.
797 ArpDriverEntryPoint (
798 IN EFI_HANDLE ImageHandle
,
799 IN EFI_SYSTEM_TABLE
*SystemTable
802 return EfiLibInstallDriverBindingComponentName2 (