]> git.proxmox.com Git - mirror_edk2.git/blobdiff - StdLib/EfiSocketLib/Tcp4.c
edk2: Remove AppPkg, StdLib, StdLibPrivateInternalFiles
[mirror_edk2.git] / StdLib / EfiSocketLib / Tcp4.c
diff --git a/StdLib/EfiSocketLib/Tcp4.c b/StdLib/EfiSocketLib/Tcp4.c
deleted file mode 100644 (file)
index 143b54b..0000000
+++ /dev/null
@@ -1,2426 +0,0 @@
-/** @file\r
-  Implement the TCP4 driver support for the socket layer.\r
-\r
-  Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>\r
-  SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-\r
-  \section ConnectionManagement Connection Management\r
-\r
-  The ::EslTcp4Listen routine initially places the SOCK_STREAM or\r
-  SOCK_SEQPACKET socket into a listen state.   When a remote machine\r
-  makes a connection to the socket, the TCPv4 network layer calls\r
-  ::EslTcp4ListenComplete to complete the connection processing.\r
-  EslTcp4ListenComplete manages the connections by placing them in\r
-  FIFO order in a queue to be serviced by the application.  When the\r
-  number of connections exceeds the backlog (ESL_SOCKET::MaxFifoDepth),\r
-  the new connection is closed.  Eventually, the application indirectly\r
-  calls ::EslTcp4Accept to remove the next connection from the queue\r
-  and get the associated socket.\r
-\r
-**/\r
-\r
-#include "Socket.h"\r
-\r
-\r
-/**\r
-  Attempt to connect to a remote TCP port\r
-\r
-  This routine starts the connection processing for a SOCK_STREAM\r
-  or SOCK_SEQPAKCET socket using the TCPv4 network layer.  It\r
-  configures the local TCPv4 connection point and then attempts to\r
-  connect to a remote system.  Upon completion, the\r
-  ::EslTcp4ConnectComplete routine gets called with the connection\r
-  status.\r
-\r
-  This routine is called by ::EslSocketConnect to initiate the TCPv4\r
-  network specific connect operations.  The connection processing is\r
-  initiated by this routine and finished by ::EslTcp4ConnectComplete.\r
-  This pair of routines walks through the list of local TCPv4\r
-  connection points until a connection to the remote system is\r
-  made.\r
-\r
-  @param [in] pSocket   Address of an ::ESL_SOCKET structure.\r
-\r
-  @retval EFI_SUCCESS   The connection was successfully established.\r
-  @retval EFI_NOT_READY The connection is in progress, call this routine again.\r
-  @retval Others        The connection attempt failed.\r
-\r
- **/\r
-EFI_STATUS\r
-EslTcp4ConnectStart (\r
-  IN ESL_SOCKET * pSocket\r
-  );\r
-\r
-\r
-/**\r
-  Process the connection attempt\r
-\r
-  A system has initiated a connection attempt with a socket in the\r
-  listen state.  Attempt to complete the connection.\r
-\r
-  The TCPv4 layer calls this routine when a connection is made to\r
-  the socket in the listen state.  See the\r
-  \ref ConnectionManagement section.\r
-\r
-  @param [in] Event     The listen completion event\r
-\r
-  @param [in] pPort     Address of an ::ESL_PORT structure.\r
-\r
-**/\r
-VOID\r
-EslTcp4ListenComplete (\r
-  IN EFI_EVENT Event,\r
-  IN ESL_PORT * pPort\r
-  );\r
-\r
-\r
-/**\r
-  Accept a network connection.\r
-\r
-  This routine waits for a network connection to the socket and\r
-  returns the remote network address to the caller if requested.\r
-\r
-  This routine is called by ::EslSocketAccept to handle the TCPv4 protocol\r
-  specific accept operations for SOCK_STREAM and SOCK_SEQPACKET sockets.\r
-  See the \ref ConnectionManagement section.\r
-\r
-  @param [in] pSocket   Address of an ::ESL_SOCKET structure.\r
-\r
-  @param [in] pSockAddr       Address of a buffer to receive the remote\r
-                              network address.\r
-\r
-  @param [in, out] pSockAddrLength  Length in bytes of the address buffer.\r
-                                    On output specifies the length of the\r
-                                    remote network address.\r
-\r
-  @retval EFI_SUCCESS   Remote address is available\r
-  @retval Others        Remote address not available\r
-\r
- **/\r
-EFI_STATUS\r
-EslTcp4Accept (\r
-  IN ESL_SOCKET * pSocket,\r
-  IN struct sockaddr * pSockAddr,\r
-  IN OUT socklen_t * pSockAddrLength\r
-  )\r
-{\r
-  ESL_PORT * pPort;\r
-  struct sockaddr_in * pRemoteAddress;\r
-  ESL_TCP4_CONTEXT * pTcp4;\r
-  UINT32 RemoteAddress;\r
-  EFI_STATUS Status;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Validate the socket length\r
-  //\r
-  pRemoteAddress = (struct sockaddr_in *) pSockAddr;\r
-  if (( NULL == pSockAddrLength )\r
-    || ( sizeof ( *pRemoteAddress ) > *pSockAddrLength )) {\r
-    //\r
-    //  Invalid socket address\r
-    //\r
-    Status = EFI_INVALID_PARAMETER;\r
-    pSocket->errno = EINVAL;\r
-    DEBUG (( DEBUG_ACCEPT,\r
-              "ERROR - Invalid address length\r\n" ));\r
-  }\r
-  else {\r
-    //\r
-    //  Assume success\r
-    //\r
-    Status = EFI_SUCCESS;\r
-\r
-    //\r
-    //  Locate the address context\r
-    //\r
-    pPort = pSocket->pPortList;\r
-    pTcp4 = &pPort->Context.Tcp4;\r
-\r
-    //\r
-    //  Fill-in the remote address structure\r
-    //\r
-    ZeroMem ( pRemoteAddress, sizeof ( *pRemoteAddress ));\r
-    pRemoteAddress->sin_len = sizeof ( *pRemoteAddress );\r
-    pRemoteAddress->sin_family = AF_INET;\r
-    pRemoteAddress->sin_port = SwapBytes16 ( pTcp4->ConfigData.AccessPoint.RemotePort );\r
-    RemoteAddress = pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[3];\r
-    RemoteAddress <<= 8;\r
-    RemoteAddress |= pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[2];\r
-    RemoteAddress <<= 8;\r
-    RemoteAddress |= pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[1];\r
-    RemoteAddress <<= 8;\r
-    RemoteAddress |= pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[0];\r
-    pRemoteAddress->sin_addr.s_addr = RemoteAddress;\r
-  }\r
-\r
-  //\r
-  //  Return the operation status\r
-  //\r
-  DBG_EXIT_STATUS ( Status );\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Process the remote connection completion event.\r
-\r
-  This routine handles the completion of a connection attempt.  It\r
-  releases the port (TCPv4 adapter connection) in the case of an\r
-  error and start a connection attempt on the next port.  If the\r
-  connection attempt was successful then this routine releases all\r
-  of the other ports.\r
-\r
-  This routine is called by the TCPv4 layer when a connect request\r
-  completes.  It sets the ESL_SOCKET::bConnected flag to notify the\r
-  ::EslTcp4ConnectComplete routine that the connection is available.\r
-  The flag is set when the connection is established or no more ports\r
-  exist in the list.  The connection status is passed via\r
-  ESL_SOCKET::ConnectStatus.\r
-\r
-  @param [in] Event     The connect completion event\r
-\r
-  @param [in] pPort     Address of an ::ESL_PORT structure.\r
-\r
-**/\r
-VOID\r
-EslTcp4ConnectComplete (\r
-  IN EFI_EVENT Event,\r
-  IN ESL_PORT * pPort\r
-  )\r
-{\r
-  BOOLEAN bRemoveFirstPort;\r
-  BOOLEAN bRemovePorts;\r
-  ESL_PORT * pNextPort;\r
-  ESL_SOCKET * pSocket;\r
-  ESL_TCP4_CONTEXT * pTcp4;\r
-  EFI_STATUS Status;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Locate the TCP context\r
-  //\r
-  pSocket = pPort->pSocket;\r
-  pTcp4 = &pPort->Context.Tcp4;\r
-\r
-  //\r
-  //  Get the connection status\r
-  //\r
-  bRemoveFirstPort = FALSE;\r
-  bRemovePorts = FALSE;\r
-  Status = pTcp4->ConnectToken.CompletionToken.Status;\r
-  pSocket->ConnectStatus = Status;\r
-  if ( !EFI_ERROR ( Status )) {\r
-    //\r
-    //  The connection was successful\r
-    //\r
-    DEBUG (( DEBUG_CONNECT,\r
-              "0x%08x: Port connected to %d.%d.%d.%d:%d\r\n",\r
-              pPort,\r
-              pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[0],\r
-              pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[1],\r
-              pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[2],\r
-              pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[3],\r
-              pTcp4->ConfigData.AccessPoint.RemotePort ));\r
-\r
-    //\r
-    //  Start the receive operations\r
-    //\r
-    pSocket->bConfigured = TRUE;\r
-    pSocket->State = SOCKET_STATE_CONNECTED;\r
-    EslSocketRxStart ( pPort );\r
-\r
-    //\r
-    //  Remove the rest of the ports\r
-    //\r
-    bRemovePorts = TRUE;\r
-  }\r
-  else {\r
-    //\r
-    //  The connection failed\r
-    //\r
-    if ( pPort->bConfigured ) {\r
-      DEBUG (( DEBUG_CONNECT,\r
-                "0x%08x: Port connection to %d.%d.%d.%d:%d failed, Status: %r\r\n",\r
-                pPort,\r
-                pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[0],\r
-                pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[1],\r
-                pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[2],\r
-                pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[3],\r
-                pTcp4->ConfigData.AccessPoint.RemotePort,\r
-                Status ));\r
-    }\r
-\r
-    //\r
-    //  Close the current port\r
-    //\r
-    Status = EslSocketPortClose ( pPort );\r
-    if ( !EFI_ERROR ( Status )) {\r
-      DEBUG (( DEBUG_CONNECT,\r
-              "0x%08x: Port closed\r\n",\r
-              pPort ));\r
-    }\r
-    else {\r
-      DEBUG (( DEBUG_CONNECT,\r
-                "ERROR - Failed to close port 0x%08x, Status: %r\r\n",\r
-                pPort,\r
-                Status ));\r
-    }\r
-\r
-    //\r
-    //  Try to connect using the next port\r
-    //\r
-    Status = EslTcp4ConnectStart ( pSocket );\r
-    if ( EFI_NOT_READY != Status ) {\r
-      bRemoveFirstPort = TRUE;\r
-    }\r
-  }\r
-\r
-  //\r
-  //  Remove the ports if necessary\r
-  //\r
-  if ( bRemoveFirstPort || bRemovePorts ) {\r
-    //\r
-    //  Remove the first port if necessary\r
-    //\r
-    pPort = pSocket->pPortList;\r
-    if (( !bRemoveFirstPort ) && ( NULL != pPort )) {\r
-      pPort = pPort->pLinkSocket;\r
-    }\r
-\r
-    //\r
-    //  Remove the rest of the list\r
-    //\r
-    while ( NULL != pPort ) {\r
-      pNextPort = pPort->pLinkSocket;\r
-      EslSocketPortClose ( pPort );\r
-      if ( !EFI_ERROR ( Status )) {\r
-        DEBUG (( DEBUG_CONNECT,\r
-                "0x%08x: Port closed\r\n",\r
-                pPort ));\r
-      }\r
-      else {\r
-        DEBUG (( DEBUG_CONNECT,\r
-                  "ERROR - Failed to close port 0x%08x, Status: %r\r\n",\r
-                  pPort,\r
-                  Status ));\r
-      }\r
-      pPort = pNextPort;\r
-    }\r
-\r
-    //\r
-    //  Notify the poll routine\r
-    //\r
-    pSocket->bConnected = TRUE;\r
-  }\r
-\r
-  DBG_EXIT ( );\r
-}\r
-\r
-\r
-/**\r
-  Poll for completion of the connection attempt.\r
-\r
-  This routine polls the ESL_SOCKET::bConnected flag to determine\r
-  when the connection attempt is complete.\r
-\r
-  This routine is called from ::EslSocketConnect to determine when\r
-  the connection is complete.  The ESL_SOCKET::bConnected flag is\r
-  set by ::EslTcp4ConnectComplete when the TCPv4 layer establishes\r
-  a connection or runs out of local network adapters.  This routine\r
-  gets the connection status from ESL_SOCKET::ConnectStatus.\r
-\r
-  @param [in] pSocket   Address of an ::ESL_SOCKET structure.\r
-\r
-  @retval EFI_SUCCESS   The connection was successfully established.\r
-  @retval EFI_NOT_READY The connection is in progress, call this routine again.\r
-  @retval Others        The connection attempt failed.\r
-\r
- **/\r
-EFI_STATUS\r
-EslTcp4ConnectPoll (\r
-  IN ESL_SOCKET * pSocket\r
-  )\r
-{\r
-  EFI_STATUS Status;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Determine if the connection is complete\r
-  //\r
-  if ( !pSocket->bConnected ) {\r
-    //\r
-    //  Not connected\r
-    //\r
-    pSocket->errno = EAGAIN;\r
-    Status = EFI_NOT_READY;\r
-  }\r
-  else {\r
-    //\r
-    //  The connection processing is complete\r
-    //\r
-    pSocket->bConnected = FALSE;\r
-\r
-    //\r
-    //  Translate the connection status\r
-    //\r
-    Status = pSocket->ConnectStatus;\r
-    switch ( Status ) {\r
-    default:\r
-    case EFI_DEVICE_ERROR:\r
-      pSocket->errno = EIO;\r
-      break;\r
-\r
-    case EFI_ABORTED:\r
-      pSocket->errno = ECONNABORTED;\r
-      break;\r
-\r
-    case EFI_ACCESS_DENIED:\r
-      pSocket->errno = EACCES;\r
-      break;\r
-\r
-    case EFI_CONNECTION_RESET:\r
-      pSocket->errno = ECONNRESET;\r
-      break;\r
-\r
-    case EFI_INVALID_PARAMETER:\r
-      pSocket->errno = EADDRNOTAVAIL;\r
-      break;\r
-\r
-    case EFI_HOST_UNREACHABLE:\r
-    case EFI_NO_RESPONSE:\r
-      pSocket->errno = EHOSTUNREACH;\r
-      break;\r
-\r
-    case EFI_NO_MAPPING:\r
-      pSocket->errno = EAFNOSUPPORT;\r
-      break;\r
-\r
-    case EFI_NO_MEDIA:\r
-    case EFI_NETWORK_UNREACHABLE:\r
-      pSocket->errno = ENETDOWN;\r
-      break;\r
-\r
-    case EFI_OUT_OF_RESOURCES:\r
-      pSocket->errno = ENOBUFS;\r
-      break;\r
-\r
-    case EFI_PORT_UNREACHABLE:\r
-    case EFI_PROTOCOL_UNREACHABLE:\r
-    case EFI_CONNECTION_REFUSED:\r
-      pSocket->errno = ECONNREFUSED;\r
-      break;\r
-\r
-    case EFI_SUCCESS:\r
-      pSocket->errno = 0;\r
-      break;\r
-\r
-    case EFI_TIMEOUT:\r
-      pSocket->errno = ETIMEDOUT;\r
-      break;\r
-\r
-    case EFI_UNSUPPORTED:\r
-      pSocket->errno = EOPNOTSUPP;\r
-      break;\r
-    }\r
-\r
-    //\r
-    //  Display the translation\r
-    //\r
-    DEBUG (( DEBUG_CONNECT,\r
-              "ERROR - errno: %d, Status: %r\r\n",\r
-              pSocket->errno,\r
-              Status ));\r
-  }\r
-\r
-  //\r
-  //  Return the initialization status\r
-  //\r
-  DBG_EXIT_STATUS ( Status );\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Attempt to connect to a remote TCP port\r
-\r
-  This routine starts the connection processing for a SOCK_STREAM\r
-  or SOCK_SEQPAKCET socket using the TCPv4 network layer.  It\r
-  configures the local TCPv4 connection point and then attempts to\r
-  connect to a remote system.  Upon completion, the\r
-  ::EslTcp4ConnectComplete routine gets called with the connection\r
-  status.\r
-\r
-  This routine is called by ::EslSocketConnect to initiate the TCPv4\r
-  network specific connect operations.  The connection processing is\r
-  initiated by this routine and finished by ::EslTcp4ConnectComplete.\r
-  This pair of routines walks through the list of local TCPv4\r
-  connection points until a connection to the remote system is\r
-  made.\r
-\r
-  @param [in] pSocket   Address of an ::ESL_SOCKET structure.\r
-\r
-  @retval EFI_SUCCESS   The connection was successfully established.\r
-  @retval EFI_NOT_READY The connection is in progress, call this routine again.\r
-  @retval Others        The connection attempt failed.\r
-\r
- **/\r
-EFI_STATUS\r
-EslTcp4ConnectStart (\r
-  IN ESL_SOCKET * pSocket\r
-  )\r
-{\r
-  ESL_PORT * pPort;\r
-  ESL_TCP4_CONTEXT * pTcp4;\r
-  EFI_TCP4_PROTOCOL * pTcp4Protocol;\r
-  EFI_SIMPLE_NETWORK_MODE SnpModeData;\r
-  EFI_STATUS Status;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Determine if any more local adapters are available\r
-  //\r
-  pPort = pSocket->pPortList;\r
-  if ( NULL != pPort ) {\r
-    //\r
-    //  Configure the port\r
-    //\r
-    pTcp4 = &pPort->Context.Tcp4;\r
-    pTcp4->ConfigData.AccessPoint.ActiveFlag = TRUE;\r
-    pTcp4->ConfigData.TimeToLive = 255;\r
-    pTcp4Protocol = pPort->pProtocol.TCPv4;\r
-    Status = pTcp4Protocol->Configure ( pTcp4Protocol,\r
-                                        &pTcp4->ConfigData );\r
-    if ( EFI_ERROR ( Status )) {\r
-      DEBUG (( DEBUG_CONNECT,\r
-                "ERROR - Failed to configure the Tcp4 port, Status: %r\r\n",\r
-                Status ));\r
-    }\r
-    else {\r
-      DEBUG (( DEBUG_CONNECT,\r
-                "0x%08x: Port configured\r\n",\r
-                pPort ));\r
-      pPort->bConfigured = TRUE;\r
-\r
-      //\r
-      //  Verify the port connection\r
-      //\r
-      Status = pTcp4Protocol->GetModeData ( pTcp4Protocol,\r
-                                            NULL,\r
-                                            NULL,\r
-                                            NULL,\r
-                                            NULL,\r
-                                            &SnpModeData );\r
-      if ( !EFI_ERROR ( Status )) {\r
-        if ( SnpModeData.MediaPresentSupported\r
-          && ( !SnpModeData.MediaPresent )) {\r
-          //\r
-          //  Port is not connected to the network\r
-          //\r
-          Status = EFI_NO_MEDIA;\r
-        }\r
-        else {\r
-          //\r
-          //  Attempt the connection to the remote system\r
-          //\r
-          Status = pTcp4Protocol->Connect ( pTcp4Protocol,\r
-                                            &pTcp4->ConnectToken );\r
-        }\r
-      }\r
-      if ( EFI_ERROR ( Status )) {\r
-        //\r
-        //  Connection error\r
-        //\r
-        DEBUG (( DEBUG_CONNECT,\r
-                  "ERROR - Port 0x%08x not connected, Status: %r\r\n",\r
-                  pPort,\r
-                  Status ));\r
-      }\r
-    }\r
-    if ( !EFI_ERROR ( Status )) {\r
-      //\r
-      //  Connection in progress\r
-      //\r
-      pSocket->errno = EINPROGRESS;\r
-      DEBUG (( DEBUG_CONNECT,\r
-                "0x%08x: Port attempting connection to %d.%d.%d.%d:%d\r\n",\r
-                pPort,\r
-                pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[0],\r
-                pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[1],\r
-                pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[2],\r
-                pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[3],\r
-                pTcp4->ConfigData.AccessPoint.RemotePort ));\r
-    }\r
-    else {\r
-      //\r
-      //  Error return path is through EslTcp4ConnectComplete to\r
-      //  enable retry on other ports\r
-      //\r
-      //  Status to errno translation gets done in EslTcp4ConnectPoll\r
-      //\r
-      pTcp4->ConnectToken.CompletionToken.Status = Status;\r
-\r
-      //\r
-      //  Continue with the next port\r
-      //\r
-      gBS->CheckEvent ( pTcp4->ConnectToken.CompletionToken.Event );\r
-      gBS->SignalEvent ( pTcp4->ConnectToken.CompletionToken.Event );\r
-    }\r
-    Status = EFI_NOT_READY;\r
-  }\r
-  else {\r
-    //\r
-    //  No more local adapters available\r
-    //\r
-    pSocket->errno = ENETUNREACH;\r
-    Status = EFI_NO_RESPONSE;\r
-  }\r
-\r
-  //\r
-  //  Return the operation status\r
-  //\r
-  DBG_EXIT_STATUS ( Status );\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Establish the known port to listen for network connections.\r
-\r
-  This routine places the port into a state that enables connection\r
-  attempts.\r
-\r
-  This routine is called by ::EslSocketListen to handle the network\r
-  specifics of the listen operation for SOCK_STREAM and SOCK_SEQPACKET\r
-  sockets.  See the \ref ConnectionManagement section.\r
-\r
-  @param [in] pSocket   Address of an ::ESL_SOCKET structure.\r
-\r
-  @retval EFI_SUCCESS - Socket successfully created\r
-  @retval Other - Failed to enable the socket for listen\r
-\r
-**/\r
-EFI_STATUS\r
-EslTcp4Listen (\r
-  IN ESL_SOCKET * pSocket\r
-  )\r
-{\r
-  ESL_PORT * pNextPort;\r
-  ESL_PORT * pPort;\r
-  ESL_TCP4_CONTEXT * pTcp4;\r
-  EFI_TCP4_PROTOCOL * pTcp4Protocol;\r
-  EFI_STATUS Status;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Verify the socket layer synchronization\r
-  //\r
-  VERIFY_TPL ( TPL_SOCKETS );\r
-\r
-  //\r
-  //  Use for/break instead of goto\r
-  //\r
-  for ( ; ; ) {\r
-    //\r
-    //  Assume no ports are available\r
-    //\r
-    pSocket->errno = EOPNOTSUPP;\r
-    Status = EFI_NOT_READY;\r
-\r
-    //\r
-    //  Walk the list of ports\r
-    //\r
-    pPort = pSocket->pPortList;\r
-    while ( NULL != pPort ) {\r
-      //\r
-      //  Assume success\r
-      //\r
-      pSocket->errno = 0;\r
-\r
-      //\r
-      //  Use for/break insteak of goto\r
-      //\r
-      for ( ; ; ) {\r
-        //\r
-        //  Create the listen completion event\r
-        //\r
-        pTcp4 = &pPort->Context.Tcp4;\r
-        Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL,\r
-                                    TPL_SOCKETS,\r
-                                    (EFI_EVENT_NOTIFY)EslTcp4ListenComplete,\r
-                                    pPort,\r
-                                    &pTcp4->ListenToken.CompletionToken.Event );\r
-        if ( EFI_ERROR ( Status )) {\r
-          DEBUG (( DEBUG_ERROR | DEBUG_LISTEN,\r
-                    "ERROR - Failed to create the listen completion event, Status: %r\r\n",\r
-                    Status ));\r
-          pSocket->errno = ENOMEM;\r
-          break;\r
-        }\r
-        DEBUG (( DEBUG_POOL,\r
-                  "0x%08x: Created listen completion event\r\n",\r
-                  pTcp4->ListenToken.CompletionToken.Event ));\r
-\r
-        //\r
-        //  Configure the port\r
-        //\r
-        pTcp4Protocol = pPort->pProtocol.TCPv4;\r
-        Status = pTcp4Protocol->Configure ( pTcp4Protocol,\r
-                                            &pTcp4->ConfigData );\r
-        if ( EFI_ERROR ( Status )) {\r
-          DEBUG (( DEBUG_LISTEN,\r
-                    "ERROR - Failed to configure the Tcp4 port, Status: %r\r\n",\r
-                    Status ));\r
-          switch ( Status ) {\r
-          case EFI_ACCESS_DENIED:\r
-            pSocket->errno = EACCES;\r
-            break;\r
-\r
-          default:\r
-          case EFI_DEVICE_ERROR:\r
-            pSocket->errno = EIO;\r
-            break;\r
-\r
-          case EFI_INVALID_PARAMETER:\r
-            pSocket->errno = EADDRNOTAVAIL;\r
-            break;\r
-\r
-          case EFI_NO_MAPPING:\r
-            pSocket->errno = EAFNOSUPPORT;\r
-            break;\r
-\r
-          case EFI_OUT_OF_RESOURCES:\r
-            pSocket->errno = ENOBUFS;\r
-            break;\r
-\r
-          case EFI_UNSUPPORTED:\r
-            pSocket->errno = EOPNOTSUPP;\r
-            break;\r
-          }\r
-          break;\r
-        }\r
-        DEBUG (( DEBUG_LISTEN,\r
-                  "0x%08x: Port configured\r\n",\r
-                  pPort ));\r
-        pPort->bConfigured = TRUE;\r
-\r
-        //\r
-        //  Start the listen operation on the port\r
-        //\r
-        Status = pTcp4Protocol->Accept ( pTcp4Protocol,\r
-                                         &pTcp4->ListenToken );\r
-        if ( EFI_ERROR ( Status )) {\r
-          DEBUG (( DEBUG_LISTEN,\r
-                    "ERROR - Failed Tcp4 accept, Status: %r\r\n",\r
-                    Status ));\r
-          switch ( Status ) {\r
-          case EFI_ACCESS_DENIED:\r
-            pSocket->errno = EACCES;\r
-            break;\r
-\r
-          default:\r
-          case EFI_DEVICE_ERROR:\r
-            pSocket->errno = EIO;\r
-            break;\r
-\r
-          case EFI_INVALID_PARAMETER:\r
-            pSocket->errno = EADDRNOTAVAIL;\r
-            break;\r
-\r
-          case EFI_NOT_STARTED:\r
-            pSocket->errno = ENETDOWN;\r
-            break;\r
-\r
-          case EFI_OUT_OF_RESOURCES:\r
-            pSocket->errno = ENOBUFS;\r
-            break;\r
-          }\r
-          break;\r
-        }\r
-        DEBUG (( DEBUG_LISTEN,\r
-                  "0x%08x: Listen pending on Port\r\n",\r
-                  pPort ));\r
-\r
-        //\r
-        //  Listen is pending on this port\r
-        //\r
-        break;\r
-      }\r
-\r
-      //\r
-      //  Get the next port\r
-      //\r
-      pNextPort = pPort->pLinkSocket;\r
-\r
-      //\r
-      //  Close the port upon error\r
-      //\r
-      if ( EFI_ERROR ( Status )) {\r
-        EslSocketPortCloseStart ( pPort, TRUE, DEBUG_LISTEN );\r
-      }\r
-\r
-      //\r
-      //  Set the next port\r
-      //\r
-      pPort = pNextPort;\r
-    }\r
-\r
-    //\r
-    //  Determine if any ports are in the listen state\r
-    //\r
-    if ( NULL == pSocket->pPortList ) {\r
-      //\r
-      //  No ports in the listen state\r
-      //\r
-      pSocket->MaxFifoDepth = 0;\r
-\r
-      //\r
-      //  Return the last error detected\r
-      //\r
-      break;\r
-    }\r
-\r
-    //\r
-    //  Mark the socket as configured\r
-    //\r
-    pSocket->bConfigured = TRUE;\r
-    Status = EFI_SUCCESS;\r
-    pSocket->errno = 0;\r
-\r
-    //\r
-    //  All done\r
-    //\r
-    DEBUG (( DEBUG_LISTEN,\r
-              "0x%08x: pSocket - Listen pending on socket\r\n",\r
-              pSocket ));\r
-    break;\r
-  }\r
-\r
-  //\r
-  //  Return the operation status\r
-  //\r
-  DBG_EXIT_STATUS ( Status );\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Process the connection attempt\r
-\r
-  A system has initiated a connection attempt with a socket in the\r
-  listen state.  Attempt to complete the connection.\r
-\r
-  The TCPv4 layer calls this routine when a connection is made to\r
-  the socket in the listen state.  See the\r
-  \ref ConnectionManagement section.\r
-\r
-  @param [in] Event     The listen completion event\r
-\r
-  @param [in] pPort     Address of an ::ESL_PORT structure.\r
-\r
-**/\r
-VOID\r
-EslTcp4ListenComplete (\r
-  IN EFI_EVENT Event,\r
-  IN ESL_PORT * pPort\r
-  )\r
-{\r
-  EFI_HANDLE ChildHandle;\r
-  struct sockaddr_in LocalAddress;\r
-  EFI_TCP4_CONFIG_DATA * pConfigData;\r
-  ESL_PORT * pNewPort;\r
-  ESL_SOCKET * pNewSocket;\r
-  ESL_SOCKET * pSocket;\r
-  ESL_TCP4_CONTEXT * pTcp4;\r
-  EFI_TCP4_PROTOCOL * pTcp4Protocol;\r
-  EFI_STATUS Status;\r
-  EFI_HANDLE TcpPortHandle;\r
-  EFI_STATUS TempStatus;\r
-\r
-  DBG_ENTER ( );\r
-  VERIFY_AT_TPL ( TPL_SOCKETS );\r
-\r
-  //\r
-  //  Assume success\r
-  //\r
-  Status = EFI_SUCCESS;\r
-\r
-  //\r
-  //  Determine if this connection fits into the connection FIFO\r
-  //\r
-  pSocket = pPort->pSocket;\r
-  TcpPortHandle = pPort->Context.Tcp4.ListenToken.NewChildHandle;\r
-  if (( SOCKET_STATE_LISTENING == pSocket->State )\r
-    && ( pSocket->MaxFifoDepth > pSocket->FifoDepth )) {\r
-    //\r
-    //  Allocate a socket for this connection\r
-    //\r
-    ChildHandle = NULL;\r
-    Status = EslSocketAllocate ( &ChildHandle,\r
-                                 DEBUG_CONNECTION,\r
-                                 &pNewSocket );\r
-    if ( !EFI_ERROR ( Status )) {\r
-      //\r
-      //  Clone the socket parameters\r
-      //\r
-      pNewSocket->pApi = pSocket->pApi;\r
-      pNewSocket->Domain = pSocket->Domain;\r
-      pNewSocket->Protocol = pSocket->Protocol;\r
-      pNewSocket->Type = pSocket->Type;\r
-\r
-      //\r
-      //  Build the local address\r
-      //\r
-      pTcp4 = &pPort->Context.Tcp4;\r
-      LocalAddress.sin_len = (uint8_t)pNewSocket->pApi->MinimumAddressLength;\r
-      LocalAddress.sin_family = AF_INET;\r
-      LocalAddress.sin_port = 0;\r
-      LocalAddress.sin_addr.s_addr = *(UINT32 *)&pTcp4->ConfigData.AccessPoint.StationAddress.Addr[0];\r
-\r
-      //\r
-      //  Allocate a port for this connection\r
-      //  Note in this instance Configure may not be called with NULL!\r
-      //\r
-      Status = EslSocketPortAllocate ( pNewSocket,\r
-                                       pPort->pService,\r
-                                       TcpPortHandle,\r
-                                       (struct sockaddr *)&LocalAddress,\r
-                                       FALSE,\r
-                                       DEBUG_CONNECTION,\r
-                                       &pNewPort );\r
-      if ( !EFI_ERROR ( Status )) {\r
-        //\r
-        //  Restart the listen operation on the port\r
-        //\r
-        pTcp4Protocol = pPort->pProtocol.TCPv4;\r
-        Status = pTcp4Protocol->Accept ( pTcp4Protocol,\r
-                                         &pTcp4->ListenToken );\r
-\r
-        //\r
-        //  Close the TCP port using SocketClose\r
-        //\r
-        TcpPortHandle = NULL;\r
-        pTcp4 = &pNewPort->Context.Tcp4;\r
-\r
-        //\r
-        //  Check for an accept call error\r
-        //\r
-        if ( !EFI_ERROR ( Status )) {\r
-          //\r
-          //  Get the port configuration\r
-          //\r
-          pNewPort->bConfigured = TRUE;\r
-          pConfigData = &pTcp4->ConfigData;\r
-          pConfigData->ControlOption = &pTcp4->Option;\r
-          pTcp4Protocol = pNewPort->pProtocol.TCPv4;\r
-          Status = pTcp4Protocol->GetModeData ( pTcp4Protocol,\r
-                                                NULL,\r
-                                                pConfigData,\r
-                                                NULL,\r
-                                                NULL,\r
-                                                NULL );\r
-          if ( !EFI_ERROR ( Status )) {\r
-            //\r
-            //  Add the new socket to the connection FIFO\r
-            //\r
-            if ( NULL == pSocket->pFifoTail ) {\r
-              //\r
-              //  First connection\r
-              //\r
-              pSocket->pFifoHead = pNewSocket;\r
-            }\r
-            else {\r
-              //\r
-              //  Add to end of list.\r
-              //\r
-              pSocket->pFifoTail->pNextConnection = pNewSocket;\r
-            }\r
-            pSocket->pFifoTail = pNewSocket;\r
-            pSocket->FifoDepth += 1;\r
-\r
-            //\r
-            //  Update the socket state\r
-            //\r
-            pNewSocket->State = SOCKET_STATE_IN_FIFO;\r
-\r
-            //\r
-            //  Log the connection\r
-            //\r
-            DEBUG (( DEBUG_CONNECTION | DEBUG_INFO,\r
-                      "0x%08x: Socket on port %d.%d.%d.%d:%d connected to %d.%d.%d.%d:%d\r\n",\r
-                      pNewSocket,\r
-                      pConfigData->AccessPoint.StationAddress.Addr[0],\r
-                      pConfigData->AccessPoint.StationAddress.Addr[1],\r
-                      pConfigData->AccessPoint.StationAddress.Addr[2],\r
-                      pConfigData->AccessPoint.StationAddress.Addr[3],\r
-                      pConfigData->AccessPoint.StationPort,\r
-                      pConfigData->AccessPoint.RemoteAddress.Addr[0],\r
-                      pConfigData->AccessPoint.RemoteAddress.Addr[1],\r
-                      pConfigData->AccessPoint.RemoteAddress.Addr[2],\r
-                      pConfigData->AccessPoint.RemoteAddress.Addr[3],\r
-                      pConfigData->AccessPoint.RemotePort ));\r
-            DEBUG (( DEBUG_CONNECTION | DEBUG_INFO,\r
-                      "0x%08x: Listen socket adding socket 0x%08x to FIFO, depth: %d\r\n",\r
-                      pSocket,\r
-                      pNewSocket,\r
-                      pSocket->FifoDepth ));\r
-\r
-            //\r
-            //  Start the receive operation\r
-            //\r
-            EslSocketRxStart ( pNewPort );\r
-          }\r
-          else {\r
-            DEBUG (( DEBUG_ERROR | DEBUG_CONNECTION | DEBUG_INFO,\r
-                      "ERROR - GetModeData failed on port 0x%08x, Status: %r\r\n",\r
-                      pNewPort,\r
-                      Status ));\r
-          }\r
-        }\r
-        else {\r
-          //\r
-          //  The listen failed on this port\r
-          //\r
-          DEBUG (( DEBUG_LISTEN | DEBUG_INFO,\r
-                    "ERROR - Listen failed on port 0x%08x, Status: %r\r\n",\r
-                    pPort,\r
-                    Status ));\r
-\r
-          //\r
-          //  Close the listening port\r
-          //\r
-          EslSocketPortCloseStart ( pPort, TRUE, DEBUG_LISTEN );\r
-        }\r
-      }\r
-\r
-      //\r
-      //  Done with the socket if necessary\r
-      //\r
-      if ( EFI_ERROR ( Status )) {\r
-        TempStatus = EslSocketCloseStart ( &pNewSocket->SocketProtocol,\r
-                                           TRUE,\r
-                                           &pSocket->errno );\r
-        ASSERT ( EFI_SUCCESS == TempStatus );\r
-      }\r
-    }\r
-  }\r
-  else {\r
-    DEBUG (( DEBUG_CONNECTION,\r
-              "0x%08x: Socket FIFO full, connection refused\r\n",\r
-              pSocket ));\r
-\r
-    //\r
-    //  The FIFO is full or the socket is in the wrong state\r
-    //\r
-    Status = EFI_BUFFER_TOO_SMALL;\r
-  }\r
-\r
-  //\r
-  //  Close the connection if necessary\r
-  //\r
-  if (( EFI_ERROR ( Status ))\r
-    && ( NULL == TcpPortHandle )) {\r
-    //\r
-    // TODO: Finish this code path\r
-    //  The new connection does not fit into the connection FIFO\r
-    //\r
-    //  Process:\r
-    //    Call close\r
-    //    Release the resources\r
-\r
-  }\r
-\r
-  DBG_EXIT ( );\r
-}\r
-\r
-\r
-/**\r
-  Get the local socket address.\r
-\r
-  This routine returns the IPv4 address and TCP port number associated\r
-  with the local socket.\r
-\r
-  This routine is called by ::EslSocketGetLocalAddress to determine the\r
-  network address for the SOCK_STREAM or SOCK_SEQPACKET socket.\r
-\r
-  @param [in] pPort       Address of an ::ESL_PORT structure.\r
-\r
-  @param [out] pSockAddr  Network address to receive the local system address\r
-\r
-**/\r
-VOID\r
-EslTcp4LocalAddressGet (\r
-  IN ESL_PORT * pPort,\r
-  OUT struct sockaddr * pSockAddr\r
-  )\r
-{\r
-  struct sockaddr_in * pLocalAddress;\r
-  ESL_TCP4_CONTEXT * pTcp4;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Return the local address\r
-  //\r
-  pTcp4 = &pPort->Context.Tcp4;\r
-  pLocalAddress = (struct sockaddr_in *)pSockAddr;\r
-  pLocalAddress->sin_family = AF_INET;\r
-  pLocalAddress->sin_port = SwapBytes16 ( pTcp4->ConfigData.AccessPoint.StationPort );\r
-  CopyMem ( &pLocalAddress->sin_addr,\r
-            &pTcp4->ConfigData.AccessPoint.StationAddress.Addr[0],\r
-            sizeof ( pLocalAddress->sin_addr ));\r
-\r
-  DBG_EXIT ( );\r
-}\r
-\r
-\r
-/**\r
-  Set the local port address.\r
-\r
-  This routine sets the local port address.\r
-\r
-  This support routine is called by ::EslSocketPortAllocate.\r
-\r
-  @param [in] pPort       Address of an ESL_PORT structure\r
-  @param [in] pSockAddr   Address of a sockaddr structure that contains the\r
-                          connection point on the local machine.  An IPv4 address\r
-                          of INADDR_ANY specifies that the connection is made to\r
-                          all of the network stacks on the platform.  Specifying a\r
-                          specific IPv4 address restricts the connection to the\r
-                          network stack supporting that address.  Specifying zero\r
-                          for the port causes the network layer to assign a port\r
-                          number from the dynamic range.  Specifying a specific\r
-                          port number causes the network layer to use that port.\r
-\r
-  @param [in] bBindTest   TRUE = run bind testing\r
-\r
-  @retval EFI_SUCCESS     The operation was successful\r
-\r
- **/\r
-EFI_STATUS\r
-EslTcp4LocalAddressSet (\r
-  IN ESL_PORT * pPort,\r
-  IN CONST struct sockaddr * pSockAddr,\r
-  IN BOOLEAN bBindTest\r
-  )\r
-{\r
-  EFI_TCP4_ACCESS_POINT * pAccessPoint;\r
-  CONST struct sockaddr_in * pIpAddress;\r
-  CONST UINT8 * pIpv4Address;\r
-  EFI_STATUS Status;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Validate the address\r
-  //\r
-  pIpAddress = (struct sockaddr_in *)pSockAddr;\r
-  if ( INADDR_BROADCAST == pIpAddress->sin_addr.s_addr ) {\r
-    //\r
-    //  The local address must not be the broadcast address\r
-    //\r
-    Status = EFI_INVALID_PARAMETER;\r
-    pPort->pSocket->errno = EADDRNOTAVAIL;\r
-  }\r
-  else {\r
-    //\r
-    //  Set the local address\r
-    //\r
-    pIpv4Address = (UINT8 *)&pIpAddress->sin_addr.s_addr;\r
-    pAccessPoint = &pPort->Context.Tcp4.ConfigData.AccessPoint;\r
-    pAccessPoint->StationAddress.Addr[0] = pIpv4Address[0];\r
-    pAccessPoint->StationAddress.Addr[1] = pIpv4Address[1];\r
-    pAccessPoint->StationAddress.Addr[2] = pIpv4Address[2];\r
-    pAccessPoint->StationAddress.Addr[3] = pIpv4Address[3];\r
-\r
-    //\r
-    //  Determine if the default address is used\r
-    //\r
-    pAccessPoint->UseDefaultAddress = (BOOLEAN)( 0 == pIpAddress->sin_addr.s_addr );\r
-\r
-    //\r
-    //  Set the subnet mask\r
-    //\r
-    if ( pAccessPoint->UseDefaultAddress ) {\r
-      pAccessPoint->SubnetMask.Addr[0] = 0;\r
-      pAccessPoint->SubnetMask.Addr[1] = 0;\r
-      pAccessPoint->SubnetMask.Addr[2] = 0;\r
-      pAccessPoint->SubnetMask.Addr[3] = 0;\r
-    }\r
-    else {\r
-      pAccessPoint->SubnetMask.Addr[0] = 0xff;\r
-      pAccessPoint->SubnetMask.Addr[1] = ( 128 <= pAccessPoint->StationAddress.Addr[0]) ? 0xff : 0;\r
-      pAccessPoint->SubnetMask.Addr[2] = ( 192 <= pAccessPoint->StationAddress.Addr[0]) ? 0xff : 0;\r
-      pAccessPoint->SubnetMask.Addr[3] = ( 224 <= pAccessPoint->StationAddress.Addr[0]) ? 0xff : 0;\r
-    }\r
-\r
-    //\r
-    //  Validate the IP address\r
-    //\r
-    pAccessPoint->StationPort = 0;\r
-    Status = bBindTest ? EslSocketBindTest ( pPort, EADDRNOTAVAIL )\r
-                       : EFI_SUCCESS;\r
-    if ( !EFI_ERROR ( Status )) {\r
-      //\r
-      //  Set the port number\r
-      //\r
-      pAccessPoint->StationPort = SwapBytes16 ( pIpAddress->sin_port );\r
-      pPort->pSocket->bAddressSet = TRUE;\r
-\r
-      //\r
-      //  Display the local address\r
-      //\r
-      DEBUG (( DEBUG_BIND,\r
-                "0x%08x: Port, Local TCP4 Address: %d.%d.%d.%d:%d\r\n",\r
-                pPort,\r
-                pAccessPoint->StationAddress.Addr[0],\r
-                pAccessPoint->StationAddress.Addr[1],\r
-                pAccessPoint->StationAddress.Addr[2],\r
-                pAccessPoint->StationAddress.Addr[3],\r
-                pAccessPoint->StationPort ));\r
-    }\r
-  }\r
-\r
-  //\r
-  //  Return the operation status\r
-  //\r
-  DBG_EXIT_STATUS ( Status );\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Free a receive packet\r
-\r
-  This routine performs the network specific operations necessary\r
-  to free a receive packet.\r
-\r
-  This routine is called by ::EslSocketPortCloseTxDone to free a\r
-  receive packet.\r
-\r
-  @param [in] pPacket         Address of an ::ESL_PACKET structure.\r
-  @param [in, out] pRxBytes   Address of the count of RX bytes\r
-\r
-**/\r
-VOID\r
-EslTcp4PacketFree (\r
-  IN ESL_PACKET * pPacket,\r
-  IN OUT size_t * pRxBytes\r
-  )\r
-{\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Account for the receive bytes\r
-  //\r
-  *pRxBytes -= pPacket->Op.Tcp4Rx.RxData.DataLength;\r
-  DBG_EXIT ( );\r
-}\r
-\r
-\r
-/**\r
-  Initialize the network specific portions of an ::ESL_PORT structure.\r
-\r
-  This routine initializes the network specific portions of an\r
-  ::ESL_PORT structure for use by the socket.\r
-\r
-  This support routine is called by ::EslSocketPortAllocate\r
-  to connect the socket with the underlying network adapter\r
-  running the TCPv4 protocol.\r
-\r
-  @param [in] pPort       Address of an ESL_PORT structure\r
-  @param [in] DebugFlags  Flags for debug messages\r
-\r
-  @retval EFI_SUCCESS - Socket successfully created\r
-\r
- **/\r
-EFI_STATUS\r
-EslTcp4PortAllocate (\r
-  IN ESL_PORT * pPort,\r
-  IN UINTN DebugFlags\r
-  )\r
-{\r
-  EFI_TCP4_ACCESS_POINT * pAccessPoint;\r
-  ESL_SOCKET * pSocket;\r
-  ESL_TCP4_CONTEXT * pTcp4;\r
-  EFI_STATUS Status;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Use for/break instead of goto\r
-  for ( ; ; ) {\r
-    //\r
-    //  Allocate the close event\r
-    //\r
-    pSocket = pPort->pSocket;\r
-    pTcp4 = &pPort->Context.Tcp4;\r
-    Status = gBS->CreateEvent (  EVT_NOTIFY_SIGNAL,\r
-                                 TPL_SOCKETS,\r
-                                 (EFI_EVENT_NOTIFY)EslSocketPortCloseComplete,\r
-                                 pPort,\r
-                                 &pTcp4->CloseToken.CompletionToken.Event);\r
-    if ( EFI_ERROR ( Status )) {\r
-      DEBUG (( DEBUG_ERROR | DebugFlags,\r
-                "ERROR - Failed to create the close event, Status: %r\r\n",\r
-                Status ));\r
-      pSocket->errno = ENOMEM;\r
-      break;\r
-    }\r
-    DEBUG (( DEBUG_CLOSE | DEBUG_POOL,\r
-              "0x%08x: Created close event\r\n",\r
-              pTcp4->CloseToken.CompletionToken.Event ));\r
-\r
-    //\r
-    //  Allocate the connection event\r
-    //\r
-    Status = gBS->CreateEvent (  EVT_NOTIFY_SIGNAL,\r
-                                 TPL_SOCKETS,\r
-                                 (EFI_EVENT_NOTIFY)EslTcp4ConnectComplete,\r
-                                 pPort,\r
-                                 &pTcp4->ConnectToken.CompletionToken.Event);\r
-    if ( EFI_ERROR ( Status )) {\r
-      DEBUG (( DEBUG_ERROR | DebugFlags,\r
-                "ERROR - Failed to create the connect event, Status: %r\r\n",\r
-                Status ));\r
-      pSocket->errno = ENOMEM;\r
-      break;\r
-    }\r
-    DEBUG (( DEBUG_CLOSE | DEBUG_POOL,\r
-              "0x%08x: Created connect event\r\n",\r
-              pTcp4->ConnectToken.CompletionToken.Event ));\r
-\r
-    //\r
-    //  Initialize the port\r
-    //\r
-    pSocket->TxPacketOffset = OFFSET_OF ( ESL_PACKET, Op.Tcp4Tx.TxData );\r
-    pSocket->TxTokenEventOffset = OFFSET_OF ( ESL_IO_MGMT, Token.Tcp4Tx.CompletionToken.Event );\r
-    pSocket->TxTokenOffset = OFFSET_OF ( EFI_TCP4_IO_TOKEN, Packet.TxData );\r
-\r
-    //\r
-    //  Save the cancel, receive and transmit addresses\r
-    //  pPort->pfnRxCancel = NULL; since the UEFI implementation returns EFI_UNSUPPORTED\r
-    //\r
-    pPort->pfnConfigure = (PFN_NET_CONFIGURE)pPort->pProtocol.TCPv4->Configure;\r
-    pPort->pfnRxPoll = (PFN_NET_POLL)pPort->pProtocol.TCPv4->Poll;\r
-    pPort->pfnRxStart = (PFN_NET_IO_START)pPort->pProtocol.TCPv4->Receive;\r
-    pPort->pfnTxStart = (PFN_NET_IO_START)pPort->pProtocol.TCPv4->Transmit;\r
-\r
-    //\r
-    //  Set the configuration flags\r
-    //\r
-    pAccessPoint = &pPort->Context.Tcp4.ConfigData.AccessPoint;\r
-    pAccessPoint->ActiveFlag = FALSE;\r
-    pTcp4->ConfigData.TimeToLive = 255;\r
-    break;\r
-  }\r
-\r
-  //\r
-  //  Return the operation status\r
-  //\r
-  DBG_EXIT_STATUS ( Status );\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Close a TCP4 port.\r
-\r
-  This routine releases the network specific resources allocated by\r
-  ::EslTcp4PortAllocate.\r
-\r
-  This routine is called by ::EslSocketPortClose.\r
-  See the \ref PortCloseStateMachine section.\r
-\r
-  @param [in] pPort       Address of an ::ESL_PORT structure.\r
-\r
-  @retval EFI_SUCCESS     The port is closed\r
-  @retval other           Port close error\r
-\r
-**/\r
-EFI_STATUS\r
-EslTcp4PortClose (\r
-  IN ESL_PORT * pPort\r
-  )\r
-{\r
-  UINTN DebugFlags;\r
-  ESL_TCP4_CONTEXT * pTcp4;\r
-  EFI_STATUS Status;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Locate the port in the socket list\r
-  //\r
-  Status = EFI_SUCCESS;\r
-  DebugFlags = pPort->DebugFlags;\r
-  pTcp4 = &pPort->Context.Tcp4;\r
-\r
-  //\r
-  //  Done with the connect event\r
-  //\r
-  if ( NULL != pTcp4->ConnectToken.CompletionToken.Event ) {\r
-    Status = gBS->CloseEvent ( pTcp4->ConnectToken.CompletionToken.Event );\r
-    if ( !EFI_ERROR ( Status )) {\r
-      DEBUG (( DebugFlags | DEBUG_POOL,\r
-                "0x%08x: Closed connect event\r\n",\r
-                pTcp4->ConnectToken.CompletionToken.Event ));\r
-    }\r
-    else {\r
-      DEBUG (( DEBUG_ERROR | DebugFlags,\r
-                "ERROR - Failed to close the connect event, Status: %r\r\n",\r
-                Status ));\r
-      ASSERT ( EFI_SUCCESS == Status );\r
-    }\r
-  }\r
-\r
-  //\r
-  //  Done with the close event\r
-  //\r
-  if ( NULL != pTcp4->CloseToken.CompletionToken.Event ) {\r
-    Status = gBS->CloseEvent ( pTcp4->CloseToken.CompletionToken.Event );\r
-    if ( !EFI_ERROR ( Status )) {\r
-      DEBUG (( DebugFlags | DEBUG_POOL,\r
-                "0x%08x: Closed close event\r\n",\r
-                pTcp4->CloseToken.CompletionToken.Event ));\r
-    }\r
-    else {\r
-      DEBUG (( DEBUG_ERROR | DebugFlags,\r
-                "ERROR - Failed to close the close event, Status: %r\r\n",\r
-                Status ));\r
-      ASSERT ( EFI_SUCCESS == Status );\r
-    }\r
-  }\r
-\r
-  //\r
-  //  Done with the listen completion event\r
-  //\r
-  if ( NULL != pTcp4->ListenToken.CompletionToken.Event ) {\r
-    Status = gBS->CloseEvent ( pTcp4->ListenToken.CompletionToken.Event );\r
-    if ( !EFI_ERROR ( Status )) {\r
-      DEBUG (( DebugFlags | DEBUG_POOL,\r
-                "0x%08x: Closed listen completion event\r\n",\r
-                pTcp4->ListenToken.CompletionToken.Event ));\r
-    }\r
-    else {\r
-      DEBUG (( DEBUG_ERROR | DebugFlags,\r
-                "ERROR - Failed to close the listen completion event, Status: %r\r\n",\r
-                Status ));\r
-      ASSERT ( EFI_SUCCESS == Status );\r
-    }\r
-  }\r
-\r
-  //\r
-  //  Return the operation status\r
-  //\r
-  DBG_EXIT_STATUS ( Status );\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Perform the network specific close operation on the port.\r
-\r
-  This routine performs a cancel operations on the TCPv4 port to\r
-  shutdown the receive operations on the port.\r
-\r
-  This routine is called by the ::EslSocketPortCloseTxDone\r
-  routine after the port completes all of the transmission.\r
-\r
-  @param [in] pPort           Address of an ::ESL_PORT structure.\r
-\r
-  @retval EFI_SUCCESS         The port is closed, not normally returned\r
-  @retval EFI_NOT_READY       The port is still closing\r
-  @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,\r
-                              most likely the routine was called already.\r
-\r
-**/\r
-EFI_STATUS\r
-EslTcp4PortCloseOp (\r
-  IN ESL_PORT * pPort\r
-  )\r
-{\r
-  ESL_TCP4_CONTEXT * pTcp4;\r
-  EFI_TCP4_PROTOCOL * pTcp4Protocol;\r
-  EFI_STATUS Status;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Close the configured port\r
-  //\r
-  Status = EFI_SUCCESS;\r
-  pTcp4 = &pPort->Context.Tcp4;\r
-  pTcp4Protocol = pPort->pProtocol.TCPv4;\r
-  pTcp4->CloseToken.AbortOnClose = pPort->bCloseNow;\r
-  Status = pTcp4Protocol->Close ( pTcp4Protocol,\r
-                                  &pTcp4->CloseToken );\r
-  if ( !EFI_ERROR ( Status )) {\r
-    DEBUG (( pPort->DebugFlags | DEBUG_CLOSE | DEBUG_INFO,\r
-              "0x%08x: Port close started\r\n",\r
-              pPort ));\r
-  }\r
-  else {\r
-    DEBUG (( DEBUG_ERROR | pPort->DebugFlags | DEBUG_CLOSE | DEBUG_INFO,\r
-             "ERROR - Close failed on port 0x%08x, Status: %r\r\n",\r
-             pPort,\r
-             Status ));\r
-  }\r
-\r
-  //\r
-  //  Return the operation status\r
-  //\r
-  DBG_EXIT_STATUS ( Status );\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Receive data from a network connection.\r
-\r
-  This routine attempts to return buffered data to the caller.  The\r
-  data is removed from the urgent queue if the message flag MSG_OOB\r
-  is specified, otherwise data is removed from the normal queue.\r
-  See the \ref ReceiveEngine section.\r
-\r
-  This routine is called by ::EslSocketReceive to handle the network\r
-  specific receive operation to support SOCK_STREAM and SOCK_SEQPACKET\r
-  sockets.\r
-\r
-  @param [in] pPort           Address of an ::ESL_PORT structure.\r
-\r
-  @param [in] pPacket         Address of an ::ESL_PACKET structure.\r
-\r
-  @param [in] pbConsumePacket Address of a BOOLEAN indicating if the packet is to be consumed\r
-\r
-  @param [in] BufferLength    Length of the the buffer\r
-\r
-  @param [in] pBuffer         Address of a buffer to receive the data.\r
-\r
-  @param [in] pDataLength     Number of received data bytes in the buffer.\r
-\r
-  @param [out] pAddress       Network address to receive the remote system address\r
-\r
-  @param [out] pSkipBytes     Address to receive the number of bytes skipped\r
-\r
-  @return   Returns the address of the next free byte in the buffer.\r
-\r
- **/\r
-UINT8 *\r
-EslTcp4Receive (\r
-  IN ESL_PORT * pPort,\r
-  IN ESL_PACKET * pPacket,\r
-  IN BOOLEAN * pbConsumePacket,\r
-  IN size_t BufferLength,\r
-  IN UINT8 * pBuffer,\r
-  OUT size_t * pDataLength,\r
-  OUT struct sockaddr * pAddress,\r
-  OUT size_t * pSkipBytes\r
-  )\r
-{\r
-  size_t DataLength;\r
-  struct sockaddr_in * pRemoteAddress;\r
-  ESL_TCP4_CONTEXT * pTcp4;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Return the remote system address if requested\r
-  //\r
-  if ( NULL != pAddress ) {\r
-    //\r
-    //  Build the remote address\r
-    //\r
-    pTcp4 = &pPort->Context.Tcp4;\r
-    DEBUG (( DEBUG_RX,\r
-              "Getting packet remote address: %d.%d.%d.%d:%d\r\n",\r
-              pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[0],\r
-              pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[1],\r
-              pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[2],\r
-              pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[3],\r
-              pTcp4->ConfigData.AccessPoint.RemotePort ));\r
-    pRemoteAddress = (struct sockaddr_in *)pAddress;\r
-    CopyMem ( &pRemoteAddress->sin_addr,\r
-              &pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[0],\r
-              sizeof ( pRemoteAddress->sin_addr ));\r
-    pRemoteAddress->sin_port = SwapBytes16 ( pTcp4->ConfigData.AccessPoint.RemotePort );\r
-  }\r
-\r
-  //\r
-  //  Determine the amount of received data\r
-  //\r
-  DataLength = pPacket->ValidBytes;\r
-  if ( BufferLength < DataLength ) {\r
-    DataLength = BufferLength;\r
-  }\r
-\r
-  //\r
-  //  Move the data into the buffer\r
-  //\r
-  DEBUG (( DEBUG_RX,\r
-            "0x%08x: Port copy packet 0x%08x data into 0x%08x, 0x%08x bytes\r\n",\r
-            pPort,\r
-            pPacket,\r
-            pBuffer,\r
-            DataLength ));\r
-  CopyMem ( pBuffer, pPacket->pBuffer, DataLength );\r
-\r
-  //\r
-  //  Set the next buffer address\r
-  //\r
-  pBuffer += DataLength;\r
-\r
-  //\r
-  //  Determine if the data is being read\r
-  //\r
-  if ( *pbConsumePacket ) {\r
-    //\r
-    //  Account for the bytes consumed\r
-    //\r
-    pPacket->pBuffer += DataLength;\r
-    pPacket->ValidBytes -= DataLength;\r
-    DEBUG (( DEBUG_RX,\r
-              "0x%08x: Port account for 0x%08x bytes\r\n",\r
-              pPort,\r
-              DataLength ));\r
-\r
-    //\r
-    //  Determine if the entire packet was consumed\r
-    //\r
-    if (( 0 == pPacket->ValidBytes )\r
-      || ( SOCK_STREAM != pPort->pSocket->Type )) {\r
-      //\r
-      //  All done with this packet\r
-      //  Account for any discarded data\r
-      //\r
-      *pSkipBytes = pPacket->ValidBytes;\r
-    }\r
-    else\r
-    {\r
-      //\r
-      //  More data to consume later\r
-      //\r
-      *pbConsumePacket = FALSE;\r
-    }\r
-  }\r
-\r
-  //\r
-  //  Return the data length and the buffer address\r
-  //\r
-  *pDataLength = DataLength;\r
-  DBG_EXIT_HEX ( pBuffer );\r
-  return pBuffer;\r
-}\r
-\r
-\r
-/**\r
-  Get the remote socket address.\r
-\r
-  This routine returns the address of the remote connection point\r
-  associated with the SOCK_STREAM or SOCK_SEQPACKET socket.\r
-\r
-  This routine is called by ::EslSocketGetPeerAddress to detemine\r
-  the TCPv4 address and por number associated with the network adapter.\r
-\r
-  @param [in] pPort       Address of an ::ESL_PORT structure.\r
-\r
-  @param [out] pAddress   Network address to receive the remote system address\r
-\r
-**/\r
-VOID\r
-EslTcp4RemoteAddressGet (\r
-  IN ESL_PORT * pPort,\r
-  OUT struct sockaddr * pAddress\r
-  )\r
-{\r
-  struct sockaddr_in * pRemoteAddress;\r
-  ESL_TCP4_CONTEXT * pTcp4;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Return the remote address\r
-  //\r
-  pTcp4 = &pPort->Context.Tcp4;\r
-  pRemoteAddress = (struct sockaddr_in *)pAddress;\r
-  pRemoteAddress->sin_family = AF_INET;\r
-  pRemoteAddress->sin_port = SwapBytes16 ( pTcp4->ConfigData.AccessPoint.RemotePort );\r
-  CopyMem ( &pRemoteAddress->sin_addr,\r
-            &pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[0],\r
-            sizeof ( pRemoteAddress->sin_addr ));\r
-\r
-  DBG_EXIT ( );\r
-}\r
-\r
-\r
-/**\r
-  Set the remote address\r
-\r
-  This routine sets the remote address in the port.\r
-\r
-  This routine is called by ::EslSocketConnect to specify the\r
-  remote network address.\r
-\r
-  @param [in] pPort           Address of an ::ESL_PORT structure.\r
-\r
-  @param [in] pSockAddr       Network address of the remote system.\r
-\r
-  @param [in] SockAddrLength  Length in bytes of the network address.\r
-\r
-  @retval EFI_SUCCESS     The operation was successful\r
-\r
- **/\r
-EFI_STATUS\r
-EslTcp4RemoteAddressSet (\r
-  IN ESL_PORT * pPort,\r
-  IN CONST struct sockaddr * pSockAddr,\r
-  IN socklen_t SockAddrLength\r
-  )\r
-{\r
-  CONST struct sockaddr_in * pRemoteAddress;\r
-  ESL_TCP4_CONTEXT * pTcp4;\r
-  EFI_STATUS Status;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Set the remote address\r
-  //\r
-  pTcp4 = &pPort->Context.Tcp4;\r
-  pRemoteAddress = (struct sockaddr_in *)pSockAddr;\r
-  pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[0] = (UINT8)( pRemoteAddress->sin_addr.s_addr );\r
-  pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[1] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 8 );\r
-  pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[2] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 16 );\r
-  pTcp4->ConfigData.AccessPoint.RemoteAddress.Addr[3] = (UINT8)( pRemoteAddress->sin_addr.s_addr >> 24 );\r
-  pTcp4->ConfigData.AccessPoint.RemotePort = SwapBytes16 ( pRemoteAddress->sin_port );\r
-  Status = EFI_SUCCESS;\r
-  if ( INADDR_BROADCAST == pRemoteAddress->sin_addr.s_addr ) {\r
-    DEBUG (( DEBUG_CONNECT,\r
-              "ERROR - Invalid remote address\r\n" ));\r
-    Status = EFI_INVALID_PARAMETER;\r
-    pPort->pSocket->errno = EAFNOSUPPORT;\r
-  }\r
-\r
-  //\r
-  //  Return the operation status\r
-  //\r
-  DBG_EXIT_STATUS ( Status );\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Process the receive completion\r
-\r
-  This routine queues the data in FIFO order in either the urgent\r
-  or normal data queues depending upon the type of data received.\r
-  See the \ref ReceiveEngine section.\r
-\r
-  This routine is called by the TCPv4 driver when some data is\r
-  received.\r
-\r
-  Buffer the data that was just received.\r
-\r
-  @param [in] Event     The receive completion event\r
-\r
-  @param [in] pIo       Address of an ::ESL_IO_MGMT structure\r
-\r
-**/\r
-VOID\r
-EslTcp4RxComplete (\r
-  IN EFI_EVENT Event,\r
-  IN ESL_IO_MGMT * pIo\r
-  )\r
-{\r
-  BOOLEAN bUrgent;\r
-  size_t LengthInBytes;\r
-  ESL_PACKET * pPacket;\r
-  EFI_STATUS Status;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Get the operation status.\r
-  //\r
-  Status = pIo->Token.Tcp4Rx.CompletionToken.Status;\r
-\r
-  //\r
-  //      +--------------------+   +---------------------------+\r
-  //      | ESL_IO_MGMT        |   | ESL_PACKET                |\r
-  //      |                    |   |                           |\r
-  //      |    +---------------+   +-----------------------+   |\r
-  //      |    | Token         |   | EFI_TCP4_RECEIVE_DATA |   |\r
-  //      |    |        RxData --> |                       |   |\r
-  //      |    |               |   +-----------------------+---+\r
-  //      |    |        Event  |   |       Data Buffer         |\r
-  //      +----+---------------+   |                           |\r
-  //                               |                           |\r
-  //                               +---------------------------+\r
-  //\r
-  //\r
-  //  Duplicate the buffer address and length for use by the\r
-  //  buffer handling code in EslTcp4Receive.  These fields are\r
-  //  used when a partial read is done of the data from the\r
-  //  packet.\r
-  //\r
-  pPacket = pIo->pPacket;\r
-  pPacket->pBuffer = pPacket->Op.Tcp4Rx.RxData.FragmentTable[0].FragmentBuffer;\r
-  LengthInBytes = pPacket->Op.Tcp4Rx.RxData.DataLength;\r
-  pPacket->ValidBytes = LengthInBytes;\r
-\r
-  //\r
-  //  Get the data type so that it may be linked to the\r
-  //  correct receive buffer list on the ESL_SOCKET structure\r
-  //\r
-  bUrgent = pPacket->Op.Tcp4Rx.RxData.UrgentFlag;\r
-\r
-  //\r
-  //  Complete this request\r
-  //\r
-  EslSocketRxComplete ( pIo, Status, LengthInBytes, bUrgent );\r
-  DBG_EXIT ( );\r
-}\r
-\r
-\r
-/**\r
-  Start a receive operation\r
-\r
-  This routine posts a receive buffer to the TCPv4 driver.\r
-  See the \ref ReceiveEngine section.\r
-\r
-  This support routine is called by EslSocketRxStart.\r
-\r
-  @param [in] pPort       Address of an ::ESL_PORT structure.\r
-  @param [in] pIo         Address of an ::ESL_IO_MGMT structure.\r
-\r
- **/\r
-VOID\r
-EslTcp4RxStart (\r
-  IN ESL_PORT * pPort,\r
-  IN ESL_IO_MGMT * pIo\r
-  )\r
-{\r
-  ESL_PACKET * pPacket;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Initialize the buffer for receive\r
-  //\r
-  pPacket = pIo->pPacket;\r
-  pIo->Token.Tcp4Rx.Packet.RxData = &pPacket->Op.Tcp4Rx.RxData;\r
-  pPacket->Op.Tcp4Rx.RxData.DataLength = sizeof ( pPacket->Op.Tcp4Rx.Buffer );\r
-  pPacket->Op.Tcp4Rx.RxData.FragmentCount = 1;\r
-  pPacket->Op.Tcp4Rx.RxData.FragmentTable[0].FragmentLength = pPacket->Op.Tcp4Rx.RxData.DataLength;\r
-  pPacket->Op.Tcp4Rx.RxData.FragmentTable[0].FragmentBuffer = &pPacket->Op.Tcp4Rx.Buffer[0];\r
-\r
-  DBG_EXIT ( );\r
-}\r
-\r
-\r
-/**\r
-  Determine if the socket is configured.\r
-\r
-  This routine uses the flag ESL_SOCKET::bConfigured to determine\r
-  if the network layer's configuration routine has been called.\r
-\r
-  This routine is called by EslSocketIsConfigured to verify\r
-  that the socket has been configured.\r
-\r
-  @param [in] pSocket   Address of an ::ESL_SOCKET structure.\r
-\r
-  @retval EFI_SUCCESS - The port is connected\r
-  @retval EFI_NOT_STARTED - The port is not connected\r
-\r
- **/\r
- EFI_STATUS\r
- EslTcp4SocketIsConfigured (\r
-  IN ESL_SOCKET * pSocket\r
-  )\r
-{\r
-  EFI_STATUS Status;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Determine the socket configuration status\r
-  //\r
-  Status = pSocket->bConfigured ? EFI_SUCCESS : EFI_NOT_STARTED;\r
-\r
-  //\r
-  //  Return the port connected state.\r
-  //\r
-  DBG_EXIT_STATUS ( Status );\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Buffer data for transmission over a network connection.\r
-\r
-  This routine buffers data for the transmit engine in one of two\r
-  queues, one for urgent (out-of-band) data and the other for normal\r
-  data.  The urgent data is provided to TCP as soon as it is available,\r
-  allowing the TCP layer to schedule transmission of the urgent data\r
-  between packets of normal data.\r
-\r
-  This routine is called by ::EslSocketTransmit to buffer\r
-  data for transmission.  When the \ref TransmitEngine has resources,\r
-  this routine will start the transmission of the next buffer on\r
-  the network connection.\r
-\r
-  Transmission errors are returned during the next transmission or\r
-  during the close operation.  Only buffering errors are returned\r
-  during the current transmission attempt.\r
-\r
-  @param [in] pSocket         Address of an ::ESL_SOCKET structure\r
-\r
-  @param [in] Flags           Message control flags\r
-\r
-  @param [in] BufferLength    Length of the the buffer\r
-\r
-  @param [in] pBuffer         Address of a buffer to receive the data.\r
-\r
-  @param [in] pDataLength     Number of received data bytes in the buffer.\r
-\r
-  @param [in] pAddress        Network address of the remote system address\r
-\r
-  @param [in] AddressLength   Length of the remote network address structure\r
-\r
-  @retval EFI_SUCCESS - Socket data successfully buffered\r
-\r
- **/\r
-EFI_STATUS\r
-EslTcp4TxBuffer (\r
-  IN ESL_SOCKET * pSocket,\r
-  IN int Flags,\r
-  IN size_t BufferLength,\r
-  IN CONST UINT8 * pBuffer,\r
-  OUT size_t * pDataLength,\r
-  IN const struct sockaddr * pAddress,\r
-  IN socklen_t AddressLength\r
-  )\r
-{\r
-  BOOLEAN bUrgent;\r
-  BOOLEAN bUrgentQueue;\r
-  ESL_PACKET * pPacket;\r
-  ESL_IO_MGMT ** ppActive;\r
-  ESL_IO_MGMT ** ppFree;\r
-  ESL_PORT * pPort;\r
-  ESL_PACKET ** ppQueueHead;\r
-  ESL_PACKET ** ppQueueTail;\r
-  ESL_PACKET * pPreviousPacket;\r
-  size_t * pTxBytes;\r
-  EFI_TCP4_TRANSMIT_DATA * pTxData;\r
-  EFI_STATUS Status;\r
-  EFI_TPL TplPrevious;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Assume failure\r
-  //\r
-  Status = EFI_UNSUPPORTED;\r
-  pSocket->errno = ENOTCONN;\r
-  *pDataLength = 0;\r
-\r
-  //\r
-  //  Verify that the socket is connected\r
-  //\r
-  if ( SOCKET_STATE_CONNECTED == pSocket->State ) {\r
-    //\r
-    //  Locate the port\r
-    //\r
-    pPort = pSocket->pPortList;\r
-    if ( NULL != pPort ) {\r
-      //\r
-      //  Determine the queue head\r
-      //\r
-      bUrgent = (BOOLEAN)( 0 != ( Flags & MSG_OOB ));\r
-      bUrgentQueue = bUrgent\r
-                    && ( !pSocket->bOobInLine )\r
-                    && pSocket->pApi->bOobSupported;\r
-      if ( bUrgentQueue ) {\r
-        ppQueueHead = &pSocket->pTxOobPacketListHead;\r
-        ppQueueTail = &pSocket->pTxOobPacketListTail;\r
-        ppActive = &pPort->pTxOobActive;\r
-        ppFree = &pPort->pTxOobFree;\r
-        pTxBytes = &pSocket->TxOobBytes;\r
-      }\r
-      else {\r
-        ppQueueHead = &pSocket->pTxPacketListHead;\r
-        ppQueueTail = &pSocket->pTxPacketListTail;\r
-        ppActive = &pPort->pTxActive;\r
-        ppFree = &pPort->pTxFree;\r
-        pTxBytes = &pSocket->TxBytes;\r
-      }\r
-\r
-      //\r
-      //  Verify that there is enough room to buffer another\r
-      //  transmit operation\r
-      //\r
-      if ( pSocket->MaxTxBuf > *pTxBytes ) {\r
-        if ( pPort->bTxFlowControl ) {\r
-          DEBUG (( DEBUG_TX,\r
-                    "TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT\r\n0x%08x: pPort, TX flow control released, Max bytes: %d > %d bufferred bytes\r\n",\r
-                    pPort,\r
-                    pSocket->MaxTxBuf,\r
-                    *pTxBytes ));\r
-          pPort->bTxFlowControl = FALSE;\r
-        }\r
-\r
-        //\r
-        //  Attempt to allocate the packet\r
-        //\r
-        Status = EslSocketPacketAllocate ( &pPacket,\r
-                                           sizeof ( pPacket->Op.Tcp4Tx )\r
-                                           - sizeof ( pPacket->Op.Tcp4Tx.Buffer )\r
-                                           + BufferLength,\r
-                                           0,\r
-                                           DEBUG_TX );\r
-        if ( !EFI_ERROR ( Status )) {\r
-          //\r
-          //  Initialize the transmit operation\r
-          //\r
-          pTxData = &pPacket->Op.Tcp4Tx.TxData;\r
-          pTxData->Push = TRUE || bUrgent;\r
-          pTxData->Urgent = bUrgent;\r
-          pTxData->DataLength = (UINT32) BufferLength;\r
-          pTxData->FragmentCount = 1;\r
-          pTxData->FragmentTable[0].FragmentLength = (UINT32) BufferLength;\r
-          pTxData->FragmentTable[0].FragmentBuffer = &pPacket->Op.Tcp4Tx.Buffer[0];\r
-\r
-          //\r
-          //  Copy the data into the buffer\r
-          //\r
-          CopyMem ( &pPacket->Op.Tcp4Tx.Buffer[0],\r
-                    pBuffer,\r
-                    BufferLength );\r
-\r
-          //\r
-          //  Synchronize with the socket layer\r
-          //\r
-          RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
-\r
-          //\r
-          //  Stop transmission after an error\r
-          //\r
-          if ( !EFI_ERROR ( pSocket->TxError )) {\r
-            //\r
-            //  Display the request\r
-            //\r
-            DEBUG (( DEBUG_TX,\r
-                      "Send %d %s bytes from 0x%08x\r\n",\r
-                      BufferLength,\r
-                      bUrgent ? L"urgent" : L"normal",\r
-                      pBuffer ));\r
-\r
-            //\r
-            //  Queue the data for transmission\r
-            //\r
-            pPacket->pNext = NULL;\r
-            pPreviousPacket = *ppQueueTail;\r
-            if ( NULL == pPreviousPacket ) {\r
-              *ppQueueHead = pPacket;\r
-            }\r
-            else {\r
-              pPreviousPacket->pNext = pPacket;\r
-            }\r
-            *ppQueueTail = pPacket;\r
-            DEBUG (( DEBUG_TX,\r
-                      "0x%08x: Packet on %s transmit list\r\n",\r
-                      pPacket,\r
-                      bUrgentQueue ? L"urgent" : L"normal" ));\r
-\r
-            //\r
-            //  Account for the buffered data\r
-            //\r
-            *pTxBytes += BufferLength;\r
-            *pDataLength = BufferLength;\r
-\r
-            //\r
-            //  Start the transmit engine if it is idle\r
-            //\r
-            if ( NULL != *ppFree ) {\r
-              EslSocketTxStart ( pPort,\r
-                                 ppQueueHead,\r
-                                 ppQueueTail,\r
-                                 ppActive,\r
-                                 ppFree );\r
-            }\r
-          }\r
-          else {\r
-            //\r
-            //  Previous transmit error\r
-            //  Stop transmission\r
-            //\r
-            Status = pSocket->TxError;\r
-            pSocket->errno = EIO;\r
-\r
-            //\r
-            //  Free the packet\r
-            //\r
-            EslSocketPacketFree ( pPacket, DEBUG_TX );\r
-          }\r
-\r
-          //\r
-          //  Release the socket layer synchronization\r
-          //\r
-          RESTORE_TPL ( TplPrevious );\r
-        }\r
-        else {\r
-          //\r
-          //  Packet allocation failed\r
-          //\r
-          pSocket->errno = ENOMEM;\r
-        }\r
-      }\r
-      else {\r
-        if ( !pPort->bTxFlowControl ) {\r
-          DEBUG (( DEBUG_TX,\r
-                    "0x%08x: pPort, TX flow control applied, Max bytes %d <= %d bufferred bytes\r\nTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT\r\n",\r
-                    pPort,\r
-                    pSocket->MaxTxBuf,\r
-                    *pTxBytes ));\r
-          pPort->bTxFlowControl = TRUE;\r
-        }\r
-        //\r
-        //  Not enough buffer space available\r
-        //\r
-        pSocket->errno = EAGAIN;\r
-        Status = EFI_NOT_READY;\r
-      }\r
-    }\r
-  }\r
-\r
-  //\r
-  //  Return the operation status\r
-  //\r
-  DBG_EXIT_STATUS ( Status );\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Process the normal data transmit completion\r
-\r
-  This routine use ::EslSocketTxComplete to perform the transmit\r
-  completion processing for normal data.\r
-\r
-  This routine is called by the TCPv4 network layer when a\r
-  normal data transmit request completes.\r
-\r
-  @param [in] Event     The normal transmit completion event\r
-\r
-  @param [in] pIo       The ESL_IO_MGMT structure address\r
-\r
-**/\r
-VOID\r
-EslTcp4TxComplete (\r
-  IN EFI_EVENT Event,\r
-  IN ESL_IO_MGMT * pIo\r
-  )\r
-{\r
-  UINT32 LengthInBytes;\r
-  ESL_PACKET * pPacket;\r
-  ESL_PORT * pPort;\r
-  ESL_SOCKET * pSocket;\r
-  EFI_STATUS Status;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Locate the active transmit packet\r
-  //\r
-  pPacket = pIo->pPacket;\r
-  pPort = pIo->pPort;\r
-  pSocket = pPort->pSocket;\r
-\r
-  //\r
-  //  Get the transmit length and status\r
-  //\r
-  LengthInBytes = pPacket->Op.Tcp4Tx.TxData.DataLength;\r
-  pSocket->TxBytes -= LengthInBytes;\r
-  Status = pIo->Token.Tcp4Tx.CompletionToken.Status;\r
-\r
-  //\r
-  //  Complete the transmit operation\r
-  //\r
-  EslSocketTxComplete ( pIo,\r
-                        LengthInBytes,\r
-                        Status,\r
-                        "Normal ",\r
-                        &pSocket->pTxPacketListHead,\r
-                        &pSocket->pTxPacketListTail,\r
-                        &pPort->pTxActive,\r
-                        &pPort->pTxFree );\r
-  DBG_EXIT ( );\r
-}\r
-\r
-\r
-/**\r
-  Process the urgent data transmit completion\r
-\r
-  This routine use ::EslSocketTxComplete to perform the transmit\r
-  completion processing for urgent data.\r
-\r
-  This routine is called by the TCPv4 network layer when a\r
-  urgent data transmit request completes.\r
-\r
-  @param [in] Event     The urgent transmit completion event\r
-\r
-  @param [in] pIo       The ESL_IO_MGMT structure address\r
-\r
-**/\r
-VOID\r
-EslTcp4TxOobComplete (\r
-  IN EFI_EVENT Event,\r
-  IN ESL_IO_MGMT * pIo\r
-  )\r
-{\r
-  UINT32 LengthInBytes;\r
-  ESL_PACKET * pPacket;\r
-  ESL_PORT * pPort;\r
-  ESL_SOCKET * pSocket;\r
-  EFI_STATUS Status;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Locate the active transmit packet\r
-  //\r
-  pPacket = pIo->pPacket;\r
-  pPort = pIo->pPort;\r
-  pSocket = pPort->pSocket;\r
-\r
-  //\r
-  //  Get the transmit length and status\r
-  //\r
-  LengthInBytes = pPacket->Op.Tcp4Tx.TxData.DataLength;\r
-  pSocket->TxOobBytes -= LengthInBytes;\r
-  Status = pIo->Token.Tcp4Tx.CompletionToken.Status;\r
-\r
-  //\r
-  //  Complete the transmit operation\r
-  //\r
-  EslSocketTxComplete ( pIo,\r
-                        LengthInBytes,\r
-                        Status,\r
-                        "Urgent ",\r
-                        &pSocket->pTxOobPacketListHead,\r
-                        &pSocket->pTxOobPacketListTail,\r
-                        &pPort->pTxOobActive,\r
-                        &pPort->pTxOobFree );\r
-  DBG_EXIT ( );\r
-}\r
-\r
-\r
-/**\r
-  Verify the adapter's IP address\r
-\r
-  This support routine is called by EslSocketBindTest.\r
-\r
-  @param [in] pPort       Address of an ::ESL_PORT structure.\r
-  @param [in] pConfigData Address of the configuration data\r
-\r
-  @retval EFI_SUCCESS - The IP address is valid\r
-  @retval EFI_NOT_STARTED - The IP address is invalid\r
-\r
- **/\r
-EFI_STATUS\r
-EslTcp4VerifyLocalIpAddress (\r
-  IN ESL_PORT * pPort,\r
-  IN EFI_TCP4_CONFIG_DATA * pConfigData\r
-  )\r
-{\r
-  UINTN DataSize;\r
-  EFI_TCP4_ACCESS_POINT * pAccess;\r
-  EFI_IP4_CONFIG2_INTERFACE_INFO * pIfInfo;\r
-  EFI_IP4_CONFIG2_PROTOCOL * pIpConfig2Protocol;\r
-  ESL_SERVICE * pService;\r
-  EFI_STATUS Status;\r
-\r
-  DBG_ENTER ( );\r
-\r
-  //\r
-  //  Use break instead of goto\r
-  //\r
-  pIfInfo = NULL;\r
-  for ( ; ; ) {\r
-    //\r
-    //  Determine if the IP address is specified\r
-    //\r
-    pAccess = &pConfigData->AccessPoint;\r
-    DEBUG (( DEBUG_BIND,\r
-              "UseDefaultAddress: %s\r\n",\r
-              pAccess->UseDefaultAddress ? L"TRUE" : L"FALSE" ));\r
-    DEBUG (( DEBUG_BIND,\r
-              "Requested IP address: %d.%d.%d.%d\r\n",\r
-              pAccess->StationAddress.Addr [ 0 ],\r
-              pAccess->StationAddress.Addr [ 1 ],\r
-              pAccess->StationAddress.Addr [ 2 ],\r
-              pAccess->StationAddress.Addr [ 3 ]));\r
-    if ( pAccess->UseDefaultAddress\r
-      || (( 0 == pAccess->StationAddress.Addr [ 0 ])\r
-      && ( 0 == pAccess->StationAddress.Addr [ 1 ])\r
-      && ( 0 == pAccess->StationAddress.Addr [ 2 ])\r
-      && ( 0 == pAccess->StationAddress.Addr [ 3 ])))\r
-    {\r
-      Status = EFI_SUCCESS;\r
-      break;\r
-    }\r
-\r
-    //\r
-    //  Open the configuration protocol\r
-    //\r
-    pService = pPort->pService;\r
-    Status = gBS->OpenProtocol ( \r
-                    pService->Controller,\r
-                    &gEfiIp4Config2ProtocolGuid,\r
-                    (VOID **)&pIpConfig2Protocol,\r
-                    NULL,\r
-                    NULL,\r
-                    EFI_OPEN_PROTOCOL_GET_PROTOCOL \r
-                    );\r
-    if ( EFI_ERROR ( Status )) {\r
-      DEBUG (( DEBUG_ERROR,\r
-                "ERROR - IP Configuration Protocol not available, Status: %r\r\n",\r
-                Status ));\r
-      break;\r
-    }\r
-\r
-    //\r
-    // Get the interface information size.\r
-    //\r
-    DataSize = 0;\r
-    Status = pIpConfig2Protocol->GetData ( \r
-                                   pIpConfig2Protocol,\r
-                                   Ip4Config2DataTypeInterfaceInfo,\r
-                                   &DataSize,\r
-                                   NULL\r
-                                   );\r
-    if ( EFI_BUFFER_TOO_SMALL != Status ) {\r
-      DEBUG (( DEBUG_ERROR,\r
-                "ERROR - Failed to get the interface information size, Status: %r\r\n",\r
-                Status ));\r
-      break;\r
-    }\r
-\r
-    //\r
-    //  Allocate the interface information buffer\r
-    //\r
-    pIfInfo = AllocatePool ( DataSize );\r
-    if ( NULL == pIfInfo ) {\r
-      DEBUG (( DEBUG_ERROR,\r
-                "ERROR - Not enough memory to allocate the interface information buffer!\r\n" ));\r
-      Status = EFI_OUT_OF_RESOURCES;\r
-      break;\r
-    }\r
-\r
-    //\r
-    // Get the interface info.\r
-    //\r
-    Status = pIpConfig2Protocol->GetData ( \r
-                                  pIpConfig2Protocol,\r
-                                  Ip4Config2DataTypeInterfaceInfo,\r
-                                  &DataSize,\r
-                                  pIfInfo\r
-                                  );\r
-    if ( EFI_ERROR ( Status )) {\r
-      DEBUG (( DEBUG_ERROR,\r
-                "ERROR - Failed to return the interface info, Status: %r\r\n",\r
-                Status ));\r
-      break;\r
-    }\r
-\r
-    //\r
-    //  Display the current configuration\r
-    //\r
-    DEBUG (( DEBUG_BIND,\r
-              "Actual adapter IP address: %d.%d.%d.%d\r\n",\r
-              pIfInfo->StationAddress.Addr [ 0 ],\r
-              pIfInfo->StationAddress.Addr [ 1 ],\r
-              pIfInfo->StationAddress.Addr [ 2 ],\r
-              pIfInfo->StationAddress.Addr [ 3 ]));\r
-\r
-    //\r
-    //  Assume the port is not configured\r
-    //\r
-    Status = EFI_SUCCESS;\r
-    if (( pAccess->StationAddress.Addr [ 0 ] == pIfInfo->StationAddress.Addr [ 0 ])\r
-      && ( pAccess->StationAddress.Addr [ 1 ] == pIfInfo->StationAddress.Addr [ 1 ])\r
-      && ( pAccess->StationAddress.Addr [ 2 ] == pIfInfo->StationAddress.Addr [ 2 ])\r
-      && ( pAccess->StationAddress.Addr [ 3 ] == pIfInfo->StationAddress.Addr [ 3 ])) {\r
-      break;\r
-    }\r
-\r
-    //\r
-    //  The IP address did not match\r
-    //\r
-    Status = EFI_NOT_STARTED;\r
-    break;\r
-  }\r
-\r
-  //\r
-  //  Free the buffer if necessary\r
-  //\r
-  if ( NULL != pIfInfo ) {\r
-    FreePool ( pIfInfo );\r
-  }\r
-\r
-  //\r
-  //  Return the IP address status\r
-  //\r
-  DBG_EXIT_STATUS ( Status );\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Interface between the socket layer and the network specific\r
-  code that supports SOCK_STREAM and SOCK_SEQPACKET sockets\r
-  over TCPv4.\r
-**/\r
-CONST ESL_PROTOCOL_API cEslTcp4Api = {\r
-  "TCPv4",\r
-  IPPROTO_TCP,\r
-  OFFSET_OF ( ESL_PORT, Context.Tcp4.ConfigData ),\r
-  OFFSET_OF ( ESL_LAYER, pTcp4List ),\r
-  OFFSET_OF ( struct sockaddr_in, sin_zero ),\r
-  sizeof ( struct sockaddr_in ),\r
-  AF_INET,\r
-  sizeof (((ESL_PACKET *)0 )->Op.Tcp4Rx ),\r
-  OFFSET_OF ( ESL_PACKET, Op.Tcp4Rx.Buffer ) - OFFSET_OF ( ESL_PACKET, Op ),\r
-  OFFSET_OF ( ESL_IO_MGMT, Token.Tcp4Rx.Packet.RxData ),\r
-  TRUE,\r
-  EADDRINUSE,\r
-  EslTcp4Accept,\r
-  EslTcp4ConnectPoll,\r
-  EslTcp4ConnectStart,\r
-  EslTcp4SocketIsConfigured,\r
-  EslTcp4LocalAddressGet,\r
-  EslTcp4LocalAddressSet,\r
-  EslTcp4Listen,\r
-  NULL,   //  OptionGet\r
-  NULL,   //  OptionSet\r
-  EslTcp4PacketFree,\r
-  EslTcp4PortAllocate,\r
-  EslTcp4PortClose,\r
-  EslTcp4PortCloseOp,\r
-  FALSE,\r
-  EslTcp4Receive,\r
-  EslTcp4RemoteAddressGet,\r
-  EslTcp4RemoteAddressSet,\r
-  EslTcp4RxComplete,\r
-  EslTcp4RxStart,\r
-  EslTcp4TxBuffer,\r
-  EslTcp4TxComplete,\r
-  EslTcp4TxOobComplete,\r
-  (PFN_API_VERIFY_LOCAL_IP_ADDRESS)EslTcp4VerifyLocalIpAddress\r
-};\r