/** @file
  Implementation of EFI_TCP4_PROTOCOL and EFI_TCP6_PROTOCOL.

  (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>

  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php.

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "TcpMain.h"

/**
  Check the integrity of the data buffer.

  @param[in]  DataLen              The total length of the data buffer.
  @param[in]  FragmentCount        The fragment count of the fragment table.
  @param[in]  FragmentTable        Pointer to the fragment table of the data
                                   buffer.

  @retval EFI_SUCCESS              The integrity check passed.
  @retval EFI_INVALID_PARAMETER    The integrity check failed.

**/
EFI_STATUS
TcpChkDataBuf (
  IN UINT32                 DataLen,
  IN UINT32                 FragmentCount,
  IN EFI_TCP4_FRAGMENT_DATA *FragmentTable
  )
{
  UINT32 Index;

  UINT32 Len;

  for (Index = 0, Len = 0; Index < FragmentCount; Index++) {
    if (FragmentTable[Index].FragmentBuffer == NULL) {
      return EFI_INVALID_PARAMETER;
    }
    Len = Len + FragmentTable[Index].FragmentLength;
  }

  if (DataLen != Len) {
    return EFI_INVALID_PARAMETER;
  }

  return EFI_SUCCESS;
}

/**
  Get the current operational status.

  @param[in]   This                Pointer to the EFI_TCP4_PROTOCOL instance.
  @param[out]  Tcp4State           Pointer to the buffer to receive the current TCP
                                   state. Optional parameter that may be NULL.
  @param[out]  Tcp4ConfigData      Pointer to the buffer to receive the current TCP
                                   configuration. Optional parameter that may be NULL.
  @param[out]  Ip4ModeData         Pointer to the buffer to receive the current
                                   IPv4 configuration. Optional parameter that may be NULL.
  @param[out]  MnpConfigData       Pointer to the buffer to receive the current MNP
                                   configuration data indirectly used by the TCPv4
                                   Instance. Optional parameter that may be NULL.
  @param[out]  SnpModeData         Pointer to the buffer to receive the current SNP
                                   configuration data indirectly used by the TCPv4
                                   Instance. Optional parameter that may be NULL.

  @retval EFI_SUCCESS              The mode data was read.
  @retval EFI_NOT_STARTED          No configuration data is available because this
                                   instance hasn't been started.
  @retval EFI_INVALID_PARAMETER    This is NULL.

**/
EFI_STATUS
EFIAPI
Tcp4GetModeData (
  IN   EFI_TCP4_PROTOCOL                  *This,
  OUT  EFI_TCP4_CONNECTION_STATE          *Tcp4State      OPTIONAL,
  OUT  EFI_TCP4_CONFIG_DATA               *Tcp4ConfigData OPTIONAL,
  OUT  EFI_IP4_MODE_DATA                  *Ip4ModeData    OPTIONAL,
  OUT  EFI_MANAGED_NETWORK_CONFIG_DATA    *MnpConfigData  OPTIONAL,
  OUT  EFI_SIMPLE_NETWORK_MODE            *SnpModeData    OPTIONAL
  )
{
  TCP4_MODE_DATA  TcpMode;
  SOCKET          *Sock;

  if (NULL == This) {
    return EFI_INVALID_PARAMETER;
  }

  Sock                    = SOCK_FROM_THIS (This);

  TcpMode.Tcp4State       = Tcp4State;
  TcpMode.Tcp4ConfigData  = Tcp4ConfigData;
  TcpMode.Ip4ModeData     = Ip4ModeData;
  TcpMode.MnpConfigData   = MnpConfigData;
  TcpMode.SnpModeData     = SnpModeData;

  return SockGetMode (Sock, &TcpMode);
}

/**
  Initialize or brutally reset the operational parameters for
  this EFI TCPv4 instance.

  @param[in]   This                Pointer to the EFI_TCP4_PROTOCOL instance.
  @param[in]   TcpConfigData       Pointer to the configure data to configure the
                                   instance. Optional parameter that may be NULL.

  @retval EFI_SUCCESS              The operational settings were set, changed, or
                                   reset successfully.
  @retval EFI_NO_MAPPING           When using a default address, configuration
                                   (through DHCP, BOOTP, RARP, etc.) is not
                                   finished.
  @retval EFI_INVALID_PARAMETER    One or more parameters are invalid.
  @retval EFI_ACCESS_DENIED        Configuring TCP instance when it is already
                                   configured.
  @retval EFI_DEVICE_ERROR         An unexpected network or system error occurred.
  @retval EFI_UNSUPPORTED          One or more of the control options are not
                                   supported in the implementation.
  @retval EFI_OUT_OF_RESOURCES     Could not allocate enough system resources.

**/
EFI_STATUS
EFIAPI
Tcp4Configure (
  IN EFI_TCP4_PROTOCOL        * This,
  IN EFI_TCP4_CONFIG_DATA     * TcpConfigData OPTIONAL
  )
{
  EFI_TCP4_OPTION  *Option;
  SOCKET           *Sock;
  EFI_STATUS       Status;
  IP4_ADDR         Ip;
  IP4_ADDR         SubnetMask;

  if (NULL == This) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Tcp protocol related parameter check will be conducted here
  //
  if (NULL != TcpConfigData) {

    CopyMem (&Ip, &TcpConfigData->AccessPoint.RemoteAddress, sizeof (IP4_ADDR));
    if (IP4_IS_LOCAL_BROADCAST (NTOHL (Ip))) {
      return EFI_INVALID_PARAMETER;
    }

    if (TcpConfigData->AccessPoint.ActiveFlag && (0 == TcpConfigData->AccessPoint.RemotePort || (Ip == 0))) {
      return EFI_INVALID_PARAMETER;
    }

    if (!TcpConfigData->AccessPoint.UseDefaultAddress) {

      CopyMem (&Ip, &TcpConfigData->AccessPoint.StationAddress, sizeof (IP4_ADDR));
      CopyMem (&SubnetMask, &TcpConfigData->AccessPoint.SubnetMask, sizeof (IP4_ADDR));
      if (!IP4_IS_VALID_NETMASK (NTOHL (SubnetMask)) ||
          (SubnetMask != 0 && !NetIp4IsUnicast (NTOHL (Ip), NTOHL (SubnetMask)))) {
        return EFI_INVALID_PARAMETER;
      }
    }

    Option = TcpConfigData->ControlOption;
    if ((NULL != Option) && (Option->EnableSelectiveAck || Option->EnablePathMtuDiscovery)) {
      return EFI_UNSUPPORTED;
    }
  }

  Sock = SOCK_FROM_THIS (This);

  if (NULL == TcpConfigData) {
    return SockFlush (Sock);
  }

  Status = SockConfigure (Sock, TcpConfigData);

  if (EFI_NO_MAPPING == Status) {
    Sock->ConfigureState = SO_NO_MAPPING;
  }

  return Status;
}

