/** @file
  The driver binding and service binding protocol for the TCP driver.

  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
  Copyright (c) Microsoft Corporation
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "TcpMain.h"

UINT16  mTcp4RandomPort;
UINT16  mTcp6RandomPort;

TCP_HEARTBEAT_TIMER  mTcpTimer = {
  NULL,
  0
};

EFI_TCP4_PROTOCOL  gTcp4ProtocolTemplate = {
  Tcp4GetModeData,
  Tcp4Configure,
  Tcp4Routes,
  Tcp4Connect,
  Tcp4Accept,
  Tcp4Transmit,
  Tcp4Receive,
  Tcp4Close,
  Tcp4Cancel,
  Tcp4Poll
};

EFI_TCP6_PROTOCOL  gTcp6ProtocolTemplate = {
  Tcp6GetModeData,
  Tcp6Configure,
  Tcp6Connect,
  Tcp6Accept,
  Tcp6Transmit,
  Tcp6Receive,
  Tcp6Close,
  Tcp6Cancel,
  Tcp6Poll
};

SOCK_INIT_DATA  mTcpDefaultSockData = {
  SockStream,
  SO_CLOSED,
  NULL,
  TCP_BACKLOG,
  TCP_SND_BUF_SIZE,
  TCP_RCV_BUF_SIZE,
  IP_VERSION_4,
  NULL,
  TcpCreateSocketCallback,
  TcpDestroySocketCallback,
  NULL,
  NULL,
  0,
  TcpDispatcher,
  NULL,
};

EFI_DRIVER_BINDING_PROTOCOL  gTcp4DriverBinding = {
  Tcp4DriverBindingSupported,
  Tcp4DriverBindingStart,
  Tcp4DriverBindingStop,
  0xa,
  NULL,
  NULL
};

EFI_DRIVER_BINDING_PROTOCOL  gTcp6DriverBinding = {
  Tcp6DriverBindingSupported,
  Tcp6DriverBindingStart,
  Tcp6DriverBindingStop,
  0xa,
  NULL,
  NULL
};

EFI_SERVICE_BINDING_PROTOCOL  gTcpServiceBinding = {
  TcpServiceBindingCreateChild,
  TcpServiceBindingDestroyChild
};

//
// This is the handle for the Hash2ServiceBinding Protocol instance this driver produces
// if the platform does not provide one.
//
EFI_HANDLE  mHash2ServiceHandle = NULL;

/**
  Create and start the heartbeat timer for the TCP driver.

  @retval EFI_SUCCESS            The timer was successfully created and started.
  @retval other                  The timer was not created.

**/
EFI_STATUS
TcpCreateTimer (
  VOID
  )
{
  EFI_STATUS  Status;

  Status = EFI_SUCCESS;

  if (mTcpTimer.RefCnt == 0) {
    Status = gBS->CreateEvent (
                    EVT_TIMER | EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    TcpTicking,
                    NULL,
                    &mTcpTimer.TimerEvent
                    );
    if (!EFI_ERROR (Status)) {
      Status = gBS->SetTimer (
                      mTcpTimer.TimerEvent,
                      TimerPeriodic,
                      (UINT64)(TICKS_PER_SECOND / TCP_TICK_HZ)
                      );
    }
  }

  if (!EFI_ERROR (Status)) {
    mTcpTimer.RefCnt++;
  }

  return Status;
}

/**
  Stop and destroy the heartbeat timer for TCP driver.

**/
VOID
TcpDestroyTimer (
  VOID
  )
{
  ASSERT (mTcpTimer.RefCnt > 0);

  mTcpTimer.RefCnt--;

  if (mTcpTimer.RefCnt > 0) {
    return;
  }

  gBS->SetTimer (mTcpTimer.TimerEvent, TimerCancel, 0);
  gBS->CloseEvent (mTcpTimer.TimerEvent);
  mTcpTimer.TimerEvent = NULL;
}

