/** @file
  ARP driver functions.

Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "ArpDriver.h"
#include "ArpImpl.h"

EFI_DRIVER_BINDING_PROTOCOL  gArpDriverBinding = {
  ArpDriverBindingSupported,
  ArpDriverBindingStart,
  ArpDriverBindingStop,
  0xa,
  NULL,
  NULL
};

/**
  Create and initialize the arp service context data.

  @param[in]       ImageHandle       The image handle representing the loaded driver
                                     image.
  @param[in]       ControllerHandle  The controller handle the driver binds to.
  @param[in, out]  ArpService        Pointer to the buffer containing the arp service
                                     context data.

  @retval EFI_SUCCESS                The arp service context is initialized.

  @retval EFI_UNSUPPORTED            The underlayer Snp mode type is not ethernet.
                                     Failed to initialize the service context.
  @retval other                      Failed to initialize the arp service context.

**/
EFI_STATUS
ArpCreateService (
  IN EFI_HANDLE            ImageHandle,
  IN EFI_HANDLE            ControllerHandle,
  IN OUT ARP_SERVICE_DATA  *ArpService
  )
{
  EFI_STATUS  Status;

  ASSERT (ArpService != NULL);

  ArpService->Signature = ARP_SERVICE_DATA_SIGNATURE;

  //
  // Init the lists.
  //
  InitializeListHead (&ArpService->ChildrenList);
  InitializeListHead (&ArpService->PendingRequestTable);
  InitializeListHead (&ArpService->DeniedCacheTable);
  InitializeListHead (&ArpService->ResolvedCacheTable);

  //
  // Init the servicebinding protocol members.
  //
  ArpService->ServiceBinding.CreateChild  = ArpServiceBindingCreateChild;
  ArpService->ServiceBinding.DestroyChild = ArpServiceBindingDestroyChild;

  //
  // Save the handles.
  //
  ArpService->ImageHandle      = ImageHandle;
  ArpService->ControllerHandle = ControllerHandle;

  //
  // Create a MNP child instance.
  //
  Status = NetLibCreateServiceChild (
             ControllerHandle,
             ImageHandle,
             &gEfiManagedNetworkServiceBindingProtocolGuid,
             &ArpService->MnpChildHandle
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Open the MNP protocol.
  //
  Status = gBS->OpenProtocol (
                  ArpService->MnpChildHandle,
                  &gEfiManagedNetworkProtocolGuid,
                  (VOID **)&ArpService->Mnp,
                  ImageHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto ERROR_EXIT;
  }

  //
  // Get the underlayer Snp mode data.
  //
  Status = ArpService->Mnp->GetModeData (ArpService->Mnp, NULL, &ArpService->SnpMode);
  if ((Status != EFI_NOT_STARTED) && EFI_ERROR (Status)) {
    goto ERROR_EXIT;
  }

  if (ArpService->SnpMode.IfType != NET_IFTYPE_ETHERNET) {
    //
    // Only support the ethernet.
    //
    Status = EFI_UNSUPPORTED;
    goto ERROR_EXIT;
  }

  //
  // Set the Mnp config parameters.
  //
  ArpService->MnpConfigData.ReceivedQueueTimeoutValue = 0;
  ArpService->MnpConfigData.TransmitQueueTimeoutValue = 0;
  ArpService->MnpConfigData.ProtocolTypeFilter        = ARP_ETHER_PROTO_TYPE;
  ArpService->MnpConfigData.EnableUnicastReceive      = TRUE;
  ArpService->MnpConfigData.EnableMulticastReceive    = FALSE;
  ArpService->MnpConfigData.EnableBroadcastReceive    = TRUE;
  ArpService->MnpConfigData.EnablePromiscuousReceive  = FALSE;
  ArpService->MnpConfigData.FlushQueuesOnReset        = TRUE;
  ArpService->MnpConfigData.EnableReceiveTimestamps   = FALSE;
  ArpService->MnpConfigData.DisableBackgroundPolling  = FALSE;

  //
  // Configure the Mnp child.
  //
  Status = ArpService->Mnp->Configure (ArpService->Mnp, &ArpService->MnpConfigData);
  if (EFI_ERROR (Status)) {
    goto ERROR_EXIT;
  }

  //
  // Create the event used in the RxToken.
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  ArpOnFrameRcvd,
                  ArpService,
                  &ArpService->RxToken.Event
                  );
  if (EFI_ERROR (Status)) {
    goto ERROR_EXIT;
  }

  //
  // Create the Arp heartbeat timer.
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL | EVT_TIMER,
                  TPL_CALLBACK,
                  ArpTimerHandler,
                  ArpService,
                  &ArpService->PeriodicTimer
                  );
  if (EFI_ERROR (Status)) {
    goto ERROR_EXIT;
  }

  //
  // Start the heartbeat timer.
  //
  Status = gBS->SetTimer (
                  ArpService->PeriodicTimer,
                  TimerPeriodic,
                  ARP_PERIODIC_TIMER_INTERVAL
                  );