/**
  Add or delete routing entries.

  @param[in]  This                 Pointer to the EFI_TCP4_PROTOCOL instance.
  @param[in]  DeleteRoute          If TRUE, delete the specified route from routing
                                   table; if FALSE, add the specified route to
                                   routing table.
  @param[in]  SubnetAddress        The destination network.
  @param[in]  SubnetMask           The subnet mask for the destination network.
  @param[in]  GatewayAddress       The gateway address for this route.

  @retval EFI_SUCCESS              The operation completed successfully.
  @retval EFI_NOT_STARTED          The EFI_TCP4_PROTOCOL instance has not been
                                   configured.
  @retval EFI_NO_MAPPING           When using a default address, configuration
                                   (through DHCP, BOOTP, RARP, etc.) is not
                                   finished.
  @retval EFI_INVALID_PARAMETER    One or more parameters are invalid.
  @retval EFI_OUT_OF_RESOURCES     Could not allocate enough resources to add the
                                   entry to the routing table.
  @retval EFI_NOT_FOUND            This route is not in the routing table.
  @retval EFI_ACCESS_DENIED        This route is already in the routing table.
  @retval EFI_UNSUPPORTED          The TCP driver does not support this operation.

**/
EFI_STATUS
EFIAPI
Tcp4Routes (
  IN EFI_TCP4_PROTOCOL           *This,
  IN BOOLEAN                     DeleteRoute,
  IN EFI_IPv4_ADDRESS            *SubnetAddress,
  IN EFI_IPv4_ADDRESS            *SubnetMask,
  IN EFI_IPv4_ADDRESS            *GatewayAddress
  )
{
  SOCKET          *Sock;
  TCP4_ROUTE_INFO RouteInfo;

  if (NULL == This) {
    return EFI_INVALID_PARAMETER;
  }

  Sock                      = SOCK_FROM_THIS (This);

  RouteInfo.DeleteRoute     = DeleteRoute;
  RouteInfo.SubnetAddress   = SubnetAddress;
  RouteInfo.SubnetMask      = SubnetMask;
  RouteInfo.GatewayAddress  = GatewayAddress;

  return SockRoute (Sock, &RouteInfo);
}

/**
  Initiate a non-blocking TCP connection request for an active TCP instance.

  @param[in]  This                 Pointer to the EFI_TCP4_PROTOCOL instance.
  @param[in]  ConnectionToken      Pointer to the connection token to return when
                                   the TCP three way handshake finishes.

  @retval EFI_SUCCESS              The connection request successfully
                                   initiated.
  @retval EFI_NOT_STARTED          This EFI_TCP4_PROTOCOL instance hasn't been
                                   configured.
  @retval EFI_ACCESS_DENIED        The instance is not configured as an active one,
                                   or it is not in Tcp4StateClosed state.
  @retval EFI_INVALID_PARAMETER    One or more parameters are invalid.
  @retval EFI_OUT_OF_RESOURCES     The driver can't allocate enough resources to
                                   initiate the active open.
  @retval EFI_DEVICE_ERROR         An unexpected system or network error occurred.

**/
EFI_STATUS
EFIAPI
Tcp4Connect (
  IN EFI_TCP4_PROTOCOL           *This,
  IN EFI_TCP4_CONNECTION_TOKEN   *ConnectionToken
  )
{
  SOCKET  *Sock;

  if (NULL == This || NULL == ConnectionToken || NULL == ConnectionToken->CompletionToken.Event) {
    return EFI_INVALID_PARAMETER;
  }

  Sock = SOCK_FROM_THIS (This);

  return SockConnect (Sock, ConnectionToken);
}