/**
  The entry point for Tcp driver, which is used to install Tcp driver on the ImageHandle.

  @param[in]  ImageHandle   The firmware allocated handle for this driver image.
  @param[in]  SystemTable   Pointer to the EFI system table.

  @retval EFI_SUCCESS   The driver loaded.
  @retval other         The driver did not load.

**/
EFI_STATUS
EFIAPI
TcpDriverEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;
  UINT32      Random;

  //
  // Initialize the Secret used for hashing TCP sequence numbers
  //
  // Normally this should be regenerated periodically, but since
  // this is only used for UEFI networking and not a general purpose
  // operating system, it is not necessary to regenerate it.
  //
  Status = PseudoRandomU32 (&mTcpGlobalSecret);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status));
    return Status;
  }

  //
  // Get a random number used to generate a random port number
  // Intentionally not linking this to mTcpGlobalSecret to avoid leaking information about the secret
  //
  Status = PseudoRandomU32 (&Random);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "%a Failed to generate random number: %r\n", __func__, Status));
    return Status;
  }

  //
  // Install the TCP Driver Binding Protocol
  //
  Status = EfiLibInstallDriverBindingComponentName2 (
             ImageHandle,
             SystemTable,
             &gTcp4DriverBinding,
             ImageHandle,
             &gTcpComponentName,
             &gTcpComponentName2
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Install the TCP Driver Binding Protocol
  //
  Status = EfiLibInstallDriverBindingComponentName2 (
             ImageHandle,
             SystemTable,
             &gTcp6DriverBinding,
             NULL,
             &gTcpComponentName,
             &gTcpComponentName2
             );
  if (EFI_ERROR (Status)) {
    EfiLibUninstallDriverBindingComponentName2 (
      &gTcp4DriverBinding,
      &gTcpComponentName,
      &gTcpComponentName2
      );
    return Status;
  }

  //
  // Initialize the random port.
  //
  mTcp4RandomPort = (UINT16)(TCP_PORT_KNOWN + (Random % TCP_PORT_KNOWN));
  mTcp6RandomPort = mTcp4RandomPort;

  return EFI_SUCCESS;
}

