3 Copyright (c) 2006 - 2008, 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.
50 IN EFI_HANDLE ImageHandle
,
51 IN EFI_HANDLE ControllerHandle
,
52 IN ARP_SERVICE_DATA
*ArpService
57 ASSERT (ArpService
!= NULL
);
59 ArpService
->Signature
= ARP_SERVICE_DATA_SIGNATURE
;
62 // Init the servicebinding protocol members.
64 ArpService
->ServiceBinding
.CreateChild
= ArpServiceBindingCreateChild
;
65 ArpService
->ServiceBinding
.DestroyChild
= ArpServiceBindingDestroyChild
;
70 ArpService
->ImageHandle
= ImageHandle
;
71 ArpService
->ControllerHandle
= ControllerHandle
;
74 // Create a MNP child instance.
76 Status
= NetLibCreateServiceChild (
79 &gEfiManagedNetworkServiceBindingProtocolGuid
,
80 &ArpService
->MnpChildHandle
82 if (EFI_ERROR (Status
)) {
87 // Open the MNP protocol.
89 Status
= gBS
->OpenProtocol (
90 ArpService
->MnpChildHandle
,
91 &gEfiManagedNetworkProtocolGuid
,
92 (VOID
**)&ArpService
->Mnp
,
95 EFI_OPEN_PROTOCOL_BY_DRIVER
97 if (EFI_ERROR (Status
)) {
102 // Get the underlayer Snp mode data.
104 Status
= ArpService
->Mnp
->GetModeData (ArpService
->Mnp
, NULL
, &ArpService
->SnpMode
);
105 if ((Status
!= EFI_NOT_STARTED
) && EFI_ERROR (Status
)) {
109 if (ArpService
->SnpMode
.IfType
!= NET_IFTYPE_ETHERNET
) {
111 // Only support the ethernet.
113 Status
= EFI_UNSUPPORTED
;
118 // Set the Mnp config parameters.
120 ArpService
->MnpConfigData
.ReceivedQueueTimeoutValue
= 0;
121 ArpService
->MnpConfigData
.TransmitQueueTimeoutValue
= 0;
122 ArpService
->MnpConfigData
.ProtocolTypeFilter
= ARP_ETHER_PROTO_TYPE
;
123 ArpService
->MnpConfigData
.EnableUnicastReceive
= TRUE
;
124 ArpService
->MnpConfigData
.EnableMulticastReceive
= FALSE
;
125 ArpService
->MnpConfigData
.EnableBroadcastReceive
= TRUE
;
126 ArpService
->MnpConfigData
.EnablePromiscuousReceive
= FALSE
;
127 ArpService
->MnpConfigData
.FlushQueuesOnReset
= TRUE
;
128 ArpService
->MnpConfigData
.EnableReceiveTimestamps
= FALSE
;
129 ArpService
->MnpConfigData
.DisableBackgroundPolling
= FALSE
;
132 // Configure the Mnp child.
134 Status
= ArpService
->Mnp
->Configure (ArpService
->Mnp
, &ArpService
->MnpConfigData
);
135 if (EFI_ERROR (Status
)) {
140 // Create the event used in the RxToken.
142 Status
= gBS
->CreateEvent (
147 &ArpService
->RxToken
.Event
149 if (EFI_ERROR (Status
)) {
154 // Create the Arp heartbeat timer.
156 Status
= gBS
->CreateEvent (
157 EVT_NOTIFY_SIGNAL
| EVT_TIMER
,
161 &ArpService
->PeriodicTimer
163 if (EFI_ERROR (Status
)) {
168 // Start the heartbeat timer.
170 Status
= gBS
->SetTimer (
171 ArpService
->PeriodicTimer
,
173 ARP_PERIODIC_TIMER_INTERVAL
175 if (EFI_ERROR (Status
)) {
182 InitializeListHead (&ArpService
->ChildrenList
);
183 InitializeListHead (&ArpService
->PendingRequestTable
);
184 InitializeListHead (&ArpService
->DeniedCacheTable
);
185 InitializeListHead (&ArpService
->ResolvedCacheTable
);
194 Clean the arp service context data.
196 @param ArpService Pointer to the buffer containing the arp service
204 IN ARP_SERVICE_DATA
*ArpService
207 NET_CHECK_SIGNATURE (ArpService
, ARP_SERVICE_DATA_SIGNATURE
);
209 if (ArpService
->PeriodicTimer
!= NULL
) {
211 // Cancle and close the PeriodicTimer.
213 gBS
->SetTimer (ArpService
->PeriodicTimer
, TimerCancel
, 0);
214 gBS
->CloseEvent (ArpService
->PeriodicTimer
);
217 if (ArpService
->RxToken
.Event
!= NULL
) {
219 // Cancle the RxToken and close the event in the RxToken.
221 ArpService
->Mnp
->Cancel (ArpService
->Mnp
, NULL
);
222 gBS
->CloseEvent (ArpService
->RxToken
.Event
);
225 if (ArpService
->Mnp
!= NULL
) {
227 // Reset the Mnp child and close the Mnp protocol.
229 ArpService
->Mnp
->Configure (ArpService
->Mnp
, NULL
);
231 ArpService
->MnpChildHandle
,
232 &gEfiManagedNetworkProtocolGuid
,
233 ArpService
->ImageHandle
,
234 ArpService
->ControllerHandle
238 if (ArpService
->MnpChildHandle
!= NULL
) {
240 // Destroy the mnp child.
242 NetLibDestroyServiceChild(
243 ArpService
->ControllerHandle
,
244 ArpService
->ImageHandle
,
245 &gEfiManagedNetworkServiceBindingProtocolGuid
,
246 ArpService
->MnpChildHandle
253 Test to see if this driver supports ControllerHandle.
255 @param This Protocol instance pointer.
256 @param ControllerHandle Handle of device to test.
257 @param RemainingDevicePath Optional parameter use to pick a specific child
260 @retval EFI_SUCCES This driver supports this device
261 @retval EFI_ALREADY_STARTED This driver is already running on this device.
262 @retval other This driver does not support this device.
267 ArpDriverBindingSupported (
268 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
269 IN EFI_HANDLE ControllerHandle
,
270 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
276 // Test to see if Arp SB is already installed.
278 Status
= gBS
->OpenProtocol (
280 &gEfiArpServiceBindingProtocolGuid
,
282 This
->DriverBindingHandle
,
284 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
286 if (Status
== EFI_SUCCESS
) {
287 return EFI_ALREADY_STARTED
;
291 // Test to see if MNP SB is installed.
293 Status
= gBS
->OpenProtocol (
295 &gEfiManagedNetworkServiceBindingProtocolGuid
,
297 This
->DriverBindingHandle
,
299 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
307 Start this driver on ControllerHandle.
309 @param This Protocol instance pointer.
310 @param ControllerHandle Handle of device to bind driver to
311 @param RemainingDevicePath Optional parameter use to pick a specific child
314 @retval EFI_SUCCES This driver is added to ControllerHandle
315 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
316 @retval other This driver does not support this device
321 ArpDriverBindingStart (
322 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
323 IN EFI_HANDLE ControllerHandle
,
324 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
328 ARP_SERVICE_DATA
*ArpService
;
331 // Allocate a zero pool for ArpService.
333 ArpService
= AllocateZeroPool (sizeof(ARP_SERVICE_DATA
));
334 if (ArpService
== NULL
) {
335 return EFI_OUT_OF_RESOURCES
;
339 // Initialize the arp service context data.
341 Status
= ArpCreateService (This
->DriverBindingHandle
, ControllerHandle
, ArpService
);
342 if (EFI_ERROR (Status
)) {
347 // Install the ARP service binding protocol.
349 Status
= gBS
->InstallMultipleProtocolInterfaces (
351 &gEfiArpServiceBindingProtocolGuid
,
352 &ArpService
->ServiceBinding
,
355 if (EFI_ERROR (Status
)) {
360 // OK, start to receive arp packets from Mnp.
362 Status
= ArpService
->Mnp
->Receive (ArpService
->Mnp
, &ArpService
->RxToken
);
363 if (EFI_ERROR (Status
)) {
372 // On error, clean the arp service context data, and free the memory allocated.
374 ArpCleanService (ArpService
);
375 gBS
->FreePool (ArpService
);
382 Stop this driver on ControllerHandle.
384 @param This Protocol instance pointer.
385 @param ControllerHandle Handle of device to stop driver on
386 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number
387 of children is zero stop the entire bus driver.
388 @param ChildHandleBuffer List of Child Handles to Stop.
390 @retval EFI_SUCCES This driver is removed ControllerHandle
391 @retval other This driver was not removed from this device
396 ArpDriverBindingStop (
397 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
398 IN EFI_HANDLE ControllerHandle
,
399 IN UINTN NumberOfChildren
,
400 IN EFI_HANDLE
*ChildHandleBuffer
404 EFI_HANDLE NicHandle
;
405 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
406 ARP_SERVICE_DATA
*ArpService
;
407 ARP_INSTANCE_DATA
*Instance
;
410 // Get the NicHandle which the arp servicebinding is installed on.
412 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiManagedNetworkProtocolGuid
);
413 if (NicHandle
== NULL
) {
414 return EFI_DEVICE_ERROR
;
418 // Try to get the arp servicebinding protocol on the NicHandle.
420 Status
= gBS
->OpenProtocol (
422 &gEfiArpServiceBindingProtocolGuid
,
423 (VOID
**)&ServiceBinding
,
424 This
->DriverBindingHandle
,
426 EFI_OPEN_PROTOCOL_GET_PROTOCOL
428 if (EFI_ERROR (Status
)) {
429 DEBUG ((EFI_D_ERROR
, "ArpDriverBindingStop: Open ArpSb failed, %r.\n", Status
));
430 return EFI_DEVICE_ERROR
;
433 ArpService
= ARP_SERVICE_DATA_FROM_THIS (ServiceBinding
);
435 if (NumberOfChildren
== 0) {
437 // Uninstall the ARP ServiceBinding protocol.
439 gBS
->UninstallMultipleProtocolInterfaces (
441 &gEfiArpServiceBindingProtocolGuid
,
442 &ArpService
->ServiceBinding
,
447 // Clean the arp servicebinding context data and free the memory allocated.
449 ArpCleanService (ArpService
);
451 gBS
->FreePool (ArpService
);
454 while (!IsListEmpty (&ArpService
->ChildrenList
)) {
455 Instance
= NET_LIST_HEAD (&ArpService
->ChildrenList
, ARP_INSTANCE_DATA
, List
);
457 ServiceBinding
->DestroyChild (ServiceBinding
, Instance
->Handle
);
460 ASSERT (IsListEmpty (&ArpService
->PendingRequestTable
));
461 ASSERT (IsListEmpty (&ArpService
->DeniedCacheTable
));
462 ASSERT (IsListEmpty (&ArpService
->ResolvedCacheTable
));
469 Creates a child handle with a set of I/O services.
471 @param This Protocol instance pointer.
472 @param ChildHandle Pointer to the handle of the child to create. If
473 it is NULL, then a new handle is created. If it is
474 not NULL, then the I/O services are added to the
475 existing child handle.
477 @retval EFI_SUCCES The child handle was created with the I/O
479 @retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to create
481 @retval other The child handle was not created.
486 ArpServiceBindingCreateChild (
487 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
488 IN EFI_HANDLE
*ChildHandle
492 ARP_SERVICE_DATA
*ArpService
;
493 ARP_INSTANCE_DATA
*Instance
;
497 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
498 return EFI_INVALID_PARAMETER
;
501 ArpService
= ARP_SERVICE_DATA_FROM_THIS (This
);
504 // Allocate memory for the instance context data.
506 Instance
= AllocateZeroPool (sizeof(ARP_INSTANCE_DATA
));
507 if (Instance
== NULL
) {
508 DEBUG ((EFI_D_ERROR
, "ArpSBCreateChild: Failed to allocate memory for Instance.\n"));
510 return EFI_OUT_OF_RESOURCES
;
514 // Init the instance context data.
516 ArpInitInstance (ArpService
, Instance
);
519 // Install the ARP protocol onto the ChildHandle.
521 Status
= gBS
->InstallMultipleProtocolInterfaces (
523 &gEfiArpProtocolGuid
,
524 (VOID
*)&Instance
->ArpProto
,
527 if (EFI_ERROR (Status
)) {
528 DEBUG ((EFI_D_ERROR
, "ArpSBCreateChild: faild to install ARP protocol, %r.\n", Status
));
530 gBS
->FreePool (Instance
);
535 // Save the ChildHandle.
537 Instance
->Handle
= *ChildHandle
;
540 // Open the Managed Network protocol BY_CHILD.
542 Status
= gBS
->OpenProtocol (
543 ArpService
->MnpChildHandle
,
544 &gEfiManagedNetworkProtocolGuid
,
546 gArpDriverBinding
.DriverBindingHandle
,
548 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
550 if (EFI_ERROR (Status
)) {
554 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
557 // Insert the instance into children list managed by the arp service context data.
559 InsertTailList (&ArpService
->ChildrenList
, &Instance
->List
);
560 ArpService
->ChildrenNumber
++;
562 gBS
->RestoreTPL (OldTpl
);
566 if (EFI_ERROR (Status
)) {
569 ArpService
->MnpChildHandle
,
570 &gEfiManagedNetworkProtocolGuid
,
571 gArpDriverBinding
.DriverBindingHandle
,
575 gBS
->UninstallMultipleProtocolInterfaces (
577 &gEfiArpProtocolGuid
,
583 // Free the allocated memory.
585 gBS
->FreePool (Instance
);
593 Destroys a child handle with a set of I/O services.
595 @param This Protocol instance pointer.
596 @param ChildHandle Handle of the child to destroy.
598 @retval EFI_SUCCES The I/O services were removed from the child
600 @retval EFI_UNSUPPORTED The child handle does not support the I/O services
601 that are being removed.
602 @retval EFI_INVALID_PARAMETER Child handle is not a valid EFI Handle.
603 @retval EFI_ACCESS_DENIED The child handle could not be destroyed because
604 its I/O services are being used.
605 @retval other The child handle was not destroyed.
610 ArpServiceBindingDestroyChild (
611 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
612 IN EFI_HANDLE ChildHandle
616 ARP_SERVICE_DATA
*ArpService
;
617 ARP_INSTANCE_DATA
*Instance
;
618 EFI_ARP_PROTOCOL
*Arp
;
621 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
622 return EFI_INVALID_PARAMETER
;
625 ArpService
= ARP_SERVICE_DATA_FROM_THIS (This
);
628 // Get the arp protocol.
630 Status
= gBS
->OpenProtocol (
632 &gEfiArpProtocolGuid
,
634 ArpService
->ImageHandle
,
636 EFI_OPEN_PROTOCOL_GET_PROTOCOL
638 if (EFI_ERROR (Status
)) {
639 return EFI_UNSUPPORTED
;
642 Instance
= ARP_INSTANCE_DATA_FROM_THIS (Arp
);
644 if (Instance
->Destroyed
) {
649 // Use the Destroyed as a flag to avoid re-entrance.
651 Instance
->Destroyed
= TRUE
;
654 // Close the Managed Network protocol.
657 ArpService
->MnpChildHandle
,
658 &gEfiManagedNetworkProtocolGuid
,
659 gArpDriverBinding
.DriverBindingHandle
,
664 // Uninstall the ARP protocol.
666 Status
= gBS
->UninstallMultipleProtocolInterfaces (
668 &gEfiArpProtocolGuid
,
672 if (EFI_ERROR (Status
)) {
673 DEBUG ((EFI_D_ERROR
, "ArpSBDestroyChild: Failed to uninstall the arp protocol, %r.\n",
676 Instance
->Destroyed
= FALSE
;
680 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
682 if (Instance
->Configured
) {
684 // Delete the related cache entry.
686 ArpDeleteCacheEntry (Instance
, FALSE
, NULL
, TRUE
);
689 // Reset the instance configuration.
691 ArpConfigureInstance (Instance
, NULL
);
695 // Remove this instance from the ChildrenList.
697 RemoveEntryList (&Instance
->List
);
698 ArpService
->ChildrenNumber
--;
700 gBS
->RestoreTPL (OldTpl
);
702 gBS
->FreePool (Instance
);
708 The entry point for Arp driver which installs the driver binding and component name
709 protocol on its ImageHandle.
711 @param ImageHandle The image handle of the driver.
712 @param SystemTable The system table.
714 @retval EFI_SUCCES if the driver binding and component name protocols are successfully
715 @retval Others Failed to install the protocols.
720 ArpDriverEntryPoint (
721 IN EFI_HANDLE ImageHandle
,
722 IN EFI_SYSTEM_TABLE
*SystemTable
725 return EfiLibInstallDriverBindingComponentName2 (