/**
  Listen on the passive instance to accept an incoming connection request.

  @param[in]  This                 Pointer to the EFI_TCP4_PROTOCOL instance.
  @param[in]  ListenToken          Pointer to the listen token to return when
                                   operation finishes.

  @retval EFI_SUCCESS              The listen token was queued successfully.
  @retval EFI_NOT_STARTED          The EFI_TCP4_PROTOCOL instance hasn't been
                                   configured.
  @retval EFI_ACCESS_DENIED        The instatnce is not a passive one or it is not
                                   in Tcp4StateListen state or a same listen token
                                   has already existed in the listen token queue of
                                   this TCP instance.
  @retval EFI_INVALID_PARAMETER    One or more parameters are invalid.
  @retval EFI_OUT_OF_RESOURCES     Could not allocate enough resources to finish
                                   the operation.
  @retval EFI_DEVICE_ERROR         An unexpected system or network error occurred.

**/
EFI_STATUS
EFIAPI
Tcp4Accept (
  IN EFI_TCP4_PROTOCOL             *This,
  IN EFI_TCP4_LISTEN_TOKEN         *ListenToken
  )
{
  SOCKET  *Sock;

  if (NULL == This || NULL == ListenToken || NULL == ListenToken->CompletionToken.Event) {
    return EFI_INVALID_PARAMETER;
  }

  Sock = SOCK_FROM_THIS (This);

  return SockAccept (Sock, ListenToken);
}

/**
  Queues outgoing data into the transmit queue

  @param[in]  This                 Pointer to the EFI_TCP4_PROTOCOL instance.
  @param[in]  Token                Pointer to the completion token to queue to the
                                   transmit queue.

  @retval EFI_SUCCESS              The data has been queued for transmission.
  @retval EFI_NOT_STARTED          The EFI_TCP4_PROTOCOL instance hasn't been
                                   configured.
  @retval EFI_NO_MAPPING           When using a default address, configuration
                                   (DHCP, BOOTP, RARP, etc.) is not finished yet.
  @retval EFI_INVALID_PARAMETER    One or more parameters are invalid
  @retval EFI_ACCESS_DENIED        One or more of the following conditions is TRUE:
                                   * A transmit completion token with the same
                                   Token-> CompletionToken.Event was already in the
                                   transmission queue. * The current instance is in
                                   Tcp4StateClosed state. * The current instance is
                                   a passive one and it is in Tcp4StateListen
                                   state. * User has called Close() to disconnect
                                   this connection.
  @retval EFI_NOT_READY            The completion token could not be queued because
                                   the transmit queue is full.
  @retval EFI_OUT_OF_RESOURCES     Could not queue the transmit data because of a
                                   resource shortage.
  @retval EFI_NETWORK_UNREACHABLE  There is no route to the destination network or
                                   address.

**/
EFI_STATUS
EFIAPI
Tcp4Transmit (
  IN EFI_TCP4_PROTOCOL            *This,
  IN EFI_TCP4_IO_TOKEN            *Token
  )
{
  SOCKET      *Sock;
  EFI_STATUS  Status;

  if (NULL == This ||
      NULL == Token ||
      NULL == Token->CompletionToken.Event ||
      NULL == Token->Packet.TxData ||
      0 == Token->Packet.TxData->FragmentCount ||
      0 == Token->Packet.TxData->DataLength
      ) {
    return EFI_INVALID_PARAMETER;
  }

  Status = TcpChkDataBuf (
            Token->Packet.TxData->DataLength,
            Token->Packet.TxData->FragmentCount,
            Token->Packet.TxData->FragmentTable
            );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Sock = SOCK_FROM_THIS (This);

  return SockSend (Sock, Token);
}

/**
  Place an asynchronous receive request into the receiving queue.

  @param[in]  This                 Pointer to the EFI_TCP4_PROTOCOL instance.
  @param[in]  Token                Pointer to a token that is associated with the
                                   receive data descriptor.

  @retval EFI_SUCCESS              The receive completion token was cached
  @retval EFI_NOT_STARTED          The EFI_TCP4_PROTOCOL instance hasn't been
                                   configured.
  @retval EFI_NO_MAPPING           When using a default address, configuration
                                   (DHCP, BOOTP, RARP, etc.) is not finished yet.
  @retval EFI_INVALID_PARAMETER    One or more parameters are invalid.
  @retval EFI_OUT_OF_RESOURCES     The receive completion token could not be queued
                                   due to a lack of system resources.
  @retval EFI_DEVICE_ERROR         An unexpected system or network error occurred.
  @retval EFI_ACCESS_DENIED        One or more of the following conditions is TRUE:
                                   * A receive completion token with the same
                                   Token->CompletionToken.Event was already in the
                                   receive queue. * The current instance is in
                                   Tcp4StateClosed state. * The current instance is
                                   a passive one and it is in Tcp4StateListen
                                   state. * User has called Close() to disconnect
                                   this connection.
  @retval EFI_CONNECTION_FIN       The communication peer has closed the connection,
                                   and there is no any buffered data in the receive
                                   buffer of this instance.
  @retval EFI_NOT_READY            The receive request could not be queued because
                                   the receive queue is full.

**/
EFI_STATUS
EFIAPI
Tcp4Receive (
  IN EFI_TCP4_PROTOCOL           *This,
  IN EFI_TCP4_IO_TOKEN           *Token
  )
{
  SOCKET      *Sock;
  EFI_STATUS  Status;

  if (NULL == This ||
      NULL == Token ||
      NULL == Token->CompletionToken.Event ||
      NULL == Token->Packet.RxData ||
      0 == Token->Packet.RxData->FragmentCount ||
      0 == Token->Packet.RxData->DataLength
      ) {
    return EFI_INVALID_PARAMETER;
  }

  Status = TcpChkDataBuf (
            Token->Packet.RxData->DataLength,
            Token->Packet.RxData->FragmentCount,
            Token->Packet.RxData->FragmentTable
            );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Sock = SOCK_FROM_THIS (This);

  return SockRcv (Sock, Token);

}