/**
  Create a new TCP4 or TCP6 driver service binding protocol

  @param[in]  Controller         Controller handle of device to bind driver to.
  @param[in]  Image              The TCP driver's image handle.
  @param[in]  IpVersion          IP_VERSION_4 or IP_VERSION_6.

  @retval EFI_OUT_OF_RESOURCES   Failed to allocate some resources.
  @retval EFI_UNSUPPORTED        Service Binding Protocols are unavailable.
  @retval EFI_ALREADY_STARTED    The TCP driver is already started on the controller.
  @retval EFI_SUCCESS            A new IP6 service binding private was created.

**/
EFI_STATUS
TcpCreateService (
  IN EFI_HANDLE  Controller,
  IN EFI_HANDLE  Image,
  IN UINT8       IpVersion
  )
{
  EFI_STATUS                    Status;
  EFI_GUID                      *IpServiceBindingGuid;
  EFI_GUID                      *TcpServiceBindingGuid;
  TCP_SERVICE_DATA              *TcpServiceData;
  IP_IO_OPEN_DATA               OpenData;
  EFI_SERVICE_BINDING_PROTOCOL  *Hash2ServiceBinding;
  EFI_HASH2_PROTOCOL            *Hash2Protocol;

  if (IpVersion == IP_VERSION_4) {
    IpServiceBindingGuid  = &gEfiIp4ServiceBindingProtocolGuid;
    TcpServiceBindingGuid = &gEfiTcp4ServiceBindingProtocolGuid;
  } else {
    IpServiceBindingGuid  = &gEfiIp6ServiceBindingProtocolGuid;
    TcpServiceBindingGuid = &gEfiTcp6ServiceBindingProtocolGuid;
  }

  Status = gBS->OpenProtocol (
                  Controller,
                  TcpServiceBindingGuid,
                  NULL,
                  Image,
                  Controller,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );
  if (!EFI_ERROR (Status)) {
    return EFI_ALREADY_STARTED;
  }

  Status = gBS->OpenProtocol (
                  Controller,
                  IpServiceBindingGuid,
                  NULL,
                  Image,
                  Controller,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  Status = gBS->LocateProtocol (&gEfiHash2ProtocolGuid, NULL, (VOID **)&Hash2Protocol);
  if (EFI_ERROR (Status)) {
    //
    // If we can't find the Hashing protocol, then we need to create one.
    //

    //
    // Platform is expected to publish the hash service binding protocol to support TCP.
    //
    Status = gBS->LocateProtocol (
                    &gEfiHash2ServiceBindingProtocolGuid,
                    NULL,
                    (VOID **)&Hash2ServiceBinding
                    );
    if (EFI_ERROR (Status) || (Hash2ServiceBinding == NULL) || (Hash2ServiceBinding->CreateChild == NULL)) {
      return EFI_UNSUPPORTED;
    }

    //
    // Create an instance of the hash protocol for this controller.
    //
    Status = Hash2ServiceBinding->CreateChild (Hash2ServiceBinding, &mHash2ServiceHandle);
    if (EFI_ERROR (Status)) {
      return EFI_UNSUPPORTED;
    }
  }

  //
  // Create the TCP service data.
  //
  TcpServiceData = AllocateZeroPool (sizeof (TCP_SERVICE_DATA));
  if (TcpServiceData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  TcpServiceData->Signature           = TCP_DRIVER_SIGNATURE;
  TcpServiceData->ControllerHandle    = Controller;
  TcpServiceData->DriverBindingHandle = Image;
  TcpServiceData->IpVersion           = IpVersion;
  CopyMem (
    &TcpServiceData->ServiceBinding,
    &gTcpServiceBinding,
    sizeof (EFI_SERVICE_BINDING_PROTOCOL)
    );

  TcpServiceData->IpIo = IpIoCreate (Image, Controller, IpVersion);
  if (TcpServiceData->IpIo == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_ERROR;
  }

  InitializeListHead (&TcpServiceData->SocketList);
  ZeroMem (&OpenData, sizeof (IP_IO_OPEN_DATA));

  if (IpVersion == IP_VERSION_4) {
    CopyMem (
      &OpenData.IpConfigData.Ip4CfgData,
      &mIp4IoDefaultIpConfigData,
      sizeof (EFI_IP4_CONFIG_DATA)
      );
    OpenData.IpConfigData.Ip4CfgData.DefaultProtocol = EFI_IP_PROTO_TCP;
  } else {
    CopyMem (
      &OpenData.IpConfigData.Ip6CfgData,
      &mIp6IoDefaultIpConfigData,
      sizeof (EFI_IP6_CONFIG_DATA)
      );
    OpenData.IpConfigData.Ip6CfgData.DefaultProtocol = EFI_IP_PROTO_TCP;
  }

  OpenData.PktRcvdNotify = TcpRxCallback;
  Status                 = IpIoOpen (TcpServiceData->IpIo, &OpenData);
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  Status = TcpCreateTimer ();
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Controller,
                  TcpServiceBindingGuid,
                  &TcpServiceData->ServiceBinding,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    TcpDestroyTimer ();

    goto ON_ERROR;
  }

  return EFI_SUCCESS;

ON_ERROR:

  if (TcpServiceData->IpIo != NULL) {
    IpIoDestroy (TcpServiceData->IpIo);
    TcpServiceData->IpIo = NULL;
  }

  FreePool (TcpServiceData);

  return Status;
}

/**
  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
TcpDestroyChildEntryInHandleBuffer (
  IN LIST_ENTRY  *Entry,
  IN VOID        *Context
  )
{
  SOCKET                        *Sock;
  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;
  UINTN                         NumberOfChildren;
  EFI_HANDLE                    *ChildHandleBuffer;

  if ((Entry == NULL) || (Context == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Sock              = NET_LIST_USER_STRUCT_S (Entry, SOCKET, Link, SOCK_SIGNATURE);
  ServiceBinding    = ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->ServiceBinding;
  NumberOfChildren  = ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->NumberOfChildren;
  ChildHandleBuffer = ((TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->ChildHandleBuffer;

  if (!NetIsInHandleBuffer (Sock->SockHandle, NumberOfChildren, ChildHandleBuffer)) {
    return EFI_SUCCESS;
  }

  return ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle);
}

/**
  Destroy a TCP6 or TCP4 service binding instance. It will release all
  the resources allocated by the instance.

  @param[in]  Controller         Controller handle of device to bind driver to.
  @param[in]  ImageHandle        The TCP driver's image handle.
  @param[in]  NumberOfChildren   Number of Handles in ChildHandleBuffer. If number
                                 of children is zero stop the entire bus driver.
  @param[in]  ChildHandleBuffer  An array of child handles to be freed. May be NULL
                                 if NumberOfChildren is 0.
  @param[in]  IpVersion          IP_VERSION_4 or IP_VERSION_6

  @retval EFI_SUCCESS            The resources used by the instance were cleaned up.
  @retval Others                 Failed to clean up some of the resources.

**/
EFI_STATUS
TcpDestroyService (
  IN EFI_HANDLE  Controller,
  IN EFI_HANDLE  ImageHandle,
  IN UINTN       NumberOfChildren,
  IN EFI_HANDLE  *ChildHandleBuffer  OPTIONAL,
  IN UINT8       IpVersion
  )
{
  EFI_HANDLE                               NicHandle;
  EFI_GUID                                 *IpProtocolGuid;
  EFI_GUID                                 *ServiceBindingGuid;
  EFI_SERVICE_BINDING_PROTOCOL             *ServiceBinding;
  TCP_SERVICE_DATA                         *TcpServiceData;
  EFI_STATUS                               Status;
  LIST_ENTRY                               *List;
  TCP_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT  Context;
  EFI_SERVICE_BINDING_PROTOCOL             *Hash2ServiceBinding;

  ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6));

  if (IpVersion == IP_VERSION_4) {
    IpProtocolGuid     = &gEfiIp4ProtocolGuid;
    ServiceBindingGuid = &gEfiTcp4ServiceBindingProtocolGuid;
  } else {
    IpProtocolGuid     = &gEfiIp6ProtocolGuid;
    ServiceBindingGuid = &gEfiTcp6ServiceBindingProtocolGuid;
  }

  NicHandle = NetLibGetNicHandle (Controller, IpProtocolGuid);
  if (NicHandle == NULL) {
    return EFI_SUCCESS;
  }

  //
  // Destroy the Hash2ServiceBinding instance if it is created by Tcp driver.
  //
  if (mHash2ServiceHandle != NULL) {
    Status = gBS->LocateProtocol (
                    &gEfiHash2ServiceBindingProtocolGuid,
                    NULL,
                    (VOID **)&Hash2ServiceBinding
                    );
    if (EFI_ERROR (Status) || (Hash2ServiceBinding == NULL) || (Hash2ServiceBinding->DestroyChild == NULL)) {
      return EFI_UNSUPPORTED;
    }

    //
    // Destroy the instance of the hashing protocol for this controller.
    //
    Status = Hash2ServiceBinding->DestroyChild (Hash2ServiceBinding, mHash2ServiceHandle);
    if (EFI_ERROR (Status)) {
      return EFI_UNSUPPORTED;
    }

    mHash2ServiceHandle = NULL;
  }

  Status = gBS->OpenProtocol (
                  NicHandle,
                  ServiceBindingGuid,
                  (VOID **)&ServiceBinding,
                  ImageHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  TcpServiceData = TCP_SERVICE_FROM_THIS (ServiceBinding);

  if (NumberOfChildren != 0) {
    List                      = &TcpServiceData->SocketList;
    Context.ServiceBinding    = ServiceBinding;
    Context.NumberOfChildren  = NumberOfChildren;
    Context.ChildHandleBuffer = ChildHandleBuffer;
    Status                    = NetDestroyLinkList (
                                  List,
                                  TcpDestroyChildEntryInHandleBuffer,
                                  &Context,
                                  NULL
                                  );
  } else if (IsListEmpty (&TcpServiceData->SocketList)) {
    //
    // Uninstall TCP servicebinding protocol
    //
    gBS->UninstallMultipleProtocolInterfaces (
           NicHandle,
           ServiceBindingGuid,
           ServiceBinding,
           NULL
           );

    //
    // Destroy the IpIO consumed by TCP driver
    //
    IpIoDestroy (TcpServiceData->IpIo);
    TcpServiceData->IpIo = NULL;

    //
    // Destroy the heartbeat timer.
    //
    TcpDestroyTimer ();

    //
    // Release the TCP service data
    //
    FreePool (TcpServiceData);

    Status = EFI_SUCCESS;
  }

  return Status;
}