ERROR_EXIT:

  return Status;
}

/**
  Clean the arp service context data.

  @param[in, out]  ArpService        Pointer to the buffer containing the arp service
                                     context data.

  @return None.

**/
VOID
ArpCleanService (
  IN OUT ARP_SERVICE_DATA  *ArpService
  )
{
  NET_CHECK_SIGNATURE (ArpService, ARP_SERVICE_DATA_SIGNATURE);

  if (ArpService->PeriodicTimer != NULL) {
    //
    // Cancel and close the PeriodicTimer.
    //
    gBS->SetTimer (ArpService->PeriodicTimer, TimerCancel, 0);
    gBS->CloseEvent (ArpService->PeriodicTimer);
  }

  if (ArpService->RxToken.Event != NULL) {
    //
    // Cancel the RxToken and close the event in the RxToken.
    //
    ArpService->Mnp->Cancel (ArpService->Mnp, NULL);
    gBS->CloseEvent (ArpService->RxToken.Event);
  }

  if (ArpService->Mnp != NULL) {
    //
    // Reset the Mnp child and close the Mnp protocol.
    //
    ArpService->Mnp->Configure (ArpService->Mnp, NULL);
    gBS->CloseProtocol (
           ArpService->MnpChildHandle,
           &gEfiManagedNetworkProtocolGuid,
           ArpService->ImageHandle,
           ArpService->ControllerHandle
           );
  }

  if (ArpService->MnpChildHandle != NULL) {
    //
    // Destroy the mnp child.
    //
    NetLibDestroyServiceChild (
      ArpService->ControllerHandle,
      ArpService->ImageHandle,
      &gEfiManagedNetworkServiceBindingProtocolGuid,
      ArpService->MnpChildHandle
      );
  }
}

/**
  Callback function which provided by user to remove one node in NetDestroyLinkList process.

  @param[in]    Entry           The entry to be removed.
  @param[in]    Context         Pointer to the callback context corresponds to the Context in NetDestroyLinkList.

  @retval EFI_SUCCESS           The entry has been removed successfully.
  @retval Others                Fail to remove the entry.

**/
EFI_STATUS
EFIAPI
ArpDestroyChildEntryInHandleBuffer (
  IN LIST_ENTRY  *Entry,
  IN VOID        *Context
  )
{
  ARP_INSTANCE_DATA             *Instance;
  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;

  if ((Entry == NULL) || (Context == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Instance       = NET_LIST_USER_STRUCT_S (Entry, ARP_INSTANCE_DATA, List, ARP_INSTANCE_DATA_SIGNATURE);
  ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *)Context;

  return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
}

/**
  Tests to see if this driver supports a given controller.

  If a child device is provided, it further tests to see if this driver supports
  creating a handle for the specified child device.

  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param[in]  ControllerHandle     The handle of the controller to test. This handle
                                   must support a protocol interface that supplies
                                   an I/O abstraction to the driver.
  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.
                                   This parameter is ignored by device drivers,
                                   and is optional for bus drivers.

  @retval EFI_SUCCESS              The device specified by ControllerHandle and
                                   RemainingDevicePath is supported by the driver
                                   specified by This.
  @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle and
                                   RemainingDevicePath is already being managed
                                   by the driver specified by This.
  @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle and
                                   RemainingDevicePath is already being managed by
                                   a different driver or an application that
                                   requires exclusive access. Currently not implemented.
  @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
                                   RemainingDevicePath is not supported by the
                                   driver specified by This.

**/
EFI_STATUS
EFIAPI
ArpDriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  EFI_STATUS  Status;

  //
  // Test to see if Arp SB is already installed.
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiArpServiceBindingProtocolGuid,
                  NULL,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );
  if (Status == EFI_SUCCESS) {
    return EFI_ALREADY_STARTED;
  }

  //
  // Test to see if MNP SB is installed.
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiManagedNetworkServiceBindingProtocolGuid,
                  NULL,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );

  return Status;
}