/**
  Disconnecting a TCP connection gracefully or reset a TCP connection.

  @param[in]  This                 Pointer to the EFI_TCP4_PROTOCOL instance.
  @param[in]  CloseToken           Pointer to the close token to return when
                                   operation finishes.

  @retval EFI_SUCCESS              The operation completed successfully.
  @retval EFI_NOT_STARTED          The EFI_TCP4_PROTOCOL instance hasn't been
                                   configured.
  @retval EFI_ACCESS_DENIED        One or more of the following are TRUE: *
                                   Configure() has been called with TcpConfigData
                                   set to NULL, and this function has not returned.
                                   * Previous Close() call on this instance has not
                                   finished.
  @retval EFI_INVALID_PARAMETER    One ore more parameters are invalid.
  @retval EFI_OUT_OF_RESOURCES     Could not allocate enough resources to finish the
                                   operation.
  @retval EFI_DEVICE_ERROR         Any unexpected category error not belonging to those
                                   listed above.

**/
EFI_STATUS
EFIAPI
Tcp4Close (
  IN EFI_TCP4_PROTOCOL           *This,
  IN EFI_TCP4_CLOSE_TOKEN        *CloseToken
  )
{
  SOCKET  *Sock;

  if (NULL == This || NULL == CloseToken || NULL == CloseToken->CompletionToken.Event) {
    return EFI_INVALID_PARAMETER;
  }

  Sock = SOCK_FROM_THIS (This);

  return SockClose (Sock, CloseToken, CloseToken->AbortOnClose);
}

/**
  Abort an asynchronous connection, listen, transmission or receive request.

  @param  This  The pointer to the EFI_TCP4_PROTOCOL instance.
  @param  Token The pointer to a token that has been issued by
                EFI_TCP4_PROTOCOL.Connect(),
                EFI_TCP4_PROTOCOL.Accept(),
                EFI_TCP4_PROTOCOL.Transmit() or
                EFI_TCP4_PROTOCOL.Receive(). If NULL, all pending
                tokens issued by above four functions will be aborted. Type
                EFI_TCP4_COMPLETION_TOKEN is defined in
                EFI_TCP4_PROTOCOL.Connect().

  @retval  EFI_SUCCESS             The asynchronous I/O request is aborted and Token->Event
                                   is signaled.
  @retval  EFI_INVALID_PARAMETER   This is NULL.
  @retval  EFI_NOT_STARTED         This instance hasn't been configured.
  @retval  EFI_NO_MAPPING          When using the default address, configuration
                                   (DHCP, BOOTP,RARP, etc.) hasn't finished yet.
  @retval  EFI_NOT_FOUND           The asynchronous I/O request isn't found in the
                                   transmission or receive queue. It has either
                                   completed or wasn't issued by Transmit() and Receive().

**/
EFI_STATUS
EFIAPI
Tcp4Cancel (
  IN EFI_TCP4_PROTOCOL             *This,
  IN EFI_TCP4_COMPLETION_TOKEN     *Token OPTIONAL
  )
{
  SOCKET  *Sock;

  if (NULL == This) {
    return EFI_INVALID_PARAMETER;
  }

  Sock = SOCK_FROM_THIS (This);

  return SockCancel (Sock, Token);
}

/**
  Poll to receive incoming data and transmit outgoing segments.

  @param[in]  This                 Pointer to the EFI_TCP4_PROTOCOL instance.

  @retval EFI_SUCCESS              Incoming or outgoing data was processed.
  @retval EFI_INVALID_PARAMETER    This is NULL.
  @retval EFI_DEVICE_ERROR         An unexpected system or network error occurred.
  @retval EFI_NOT_READY            No incoming or outgoing data was processed.
  @retval EFI_TIMEOUT              Data was dropped out of the transmission or
                                   receive queue. Consider increasing the polling
                                   rate.

**/
EFI_STATUS
EFIAPI
Tcp4Poll (
  IN EFI_TCP4_PROTOCOL        *This
  )
{
  SOCKET      *Sock;
  EFI_STATUS  Status;

  if (NULL == This) {
    return EFI_INVALID_PARAMETER;
  }

  Sock   = SOCK_FROM_THIS (This);

  Status = Sock->ProtoHandler (Sock, SOCK_POLL, NULL);

  return Status;
}