/**
  Test to see if this driver supports ControllerHandle.

  @param[in]  This                Protocol instance pointer.
  @param[in]  ControllerHandle    Handle of device to test.
  @param[in]  RemainingDevicePath Optional parameter use to pick a specific
                                  child device to start.

  @retval EFI_SUCCESS             This driver supports this device.
  @retval EFI_ALREADY_STARTED     This driver is already running on this device.
  @retval other                   This driver does not support this device.

**/
EFI_STATUS
EFIAPI
Tcp4DriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  EFI_STATUS  Status;

  //
  // Test for the Tcp4ServiceBinding Protocol
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiTcp4ServiceBindingProtocolGuid,
                  NULL,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );
  if (!EFI_ERROR (Status)) {
    return EFI_ALREADY_STARTED;
  }

  //
  // Test for the Ip4ServiceBinding Protocol
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiIp4ServiceBindingProtocolGuid,
                  NULL,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );
  return Status;
}

/**
  Start this driver on ControllerHandle.

  @param[in]  This                   Protocol instance pointer.
  @param[in]  ControllerHandle       Handle of device to bind driver to.
  @param[in]  RemainingDevicePath    Optional parameter use to pick a specific child
                                     device to start.

  @retval EFI_SUCCESS            The driver is added to ControllerHandle.
  @retval EFI_OUT_OF_RESOURCES   There are not enough resources to start the
                                 driver.
  @retval other                  The driver cannot be added to ControllerHandle.

**/
EFI_STATUS
EFIAPI
Tcp4DriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  EFI_STATUS  Status;

  Status = TcpCreateService (ControllerHandle, This->DriverBindingHandle, IP_VERSION_4);
  if ((Status == EFI_ALREADY_STARTED) || (Status == EFI_UNSUPPORTED)) {
    Status = EFI_SUCCESS;
  }

  return Status;
}