/**
  Start this driver on ControllerHandle.

  The Start() function is designed to be invoked from the EFI boot service ConnectController().
  As a result, much of the error checking on the parameters to Start() has been
  moved into this common boot service. It is legal to call Start() from other locations,
  but the following calling restrictions must be followed or the system behavior
  will not be deterministic.
  1. ControllerHandle must be a valid EFI_HANDLE.
  2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally
     aligned EFI_DEVICE_PATH_PROTOCOL.
  3. Prior to calling Start(), the Supported() function for the driver specified
     by This must have been called with the same calling parameters, and Supported()
     must have returned EFI_SUCCESS.

  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param[in]  ControllerHandle     The handle of the controller to start. This handle
                                   must support a protocol interface that supplies
                                   an I/O abstraction to the driver.
  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.
                                   This parameter is ignored by device drivers,
                                   and is optional for bus drivers.

  @retval EFI_SUCCESS              The device was started.
  @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.
                                   Currently not implemented.
  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of
                                   resources.
  @retval Others                   The driver failed to start the device.

**/
EFI_STATUS
EFIAPI
ArpDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  EFI_STATUS        Status;
  ARP_SERVICE_DATA  *ArpService;

  //
  // Allocate a zero pool for ArpService.
  //
  ArpService = AllocateZeroPool (sizeof (ARP_SERVICE_DATA));
  if (ArpService == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Initialize the arp service context data.
  //
  Status = ArpCreateService (This->DriverBindingHandle, ControllerHandle, ArpService);
  if (EFI_ERROR (Status)) {
    goto ERROR;
  }

  //
  // Install the ARP service binding protocol.
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &ControllerHandle,
                  &gEfiArpServiceBindingProtocolGuid,
                  &ArpService->ServiceBinding,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    goto ERROR;
  }

  //
  // OK, start to receive arp packets from Mnp.
  //
  Status = ArpService->Mnp->Receive (ArpService->Mnp, &ArpService->RxToken);
  if (EFI_ERROR (Status)) {
    goto ERROR;
  }

  return Status;

ERROR:

  //
  // On error, clean the arp service context data, and free the memory allocated.
  //
  ArpCleanService (ArpService);
  FreePool (ArpService);

  return Status;
}