/**
  Get the current operational status.

  The GetModeData() function copies the current operational settings of this EFI TCPv6
  Protocol instance into user-supplied buffers. This function can also be used to retrieve
  the operational setting of underlying drivers such as IPv6, MNP, or SNP.

  @param[in]  This              Pointer to the EFI_TCP6_PROTOCOL instance.
  @param[out] Tcp6State         The buffer in which the current TCP state is
                                returned. Optional parameter that may be NULL.
  @param[out] Tcp6ConfigData    The buffer in which the current TCP configuration
                                is returned. Optional parameter that may be NULL.
  @param[out] Ip6ModeData       The buffer in which the current IPv6 configuration
                                data used by the TCP instance is returned.
                                Optional parameter that may be NULL.
  @param[out] MnpConfigData     The buffer in which the current MNP configuration
                                data indirectly used by the TCP instance is returned.
                                Optional parameter that may be NULL.
  @param[out] SnpModeData       The buffer in which the current SNP mode data
                                indirectly used by the TCP instance is returned.
                                Optional parameter that may be NULL.

  @retval EFI_SUCCESS           The mode data was read.
  @retval EFI_NOT_STARTED       No configuration data is available because this instance hasn't
                                been started.
  @retval EFI_INVALID_PARAMETER This is NULL.

**/
EFI_STATUS
EFIAPI
Tcp6GetModeData (
  IN  EFI_TCP6_PROTOCOL                  *This,
  OUT EFI_TCP6_CONNECTION_STATE          *Tcp6State      OPTIONAL,
  OUT EFI_TCP6_CONFIG_DATA               *Tcp6ConfigData OPTIONAL,
  OUT EFI_IP6_MODE_DATA                  *Ip6ModeData    OPTIONAL,
  OUT EFI_MANAGED_NETWORK_CONFIG_DATA    *MnpConfigData  OPTIONAL,
  OUT EFI_SIMPLE_NETWORK_MODE            *SnpModeData    OPTIONAL
  )
{
  TCP6_MODE_DATA  TcpMode;
  SOCKET          *Sock;

  if (NULL == This) {
    return EFI_INVALID_PARAMETER;
  }

  Sock                   = SOCK_FROM_THIS (This);

  TcpMode.Tcp6State      = Tcp6State;
  TcpMode.Tcp6ConfigData = Tcp6ConfigData;
  TcpMode.Ip6ModeData    = Ip6ModeData;
  TcpMode.MnpConfigData  = MnpConfigData;
  TcpMode.SnpModeData    = SnpModeData;

  return SockGetMode (Sock, &TcpMode);
}

/**
  Initialize or brutally reset the operational parameters for this EFI TCPv6 instance.

  The Configure() function does the following:
  - Initialize this TCP instance, i.e., initialize the communication end settings and
    specify active open or passive open for an instance.
  - Reset this TCP instance brutally, i.e., cancel all pending asynchronous tokens, flush
    transmission and receiving buffer directly without informing the communication peer.

  No other TCPv6 Protocol operation except Poll() can be executed by this instance until
  it is configured properly. For an active TCP instance, after a proper configuration it
  may call Connect() to initiate a three-way handshake. For a passive TCP instance,
  its state transits to Tcp6StateListen after configuration, and Accept() may be
  called to listen the incoming TCP connection requests. If Tcp6ConfigData is set to NULL,
  the instance is reset. The resetting process will be done brutally, the state machine will
  be set to Tcp6StateClosed directly, the receive queue and transmit queue will be flushed,
  and no traffic is allowed through this instance.

  @param[in] This               Pointer to the EFI_TCP6_PROTOCOL instance.
  @param[in] Tcp6ConfigData     Pointer to the configure data to configure the instance.
                                If Tcp6ConfigData is set to NULL, the instance is reset.

  @retval EFI_SUCCESS           The operational settings were set, changed, or reset
                                successfully.
  @retval EFI_NO_MAPPING        The underlying IPv6 driver was responsible for choosing a source
                                address for this instance, but no source address was available for
                                use.
  @retval EFI_INVALID_PARAMETER One or more of the following conditions are TRUE:
                                - This is NULL.
                                - Tcp6ConfigData->AccessPoint.StationAddress is neither zero nor
                                  one of the configured IP addresses in the underlying IPv6 driver.
                                - Tcp6ConfigData->AccessPoint.RemoteAddress isn't a valid unicast
                                  IPv6 address.
                                - Tcp6ConfigData->AccessPoint.RemoteAddress is zero or
                                  Tcp6ConfigData->AccessPoint.RemotePort is zero when
                                  Tcp6ConfigData->AccessPoint.ActiveFlag is TRUE.
                                - A same access point has been configured in other TCP
                                  instance properly.
  @retval EFI_ACCESS_DENIED     Configuring a TCP instance when it is configured without
                                calling Configure() with NULL to reset it.
  @retval EFI_UNSUPPORTED       One or more of the control options are not supported in
                                the implementation.
  @retval EFI_OUT_OF_RESOURCES  Could not allocate enough system resources when
                                executing Configure().
  @retval EFI_DEVICE_ERROR      An unexpected network or system error occurred.

**/
EFI_STATUS
EFIAPI
Tcp6Configure (
  IN EFI_TCP6_PROTOCOL        *This,
  IN EFI_TCP6_CONFIG_DATA     *Tcp6ConfigData OPTIONAL
  )
{
  EFI_TCP6_OPTION   *Option;
  SOCKET            *Sock;
  EFI_STATUS        Status;
  EFI_IPv6_ADDRESS  *Ip;

  if (NULL == This) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Tcp protocol related parameter check will be conducted here
  //
  if (NULL != Tcp6ConfigData) {

    Ip = &Tcp6ConfigData->AccessPoint.RemoteAddress;
    if (!NetIp6IsUnspecifiedAddr (Ip) && !NetIp6IsValidUnicast (Ip)) {
      return EFI_INVALID_PARAMETER;
    }

    if (Tcp6ConfigData->AccessPoint.ActiveFlag &&
        (0 == Tcp6ConfigData->AccessPoint.RemotePort || NetIp6IsUnspecifiedAddr (Ip))
        ) {
      return EFI_INVALID_PARAMETER;
    }

    Ip = &Tcp6ConfigData->AccessPoint.StationAddress;
    if (!NetIp6IsUnspecifiedAddr (Ip) && !NetIp6IsValidUnicast (Ip)) {
      return EFI_INVALID_PARAMETER;
    }

    Option = Tcp6ConfigData->ControlOption;
    if ((NULL != Option) && (Option->EnableSelectiveAck || Option->EnablePathMtuDiscovery)) {
      return EFI_UNSUPPORTED;
    }
  }

  Sock = SOCK_FROM_THIS (This);

  if (NULL == Tcp6ConfigData) {
    return SockFlush (Sock);
  }

  Status = SockConfigure (Sock, Tcp6ConfigData);

  if (EFI_NO_MAPPING == Status) {
    Sock->ConfigureState = SO_NO_MAPPING;
  }

  return Status;
}