/**
  Stop this driver on ControllerHandle.

  @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.
  @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
                                if NumberOfChildren is 0.

  @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
Tcp4DriverBindingStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   ControllerHandle,
  IN  UINTN                        NumberOfChildren,
  IN  EFI_HANDLE                   *ChildHandleBuffer OPTIONAL
  )
{
  return TcpDestroyService (
           ControllerHandle,
           This->DriverBindingHandle,
           NumberOfChildren,
           ChildHandleBuffer,
           IP_VERSION_4
           );
}

/**
  Test to see if this driver supports ControllerHandle.

  @param[in]  This                Protocol instance pointer.
  @param[in]  ControllerHandle    Handle of device to test.
  @param[in]  RemainingDevicePath Optional parameter use to pick a specific
                                  child device to start.

  @retval EFI_SUCCESS             This driver supports this device.
  @retval EFI_ALREADY_STARTED     This driver is already running on this device.
  @retval other                   This driver does not support this device.

**/
EFI_STATUS
EFIAPI
Tcp6DriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  EFI_STATUS  Status;

  //
  // Test for the Tcp6ServiceBinding Protocol
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiTcp6ServiceBindingProtocolGuid,
                  NULL,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );
  if (!EFI_ERROR (Status)) {
    return EFI_ALREADY_STARTED;
  }

  //
  // Test for the Ip6ServiceBinding Protocol
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiIp6ServiceBindingProtocolGuid,
                  NULL,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );
  return Status;
}