/**
  Stop this driver on ControllerHandle.

  Release the control of this controller and remove the IScsi functions. The Stop()
  function is designed to be invoked from the EFI boot service DisconnectController().
  As a result, much of the error checking on the parameters to Stop() has been moved
  into this common boot service. It is legal to call Stop() from other locations,
  but the following calling restrictions must be followed or the system behavior
  will not be deterministic.
  1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
     same driver's Start() function.
  2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
     EFI_HANDLE. In addition, all of these handles must have been created in this driver's
     Start() function, and the Start() function must have called OpenProtocol() on
     ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.

  @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param[in]  ControllerHandle  A handle to the device being stopped. The handle must
                                support a bus specific I/O protocol for the driver
                                to use to stop the device.
  @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.
                                Not used.
  @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
                                if NumberOfChildren is 0.Not used.

  @retval EFI_SUCCESS           The device was stopped.
  @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.

**/
EFI_STATUS
EFIAPI
ArpDriverBindingStop (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN UINTN                        NumberOfChildren,
  IN EFI_HANDLE                   *ChildHandleBuffer
  )
{
  EFI_STATUS                    Status;
  EFI_HANDLE                    NicHandle;
  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;
  ARP_SERVICE_DATA              *ArpService;
  LIST_ENTRY                    *List;

  //
  // Get the NicHandle which the arp servicebinding is installed on.
  //
  NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
  if (NicHandle == NULL) {
    return EFI_SUCCESS;
  }

  //
  // Try to get the arp servicebinding protocol on the NicHandle.
  //
  Status = gBS->OpenProtocol (
                  NicHandle,
                  &gEfiArpServiceBindingProtocolGuid,
                  (VOID **)&ServiceBinding,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "ArpDriverBindingStop: Open ArpSb failed, %r.\n", Status));
    return EFI_DEVICE_ERROR;
  }

  ArpService = ARP_SERVICE_DATA_FROM_THIS (ServiceBinding);

  if (NumberOfChildren != 0) {
    //
    // NumberOfChildren is not zero, destroy all the ARP children instances.
    //
    List   = &ArpService->ChildrenList;
    Status = NetDestroyLinkList (
               List,
               ArpDestroyChildEntryInHandleBuffer,
               ServiceBinding,
               NULL
               );
    ASSERT (IsListEmpty (&ArpService->PendingRequestTable));
    ASSERT (IsListEmpty (&ArpService->DeniedCacheTable));
    ASSERT (IsListEmpty (&ArpService->ResolvedCacheTable));
  } else if (IsListEmpty (&ArpService->ChildrenList)) {
    //
    // Uninstall the ARP ServiceBinding protocol.
    //
    gBS->UninstallMultipleProtocolInterfaces (
           NicHandle,
           &gEfiArpServiceBindingProtocolGuid,
           &ArpService->ServiceBinding,
           NULL
           );

    //
    // Clean the arp servicebinding context data and free the memory allocated.
    //
    ArpCleanService (ArpService);

    FreePool (ArpService);
  }

  return EFI_SUCCESS;
}

