4 Copyright (c) 2006 - 2008, Intel Corporation.<BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at<BR>
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "ArpDriver.h"
18 EFI_DRIVER_BINDING_PROTOCOL gArpDriverBinding
= {
19 ArpDriverBindingSupported
,
20 ArpDriverBindingStart
,
29 Create and initialize the arp service context data.
31 @param[in] ImageHandle The image handle representing the loaded driver
33 @param[in] ControllerHandle The controller handle the driver binds to.
34 @param[in] ArpService Pointer to the buffer containing the arp service
37 @retval EFI_SUCCESS The arp service context is initialized.
38 @retval other Failed to initialize the arp service context.
43 IN EFI_HANDLE ImageHandle
,
44 IN EFI_HANDLE ControllerHandle
,
45 IN ARP_SERVICE_DATA
*ArpService
50 ASSERT (ArpService
!= NULL
);
52 ArpService
->Signature
= ARP_SERVICE_DATA_SIGNATURE
;
55 // Init the servicebinding protocol members.
57 ArpService
->ServiceBinding
.CreateChild
= ArpServiceBindingCreateChild
;
58 ArpService
->ServiceBinding
.DestroyChild
= ArpServiceBindingDestroyChild
;
63 ArpService
->ImageHandle
= ImageHandle
;
64 ArpService
->ControllerHandle
= ControllerHandle
;
67 // Create a MNP child instance.
69 Status
= NetLibCreateServiceChild (
72 &gEfiManagedNetworkServiceBindingProtocolGuid
,
73 &ArpService
->MnpChildHandle
75 if (EFI_ERROR (Status
)) {
80 // Open the MNP protocol.
82 Status
= gBS
->OpenProtocol (
83 ArpService
->MnpChildHandle
,
84 &gEfiManagedNetworkProtocolGuid
,
85 (VOID
**)&ArpService
->Mnp
,
88 EFI_OPEN_PROTOCOL_BY_DRIVER
90 if (EFI_ERROR (Status
)) {
95 // Get the underlayer Snp mode data.
97 Status
= ArpService
->Mnp
->GetModeData (ArpService
->Mnp
, NULL
, &ArpService
->SnpMode
);
98 if ((Status
!= EFI_NOT_STARTED
) && EFI_ERROR (Status
)) {
102 if (ArpService
->SnpMode
.IfType
!= NET_IFTYPE_ETHERNET
) {
104 // Only support the ethernet.
106 Status
= EFI_UNSUPPORTED
;
111 // Set the Mnp config parameters.
113 ArpService
->MnpConfigData
.ReceivedQueueTimeoutValue
= 0;
114 ArpService
->MnpConfigData
.TransmitQueueTimeoutValue
= 0;
115 ArpService
->MnpConfigData
.ProtocolTypeFilter
= ARP_ETHER_PROTO_TYPE
;
116 ArpService
->MnpConfigData
.EnableUnicastReceive
= TRUE
;
117 ArpService
->MnpConfigData
.EnableMulticastReceive
= FALSE
;
118 ArpService
->MnpConfigData
.EnableBroadcastReceive
= TRUE
;
119 ArpService
->MnpConfigData
.EnablePromiscuousReceive
= FALSE
;
120 ArpService
->MnpConfigData
.FlushQueuesOnReset
= TRUE
;
121 ArpService
->MnpConfigData
.EnableReceiveTimestamps
= FALSE
;
122 ArpService
->MnpConfigData
.DisableBackgroundPolling
= FALSE
;
125 // Configure the Mnp child.
127 Status
= ArpService
->Mnp
->Configure (ArpService
->Mnp
, &ArpService
->MnpConfigData
);
128 if (EFI_ERROR (Status
)) {
133 // Create the event used in the RxToken.
135 Status
= gBS
->CreateEvent (
140 &ArpService
->RxToken
.Event
142 if (EFI_ERROR (Status
)) {
147 // Create the Arp heartbeat timer.
149 Status
= gBS
->CreateEvent (
150 EVT_NOTIFY_SIGNAL
| EVT_TIMER
,
154 &ArpService
->PeriodicTimer
156 if (EFI_ERROR (Status
)) {
161 // Start the heartbeat timer.
163 Status
= gBS
->SetTimer (
164 ArpService
->PeriodicTimer
,
166 ARP_PERIODIC_TIMER_INTERVAL
168 if (EFI_ERROR (Status
)) {
175 InitializeListHead (&ArpService
->ChildrenList
);
176 InitializeListHead (&ArpService
->PendingRequestTable
);
177 InitializeListHead (&ArpService
->DeniedCacheTable
);
178 InitializeListHead (&ArpService
->ResolvedCacheTable
);
187 Clean the arp service context data.
189 @param[in] ArpService Pointer to the buffer containing the arp service
197 IN ARP_SERVICE_DATA
*ArpService
200 NET_CHECK_SIGNATURE (ArpService
, ARP_SERVICE_DATA_SIGNATURE
);
202 if (ArpService
->PeriodicTimer
!= NULL
) {
204 // Cancle and close the PeriodicTimer.
206 gBS
->SetTimer (ArpService
->PeriodicTimer
, TimerCancel
, 0);
207 gBS
->CloseEvent (ArpService
->PeriodicTimer
);
210 if (ArpService
->RxToken
.Event
!= NULL
) {
212 // Cancle the RxToken and close the event in the RxToken.
214 ArpService
->Mnp
->Cancel (ArpService
->Mnp
, NULL
);
215 gBS
->CloseEvent (ArpService
->RxToken
.Event
);
218 if (ArpService
->Mnp
!= NULL
) {
220 // Reset the Mnp child and close the Mnp protocol.
222 ArpService
->Mnp
->Configure (ArpService
->Mnp
, NULL
);
224 ArpService
->MnpChildHandle
,
225 &gEfiManagedNetworkProtocolGuid
,
226 ArpService
->ImageHandle
,
227 ArpService
->ControllerHandle
231 if (ArpService
->MnpChildHandle
!= NULL
) {
233 // Destroy the mnp child.
235 NetLibDestroyServiceChild(
236 ArpService
->ControllerHandle
,
237 ArpService
->ImageHandle
,
238 &gEfiManagedNetworkServiceBindingProtocolGuid
,
239 ArpService
->MnpChildHandle
245 Test to see if this driver supports ControllerHandle.
247 This service is called by the EFI boot service ConnectController(). In
248 order to make drivers as small as possible, there are a few calling
249 restrictions for this service. ConnectController() must
250 follow these calling restrictions. If any other agent wishes to call
251 Supported() it must also follow these calling restrictions.
253 @param[in] This Protocol instance pointer.
254 @param[in] ControllerHandle Handle of device to test.
255 @param[in] RemainingDevicePath Optional parameter use to pick a specific child
258 @retval EFI_SUCCES This driver supports this device
259 @retval EFI_ALREADY_STARTED This driver is already running on this device.
260 @retval other This driver does not support this device.
265 ArpDriverBindingSupported (
266 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
267 IN EFI_HANDLE ControllerHandle
,
268 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
274 // Test to see if Arp SB is already installed.
276 Status
= gBS
->OpenProtocol (
278 &gEfiArpServiceBindingProtocolGuid
,
280 This
->DriverBindingHandle
,
282 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
284 if (Status
== EFI_SUCCESS
) {
285 return EFI_ALREADY_STARTED
;
289 // Test to see if MNP SB is installed.
291 Status
= gBS
->OpenProtocol (
293 &gEfiManagedNetworkServiceBindingProtocolGuid
,
295 This
->DriverBindingHandle
,
297 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
305 Start this driver on ControllerHandle.
307 This service is called by the EFI boot service ConnectController(). In order to make
308 drivers as small as possible, there are a few calling restrictions for
309 this service. ConnectController() must follow these
310 calling restrictions. If any other agent wishes to call Start() it
311 must also follow these calling restrictions.
313 @param[in] This Protocol instance pointer.
314 @param[in] ControllerHandle Handle of device to bind driver to.
315 @param[in] RemainingDevicePath Optional parameter use to pick a specific child
318 @retval EFI_SUCCES This driver is added to ControllerHandle.
319 @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.
320 @retval other This driver does not support this device.
325 ArpDriverBindingStart (
326 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
327 IN EFI_HANDLE ControllerHandle
,
328 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath OPTIONAL
332 ARP_SERVICE_DATA
*ArpService
;
335 // Allocate a zero pool for ArpService.
337 ArpService
= AllocateZeroPool (sizeof(ARP_SERVICE_DATA
));
338 if (ArpService
== NULL
) {
339 return EFI_OUT_OF_RESOURCES
;
343 // Initialize the arp service context data.
345 Status
= ArpCreateService (This
->DriverBindingHandle
, ControllerHandle
, ArpService
);
346 if (EFI_ERROR (Status
)) {
351 // Install the ARP service binding protocol.
353 Status
= gBS
->InstallMultipleProtocolInterfaces (
355 &gEfiArpServiceBindingProtocolGuid
,
356 &ArpService
->ServiceBinding
,
359 if (EFI_ERROR (Status
)) {
364 // OK, start to receive arp packets from Mnp.
366 Status
= ArpService
->Mnp
->Receive (ArpService
->Mnp
, &ArpService
->RxToken
);
367 if (EFI_ERROR (Status
)) {
376 // On error, clean the arp service context data, and free the memory allocated.
378 ArpCleanService (ArpService
);
379 gBS
->FreePool (ArpService
);
386 Stop this driver on ControllerHandle.
388 This service is called by the EFI boot service DisconnectController(). In order to
389 make drivers as small as possible, there are a few calling
390 restrictions for this service. DisconnectController()
391 must follow these calling restrictions. If any other agent wishes
392 to call Stop() it must also follow these calling restrictions.
394 @param[in] This Protocol instance pointer.
395 @param[in] ControllerHandle Handle of device to stop driver on
396 @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number
397 of children is zero stop the entire bus driver.
398 @param[in] ChildHandleBuffer List of Child Handles to Stop.
400 @retval EFI_SUCCES This driver is removed ControllerHandle
401 @retval other This driver was not removed from this device
406 ArpDriverBindingStop (
407 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
408 IN EFI_HANDLE ControllerHandle
,
409 IN UINTN NumberOfChildren
,
410 IN EFI_HANDLE
*ChildHandleBuffer
414 EFI_HANDLE NicHandle
;
415 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
416 ARP_SERVICE_DATA
*ArpService
;
417 ARP_INSTANCE_DATA
*Instance
;
420 // Get the NicHandle which the arp servicebinding is installed on.
422 NicHandle
= NetLibGetNicHandle (ControllerHandle
, &gEfiManagedNetworkProtocolGuid
);
423 if (NicHandle
== NULL
) {
424 return EFI_DEVICE_ERROR
;
428 // Try to get the arp servicebinding protocol on the NicHandle.
430 Status
= gBS
->OpenProtocol (
432 &gEfiArpServiceBindingProtocolGuid
,
433 (VOID
**)&ServiceBinding
,
434 This
->DriverBindingHandle
,
436 EFI_OPEN_PROTOCOL_GET_PROTOCOL
438 if (EFI_ERROR (Status
)) {
439 DEBUG ((EFI_D_ERROR
, "ArpDriverBindingStop: Open ArpSb failed, %r.\n", Status
));
440 return EFI_DEVICE_ERROR
;
443 ArpService
= ARP_SERVICE_DATA_FROM_THIS (ServiceBinding
);
445 if (NumberOfChildren
== 0) {
447 // Uninstall the ARP ServiceBinding protocol.
449 gBS
->UninstallMultipleProtocolInterfaces (
451 &gEfiArpServiceBindingProtocolGuid
,
452 &ArpService
->ServiceBinding
,
457 // Clean the arp servicebinding context data and free the memory allocated.
459 ArpCleanService (ArpService
);
461 gBS
->FreePool (ArpService
);
464 while (!IsListEmpty (&ArpService
->ChildrenList
)) {
465 Instance
= NET_LIST_HEAD (&ArpService
->ChildrenList
, ARP_INSTANCE_DATA
, List
);
467 ServiceBinding
->DestroyChild (ServiceBinding
, Instance
->Handle
);
470 ASSERT (IsListEmpty (&ArpService
->PendingRequestTable
));
471 ASSERT (IsListEmpty (&ArpService
->DeniedCacheTable
));
472 ASSERT (IsListEmpty (&ArpService
->ResolvedCacheTable
));
479 Creates a child handle with a set of I/O services.
481 @param[in] This Protocol instance pointer.
482 @param[in] ChildHandle Pointer to the handle of the child to create. If
483 it is NULL, then a new handle is created. If it is
484 not NULL, then the I/O services are added to the
485 existing child handle.
487 @retval EFI_SUCCES The child handle was created with the I/O
489 @retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to create
491 @retval other The child handle was not created.
496 ArpServiceBindingCreateChild (
497 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
498 IN EFI_HANDLE
*ChildHandle
502 ARP_SERVICE_DATA
*ArpService
;
503 ARP_INSTANCE_DATA
*Instance
;
507 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
508 return EFI_INVALID_PARAMETER
;
511 ArpService
= ARP_SERVICE_DATA_FROM_THIS (This
);
514 // Allocate memory for the instance context data.
516 Instance
= AllocateZeroPool (sizeof(ARP_INSTANCE_DATA
));
517 if (Instance
== NULL
) {
518 DEBUG ((EFI_D_ERROR
, "ArpSBCreateChild: Failed to allocate memory for Instance.\n"));
520 return EFI_OUT_OF_RESOURCES
;
524 // Init the instance context data.
526 ArpInitInstance (ArpService
, Instance
);
529 // Install the ARP protocol onto the ChildHandle.
531 Status
= gBS
->InstallMultipleProtocolInterfaces (
533 &gEfiArpProtocolGuid
,
534 (VOID
*)&Instance
->ArpProto
,
537 if (EFI_ERROR (Status
)) {
538 DEBUG ((EFI_D_ERROR
, "ArpSBCreateChild: faild to install ARP protocol, %r.\n", Status
));
540 gBS
->FreePool (Instance
);
545 // Save the ChildHandle.
547 Instance
->Handle
= *ChildHandle
;
550 // Open the Managed Network protocol BY_CHILD.
552 Status
= gBS
->OpenProtocol (
553 ArpService
->MnpChildHandle
,
554 &gEfiManagedNetworkProtocolGuid
,
556 gArpDriverBinding
.DriverBindingHandle
,
558 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
560 if (EFI_ERROR (Status
)) {
564 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
567 // Insert the instance into children list managed by the arp service context data.
569 InsertTailList (&ArpService
->ChildrenList
, &Instance
->List
);
570 ArpService
->ChildrenNumber
++;
572 gBS
->RestoreTPL (OldTpl
);
576 if (EFI_ERROR (Status
)) {
579 ArpService
->MnpChildHandle
,
580 &gEfiManagedNetworkProtocolGuid
,
581 gArpDriverBinding
.DriverBindingHandle
,
585 gBS
->UninstallMultipleProtocolInterfaces (
587 &gEfiArpProtocolGuid
,
593 // Free the allocated memory.
595 gBS
->FreePool (Instance
);
603 Destroys a child handle with a set of I/O services.
605 @param[in] This Protocol instance pointer.
606 @param[in] ChildHandle Handle of the child to destroy.
608 @retval EFI_SUCCES The I/O services were removed from the child
610 @retval EFI_UNSUPPORTED The child handle does not support the I/O services
611 that are being removed.
612 @retval EFI_INVALID_PARAMETER Child handle is not a valid EFI Handle.
613 @retval EFI_ACCESS_DENIED The child handle could not be destroyed because
614 its I/O services are being used.
615 @retval other The child handle was not destroyed.
620 ArpServiceBindingDestroyChild (
621 IN EFI_SERVICE_BINDING_PROTOCOL
*This
,
622 IN EFI_HANDLE ChildHandle
626 ARP_SERVICE_DATA
*ArpService
;
627 ARP_INSTANCE_DATA
*Instance
;
628 EFI_ARP_PROTOCOL
*Arp
;
631 if ((This
== NULL
) || (ChildHandle
== NULL
)) {
632 return EFI_INVALID_PARAMETER
;
635 ArpService
= ARP_SERVICE_DATA_FROM_THIS (This
);
638 // Get the arp protocol.
640 Status
= gBS
->OpenProtocol (
642 &gEfiArpProtocolGuid
,
644 ArpService
->ImageHandle
,
646 EFI_OPEN_PROTOCOL_GET_PROTOCOL
648 if (EFI_ERROR (Status
)) {
649 return EFI_UNSUPPORTED
;
652 Instance
= ARP_INSTANCE_DATA_FROM_THIS (Arp
);
654 if (Instance
->Destroyed
) {
659 // Use the Destroyed as a flag to avoid re-entrance.
661 Instance
->Destroyed
= TRUE
;
664 // Close the Managed Network protocol.
667 ArpService
->MnpChildHandle
,
668 &gEfiManagedNetworkProtocolGuid
,
669 gArpDriverBinding
.DriverBindingHandle
,
674 // Uninstall the ARP protocol.
676 Status
= gBS
->UninstallMultipleProtocolInterfaces (
678 &gEfiArpProtocolGuid
,
682 if (EFI_ERROR (Status
)) {
683 DEBUG ((EFI_D_ERROR
, "ArpSBDestroyChild: Failed to uninstall the arp protocol, %r.\n",
686 Instance
->Destroyed
= FALSE
;
690 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
692 if (Instance
->Configured
) {
694 // Delete the related cache entry.
696 ArpDeleteCacheEntry (Instance
, FALSE
, NULL
, TRUE
);
699 // Reset the instance configuration.
701 ArpConfigureInstance (Instance
, NULL
);
705 // Remove this instance from the ChildrenList.
707 RemoveEntryList (&Instance
->List
);
708 ArpService
->ChildrenNumber
--;
710 gBS
->RestoreTPL (OldTpl
);
712 gBS
->FreePool (Instance
);
718 The entry point for Arp driver which installs the driver binding and component name
719 protocol on its ImageHandle.
721 @param[in] ImageHandle The image handle of the driver.
722 @param[in] SystemTable The system table.
724 @retval EFI_SUCCES if the driver binding and component name protocols are successfully
725 @retval Others Failed to install the protocols.
730 ArpDriverEntryPoint (
731 IN EFI_HANDLE ImageHandle
,
732 IN EFI_SYSTEM_TABLE
*SystemTable
735 return EfiLibInstallDriverBindingComponentName2 (