/**
  Start this driver on ControllerHandle.

  @param[in]  This                   Protocol instance pointer.
  @param[in]  ControllerHandle       Handle of device to bind driver to.
  @param[in]  RemainingDevicePath    Optional parameter use to pick a specific child
                                     device to start.

  @retval EFI_SUCCESS            The driver is added to ControllerHandle.
  @retval EFI_OUT_OF_RESOURCES   There are not enough resources to start the
                                 driver.
  @retval other                  The driver cannot be added to ControllerHandle.

**/
EFI_STATUS
EFIAPI
Tcp6DriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  EFI_STATUS  Status;

  Status = TcpCreateService (ControllerHandle, This->DriverBindingHandle, IP_VERSION_6);
  if ((Status == EFI_ALREADY_STARTED) || (Status == EFI_UNSUPPORTED)) {
    Status = EFI_SUCCESS;
  }

  return Status;
}

/**
  Stop this driver on ControllerHandle.

  @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.
  @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
                                if NumberOfChildren is 0.

  @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
Tcp6DriverBindingStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   ControllerHandle,
  IN  UINTN                        NumberOfChildren,
  IN  EFI_HANDLE                   *ChildHandleBuffer OPTIONAL
  )
{
  return TcpDestroyService (
           ControllerHandle,
           This->DriverBindingHandle,
           NumberOfChildren,
           ChildHandleBuffer,
           IP_VERSION_6
           );
}

/**
  The Callback function called after the TCP socket was created.

  @param[in]  This            Pointer to the socket just created
  @param[in]  Context         Context of the socket

  @retval EFI_SUCCESS         This protocol installed successfully.
  @retval other               An error occurred.

**/
EFI_STATUS
TcpCreateSocketCallback (
  IN SOCKET  *This,
  IN VOID    *Context
  )
{
  EFI_STATUS        Status;
  TCP_SERVICE_DATA  *TcpServiceData;
  EFI_GUID          *IpProtocolGuid;
  VOID              *Ip;

  if (This->IpVersion == IP_VERSION_4) {
    IpProtocolGuid = &gEfiIp4ProtocolGuid;
  } else {
    IpProtocolGuid = &gEfiIp6ProtocolGuid;
  }

  TcpServiceData = ((TCP_PROTO_DATA *)This->ProtoReserved)->TcpService;

  //
  // Open the default IP protocol of IP_IO BY_DRIVER.
  //
  Status = gBS->OpenProtocol (
                  TcpServiceData->IpIo->ChildHandle,
                  IpProtocolGuid,
                  &Ip,
                  TcpServiceData->DriverBindingHandle,
                  This->SockHandle,
                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Open the device path on the handle where service binding resides on.
  //
  Status = gBS->OpenProtocol (
                  TcpServiceData->ControllerHandle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **)&This->ParentDevicePath,
                  TcpServiceData->DriverBindingHandle,
                  This->SockHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    gBS->CloseProtocol (
           TcpServiceData->IpIo->ChildHandle,
           IpProtocolGuid,
           TcpServiceData->DriverBindingHandle,
           This->SockHandle
           );
  } else {
    //
    // Insert this socket into the SocketList.
    //
    InsertTailList (&TcpServiceData->SocketList, &This->Link);
  }

  return Status;
}