/**
  Creates a child handle and installs a protocol.

  The CreateChild() function installs a protocol on ChildHandle.
  If ChildHandle is a pointer to NULL, then a new handle is created and returned
  in ChildHandle. If ChildHandle is not a pointer to NULL, then the protocol
  installs on the existing ChildHandle.

  @param  This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
  @param  ChildHandle Pointer to the handle of the child to create. If it is NULL,
                      then a new handle is created. If it is a pointer to an existing
                      UEFI handle, then the protocol is added to the existing UEFI handle.

  @retval EFI_SUCCESS           The protocol was added to ChildHandle.
  @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
  @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to create
                                the child
  @retval other                 The child handle was not created

**/
EFI_STATUS
EFIAPI
ArpServiceBindingCreateChild (
  IN EFI_SERVICE_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                    *ChildHandle
  )
{
  EFI_STATUS         Status;
  ARP_SERVICE_DATA   *ArpService;
  ARP_INSTANCE_DATA  *Instance;
  VOID               *Mnp;
  EFI_TPL            OldTpl;

  if ((This == NULL) || (ChildHandle == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  ArpService = ARP_SERVICE_DATA_FROM_THIS (This);

  //
  // Allocate memory for the instance context data.
  //
  Instance = AllocateZeroPool (sizeof (ARP_INSTANCE_DATA));
  if (Instance == NULL) {
    DEBUG ((DEBUG_ERROR, "ArpSBCreateChild: Failed to allocate memory for Instance.\n"));

    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Init the instance context data.
  //
  ArpInitInstance (ArpService, Instance);

  //
  // Install the ARP protocol onto the ChildHandle.
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  ChildHandle,
                  &gEfiArpProtocolGuid,
                  (VOID *)&Instance->ArpProto,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "ArpSBCreateChild: failed to install ARP protocol, %r.\n", Status));

    FreePool (Instance);
    return Status;
  }

  //
  // Save the ChildHandle.
  //
  Instance->Handle = *ChildHandle;

  //
  // Open the Managed Network protocol BY_CHILD.
  //
  Status = gBS->OpenProtocol (
                  ArpService->MnpChildHandle,
                  &gEfiManagedNetworkProtocolGuid,
                  (VOID **)&Mnp,
                  gArpDriverBinding.DriverBindingHandle,
                  Instance->Handle,
                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                  );
  if (EFI_ERROR (Status)) {
    goto ERROR;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  //
  // Insert the instance into children list managed by the arp service context data.
  //
  InsertTailList (&ArpService->ChildrenList, &Instance->List);
  ArpService->ChildrenNumber++;

  gBS->RestoreTPL (OldTpl);

ERROR:

  if (EFI_ERROR (Status)) {
    gBS->CloseProtocol (
           ArpService->MnpChildHandle,
           &gEfiManagedNetworkProtocolGuid,
           gArpDriverBinding.DriverBindingHandle,
           Instance->Handle
           );

    gBS->UninstallMultipleProtocolInterfaces (
           Instance->Handle,
           &gEfiArpProtocolGuid,
           &Instance->ArpProto,
           NULL
           );

    //
    // Free the allocated memory.
    //
    FreePool (Instance);
  }

  return Status;
}

/**
  Destroys a child handle with a protocol installed on it.

  The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
  that was installed by CreateChild() from ChildHandle. If the removed protocol is the
  last protocol on ChildHandle, then ChildHandle is destroyed.

  @param  This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
  @param  ChildHandle Handle of the child to destroy

  @retval EFI_SUCCESS           The protocol was removed from ChildHandle.
  @retval EFI_UNSUPPORTED       ChildHandle does not support the protocol that is
                                being removed.
  @retval EFI_INVALID_PARAMETER Child handle is NULL.
  @retval EFI_ACCESS_DENIED     The protocol could not be removed from the ChildHandle
                                because its services are being used.
  @retval other                 The child handle was not destroyed

**/
EFI_STATUS
EFIAPI
ArpServiceBindingDestroyChild (
  IN EFI_SERVICE_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                    ChildHandle
  )
{
  EFI_STATUS         Status;
  ARP_SERVICE_DATA   *ArpService;
  ARP_INSTANCE_DATA  *Instance;
  EFI_ARP_PROTOCOL   *Arp;
  EFI_TPL            OldTpl;

  if ((This == NULL) || (ChildHandle == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  ArpService = ARP_SERVICE_DATA_FROM_THIS (This);

  //
  // Get the arp protocol.
  //
  Status = gBS->OpenProtocol (
                  ChildHandle,
                  &gEfiArpProtocolGuid,
                  (VOID **)&Arp,
                  ArpService->ImageHandle,
                  ChildHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  Instance = ARP_INSTANCE_DATA_FROM_THIS (Arp);

  if (Instance->InDestroy) {
    return EFI_SUCCESS;
  }

  //
  // Use the InDestroy as a flag to avoid re-entrance.
  //
  Instance->InDestroy = TRUE;

  //
  // Close the Managed Network protocol.
  //
  gBS->CloseProtocol (
         ArpService->MnpChildHandle,
         &gEfiManagedNetworkProtocolGuid,
         gArpDriverBinding.DriverBindingHandle,
         ChildHandle
         );

  //
  // Uninstall the ARP protocol.
  //
  Status = gBS->UninstallMultipleProtocolInterfaces (
                  ChildHandle,
                  &gEfiArpProtocolGuid,
                  &Instance->ArpProto,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "ArpSBDestroyChild: Failed to uninstall the arp protocol, %r.\n",
      Status
      ));

    Instance->InDestroy = FALSE;
    return Status;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  if (Instance->Configured) {
    //
    // Delete the related cache entry.
    //
    ArpDeleteCacheEntry (Instance, FALSE, NULL, TRUE);

    //
    // Reset the instance configuration.
    //
    ArpConfigureInstance (Instance, NULL);
  }

  //
  // Remove this instance from the ChildrenList.
  //
  RemoveEntryList (&Instance->List);
  ArpService->ChildrenNumber--;

  gBS->RestoreTPL (OldTpl);

  FreePool (Instance);

  return Status;
}

/**
  The entry point for Arp driver which installs the driver binding and component name
  protocol on its ImageHandle.

  @param[in]  ImageHandle        The image handle of the driver.
  @param[in]  SystemTable        The system table.

  @retval EFI_SUCCESS            if the driver binding and component name protocols
                                 are successfully
  @retval Others                 Failed to install the protocols.

**/
EFI_STATUS
EFIAPI
ArpDriverEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  return EfiLibInstallDriverBindingComponentName2 (
           ImageHandle,
           SystemTable,
           &gArpDriverBinding,
           ImageHandle,
           &gArpComponentName,
           &gArpComponentName2
           );
}