/**
  Initiate a nonblocking TCP connection request for an active TCP instance.

  The Connect() function will initiate an active open to the remote peer configured
  in a current TCP instance if it is configured active. If the connection succeeds or
  fails due to any error, the ConnectionToken->CompletionToken.Event will be signaled
  and ConnectionToken->CompletionToken.Status will be updated accordingly. This
  function can only be called for the TCP instance in the Tcp6StateClosed state. The
  instance will transfer into Tcp6StateSynSent if the function returns EFI_SUCCESS.
  If a TCP three-way handshake succeeds, its state will become Tcp6StateEstablished.
  Otherwise, the state will return to Tcp6StateClosed.

  @param[in] This                Pointer to the EFI_TCP6_PROTOCOL instance.
  @param[in] ConnectionToken     Pointer to the connection token to return when the TCP three
                                 way handshake finishes.

  @retval EFI_SUCCESS            The connection request successfully initiated and the state of
                                 this TCP instance has been changed to Tcp6StateSynSent.
  @retval EFI_NOT_STARTED        This EFI TCPv6 Protocol instance has not been configured.
  @retval EFI_ACCESS_DENIED      One or more of the following conditions are TRUE:
                                 - This instance is not configured as an active one.
                                 - This instance is not in Tcp6StateClosed state.
  @retval EFI_INVALID_PARAMETER  One or more of the following are TRUE:
                                 - This is NULL.
                                 - ConnectionToken is NULL.
                                 - ConnectionToken->CompletionToken.Event is NULL.
  @retval EFI_OUT_OF_RESOURCES   The driver can't allocate enough resources to initiate the active open.
  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.

**/
EFI_STATUS
EFIAPI
Tcp6Connect (
  IN EFI_TCP6_PROTOCOL           *This,
  IN EFI_TCP6_CONNECTION_TOKEN   *ConnectionToken
  )
{
  SOCKET  *Sock;

  if (NULL == This || NULL == ConnectionToken || NULL == ConnectionToken->CompletionToken.Event) {
    return EFI_INVALID_PARAMETER;
  }

  Sock = SOCK_FROM_THIS (This);

  return SockConnect (Sock, ConnectionToken);
}

/**
  Listen on the passive instance to accept an incoming connection request. This is a
  nonblocking operation.

  The Accept() function initiates an asynchronous accept request to wait for an incoming
  connection on the passive TCP instance. If a remote peer successfully establishes a
  connection with this instance, a new TCP instance will be created and its handle will
  be returned in ListenToken->NewChildHandle. The newly created instance is configured
  by inheriting the passive instance's configuration and is ready for use upon return.
  The new instance is in the Tcp6StateEstablished state.

  The ListenToken->CompletionToken.Event will be signaled when a new connection is
  accepted, when a user aborts the listen or when a connection is reset.

  This function only can be called when a current TCP instance is in Tcp6StateListen state.

  @param[in] This                Pointer to the EFI_TCP6_PROTOCOL instance.
  @param[in] ListenToken         Pointer to the listen token to return when operation finishes.


  @retval EFI_SUCCESS            The listen token queued successfully.
  @retval EFI_NOT_STARTED        This EFI TCPv6 Protocol instance has not been configured.
  @retval EFI_ACCESS_DENIED      One or more of the following are TRUE:
                                 - This instance is not a passive instance.
                                 - This instance is not in Tcp6StateListen state.
                                 - The same listen token has already existed in the listen
                                   token queue of this TCP instance.
  @retval EFI_INVALID_PARAMETER  One or more of the following are TRUE:
                                 - This is NULL.
                                 - ListenToken is NULL.
                                 - ListentToken->CompletionToken.Event is NULL.
  @retval EFI_OUT_OF_RESOURCES   Could not allocate enough resource to finish the operation.
  @retval EFI_DEVICE_ERROR       Any unexpected error not belonging to a category listed above.

**/
EFI_STATUS
EFIAPI
Tcp6Accept (
  IN EFI_TCP6_PROTOCOL             *This,
  IN EFI_TCP6_LISTEN_TOKEN         *ListenToken
  )
{
  SOCKET  *Sock;

  if (NULL == This || NULL == ListenToken || NULL == ListenToken->CompletionToken.Event) {
    return EFI_INVALID_PARAMETER;
  }

  Sock = SOCK_FROM_THIS (This);

  return SockAccept (Sock, ListenToken);
}