/**
  The callback function called before the TCP socket was to be destroyed.

  @param[in]  This                   The TCP socket to be destroyed.
  @param[in]  Context                The context of the socket.

**/
VOID
TcpDestroySocketCallback (
  IN SOCKET  *This,
  IN VOID    *Context
  )
{
  TCP_SERVICE_DATA  *TcpServiceData;
  EFI_GUID          *IpProtocolGuid;

  if (This->IpVersion == IP_VERSION_4) {
    IpProtocolGuid = &gEfiIp4ProtocolGuid;
  } else {
    IpProtocolGuid = &gEfiIp6ProtocolGuid;
  }

  TcpServiceData = ((TCP_PROTO_DATA *)This->ProtoReserved)->TcpService;

  //
  // Remove this node from the list.
  //
  RemoveEntryList (&This->Link);

  //
  // Close the IP protocol.
  //
  gBS->CloseProtocol (
         TcpServiceData->IpIo->ChildHandle,
         IpProtocolGuid,
         TcpServiceData->DriverBindingHandle,
         This->SockHandle
         );
}

/**
  Creates a child handle with a set of TCP services.

  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[in]      This          Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
  @param[in, out] 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
TcpServiceBindingCreateChild (
  IN     EFI_SERVICE_BINDING_PROTOCOL  *This,
  IN OUT EFI_HANDLE                    *ChildHandle
  )
{
  SOCKET            *Sock;
  TCP_SERVICE_DATA  *TcpServiceData;
  TCP_PROTO_DATA    TcpProto;
  EFI_STATUS        Status;
  EFI_TPL           OldTpl;

  if ((NULL == This) || (NULL == ChildHandle)) {
    return EFI_INVALID_PARAMETER;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Status              = EFI_SUCCESS;
  TcpServiceData      = TCP_SERVICE_FROM_THIS (This);
  TcpProto.TcpService = TcpServiceData;
  TcpProto.TcpPcb     = NULL;

  //
  // Create a tcp instance with default Tcp default
  // sock init data and TcpProto
  //
  mTcpDefaultSockData.ProtoData     = &TcpProto;
  mTcpDefaultSockData.DataSize      = sizeof (TCP_PROTO_DATA);
  mTcpDefaultSockData.DriverBinding = TcpServiceData->DriverBindingHandle;
  mTcpDefaultSockData.IpVersion     = TcpServiceData->IpVersion;

  if (TcpServiceData->IpVersion == IP_VERSION_4) {
    mTcpDefaultSockData.Protocol = &gTcp4ProtocolTemplate;
  } else {
    mTcpDefaultSockData.Protocol = &gTcp6ProtocolTemplate;
  }

  Sock = SockCreateChild (&mTcpDefaultSockData);
  if (NULL == Sock) {
    DEBUG (
      (DEBUG_ERROR,
       "TcpDriverBindingCreateChild: No resource to create a Tcp Child\n")
      );

    Status = EFI_OUT_OF_RESOURCES;
  } else {
    *ChildHandle = Sock->SockHandle;
  }

  mTcpDefaultSockData.ProtoData = NULL;

  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Destroys a child handle with a set of TCP services.

  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 be destroyed.

  @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
TcpServiceBindingDestroyChild (
  IN EFI_SERVICE_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                    ChildHandle
  )
{
  EFI_STATUS  Status;
  VOID        *Tcp;
  SOCKET      *Sock;

  if ((NULL == This) || (NULL == ChildHandle)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // retrieve the Tcp4 protocol from ChildHandle
  //
  Status = gBS->OpenProtocol (
                  ChildHandle,
                  &gEfiTcp4ProtocolGuid,
                  &Tcp,
                  gTcp4DriverBinding.DriverBindingHandle,
                  ChildHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    //
    // No Tcp4, try the Tcp6 protocol
    //
    Status = gBS->OpenProtocol (
                    ChildHandle,
                    &gEfiTcp6ProtocolGuid,
                    &Tcp,
                    gTcp6DriverBinding.DriverBindingHandle,
                    ChildHandle,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      Status = EFI_UNSUPPORTED;
    }
  }

  if (!EFI_ERROR (Status)) {
    //
    // destroy this sock and related Tcp protocol control
    // block
    //
    Sock = SOCK_FROM_THIS (Tcp);

    SockDestroyChild (Sock);
  }

  return Status;
}
