3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
22 #include "ArpDriver.h"
25 EFI_DRIVER_BINDING_PROTOCOL gArpDriverBinding
= {
26 ArpDriverBindingSupported
,
27 ArpDriverBindingStart
,
36 Create and initialize the arp service context data.
38 @param ImageHandle The image handle representing the loaded driver
40 @param ControllerHandle The controller handle the driver binds to.
41 @param ArpService Pointer to the buffer containing the arp service
44 @retval EFI_SUCCESS The arp service context is initialized.
45 @retval other Failed to initialize the arp service context.
51 IN EFI_HANDLE ImageHandle
,
52 IN EFI_HANDLE ControllerHandle
,
53 IN ARP_SERVICE_DATA
*ArpService
58 ASSERT (ArpService
!= NULL
);
60 ArpService
->Signature
= ARP_SERVICE_DATA_SIGNATURE
;
63 // Init the servicebinding protocol members.
65 ArpService
->ServiceBinding
.CreateChild
= ArpServiceBindingCreateChild
;
66 ArpService
->ServiceBinding
.DestroyChild
= ArpServiceBindingDestroyChild
;
71 ArpService
->ImageHandle
= ImageHandle
;
72 ArpService
->ControllerHandle
= ControllerHandle
;
75 // Create a MNP child instance.
77 Status
= NetLibCreateServiceChild (
80 &gEfiManagedNetworkServiceBindingProtocolGuid
,
81 &ArpService
->MnpChildHandle
83 if (EFI_ERROR (Status
)) {
88 // Open the MNP protocol.
90 Status
= gBS
->OpenProtocol (
91 ArpService
->MnpChildHandle
,
92 &gEfiManagedNetworkProtocolGuid
,
93 (VOID
**)&ArpService
->Mnp
,
96 EFI_OPEN_PROTOCOL_BY_DRIVER
98 if (EFI_ERROR (Status
)) {
103 // Get the underlayer Snp mode data.
105 Status
= ArpService
->Mnp
->GetModeData (ArpService
->Mnp
, NULL
, &ArpService
->SnpMode
);
106 if ((Status
!= EFI_NOT_STARTED
) && EFI_ERROR (Status
)) {
110 if (ArpService
->SnpMode
.IfType
!= NET_IFTYPE_ETHERNET
) {
112 // Only support the ethernet.
114 Status
= EFI_UNSUPPORTED
;
119 // Set the Mnp config parameters.
121 ArpService
->MnpConfigData
.ReceivedQueueTimeoutValue
= 0;
122 ArpService
->MnpConfigData
.TransmitQueueTimeoutValue
= 0;
123 ArpService
->MnpConfigData
.ProtocolTypeFilter
= ARP_ETHER_PROTO_TYPE
;
124 ArpService
->MnpConfigData
.EnableUnicastReceive
= TRUE
;
125 ArpService
->MnpConfigData
.EnableMulticastReceive
= FALSE
;
126 ArpService
->MnpConfigData
.EnableBroadcastReceive
= TRUE
;
127 ArpService
->MnpConfigData
.EnablePromiscuousReceive
= FALSE
;
128 ArpService
->MnpConfigData
.FlushQueuesOnReset
= TRUE
;
129 ArpService
->MnpConfigData
.EnableReceiveTimestamps
= FALSE
;
130 ArpService
->MnpConfigData
.DisableBackgroundPolling
= FALSE
;
133 // Configure the Mnp child.
135 Status
= ArpService
->Mnp
->Configure (ArpService
->Mnp
, &ArpService
->MnpConfigData
);
136 if (EFI_ERROR (Status
)) {
141 // Create the event used in the RxToken.
143 Status
= gBS
->CreateEvent (
148 &ArpService
->RxToken
.Event
150 if (EFI_ERROR (Status
)) {
155 // Create the Arp heartbeat timer.
157 Status
= gBS
->CreateEvent (
158 EVT_NOTIFY_SIGNAL
| EVT_TIMER
,
162 &ArpService
->PeriodicTimer
164 if (EFI_ERROR (Status
)) {
169 // Start the heartbeat timer.
171 Status
= gBS
->SetTimer (
172 ArpService
->PeriodicTimer
,
174 ARP_PERIODIC_TIMER_INTERVAL
176 if (EFI_ERROR (Status
)) {
183 NET_LOCK_INIT (&ArpService
->Lock
);
188 NetListInit (&ArpService
->ChildrenList
);
189 NetListInit (&ArpService
->PendingRequestTable
);
190 NetListInit (&ArpService
->DeniedCacheTable
);
191 NetListInit (&ArpService
->ResolvedCacheTable
);
200 Clean the arp service context data.
202 @param ArpService Pointer to the buffer containing the arp service
211 IN ARP_SERVICE_DATA
*ArpService
214 NET_CHECK_SIGNATURE (ArpService
, ARP_SERVICE_DATA_SIGNATURE
);
216 if (ArpService
->PeriodicTimer
!= NULL
) {
218 // Cancle and close the PeriodicTimer.
220 gBS
->SetTimer (ArpService
->PeriodicTimer
, TimerCancel
, 0);
221 gBS
->CloseEvent (ArpService
->PeriodicTimer
);
224 if (ArpService
->RxToken
.Event
!= NULL
) {
226 // Cancle the RxToken and close the event in the RxToken.
228 ArpService
->Mnp
->Cancel (ArpService
->Mnp
, NULL
);
229 gBS
->CloseEvent (ArpService
->RxToken
.Event
);
232 if (ArpService
->Mnp
!= NULL
) {
234 // Reset the Mnp child and close the Mnp protocol.
236 ArpService
->Mnp
->Configure (ArpService
->Mnp
, NULL
);
238 ArpService
->MnpChildHandle
,
239 &gEfiManagedNetworkProtocolGuid
,
240 ArpService
->ImageHandle
,
241 ArpService
->ControllerHandle
245 if (ArpService
->MnpChildHandle
!= NULL
) {
247 // Destroy the mnp child.
249 NetLibDestroyServiceChild(
250 ArpService
->ControllerHandle
,
251 ArpService
->ImageHandle
,
252 &gEfiManagedNetworkServiceBindingProtocolGuid
,
253 ArpService
->MnpChildHandle
260 Test to see if this driver supports ControllerHandle.
262 @param This Protocol instance pointer.
263 @param ControllerHandle Handle of device to test.
264 @param RemainingDevicePath Optional parameter use to pick a specific child
267 @retval EFI_SUCCES This driver supports this device
268 @retval EFI_ALREADY_STARTED This driver is already running on this device.
269 @retval other This driver does not support this device.
274 ArpDriverBindingSupported (
275 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
276 IN EFI_HANDLE ControllerHandle
,
277 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
283 // Test to see if Arp SB is already installed.
285 Status
= gBS
->OpenProtocol (
287 &gEfiArpServiceBindingProtocolGuid
,
289 This
->DriverBindingHandle
,
291 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
293 if (Status
== EFI_SUCCESS
) {
294 return EFI_ALREADY_STARTED
;
298 // Test to see if MNP SB is installed.
300 Status
= gBS
->OpenProtocol (
302 &gEfiManagedNetworkServiceBindingProtocolGuid
,
304 This
->DriverBindingHandle
,
306 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
314 Start this driver on ControllerHandle.
316 @param This Protocol instance pointer.
317 @param ControllerHandle Handle of device to bind driver to
318 @param RemainingDevicePath Optional parameter use to pick a specific child
321 @retval EFI_SUCCES This driver is added to ControllerHandle
322 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
323 @retval other This driver does not support this device
328 ArpDriverBindingStart (
329 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
330 IN EFI_HANDLE ControllerHandle
,
331 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
335 ARP_SERVICE_DATA
*ArpService
;
338 // Allocate a zero pool for ArpService.
340 ArpService
= NetAllocateZeroPool (sizeof(ARP_SERVICE_DATA
));
341 if (ArpService
== NULL
) {
342 return EFI_OUT_OF_RESOURCES
;
346 // Initialize the arp service context data.
348 Status
= ArpCreateService (This
->DriverBindingHandle
, ControllerHandle
, ArpService
);
349 if (EFI_ERROR (Status
)) {
354 // Install the ARP service binding protocol.
356 Status
= gBS
->InstallMultipleProtocolInterfaces (
358 &gEfiArpServiceBindingProtocolGuid
,
359 &ArpService
->ServiceBinding
,
362 if (EFI_ERROR (Status
)) {
367 // OK, start to receive arp packets from Mnp.
369 Status
= ArpService
->Mnp
->Receive (ArpService
->Mnp
, &ArpService
->RxToken
);
370 if (EFI_ERROR (Status
)) {
379 // On error, clean the arp service context data, and free the memory allocated.
381 ArpCleanService (ArpService
);
382 NetFreePool (ArpService
);
389 Stop this driver on ControllerHandle.
391 @param This Protocol instance pointer.
392 @param ControllerHandle Handle of device to stop driver on
393 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number
394 of children is zero stop the entire bus driver.
395 @param ChildHandleBuffer List of Child Handles to Stop.
397 @retval EFI_SUCCES This driver is removed ControllerHandle
398 @retval other This driver was not removed from this device
403 ArpDriverBindingStop (
404 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
405 IN EFI_HANDLE ControllerHandle
,
406 IN UINTN NumberOfChildren
,
407 IN EFI_HANDLE
*ChildHandleBuffer
411 EFI_HANDLE NicHandle
;
412 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
413 ARP_SERVICE_DATA
*ArpService
;
414 ARP_INSTANCE_DATA
*Instance
;
417 // Get the NicHandle which the arp servicebinding is installed on.
419 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiManagedNetworkProtocolGuid
);
420 if (NicHandle
== NULL
) {
425 // Try to get the arp servicebinding protocol on the NicHandle.
427 Status
= gBS
->OpenProtocol (
429 &gEfiArpServiceBindingProtocolGuid
,
430 (VOID
**)&ServiceBinding
,
431 This
->DriverBindingHandle
,
433 EFI_OPEN_PROTOCOL_GET_PROTOCOL
435 if (EFI_ERROR (Status
)) {
436 ARP_DEBUG_ERROR (("ArpDriverBindingStop: Open ArpSb failed, %r.\n", Status
));
440 ArpService
= ARP_SERVICE_DATA_FROM_THIS (ServiceBinding
);
442 while (!NetListIsEmpty (&ArpService
->ChildrenList
)) {
444 // Iterate all the instances.
446 Instance
= NET_LIST_HEAD (&ArpService
->ChildrenList
, ARP_INSTANCE_DATA
, List
);
449 // Destroy this arp child.
451 ServiceBinding
->DestroyChild (ServiceBinding
, Instance
->Handle
);
454 ASSERT (NetListIsEmpty (&ArpService
->PendingRequestTable
));
455 ASSERT (NetListIsEmpty (&ArpService
->DeniedCacheTable
));
456 ASSERT (NetListIsEmpty (&ArpService
->ResolvedCacheTable
));
459 // Uninstall the ARP ServiceBinding protocol.
461 Status
= gBS
->UninstallMultipleProtocolInterfaces (
463 &gEfiArpServiceBindingProtocolGuid
,
464 &ArpService
->ServiceBinding
,
467 if (EFI_ERROR (Status
)) {
468 ARP_DEBUG_ERROR (("ArpDriverBindingStop: Failed to uninstall ArpSb, %r.\n", Status
));
473 // Clean the arp servicebinding context data and free the memory allocated.
475 ArpCleanService (ArpService
);
476 NetFreePool (ArpService
);
483 Creates a child handle with a set of I/O services.
485 @param This Protocol instance pointer.
486 @param ChildHandle Pointer to the handle of the child to create. If
487 it is NULL, then a new handle is created. If it is
488 not NULL, then the I/O services are added to the
489 existing child handle.
491 @retval EFI_SUCCES The child handle was created with the I/O
493 @retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to create
495 @retval other The child handle was not created.
500 ArpServiceBindingCreateChild (
501 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
502 IN EFI_HANDLE
*ChildHandle
506 ARP_SERVICE_DATA
*ArpService
;
507 ARP_INSTANCE_DATA
*Instance
;
510 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
511 return EFI_INVALID_PARAMETER
;
514 ArpService
= ARP_SERVICE_DATA_FROM_THIS (This
);
517 // Allocate memory for the instance context data.
519 Instance
= NetAllocateZeroPool (sizeof(ARP_INSTANCE_DATA
));
520 if (Instance
== NULL
) {
521 ARP_DEBUG_ERROR (("ArpSBCreateChild: Failed to allocate memory for Instance.\n"));
523 return EFI_OUT_OF_RESOURCES
;
527 // Init the instance context data.
529 ArpInitInstance (ArpService
, Instance
);
532 // Install the ARP protocol onto the ChildHandle.
534 Status
= gBS
->InstallMultipleProtocolInterfaces (
536 &gEfiArpProtocolGuid
,
537 (VOID
*)&Instance
->ArpProto
,
540 if (EFI_ERROR (Status
)) {
541 ARP_DEBUG_ERROR (("ArpSBCreateChild: faild to install ARP protocol, %r.\n", Status
));
543 NetFreePool (Instance
);
548 // Save the ChildHandle.
550 Instance
->Handle
= *ChildHandle
;
553 // Open the Managed Network protocol BY_CHILD.
555 Status
= gBS
->OpenProtocol (
556 ArpService
->MnpChildHandle
,
557 &gEfiManagedNetworkProtocolGuid
,
559 gArpDriverBinding
.DriverBindingHandle
,
561 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
563 if (EFI_ERROR (Status
)) {
567 if (EFI_ERROR (NET_TRYLOCK (&ArpService
->Lock
))) {
569 Status
= EFI_ACCESS_DENIED
;
574 // Insert the instance into children list managed by the arp service context data.
576 NetListInsertTail (&ArpService
->ChildrenList
, &Instance
->List
);
577 ArpService
->ChildrenNumber
++;
579 NET_UNLOCK (&ArpService
->Lock
);
583 if (EFI_ERROR (Status
)) {
586 ArpService
->MnpChildHandle
,
587 &gEfiManagedNetworkProtocolGuid
,
588 gArpDriverBinding
.DriverBindingHandle
,
592 gBS
->UninstallMultipleProtocolInterfaces (
594 &gEfiArpProtocolGuid
,
600 // Free the allocated memory.
602 NetFreePool (Instance
);
610 Destroys a child handle with a set of I/O services.
612 @param This Protocol instance pointer.
613 @param ChildHandle Handle of the child to destroy.
615 @retval EFI_SUCCES The I/O services were removed from the child
617 @retval EFI_UNSUPPORTED The child handle does not support the I/O services
618 that are being removed.
619 @retval EFI_INVALID_PARAMETER Child handle is not a valid EFI Handle.
620 @retval EFI_ACCESS_DENIED The child handle could not be destroyed because
621 its I/O services are being used.
622 @retval other The child handle was not destroyed.
627 ArpServiceBindingDestroyChild (
628 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
629 IN EFI_HANDLE ChildHandle
633 ARP_SERVICE_DATA
*ArpService
;
634 ARP_INSTANCE_DATA
*Instance
;
635 EFI_ARP_PROTOCOL
*Arp
;
637 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
638 return EFI_INVALID_PARAMETER
;
641 ArpService
= ARP_SERVICE_DATA_FROM_THIS (This
);
644 // Get the arp protocol.
646 Status
= gBS
->OpenProtocol (
648 &gEfiArpProtocolGuid
,
650 ArpService
->ImageHandle
,
652 EFI_OPEN_PROTOCOL_GET_PROTOCOL
654 if (EFI_ERROR (Status
)) {
655 return EFI_UNSUPPORTED
;
658 Instance
= ARP_INSTANCE_DATA_FROM_THIS (Arp
);
660 if (Instance
->Destroyed
) {
665 // Use the Destroyed as a flag to avoid re-entrance.
667 Instance
->Destroyed
= TRUE
;
670 // Close the Managed Network protocol.
673 ArpService
->MnpChildHandle
,
674 &gEfiManagedNetworkProtocolGuid
,
675 gArpDriverBinding
.DriverBindingHandle
,
680 // Uninstall the ARP protocol.
682 Status
= gBS
->UninstallMultipleProtocolInterfaces (
684 &gEfiArpProtocolGuid
,
688 if (EFI_ERROR (Status
)) {
689 ARP_DEBUG_ERROR (("ArpSBDestroyChild: Failed to uninstall the arp protocol, %r.\n",
692 Instance
->Destroyed
= FALSE
;
696 if (EFI_ERROR (NET_TRYLOCK (&ArpService
->Lock
))) {
697 Instance
->Destroyed
= FALSE
;
698 return EFI_ACCESS_DENIED
;
701 if (Instance
->Configured
) {
703 // Delete the related cache entry.
705 ArpDeleteCacheEntry (Instance
, FALSE
, NULL
, TRUE
);
708 // Reset the instance configuration.
710 ArpConfigureInstance (Instance
, NULL
);
714 // Remove this instance from the ChildrenList.
716 NetListRemoveEntry (&Instance
->List
);
717 ArpService
->ChildrenNumber
--;
719 NET_UNLOCK (&ArpService
->Lock
);
721 NetFreePool (Instance
);
729 ArpDriverEntryPoint (
730 IN EFI_HANDLE ImageHandle
,
731 IN EFI_SYSTEM_TABLE
*SystemTable
737 The entry point for Arp driver which installs the driver binding and component name
738 protocol on its ImageHandle.
742 ImageHandle - The image handle of the driver.
743 SystemTable - The system table.
747 EFI_SUCCESS - if the driver binding and component name protocols are successfully
748 installed, otherwise if failed.
752 return NetLibInstallAllDriverProtocols (