/**
  Queues outgoing data into the transmit queue.

  The Transmit() function queues a sending request to this TCP instance along with the
  user data. The status of the token is updated and the event in the token will be
  signaled once the data is sent out or an error occurs.

  @param[in] This                 Pointer to the EFI_TCP6_PROTOCOL instance.
  @param[in] Token                Pointer to the completion token to queue to the transmit queue.

  @retval EFI_SUCCESS             The data has been queued for transmission.
  @retval EFI_NOT_STARTED         This EFI TCPv6 Protocol instance has not been configured.
  @retval EFI_NO_MAPPING          The underlying IPv6 driver was responsible for choosing a
                                  source address for this instance, but no source address was
                                  available for use.
  @retval EFI_INVALID_PARAMETER   One or more of the following are TRUE:
                                  - This is NULL.
                                  - Token is NULL.
                                  - Token->CompletionToken.Event is NULL.
                                  - Token->Packet.TxData is NULL.
                                  - Token->Packet.FragmentCount is zero.
                                  - Token->Packet.DataLength is not equal to the sum of fragment lengths.
  @retval EFI_ACCESS_DENIED       One or more of the following conditions are TRUE:
                                  - A transmit completion token with the same Token->
                                    CompletionToken.Event was already in the
                                    transmission queue.
                                  - The current instance is in Tcp6StateClosed state.
                                  - The current instance is a passive one and it is in
                                    Tcp6StateListen state.
                                  - User has called Close() to disconnect this connection.
  @retval EFI_NOT_READY           The completion token could not be queued because the
                                  transmit queue is full.
  @retval EFI_OUT_OF_RESOURCES    Could not queue the transmit data because of resource
                                  shortage.
  @retval EFI_NETWORK_UNREACHABLE There is no route to the destination network or address.

**/
EFI_STATUS
EFIAPI
Tcp6Transmit (
  IN EFI_TCP6_PROTOCOL            *This,
  IN EFI_TCP6_IO_TOKEN            *Token
  )
{
  SOCKET      *Sock;
  EFI_STATUS  Status;

  if (NULL == This ||
      NULL == Token ||
      NULL == Token->CompletionToken.Event ||
      NULL == Token->Packet.TxData ||
      0 == Token->Packet.TxData->FragmentCount ||
      0 == Token->Packet.TxData->DataLength
      ) {
    return EFI_INVALID_PARAMETER;
  }

  Status = TcpChkDataBuf (
            Token->Packet.TxData->DataLength,
            Token->Packet.TxData->FragmentCount,
            (EFI_TCP4_FRAGMENT_DATA *) Token->Packet.TxData->FragmentTable
            );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Sock = SOCK_FROM_THIS (This);

  return SockSend (Sock, Token);
}

/**
  Places an asynchronous receive request into the receiving queue.

  The Receive() function places a completion token into the receive packet queue. This
  function is always asynchronous. The caller must allocate the Token->CompletionToken.Event
  and the FragmentBuffer used to receive data. The caller also must fill the DataLength that
  represents the whole length of all FragmentBuffer. When the receive operation completes, the
  EFI TCPv6 Protocol driver updates the Token->CompletionToken.Status and Token->Packet.RxData
  fields, and the Token->CompletionToken.Event is signaled. If data obtained, the data and its length
  will be copied into the FragmentTable; at the same time the full length of received data will
  be recorded in the DataLength fields. Providing a proper notification function and context
  for the event enables the user to receive the notification and receiving status. That
  notification function is guaranteed to not be re-entered.

  @param[in] This               Pointer to the EFI_TCP6_PROTOCOL instance.
  @param[in] Token              Pointer to a token that is associated with the receive data
                                descriptor.

  @retval EFI_SUCCESS            The receive completion token was cached.
  @retval EFI_NOT_STARTED        This EFI TCPv6 Protocol instance has not been configured.
  @retval EFI_NO_MAPPING         The underlying IPv6 driver was responsible for choosing a source
                                 address for this instance, but no source address was available for use.
  @retval EFI_INVALID_PARAMETER  One or more of the following conditions is TRUE:
                                 - This is NULL.
                                 - Token is NULL.
                                 - Token->CompletionToken.Event is NULL.
                                 - Token->Packet.RxData is NULL.
                                 - Token->Packet.RxData->DataLength is 0.
                                 - The Token->Packet.RxData->DataLength is not the
                                   sum of all FragmentBuffer length in FragmentTable.
  @retval EFI_OUT_OF_RESOURCES   The receive completion token could not be queued due to a lack of
                                 system resources (usually memory).
  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.
                                 The EFI TCPv6 Protocol instance has been reset to startup defaults.
  @retval EFI_ACCESS_DENIED      One or more of the following conditions is TRUE:
                                 - A receive completion token with the same Token->CompletionToken.Event
                                   was already in the receive queue.
                                 - The current instance is in Tcp6StateClosed state.
                                 - The current instance is a passive one and it is in
                                   Tcp6StateListen state.
                                 - User has called Close() to disconnect this connection.
  @retval EFI_CONNECTION_FIN     The communication peer has closed the connection and there is no
                                 buffered data in the receive buffer of this instance.
  @retval EFI_NOT_READY          The receive request could not be queued because the receive queue is full.

**/
EFI_STATUS
EFIAPI
Tcp6Receive (
  IN EFI_TCP6_PROTOCOL           *This,
  IN EFI_TCP6_IO_TOKEN           *Token
  )
{
  SOCKET      *Sock;
  EFI_STATUS  Status;

  if (NULL == This ||
      NULL == Token ||
      NULL == Token->CompletionToken.Event ||
      NULL == Token->Packet.RxData ||
      0 == Token->Packet.RxData->FragmentCount ||
      0 == Token->Packet.RxData->DataLength
      ) {
    return EFI_INVALID_PARAMETER;
  }

  Status = TcpChkDataBuf (
            Token->Packet.RxData->DataLength,
            Token->Packet.RxData->FragmentCount,
            (EFI_TCP4_FRAGMENT_DATA *) Token->Packet.RxData->FragmentTable
            );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Sock = SOCK_FROM_THIS (This);

  return SockRcv (Sock, Token);
}

/**
  Disconnecting a TCP connection gracefully or reset a TCP connection. This function is a
  nonblocking operation.

  Initiate an asynchronous close token to the TCP driver. After Close() is called, any buffered
  transmission data will be sent by the TCP driver, and the current instance will have a graceful close
  working flow described as RFC 793 if AbortOnClose is set to FALSE. Otherwise, a rest packet
  will be sent by TCP driver to fast disconnect this connection. When the close operation completes
  successfully the TCP instance is in Tcp6StateClosed state, all pending asynchronous
  operations are signaled, and any buffers used for TCP network traffic are flushed.

  @param[in] This                Pointer to the EFI_TCP6_PROTOCOL instance.
  @param[in] CloseToken          Pointer to the close token to return when operation finishes.

  @retval EFI_SUCCESS            The Close() was called successfully.
  @retval EFI_NOT_STARTED        This EFI TCPv6 Protocol instance has not been configured.
  @retval EFI_ACCESS_DENIED      One or more of the following are TRUE:
                                 - CloseToken or CloseToken->CompletionToken.Event is already in use.
                                 - Previous Close() call on this instance has not finished.
  @retval EFI_INVALID_PARAMETER  One or more of the following are TRUE:
                                 - This is NULL.
                                 - CloseToken is NULL.
                                 - CloseToken->CompletionToken.Event is NULL.
  @retval EFI_OUT_OF_RESOURCES   Could not allocate enough resource to finish the operation.
  @retval EFI_DEVICE_ERROR       Any unexpected error not belonging to error categories given above.

**/
EFI_STATUS
EFIAPI
Tcp6Close (
  IN EFI_TCP6_PROTOCOL           *This,
  IN EFI_TCP6_CLOSE_TOKEN        *CloseToken
  )
{
  SOCKET  *Sock;

  if (NULL == This || NULL == CloseToken || NULL == CloseToken->CompletionToken.Event) {
    return EFI_INVALID_PARAMETER;
  }

  Sock = SOCK_FROM_THIS (This);

  return SockClose (Sock, CloseToken, CloseToken->AbortOnClose);
}

/**
  Abort an asynchronous connection, listen, transmission or receive request.

  The Cancel() function aborts a pending connection, listen, transmit or
  receive request.

  If Token is not NULL and the token is in the connection, listen, transmission
  or receive queue when it is being cancelled, its Token->Status will be set
  to EFI_ABORTED and then Token->Event will be signaled.

  If the token is not in one of the queues, which usually means that the
  asynchronous operation has completed, EFI_NOT_FOUND is returned.

  If Token is NULL all asynchronous token issued by Connect(), Accept(),
  Transmit() and Receive() will be aborted.

  @param[in] This                Pointer to the EFI_TCP6_PROTOCOL instance.
  @param[in] Token               Pointer to a token that has been issued by
                                 EFI_TCP6_PROTOCOL.Connect(),
                                 EFI_TCP6_PROTOCOL.Accept(),
                                 EFI_TCP6_PROTOCOL.Transmit() or
                                 EFI_TCP6_PROTOCOL.Receive(). If NULL, all pending
                                 tokens issued by above four functions will be aborted. Type
                                 EFI_TCP6_COMPLETION_TOKEN is defined in
                                 EFI_TCP_PROTOCOL.Connect().

  @retval EFI_SUCCESS            The asynchronous I/O request is aborted and Token->Event
                                 is signaled.
  @retval EFI_INVALID_PARAMETER  This is NULL.
  @retval EFI_NOT_STARTED        This instance hasn't been configured.
  @retval EFI_NOT_FOUND          The asynchronous I/O request isn't found in the transmission or
                                 receive queue. It has either completed or wasn't issued by
                                 Transmit() and Receive().

**/
EFI_STATUS
EFIAPI
Tcp6Cancel (
  IN EFI_TCP6_PROTOCOL           *This,
  IN EFI_TCP6_COMPLETION_TOKEN   *Token OPTIONAL
  )
{
  SOCKET  *Sock;

  if (NULL == This) {
    return EFI_INVALID_PARAMETER;
  }

  Sock = SOCK_FROM_THIS (This);

  return SockCancel (Sock, Token);
}

/**
  Poll to receive incoming data and transmit outgoing segments.

  The Poll() function increases the rate that data is moved between the network
  and application, and can be called when the TCP instance is created successfully.
  Its use is optional.

  @param[in] This                Pointer to the EFI_TCP6_PROTOCOL instance.

  @retval EFI_SUCCESS            Incoming or outgoing data was processed.
  @retval EFI_INVALID_PARAMETER  This is NULL.
  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.
  @retval EFI_NOT_READY          No incoming or outgoing data is processed.
  @retval EFI_TIMEOUT            Data was dropped out of the transmission or receive queue.
                                 Consider increasing the polling rate.

**/
EFI_STATUS
EFIAPI
Tcp6Poll (
  IN EFI_TCP6_PROTOCOL        *This
  )
{
  SOCKET      *Sock;
  EFI_STATUS  Status;

  if (NULL == This) {
    return EFI_INVALID_PARAMETER;
  }

  Sock   = SOCK_FROM_THIS (This);

  Status = Sock->ProtoHandler (Sock, SOCK_POLL, NULL);

  return Status;
}

