Home | History | Annotate | Download | only in EfiSocketLib
      1 /** @file
      2   Definitions for the Socket layer driver.
      3 
      4   Copyright (c) 2011, Intel Corporation
      5   All rights reserved. This program and the accompanying materials
      6   are licensed and made available under the terms and conditions of the BSD License
      7   which accompanies this distribution.  The full text of the license may be found at
      8   http://opensource.org/licenses/bsd-license
      9 
     10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 #ifndef _SOCKET_H_
     15 #define _SOCKET_H_
     16 
     17 #include <Efi/EfiSocketLib.h>
     18 
     19 //------------------------------------------------------------------------------
     20 //  Constants
     21 //------------------------------------------------------------------------------
     22 
     23 #define DEBUG_SOCKET        0x20000000  ///<  Display Socket related messages
     24 #define DEBUG_BIND          0x10000000  ///<  Display bind related messages
     25 #define DEBUG_LISTEN        0x08000000  ///<  Display listen related messages
     26 #define DEBUG_CONNECTION    0x04000000  ///<  Display connection list related messages
     27 #define DEBUG_POLL          0x02000000  ///<  Display poll messages
     28 #define DEBUG_ACCEPT        0x01000000  ///<  Display accept related messages
     29 #define DEBUG_RX            0x00800000  ///<  Display receive messages
     30 #define DEBUG_TX            0x00400000  ///<  Display transmit messages
     31 #define DEBUG_CLOSE         0x00200000  ///<  Display close messages
     32 #define DEBUG_CONNECT       0x00100000  ///<  Display connect messages
     33 #define DEBUG_OPTION        0x00080000  ///<  Display option messages
     34 
     35 #define MAX_PENDING_CONNECTIONS     1   ///<  Maximum connection FIFO depth
     36 #define MAX_RX_DATA         0x01000000  ///<  Maximum receive data size
     37 #define MAX_TX_DATA         ( MAX_RX_DATA * 2 ) ///<  Maximum buffered transmit data in bytes
     38 #define RX_PACKET_DATA      0x00100000  ///<  Maximum number of bytes in a RX packet
     39 #define MAX_UDP_RETRANSMIT  16          ///<  UDP retransmit attempts to handle address not mapped
     40 
     41 #define ESL_STRUCTURE_ALIGNMENT_BYTES   15  ///<  Number of bytes for structure alignment
     42 #define ESL_STRUCTURE_ALIGNMENT_MASK    ( ~ESL_STRUCTURE_ALIGNMENT_BYTES )  ///<  Mask to align structures
     43 
     44 #define LAYER_SIGNATURE           SIGNATURE_32 ('S','k','t','L')  ///<  ESL_LAYER memory signature
     45 #define SERVICE_SIGNATURE         SIGNATURE_32 ('S','k','t','S')  ///<  ESL_SERVICE memory signature
     46 #define SOCKET_SIGNATURE          SIGNATURE_32 ('S','c','k','t')  ///<  ESL_SOCKET memory signature
     47 #define PORT_SIGNATURE            SIGNATURE_32 ('P','o','r','t')  ///<  ESL_PORT memory signature
     48 
     49 
     50 /**
     51   Socket states
     52 **/
     53 typedef enum
     54 {
     55   SOCKET_STATE_NOT_CONFIGURED = 0,  ///<  socket call was successful
     56   SOCKET_STATE_BOUND,               ///<  bind call was successful
     57   SOCKET_STATE_LISTENING,           ///<  listen call was successful
     58   SOCKET_STATE_NO_PORTS,            ///<  No ports available
     59   SOCKET_STATE_IN_FIFO,             ///<  Socket on FIFO
     60   SOCKET_STATE_CONNECTING,          ///<  Connecting to a remote system
     61   SOCKET_STATE_CONNECTED,           ///<  Accept or connect call was successful
     62 
     63   //
     64   //  Close state must be the last in the list
     65   //
     66   SOCKET_STATE_CLOSED               ///<  Close call was successful
     67 } SOCKET_STATE;
     68 
     69 
     70 /**
     71   Port states
     72 **/
     73 typedef enum
     74 {
     75   PORT_STATE_ALLOCATED = 0, ///<  Port allocated
     76   PORT_STATE_OPEN,          ///<  Port opened
     77   PORT_STATE_RX_ERROR,      ///<  Receive error detected
     78 
     79   //
     80   //  Close state must be last in the list!
     81   //
     82   //  Using < <= > >= in tests code to detect port close state
     83   //  machine has started
     84   //
     85   PORT_STATE_CLOSE_STARTED, ///<  Close started on port
     86   PORT_STATE_CLOSE_TX_DONE, ///<  Transmits shutdown
     87   PORT_STATE_CLOSE_DONE,    ///<  Port close operation complete
     88   PORT_STATE_CLOSE_RX_DONE  ///<  Receives shutdown
     89 } PORT_STATE;
     90 
     91 //------------------------------------------------------------------------------
     92 //  Data Types
     93 //------------------------------------------------------------------------------
     94 
     95 typedef struct _ESL_IO_MGMT ESL_IO_MGMT;///<  Forward declaration
     96 typedef struct _ESL_PACKET ESL_PACKET;  ///<  Forward declaration
     97 typedef struct _ESL_PORT ESL_PORT;      ///<  Forward declaration
     98 typedef struct _ESL_SOCKET ESL_SOCKET;  ///<  Forward declaration
     99 
    100 /**
    101   Receive context for SOCK_RAW sockets using IPv4.
    102 **/
    103 typedef struct
    104 {
    105   EFI_IP4_RECEIVE_DATA * pRxData;       ///<  Receive operation description
    106 } ESL_IP4_RX_DATA;
    107 
    108 
    109 /**
    110   Transmit context for SOCK_RAW sockets using IPv4.
    111 **/
    112 typedef struct
    113 {
    114   EFI_IP4_OVERRIDE_DATA Override;       ///<  Override data
    115   EFI_IP4_TRANSMIT_DATA TxData;         ///<  Transmit operation description
    116   UINT8 Buffer[ 1 ];                    ///<  Data buffer
    117 } ESL_IP4_TX_DATA;
    118 
    119 
    120 /**
    121   Receive context for SOCK_STREAM and SOCK_SEQPACKET sockets using TCPv4.
    122 **/
    123 typedef struct
    124 {
    125   EFI_TCP4_RECEIVE_DATA RxData;         ///<  Receive operation description
    126   UINT8 Buffer[ RX_PACKET_DATA ];       ///<  Data buffer
    127 } ESL_TCP4_RX_DATA;
    128 
    129 
    130 /**
    131   Transmit context for SOCK_STREAM and SOCK_SEQPACKET sockets using TCPv4.
    132 **/
    133 typedef struct
    134 {
    135   EFI_TCP4_TRANSMIT_DATA TxData;        ///<  Transmit operation description
    136   UINT8 Buffer[ 1 ];                    ///<  Data buffer
    137 } ESL_TCP4_TX_DATA;
    138 
    139 
    140 /**
    141   Receive context for SOCK_STREAM and SOCK_SEQPACKET sockets using TCPv6.
    142 **/
    143 typedef struct
    144 {
    145   EFI_TCP6_RECEIVE_DATA RxData;         ///<  Receive operation description
    146   UINT8 Buffer[ RX_PACKET_DATA ];       ///<  Data buffer
    147 } ESL_TCP6_RX_DATA;
    148 
    149 
    150 /**
    151   Transmit context for SOCK_STREAM and SOCK_SEQPACKET sockets using TCPv6.
    152 **/
    153 typedef struct
    154 {
    155   EFI_TCP6_TRANSMIT_DATA TxData;        ///<  Transmit operation description
    156   UINT8 Buffer[ 1 ];                    ///<  Data buffer
    157 } ESL_TCP6_TX_DATA;
    158 
    159 
    160 /**
    161   Receive context for SOCK_DGRAM sockets using UDPv4.
    162 **/
    163 typedef struct
    164 {
    165   EFI_UDP4_SESSION_DATA Session;        ///<  Remote network address
    166   EFI_UDP4_RECEIVE_DATA * pRxData;      ///<  Receive operation description
    167 } ESL_UDP4_RX_DATA;
    168 
    169 
    170 /**
    171   Transmit context for SOCK_DGRAM sockets using UDPv4.
    172 **/
    173 typedef struct
    174 {
    175   EFI_UDP4_SESSION_DATA Session;        ///<  Remote network address
    176   EFI_UDP4_TRANSMIT_DATA TxData;        ///<  Transmit operation description
    177   UINTN RetransmitCount;                ///<  Retransmit to handle ARP negotiation
    178   UINT8 Buffer[ 1 ];                    ///<  Data buffer
    179 } ESL_UDP4_TX_DATA;
    180 
    181 
    182 /**
    183   Receive context for SOCK_DGRAM sockets using UDPv6.
    184 **/
    185 typedef struct
    186 {
    187   EFI_UDP6_SESSION_DATA Session;        ///<  Remote network address
    188   EFI_UDP6_RECEIVE_DATA * pRxData;      ///<  Receive operation description
    189 } ESL_UDP6_RX_DATA;
    190 
    191 
    192 /**
    193   Transmit context for SOCK_DGRAM sockets using UDPv6.
    194 **/
    195 typedef struct
    196 {
    197   EFI_UDP6_SESSION_DATA Session;        ///<  Remote network address
    198   EFI_UDP6_TRANSMIT_DATA TxData;        ///<  Transmit operation description
    199   UINTN RetransmitCount;                ///<  Retransmit to handle ARP negotiation
    200   UINT8 Buffer[ 1 ];                    ///<  Data buffer
    201 } ESL_UDP6_TX_DATA;
    202 
    203 
    204 /**
    205   Network specific context for transmit and receive packets.
    206 **/
    207 typedef struct _ESL_PACKET {
    208   ESL_PACKET * pNext;                   ///<  Next packet in the receive list
    209   size_t PacketSize;                    ///<  Size of this data structure
    210   size_t ValidBytes;                    ///<  Length of valid data in bytes
    211   UINT8 * pBuffer;                      ///<  Current data pointer
    212   union {
    213     ESL_IP4_RX_DATA Ip4Rx;              ///<  Receive operation description
    214     ESL_IP4_TX_DATA Ip4Tx;              ///<  Transmit operation description
    215     ESL_TCP4_RX_DATA Tcp4Rx;            ///<  Receive operation description
    216     ESL_TCP4_TX_DATA Tcp4Tx;            ///<  Transmit operation description
    217     ESL_TCP6_RX_DATA Tcp6Rx;            ///<  Receive operation description
    218     ESL_TCP6_TX_DATA Tcp6Tx;            ///<  Transmit operation description
    219     ESL_UDP4_RX_DATA Udp4Rx;            ///<  Receive operation description
    220     ESL_UDP4_TX_DATA Udp4Tx;            ///<  Transmit operation description
    221     ESL_UDP6_RX_DATA Udp6Rx;            ///<  Receive operation description
    222     ESL_UDP6_TX_DATA Udp6Tx;            ///<  Transmit operation description
    223   } Op;                                 ///<  Network specific context
    224 } GCC_ESL_PACKET;
    225 
    226 /**
    227   Service control structure
    228 
    229   The driver uses this structure to manage the network devices.
    230 **/
    231 typedef struct _ESL_SERVICE {
    232   UINTN Signature;          ///<  Structure identification
    233 
    234   //
    235   //  Links
    236   //
    237   ESL_SERVICE * pNext;      ///<  Next service in the service list
    238 
    239   //
    240   //  Service data
    241   //
    242   CONST ESL_SOCKET_BINDING * pSocketBinding;      ///<  Name and shutdown routine
    243   EFI_HANDLE Controller;                          ///<  Controller for the service
    244   EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding; ///<  Network layer service binding interface
    245 
    246   //
    247   //  Network data
    248   //
    249   ESL_PORT * pPortList;     ///<  List of ports using this service
    250 }GCC_ESL_SERVICE;
    251 
    252 /**
    253   IO management structure
    254 
    255   This structure manages a single operation with the network.
    256 **/
    257 typedef struct _ESL_IO_MGMT {
    258   ESL_IO_MGMT * pNext;                ///<  Next TX management structure
    259   ESL_PORT * pPort;                   ///<  Port structure address
    260   ESL_PACKET * pPacket;               ///<  Packet structure address
    261   union {
    262     EFI_IP4_COMPLETION_TOKEN Ip4Rx;   ///<  IP4 receive token
    263     EFI_IP4_COMPLETION_TOKEN Ip4Tx;   ///<  IP4 transmit token
    264     EFI_TCP4_IO_TOKEN Tcp4Rx;         ///<  TCP4 receive token
    265     EFI_TCP4_IO_TOKEN Tcp4Tx;         ///<  TCP4 transmit token
    266     EFI_TCP6_IO_TOKEN Tcp6Rx;         ///<  TCP6 receive token
    267     EFI_TCP6_IO_TOKEN Tcp6Tx;         ///<  TCP6 transmit token
    268     EFI_UDP4_COMPLETION_TOKEN Udp4Rx; ///<  UDP4 receive token
    269     EFI_UDP4_COMPLETION_TOKEN Udp4Tx; ///<  UDP4 transmit token
    270     EFI_UDP6_COMPLETION_TOKEN Udp6Rx; ///<  UDP6 receive token
    271     EFI_UDP6_COMPLETION_TOKEN Udp6Tx; ///<  UDP6 transmit token
    272   } Token;                            ///<  Completion token for the network operation
    273 } GCC_IO_MGMT;
    274 
    275 /**
    276   IP4 context structure
    277 
    278   The driver uses this structure to manage the IP4 connections.
    279 **/
    280 typedef struct {
    281   //
    282   //  IP4 context
    283   //
    284   EFI_IP4_MODE_DATA ModeData;           ///<  IP4 mode data, includes configuration data
    285   EFI_IPv4_ADDRESS DestinationAddress;  ///<  Default destination address
    286 } ESL_IP4_CONTEXT;
    287 
    288 
    289 /**
    290   TCP4 context structure
    291 
    292   The driver uses this structure to manage the TCP4 connections.
    293 **/
    294 typedef struct {
    295   //
    296   //  TCP4 context
    297   //
    298   EFI_TCP4_CONFIG_DATA ConfigData;        ///<  TCP4 configuration data
    299   EFI_TCP4_OPTION Option;                 ///<  TCP4 port options
    300 
    301   //
    302   //  Tokens
    303   //
    304   EFI_TCP4_LISTEN_TOKEN ListenToken;      ///<  Listen control
    305   EFI_TCP4_CONNECTION_TOKEN ConnectToken; ///<  Connection control
    306   EFI_TCP4_CLOSE_TOKEN CloseToken;        ///<  Close control
    307 } ESL_TCP4_CONTEXT;
    308 
    309 /**
    310   TCP6 context structure
    311 
    312   The driver uses this structure to manage the TCP6 connections.
    313 **/
    314 typedef struct {
    315   //
    316   //  TCP6 context
    317   //
    318   EFI_TCP6_CONFIG_DATA ConfigData;        ///<  TCP6 configuration data
    319   EFI_TCP6_OPTION Option;                 ///<  TCP6 port options
    320 
    321   //
    322   //  Tokens
    323   //
    324   EFI_TCP6_LISTEN_TOKEN ListenToken;      ///<  Listen control
    325   EFI_TCP6_CONNECTION_TOKEN ConnectToken; ///<  Connection control
    326   EFI_TCP6_CLOSE_TOKEN CloseToken;        ///<  Close control
    327 } ESL_TCP6_CONTEXT;
    328 
    329 /**
    330   UDP4 context structure
    331 
    332   The driver uses this structure to manage the UDP4 connections.
    333 **/
    334 typedef struct {
    335   //
    336   //  UDP4 context
    337   //
    338   EFI_UDP4_CONFIG_DATA ConfigData;  ///<  UDP4 configuration data
    339 } ESL_UDP4_CONTEXT;
    340 
    341 /**
    342   UDP6 context structure
    343 
    344   The driver uses this structure to manage the UDP6 connections.
    345 **/
    346 typedef struct {
    347   //
    348   //  UDP6 context
    349   //
    350   EFI_UDP6_CONFIG_DATA ConfigData;  ///<  UDP6 configuration data
    351 } ESL_UDP6_CONTEXT;
    352 
    353 
    354 /**
    355   Configure the network layer.
    356 
    357   @param [in] pProtocol   Protocol structure address
    358   @param [in] pConfigData Address of the confiuration data
    359 
    360   @return   Returns EFI_SUCCESS if the operation is successfully
    361             started.
    362 **/
    363 typedef
    364 EFI_STATUS
    365 (EFIAPI * PFN_NET_CONFIGURE) (
    366   IN VOID * pProtocol,
    367   IN VOID * pConfigData
    368   );
    369 
    370 /**
    371   Hand an I/O operation to the network layer.
    372 
    373   @param [in] pProtocol   Protocol structure address
    374   @param [in] pToken      Completion token address
    375 
    376   @return   Returns EFI_SUCCESS if the operation is successfully
    377             started.
    378 **/
    379 typedef
    380 EFI_STATUS
    381 (EFIAPI * PFN_NET_IO_START) (
    382   IN VOID * pProtocol,
    383   IN VOID * pToken
    384   );
    385 
    386 /**
    387   Poll the LAN adapter for receive packets.
    388 
    389   @param [in] pProtocol   Protocol structure address
    390   @param [in] pToken      Completion token address
    391 
    392   @return   Returns EFI_SUCCESS if the operation is successfully
    393             started.
    394 **/
    395 typedef
    396 EFI_STATUS
    397 (EFIAPI * PFN_NET_POLL) (
    398   IN VOID * pProtocol
    399   );
    400 
    401 /**
    402   Port control structure
    403 
    404   The driver uses this structure to manager the socket's connection
    405   with the network driver.
    406 **/
    407 typedef struct _ESL_PORT {
    408   UINTN Signature;              ///<  Structure identification
    409 
    410   //
    411   //  List links
    412   //
    413   ESL_PORT * pLinkService;      ///<  Link in service port list
    414   ESL_PORT * pLinkSocket;       ///<  Link in socket port list
    415 
    416   //
    417   //  Structures
    418   //
    419   ESL_SERVICE * pService;       ///<  Service for this port
    420   ESL_SOCKET * pSocket;         ///<  Socket for this port
    421 
    422   //
    423   //  Eliminate the pService references during port close
    424   //
    425   EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding; ///<  Service binding for network layer
    426   CONST ESL_SOCKET_BINDING * pSocketBinding;      ///<  Socket binding for network layer
    427 
    428   //
    429   //  Port management
    430   //
    431   EFI_HANDLE Handle;              ///<  Network port handle
    432   PORT_STATE State;               ///<  State of the port
    433   UINTN DebugFlags;               ///<  Debug flags used to close the port
    434   BOOLEAN bCloseNow;              ///<  TRUE = Close the port immediately
    435   BOOLEAN bConfigured;            ///<  TRUE = Configure call made to network layer
    436   PFN_NET_CONFIGURE pfnConfigure; ///<  Configure the network layer
    437 
    438   //
    439   //  Transmit data management
    440   //
    441   BOOLEAN bTxFlowControl;       ///<  TX flow control applied
    442   PFN_NET_IO_START pfnTxStart;  ///<  Start a transmit on the network
    443   ESL_IO_MGMT * pTxActive;      ///<  Normal data queue
    444   ESL_IO_MGMT * pTxFree;        ///<  Normal free queue
    445 
    446   ESL_IO_MGMT * pTxOobActive;   ///<  Urgent data queue
    447   ESL_IO_MGMT * pTxOobFree;     ///<  Urgent free queue
    448 
    449   //
    450   //  Receive data management
    451   //
    452   PFN_NET_IO_START pfnRxCancel; ///<  Cancel a receive on the network
    453   PFN_NET_POLL pfnRxPoll;       ///<  Poll the LAN adapter for receive packets
    454   PFN_NET_IO_START pfnRxStart;  ///<  Start a receive on the network
    455   ESL_IO_MGMT * pRxActive;      ///<  Active receive operation queue
    456   ESL_IO_MGMT * pRxFree;        ///<  Free structure queue
    457 
    458   //
    459   //  Protocol specific management data
    460   //
    461   union {
    462     VOID * v;                   ///<  VOID pointer
    463     EFI_IP4_PROTOCOL * IPv4;    ///<  IP4 protocol pointer
    464     EFI_TCP4_PROTOCOL * TCPv4;  ///<  TCP4 protocol pointer
    465     EFI_TCP6_PROTOCOL * TCPv6;  ///<  TCP6 protocol pointer
    466     EFI_UDP4_PROTOCOL * UDPv4;  ///<  UDP4 protocol pointer
    467     EFI_UDP6_PROTOCOL * UDPv6;  ///<  UDP6 protocol pointer
    468   } pProtocol;                  ///<  Protocol structure address
    469   union {
    470     ESL_IP4_CONTEXT Ip4;        ///<  IPv4 management data
    471     ESL_TCP4_CONTEXT Tcp4;      ///<  TCPv4 management data
    472     ESL_TCP6_CONTEXT Tcp6;      ///<  TCPv6 management data
    473     ESL_UDP4_CONTEXT Udp4;      ///<  UDPv4 management data
    474     ESL_UDP6_CONTEXT Udp6;      ///<  UDPv6 management data
    475   } Context;                    ///<  Network specific context
    476 }GCC_ESL_PORT;
    477 
    478 /**
    479   Accept a network connection.
    480 
    481   @param [in] pSocket   Address of the socket structure.
    482 
    483   @param [in] pSockAddr       Address of a buffer to receive the remote
    484                               network address.
    485 
    486   @param [in, out] pSockAddrLength  Length in bytes of the address buffer.
    487                                     On output specifies the length of the
    488                                     remote network address.
    489 
    490   @retval EFI_SUCCESS   Remote address is available
    491   @retval Others        Remote address not available
    492 
    493  **/
    494 typedef
    495 EFI_STATUS
    496 (* PFN_API_ACCEPT) (
    497   IN ESL_SOCKET * pSocket,
    498   IN struct sockaddr * pSockAddr,
    499   IN OUT socklen_t * pSockAddrLength
    500   );
    501 
    502 /**
    503   Poll for completion of the connection attempt.
    504 
    505   @param [in] pSocket   Address of an ::ESL_SOCKET structure.
    506 
    507   @retval EFI_SUCCESS   The connection was successfully established.
    508   @retval EFI_NOT_READY The connection is in progress, call this routine again.
    509   @retval Others        The connection attempt failed.
    510 
    511  **/
    512 typedef
    513 EFI_STATUS
    514 (* PFN_API_CONNECT_POLL) (
    515   IN ESL_SOCKET * pSocket
    516   );
    517 
    518 /**
    519   Attempt to connect to a remote TCP port
    520 
    521   This routine starts the connection processing for a SOCK_STREAM
    522   or SOCK_SEQPAKCET socket using the TCP network layer.
    523 
    524   This routine is called by ::EslSocketConnect to initiate the TCP
    525   network specific connect operations.
    526 
    527   @param [in] pSocket   Address of an ::ESL_SOCKET structure.
    528 
    529   @retval EFI_SUCCESS   The connection was successfully established.
    530   @retval EFI_NOT_READY The connection is in progress, call this routine again.
    531   @retval Others        The connection attempt failed.
    532 
    533  **/
    534 typedef
    535 EFI_STATUS
    536 (* PFN_API_CONNECT_START) (
    537   IN ESL_SOCKET * pSocket
    538   );
    539 
    540 /**
    541   Get the local socket address
    542 
    543   @param [in] pPort       Address of an ::ESL_PORT structure.
    544 
    545   @param [out] pAddress   Network address to receive the local system address
    546 
    547 **/
    548 typedef
    549 VOID
    550 (* PFN_API_LOCAL_ADDR_GET) (
    551   IN ESL_PORT * pPort,
    552   OUT struct sockaddr * pAddress
    553   );
    554 
    555 /**
    556   Set the local port address.
    557 
    558   This routine sets the local port address.
    559 
    560   This support routine is called by ::EslSocketPortAllocate.
    561 
    562   @param [in] ppPort      Address of an ESL_PORT structure
    563   @param [in] pSockAddr   Address of a sockaddr structure that contains the
    564                           connection point on the local machine.  An IPv4 address
    565                           of INADDR_ANY specifies that the connection is made to
    566                           all of the network stacks on the platform.  Specifying a
    567                           specific IPv4 address restricts the connection to the
    568                           network stack supporting that address.  Specifying zero
    569                           for the port causes the network layer to assign a port
    570                           number from the dynamic range.  Specifying a specific
    571                           port number causes the network layer to use that port.
    572   @param [in] bBindTest   TRUE = run bind testing
    573 
    574   @retval EFI_SUCCESS     The operation was successful
    575 
    576  **/
    577 typedef
    578 EFI_STATUS
    579 (* PFN_API_LOCAL_ADDR_SET) (
    580   IN ESL_PORT * pPort,
    581   IN CONST struct sockaddr * pSockAddr,
    582   IN BOOLEAN bBindTest
    583   );
    584 
    585 /**
    586   Process the completion event
    587 
    588   This routine handles the I/O completion event.
    589 
    590   This routine is called by the low level network driver when
    591   the operation is completed.
    592 
    593   @param [in] Event     The receive completion event
    594 
    595   @param [in] pIo       The address of an ::ESL_IO_MGMT structure
    596 
    597 **/
    598 typedef
    599 VOID
    600 (* PFN_API_IO_COMPLETE) (
    601   IN EFI_EVENT Event,
    602   IN ESL_IO_MGMT * pIo
    603   );
    604 
    605 /**
    606   Determine if the socket is configured.
    607 
    608 
    609   @param [in] pSocket         Address of a ESL_SOCKET structure
    610 
    611   @retval EFI_SUCCESS - The port is connected
    612   @retval EFI_NOT_STARTED - The port is not connected
    613 
    614  **/
    615  typedef
    616  EFI_STATUS
    617  (* PFN_API_IS_CONFIGURED) (
    618   IN ESL_SOCKET * pSocket
    619   );
    620 
    621 /**
    622   Establish the known port to listen for network connections.
    623 
    624   @param [in] pSocket     Address of the socket structure.
    625 
    626   @retval EFI_SUCCESS - Socket successfully created
    627   @retval Other - Failed to enable the socket for listen
    628 
    629 **/
    630 typedef
    631 EFI_STATUS
    632 (* PFN_API_LISTEN) (
    633   IN ESL_SOCKET * pSocket
    634   );
    635 
    636 /**
    637   Get the option value
    638 
    639   Retrieve the protocol options one at a time by name.
    640 
    641   @param [in] pSocket           Address of a ESL_SOCKET structure
    642   @param [in] OptionName        Name of the option
    643   @param [out] ppOptionData     Buffer to receive address of option value
    644   @param [out] pOptionLength    Buffer to receive the option length
    645 
    646   @retval EFI_SUCCESS - Socket data successfully received
    647 
    648  **/
    649 typedef
    650 EFI_STATUS
    651 (* PFN_API_OPTION_GET) (
    652   IN ESL_SOCKET * pSocket,
    653   IN int OptionName,
    654   OUT CONST void ** __restrict ppOptionData,
    655   OUT socklen_t * __restrict pOptionLength
    656   );
    657 
    658 /**
    659   Set the option value
    660 
    661   Adjust the protocol options one at a time by name.
    662 
    663   @param [in] pSocket         Address of a ESL_SOCKET structure
    664   @param [in] OptionName      Name of the option
    665   @param [in] pOptionValue    Buffer containing the option value
    666   @param [in] OptionLength    Length of the buffer in bytes
    667 
    668   @retval EFI_SUCCESS - Option successfully set
    669 
    670  **/
    671 typedef
    672 EFI_STATUS
    673 (* PFN_API_OPTION_SET) (
    674   IN ESL_SOCKET * pSocket,
    675   IN int OptionName,
    676   IN CONST void * pOptionValue,
    677   IN socklen_t OptionLength
    678   );
    679 
    680 /**
    681   Free a receive packet
    682 
    683   This routine performs the network specific operations necessary
    684   to free a receive packet.
    685 
    686   This routine is called by ::EslSocketPortCloseTxDone to free a
    687   receive packet.
    688 
    689   @param [in] pPacket         Address of an ::ESL_PACKET structure.
    690   @param [in, out] pRxBytes   Address of the count of RX bytes
    691 
    692 **/
    693 typedef
    694 VOID
    695 (* PFN_API_PACKET_FREE) (
    696   IN ESL_PACKET * pPacket,
    697   IN OUT size_t * pRxBytes
    698   );
    699 
    700 /**
    701   Initialize the network specific portions of an ::ESL_PORT structure.
    702 
    703   This routine initializes the network specific portions of an
    704   ::ESL_PORT structure for use by the socket.
    705 
    706   This support routine is called by ::EslSocketPortAllocate
    707   to connect the socket with the underlying network adapter
    708   running the IPv4 protocol.
    709 
    710   @param [in] ppPort      Address of an ESL_PORT structure
    711   @param [in] DebugFlags  Flags for debug messages
    712 
    713   @retval EFI_SUCCESS - Socket successfully created
    714 
    715  **/
    716 typedef
    717 EFI_STATUS
    718 (* PFN_API_PORT_ALLOC) (
    719   IN ESL_PORT * pPort,
    720   IN UINTN DebugFlags
    721   );
    722 
    723 /**
    724   Close a network specific port.
    725 
    726   This routine releases the resources allocated by the
    727   network specific PortAllocate routine.
    728 
    729   This routine is called by ::EslSocketPortCloseRxDone as
    730   the last step of closing processing.
    731   See the \ref PortCloseStateMachine section.
    732 
    733   @param [in] pPort       Address of an ::ESL_PORT structure.
    734 
    735   @retval EFI_SUCCESS     The port is closed
    736   @retval other           Port close error
    737 
    738 **/
    739 typedef
    740 EFI_STATUS
    741 (* PFN_API_PORT_CLOSE) (
    742   IN ESL_PORT * pPort
    743   );
    744 
    745 /**
    746   Perform the network specific close operation on the port.
    747 
    748   This routine performs the network specific operation to
    749   shutdown receive operations on the port.
    750 
    751   This routine is called by the ::EslSocketPortCloseTxDone
    752   routine after the port completes all of the transmission.
    753 
    754   @param [in] pPort           Address of an ::ESL_PORT structure.
    755 
    756   @retval EFI_SUCCESS         The port is closed, not normally returned
    757   @retval EFI_NOT_READY       The port is still closing
    758   @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,
    759                               most likely the routine was called already.
    760 
    761 **/
    762 typedef
    763 EFI_STATUS
    764 (* PFN_API_PORT_CLOSE_OP) (
    765   IN ESL_PORT * pPort
    766   );
    767 
    768 /**
    769   Receive data from a network connection.
    770 
    771   This routine attempts to return buffered data to the caller.  The
    772   data is removed from the urgent queue if the message flag MSG_OOB
    773   is specified, otherwise data is removed from the normal queue.
    774   See the \ref ReceiveEngine section.
    775 
    776   This routine is called by ::EslSocketReceive to handle the network
    777   specific receive operation.
    778 
    779   @param [in] pPort           Address of an ::ESL_PORT structure.
    780 
    781   @param [in] pPacket         Address of an ::ESL_PACKET structure.
    782 
    783   @param [in] pbConsumePacket Address of a BOOLEAN indicating if the packet is to be consumed
    784 
    785   @param [in] BufferLength    Length of the the buffer
    786 
    787   @param [in] pBuffer         Address of a buffer to receive the data.
    788 
    789   @param [in] pDataLength     Number of received data bytes in the buffer.
    790 
    791   @param [out] pAddress       Network address to receive the remote system address
    792 
    793   @param [out] pSkipBytes     Address to receive the number of bytes skipped
    794 
    795   @return   Returns the address of the next free byte in the buffer.
    796 
    797  **/
    798 typedef
    799 UINT8 *
    800 (* PFN_API_RECEIVE) (
    801   IN ESL_PORT * pPort,
    802   IN ESL_PACKET * pPacket,
    803   IN BOOLEAN * pbConsumePacket,
    804   IN size_t BufferLength,
    805   IN UINT8 * pBuffer,
    806   OUT size_t * pDataLength,
    807   OUT struct sockaddr * pAddress,
    808   OUT size_t * pSkipBytes
    809   );
    810 
    811 /**
    812   Get the remote socket address
    813 
    814   @param [in] pPort       Address of an ::ESL_PORT structure.
    815 
    816   @param [out] pAddress   Network address to receive the remote system address
    817 
    818 **/
    819 typedef
    820 VOID
    821 (* PFN_API_REMOTE_ADDR_GET) (
    822   IN ESL_PORT * pPort,
    823   OUT struct sockaddr * pAddress
    824   );
    825 
    826 /**
    827   Set the remote address
    828 
    829   This routine sets the remote address in the port.
    830 
    831   This routine is called by ::EslSocketConnect to specify the
    832   remote network address.
    833 
    834   @param [in] pPort           Address of an ::ESL_PORT structure.
    835 
    836   @param [in] pSockAddr       Network address of the remote system.
    837 
    838   @param [in] SockAddrLength  Length in bytes of the network address.
    839 
    840   @retval EFI_SUCCESS     The operation was successful
    841 
    842  **/
    843 typedef
    844 EFI_STATUS
    845 (* PFN_API_REMOTE_ADDR_SET) (
    846   IN ESL_PORT * pPort,
    847   IN CONST struct sockaddr * pSockAddr,
    848   IN socklen_t SockAddrLength
    849   );
    850 
    851 /**
    852   Start a receive operation
    853 
    854   This routine prepares a packet for the receive operation.
    855   See the \ref ReceiveEngine section.
    856 
    857   This support routine is called by EslSocketRxStart.
    858 
    859   @param [in] pPort       Address of an ::ESL_PORT structure.
    860   @param [in] pIo         Address of an ::ESL_IO_MGMT structure.
    861 
    862  **/
    863 typedef
    864 VOID
    865 (* PFN_API_RX_START) (
    866   IN ESL_PORT * pPort,
    867   IN ESL_IO_MGMT * pIo
    868   );
    869 
    870 /**
    871   Buffer data for transmission over a network connection.
    872 
    873   @param [in] pSocket         Address of a ESL_SOCKET structure
    874 
    875   @param [in] Flags           Message control flags
    876 
    877   @param [in] BufferLength    Length of the the buffer
    878 
    879   @param [in] pBuffer         Address of a buffer to receive the data.
    880 
    881   @param [in] pDataLength     Number of received data bytes in the buffer.
    882 
    883   @param [in] pAddress        Network address of the remote system address
    884 
    885   @param [in] AddressLength   Length of the remote network address structure
    886 
    887   @retval EFI_SUCCESS - Socket data successfully buffered
    888 
    889 **/
    890 typedef
    891 EFI_STATUS
    892 (* PFN_API_TRANSMIT) (
    893   IN ESL_SOCKET * pSocket,
    894   IN int Flags,
    895   IN size_t BufferLength,
    896   IN CONST UINT8 * pBuffer,
    897   OUT size_t * pDataLength,
    898   IN const struct sockaddr * pAddress,
    899   IN socklen_t AddressLength
    900   );
    901 
    902 /**
    903   Process the transmit completion
    904 
    905   This routine calls ::EslSocketTxComplete to handle the
    906   transmit completion.
    907 
    908   This routine is called by the network layers upon the completion
    909   of a transmit operation.
    910 
    911   @param [in] Event     The urgent transmit completion event
    912 
    913   @param [in] pIo       The ESL_IO_MGMT structure address
    914 
    915 **/
    916 typedef
    917 VOID
    918 (* PFN_API_TX_COMPLETE) (
    919   IN EFI_EVENT Event,
    920   IN ESL_IO_MGMT * pIo
    921   );
    922 
    923 /**
    924   Verify the adapter's IP address
    925 
    926   This support routine is called by EslSocketBindTest.
    927 
    928   @param [in] pPort       Address of an ::ESL_PORT structure.
    929   @param [in] pConfigData Address of the configuration data
    930 
    931   @retval EFI_SUCCESS - The IP address is valid
    932   @retval EFI_NOT_STARTED - The IP address is invalid
    933 
    934  **/
    935 typedef
    936 EFI_STATUS
    937 (* PFN_API_VERIFY_LOCAL_IP_ADDRESS) (
    938   IN ESL_PORT * pPort,
    939   IN VOID * pConfigData
    940   );
    941 
    942 /**
    943   Socket type control structure
    944 
    945   This driver uses this structure to define the API for the socket type.
    946 **/
    947 typedef struct {
    948   CONST CHAR8 * pName;                      ///<  Protocol name
    949   int DefaultProtocol;                      ///<  Default protocol
    950   UINTN ConfigDataOffset;                   ///<  Offset in ::ESL_PORT to the configuration data
    951   UINTN ServiceListOffset;                  ///<  Offset in ::ESL_LAYER for the list of services
    952   socklen_t MinimumAddressLength;           ///<  Minimum address length in bytes
    953   socklen_t AddressLength;                  ///<  Address length in bytes
    954   sa_family_t AddressFamily;                ///<  Address family
    955   UINTN RxPacketBytes;                      ///<  Length of the RX packet allocation
    956   UINTN RxZeroBytes;                        ///<  Number of bytes to zero in RX packet
    957   UINTN RxBufferOffset;                     ///<  Offset of buffer address in ESL_IO_MGMT structure
    958   BOOLEAN bOobSupported;                    ///<  TRUE if out-of-band messages are supported
    959   int BindTestErrno;                        ///<  errno value if EslSocketBindTest fails
    960   PFN_API_ACCEPT pfnAccept;                 ///<  Accept a network connection
    961   PFN_API_CONNECT_POLL pfnConnectPoll;      ///<  Poll for connection complete
    962   PFN_API_CONNECT_START pfnConnectStart;    ///<  Start the connection to a remote system
    963   PFN_API_IS_CONFIGURED pfnIsConfigured;    ///<  Determine if the socket is configured
    964   PFN_API_LOCAL_ADDR_GET pfnLocalAddrGet;   ///<  Get the local address
    965   PFN_API_LOCAL_ADDR_SET pfnLocalAddrSet;   ///<  Set the local address
    966   PFN_API_LISTEN pfnListen;                 ///<  Listen for connections on known server port
    967   PFN_API_OPTION_GET pfnOptionGet;          ///<  Get the option value
    968   PFN_API_OPTION_SET pfnOptionSet;          ///<  Set the option value
    969   PFN_API_PACKET_FREE pfnPacketFree;        ///<  Free the receive packet
    970   PFN_API_PORT_ALLOC pfnPortAllocate;       ///<  Allocate the network specific resources for the port
    971   PFN_API_PORT_CLOSE pfnPortClose;          ///<  Close the network specific resources for the port
    972   PFN_API_PORT_CLOSE_OP pfnPortCloseOp;     ///<  Perform the close operation on the port
    973   BOOLEAN bPortCloseComplete;               ///<  TRUE = Close is complete after close operation
    974   PFN_API_RECEIVE pfnReceive;               ///<  Attempt to receive some data
    975   PFN_API_REMOTE_ADDR_GET pfnRemoteAddrGet; ///<  Get remote address
    976   PFN_API_REMOTE_ADDR_SET pfnRemoteAddrSet; ///<  Set the remote system address
    977   PFN_API_IO_COMPLETE pfnRxComplete;        ///<  RX completion
    978   PFN_API_RX_START pfnRxStart;              ///<  Start a network specific receive operation
    979   PFN_API_TRANSMIT pfnTransmit;             ///<  Attempt to buffer a packet for transmit
    980   PFN_API_TX_COMPLETE pfnTxComplete;        ///<  TX completion for normal data
    981   PFN_API_TX_COMPLETE pfnTxOobComplete;     ///<  TX completion for urgent data
    982   PFN_API_VERIFY_LOCAL_IP_ADDRESS pfnVerifyLocalIpAddress;  ///< Verify the local IP address
    983 } ESL_PROTOCOL_API;
    984 
    985 
    986 /**
    987   Socket control structure
    988 
    989   The driver uses this structure to manage the socket.
    990 **/
    991 typedef struct _ESL_SOCKET {
    992   UINTN Signature;          ///<  Structure identification
    993 
    994   //
    995   //  Protocol binding
    996   //
    997   EFI_SOCKET_PROTOCOL SocketProtocol; ///<  Socket protocol declaration
    998   CONST ESL_PROTOCOL_API * pApi;      ///<  API for the protocol
    999 
   1000   //
   1001   //  Socket management
   1002   //
   1003   ESL_SOCKET * pNext;           ///<  Next socket in the list of sockets
   1004   int errno;                    ///<  Error information for this socket
   1005   EFI_STATUS Status;            ///<  Asyncronous error information for this socket
   1006   SOCKET_STATE State;           ///<  Socket state
   1007   UINT32 DebugFlags;            ///<  Debug flags
   1008 
   1009   //
   1010   //  Socket options
   1011   //
   1012   BOOLEAN bIncludeHeader;       ///<  TRUE if including the IP header
   1013   BOOLEAN bListenCalled;        ///<  TRUE if listen was successfully called
   1014   BOOLEAN bOobInLine;           ///<  TRUE if out-of-band messages are to be received inline with normal data
   1015   BOOLEAN bReUseAddr;           ///<  TRUE if using same address is allowed
   1016 
   1017   //
   1018   //  Socket data
   1019   //
   1020   int Domain;                   ///<  Specifies family of protocols
   1021   int Type;                     ///<  Specifies how to make network connection
   1022   int Protocol;                 ///<  Specifies lower layer protocol to use
   1023   BOOLEAN bAddressSet;          ///<  Set when the address is specified
   1024   BOOLEAN bConfigured;          ///<  Set after the socket is configured
   1025 
   1026   BOOLEAN bRxDisable;           ///<  Receive disabled via shutdown
   1027   size_t RxBytes;               ///<  Total Rx bytes
   1028   size_t RxOobBytes;            ///<  Urgent Rx bytes
   1029   EFI_STATUS RxError;           ///<  Error during receive
   1030 
   1031   BOOLEAN bTxDisable;           ///<  Transmit disabled via shutdown
   1032   size_t TxBytes;               ///<  Normal Tx bytes
   1033   size_t TxOobBytes;            ///<  Urgent Tx bytes
   1034   EFI_STATUS TxError;           ///<  Error during transmit
   1035 
   1036   //
   1037   //  Pending connection data
   1038   //
   1039   BOOLEAN bConnected;           ///<  Set when connected, cleared by poll
   1040   EFI_STATUS ConnectStatus;     ///<  Connection status
   1041   UINTN MaxFifoDepth;           ///<  Maximum FIFO depth
   1042   UINTN FifoDepth;              ///<  Number of sockets in the FIFO
   1043   ESL_SOCKET * pFifoHead;       ///<  Head of the FIFO
   1044   ESL_SOCKET * pFifoTail;       ///<  Tail of the FIFO
   1045   ESL_SOCKET * pNextConnection; ///<  Link in the FIFO
   1046 
   1047   //
   1048   //  Network use
   1049   //
   1050   ESL_PORT * pPortList;         ///<  List of ports managed by this socket
   1051   EFI_EVENT WaitAccept;         ///<  Wait for accept completion
   1052 
   1053   //
   1054   //  Receive data management
   1055   //
   1056   UINT32 MaxRxBuf;                  ///<  Maximum size of the receive buffer
   1057   struct timeval RxTimeout;         ///<  Receive timeout
   1058   ESL_PACKET * pRxFree;             ///<  Free packet list
   1059   ESL_PACKET * pRxOobPacketListHead;///<  Urgent data list head
   1060   ESL_PACKET * pRxOobPacketListTail;///<  Urgent data list tail
   1061   ESL_PACKET * pRxPacketListHead;   ///<  Normal data list head
   1062   ESL_PACKET * pRxPacketListTail;   ///<  Normal data list tail
   1063 
   1064   //
   1065   //  Transmit data management
   1066   //
   1067   UINTN TxPacketOffset;             ///<  Offset for data pointer in ::ESL_PACKET
   1068   UINTN TxTokenEventOffset;         ///<  Offset to the Event in the TX token
   1069   UINTN TxTokenOffset;              ///<  Offset for data pointer in TX token
   1070   UINT32 MaxTxBuf;                  ///<  Maximum size of the transmit buffer
   1071   ESL_PACKET * pTxOobPacketListHead;///<  Urgent data list head
   1072   ESL_PACKET * pTxOobPacketListTail;///<  Urgent data list tail
   1073   ESL_PACKET * pTxPacketListHead;   ///<  Normal data list head
   1074   ESL_PACKET * pTxPacketListTail;   ///<  Normal data list tail
   1075 }GCC_ESL_SOCKET;
   1076 
   1077 #define SOCKET_FROM_PROTOCOL(a)  CR (a, ESL_SOCKET, SocketProtocol, SOCKET_SIGNATURE)  ///< Locate ESL_SOCKET from protocol
   1078 
   1079 /**
   1080   Socket layer control structure
   1081 
   1082   The driver uses this structure to manage the driver.
   1083 **/
   1084 typedef struct {
   1085   UINTN Signature;              ///<  Structure identification
   1086 
   1087   //
   1088   //  Service binding interface
   1089   //
   1090   CONST EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding; ///<  Driver's binding
   1091 
   1092   //
   1093   //  Image data
   1094   //
   1095   EFI_HANDLE ImageHandle;       ///<  Image handle
   1096 
   1097   //
   1098   //  Network services
   1099   //
   1100   ESL_SERVICE * pIp4List;       ///<  List of Ip4 services
   1101   ESL_SERVICE * pTcp4List;      ///<  List of Tcp4 services
   1102   ESL_SERVICE * pTcp6List;      ///<  List of Tcp6 services
   1103   ESL_SERVICE * pUdp4List;      ///<  List of Udp4 services
   1104   ESL_SERVICE * pUdp6List;      ///<  List of Udp6 services
   1105 
   1106   //
   1107   //  Socket management
   1108   //
   1109   ESL_SOCKET * pSocketList;     ///<  List of sockets
   1110 } ESL_LAYER;
   1111 
   1112 #define LAYER_FROM_SERVICE(a) CR (a, ESL_LAYER, ServiceBinding, LAYER_SIGNATURE) ///< Locate ESL_LAYER from service binding
   1113 
   1114 //------------------------------------------------------------------------------
   1115 // Data
   1116 //------------------------------------------------------------------------------
   1117 
   1118 extern ESL_LAYER mEslLayer;
   1119 
   1120 extern CONST ESL_PROTOCOL_API cEslIp4Api;
   1121 extern CONST ESL_PROTOCOL_API cEslIp6Api;
   1122 extern CONST ESL_PROTOCOL_API cEslTcp4Api;
   1123 extern CONST ESL_PROTOCOL_API cEslTcp6Api;
   1124 extern CONST ESL_PROTOCOL_API cEslUdp4Api;
   1125 extern CONST ESL_PROTOCOL_API cEslUdp6Api;
   1126 
   1127 extern CONST EFI_SERVICE_BINDING_PROTOCOL mEfiServiceBinding;
   1128 
   1129 //------------------------------------------------------------------------------
   1130 // Socket Support Routines
   1131 //------------------------------------------------------------------------------
   1132 
   1133 /**
   1134   Allocate and initialize a ESL_SOCKET structure.
   1135 
   1136   This support function allocates an ::ESL_SOCKET structure
   1137   and installs a protocol on ChildHandle.  If pChildHandle is a
   1138   pointer to NULL, then a new handle is created and returned in
   1139   pChildHandle.  If pChildHandle is not a pointer to NULL, then
   1140   the protocol installs on the existing pChildHandle.
   1141 
   1142   @param [in, out] pChildHandle Pointer to the handle of the child to create.
   1143                                 If it is NULL, then a new handle is created.
   1144                                 If it is a pointer to an existing UEFI handle,
   1145                                 then the protocol is added to the existing UEFI
   1146                                 handle.
   1147   @param [in] DebugFlags        Flags for debug messages
   1148   @param [in, out] ppSocket     The buffer to receive an ::ESL_SOCKET structure address.
   1149 
   1150   @retval EFI_SUCCESS           The protocol was added to ChildHandle.
   1151   @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
   1152   @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to create
   1153                                 the child
   1154   @retval other                 The child handle was not created
   1155 
   1156 **/
   1157 EFI_STATUS
   1158 EFIAPI
   1159 EslSocketAllocate (
   1160   IN OUT EFI_HANDLE * pChildHandle,
   1161   IN     UINTN DebugFlags,
   1162   IN OUT ESL_SOCKET ** ppSocket
   1163   );
   1164 
   1165 /**
   1166   Test the bind configuration.
   1167 
   1168   @param [in] pPort       Address of the ::ESL_PORT structure.
   1169   @param [in] ErrnoValue  errno value if test fails
   1170 
   1171   @retval EFI_SUCCESS   The connection was successfully established.
   1172   @retval Others        The connection attempt failed.
   1173 
   1174  **/
   1175 EFI_STATUS
   1176 EslSocketBindTest (
   1177   IN ESL_PORT * pPort,
   1178   IN int ErrnoValue
   1179   );
   1180 
   1181 /**
   1182   Copy a fragmented buffer into a destination buffer.
   1183 
   1184   This support routine copies a fragmented buffer to the caller specified buffer.
   1185 
   1186   This routine is called by ::EslIp4Receive and ::EslUdp4Receive.
   1187 
   1188   @param [in] FragmentCount   Number of fragments in the table
   1189 
   1190   @param [in] pFragmentTable  Address of an EFI_IP4_FRAGMENT_DATA structure
   1191 
   1192   @param [in] BufferLength    Length of the the buffer
   1193 
   1194   @param [in] pBuffer         Address of a buffer to receive the data.
   1195 
   1196   @param [in] pDataLength     Number of received data bytes in the buffer.
   1197 
   1198   @return   Returns the address of the next free byte in the buffer.
   1199 
   1200 **/
   1201 UINT8 *
   1202 EslSocketCopyFragmentedBuffer (
   1203   IN UINT32 FragmentCount,
   1204   IN EFI_IP4_FRAGMENT_DATA * pFragmentTable,
   1205   IN size_t BufferLength,
   1206   IN UINT8 * pBuffer,
   1207   OUT size_t * pDataLength
   1208   );
   1209 
   1210 /**
   1211   Free the socket.
   1212 
   1213   This routine frees the socket structure and handle resources.
   1214 
   1215   The ::close routine calls EslServiceFreeProtocol which then calls
   1216   this routine to free the socket context structure and close the
   1217   handle.
   1218 
   1219   @param [in] pSocketProtocol Address of an ::EFI_SOCKET_PROTOCOL structure.
   1220 
   1221   @param [out] pErrno         Address to receive the errno value upon completion.
   1222 
   1223   @retval EFI_SUCCESS   The socket resources were returned successfully.
   1224 
   1225  **/
   1226 EFI_STATUS
   1227 EslSocketFree (
   1228   IN EFI_SOCKET_PROTOCOL * pSocketProtocol,
   1229   IN int * pErrno
   1230   );
   1231 
   1232 /**
   1233   Free the ESL_IO_MGMT event and structure
   1234 
   1235   This support routine walks the free list to close the event in
   1236   the ESL_IO_MGMT structure and remove the structure from the free
   1237   list.
   1238 
   1239   See the \ref TransmitEngine section.
   1240 
   1241   @param [in] pPort         Address of an ::ESL_PORT structure
   1242   @param [in] ppFreeQueue   Address of the free queue head
   1243   @param [in] DebugFlags    Flags for debug messages
   1244   @param [in] pEventName    Zero terminated string containing the event name
   1245 
   1246   @retval EFI_SUCCESS - The structures were properly initialized
   1247 
   1248 **/
   1249 EFI_STATUS
   1250 EslSocketIoFree (
   1251   IN ESL_PORT * pPort,
   1252   IN ESL_IO_MGMT ** ppFreeQueue,
   1253   IN UINTN DebugFlags,
   1254   IN CHAR8 * pEventName
   1255   );
   1256 
   1257 /**
   1258   Initialize the ESL_IO_MGMT structures
   1259 
   1260   This support routine initializes the ESL_IO_MGMT structure and
   1261   places them on to a free list.
   1262 
   1263   This routine is called by the PortAllocate routines to prepare
   1264   the transmit engines.  See the \ref TransmitEngine section.
   1265 
   1266   @param [in] pPort         Address of an ::ESL_PORT structure
   1267   @param [in, out] ppIo     Address containing the first structure address.  Upon
   1268                             return this buffer contains the next structure address.
   1269   @param [in] TokenCount    Number of structures to initialize
   1270   @param [in] ppFreeQueue   Address of the free queue head
   1271   @param [in] DebugFlags    Flags for debug messages
   1272   @param [in] pEventName    Zero terminated string containing the event name
   1273   @param [in] pfnCompletion Completion routine address
   1274 
   1275   @retval EFI_SUCCESS - The structures were properly initialized
   1276 
   1277 **/
   1278 EFI_STATUS
   1279 EslSocketIoInit (
   1280   IN ESL_PORT * pPort,
   1281   IN ESL_IO_MGMT ** ppIo,
   1282   IN UINTN TokenCount,
   1283   IN ESL_IO_MGMT ** ppFreeQueue,
   1284   IN UINTN DebugFlags,
   1285   IN CHAR8 * pEventName,
   1286   IN PFN_API_IO_COMPLETE pfnCompletion
   1287   );
   1288 
   1289 /**
   1290   Determine if the socket is configured
   1291 
   1292   This support routine is called to determine if the socket if the
   1293   configuration call was made to the network layer.  The following
   1294   routines call this routine to verify that they may be successful
   1295   in their operations:
   1296   <ul>
   1297     <li>::EslSocketGetLocalAddress</li>
   1298     <li>::EslSocketGetPeerAddress</li>
   1299     <li>::EslSocketPoll</li>
   1300     <li>::EslSocketReceive</li>
   1301     <li>::EslSocketTransmit</li>
   1302   </ul>
   1303 
   1304   @param [in] pSocket       Address of an ::ESL_SOCKET structure
   1305 
   1306   @retval EFI_SUCCESS - The socket is configured
   1307 
   1308 **/
   1309 EFI_STATUS
   1310 EslSocketIsConfigured (
   1311   IN ESL_SOCKET * pSocket
   1312   );
   1313 
   1314 /**
   1315   Allocate a packet for a receive or transmit operation
   1316 
   1317   This support routine is called by ::EslSocketRxStart and the
   1318   network specific TxBuffer routines to get buffer space for the
   1319   next operation.
   1320 
   1321   @param [in] ppPacket      Address to receive the ::ESL_PACKET structure
   1322   @param [in] LengthInBytes Length of the packet structure
   1323   @param [in] ZeroBytes     Length of packet to zero
   1324   @param [in] DebugFlags    Flags for debug messages
   1325 
   1326   @retval EFI_SUCCESS - The packet was allocated successfully
   1327 
   1328  **/
   1329 EFI_STATUS
   1330 EslSocketPacketAllocate (
   1331   IN ESL_PACKET ** ppPacket,
   1332   IN size_t LengthInBytes,
   1333   IN size_t ZeroBytes,
   1334   IN UINTN DebugFlags
   1335   );
   1336 
   1337 /**
   1338   Free a packet used for receive or transmit operation
   1339 
   1340   This support routine is called by the network specific Close
   1341   and TxComplete routines and during error cases in RxComplete
   1342   and TxBuffer.  Note that the network layers typically place
   1343   receive packets on the ESL_SOCKET::pRxFree list for reuse.
   1344 
   1345   @param [in] pPacket     Address of an ::ESL_PACKET structure
   1346   @param [in] DebugFlags  Flags for debug messages
   1347 
   1348   @retval EFI_SUCCESS - The packet was allocated successfully
   1349 
   1350  **/
   1351 EFI_STATUS
   1352 EslSocketPacketFree (
   1353   IN ESL_PACKET * pPacket,
   1354   IN UINTN DebugFlags
   1355   );
   1356 
   1357 /**
   1358   Allocate and initialize a ESL_PORT structure.
   1359 
   1360   This routine initializes an ::ESL_PORT structure for use by
   1361   the socket.  This routine calls a routine via
   1362   ESL_PROTOCOL_API::pfnPortAllocate to initialize the network
   1363   specific resources.  The resources are released later by the
   1364   \ref PortCloseStateMachine.
   1365 
   1366   This support routine is called by ::EslSocketBind and
   1367   ::EslTcp4ListenComplete to connect the socket with the
   1368   underlying network adapter to the socket.
   1369 
   1370   @param [in] pSocket     Address of an ::ESL_SOCKET structure.
   1371   @param [in] pService    Address of an ::ESL_SERVICE structure.
   1372   @param [in] ChildHandle TCP4 child handle
   1373   @param [in] pSockAddr   Address of a sockaddr structure that contains the
   1374                           connection point on the local machine.  An IPv4 address
   1375                           of INADDR_ANY specifies that the connection is made to
   1376                           all of the network stacks on the platform.  Specifying a
   1377                           specific IPv4 address restricts the connection to the
   1378                           network stack supporting that address.  Specifying zero
   1379                           for the port causes the network layer to assign a port
   1380                           number from the dynamic range.  Specifying a specific
   1381                           port number causes the network layer to use that port.
   1382   @param [in] bBindTest   TRUE if EslSocketBindTest should be called
   1383   @param [in] DebugFlags  Flags for debug messages
   1384   @param [out] ppPort     Buffer to receive new ::ESL_PORT structure address
   1385 
   1386   @retval EFI_SUCCESS - Socket successfully created
   1387 
   1388  **/
   1389 EFI_STATUS
   1390 EslSocketPortAllocate (
   1391   IN ESL_SOCKET * pSocket,
   1392   IN ESL_SERVICE * pService,
   1393   IN EFI_HANDLE ChildHandle,
   1394   IN CONST struct sockaddr * pSockAddr,
   1395   IN BOOLEAN bBindTest,
   1396   IN UINTN DebugFlags,
   1397   OUT ESL_PORT ** ppPort
   1398   );
   1399 
   1400 /**
   1401   Close a port.
   1402 
   1403   This routine releases the resources allocated by ::EslSocketPortAllocate.
   1404   This routine calls ESL_PROTOCOL_API::pfnPortClose to release the network
   1405   specific resources.
   1406 
   1407   This routine is called by:
   1408   <ul>
   1409     <li>::EslIp4PortAllocate - Port initialization failure</li>
   1410     <li>::EslSocketPortCloseRxDone - Last step of close processing</li>
   1411     <li>::EslTcp4ConnectComplete - Connection failure and reducint the port list to a single port</li>
   1412     <li>::EslTcp4PortAllocate - Port initialization failure</li>
   1413     <li>::EslUdp4PortAllocate - Port initialization failure</li>
   1414   </ul>
   1415   See the \ref PortCloseStateMachine section.
   1416 
   1417   @param [in] pPort       Address of an ::ESL_PORT structure.
   1418 
   1419   @retval EFI_SUCCESS     The port is closed
   1420   @retval other           Port close error
   1421 
   1422 **/
   1423 EFI_STATUS
   1424 EslSocketPortClose (
   1425   IN ESL_PORT * pPort
   1426   );
   1427 
   1428 /**
   1429   Process the port close completion event
   1430 
   1431   This routine attempts to complete the port close operation.
   1432 
   1433   This routine is called by the TCP layer upon completion of
   1434   the close operation.
   1435   See the \ref PortCloseStateMachine section.
   1436 
   1437   @param [in] Event     The close completion event
   1438 
   1439   @param [in] pPort     Address of an ::ESL_PORT structure.
   1440 
   1441 **/
   1442 VOID
   1443 EslSocketPortCloseComplete (
   1444   IN EFI_EVENT Event,
   1445   IN ESL_PORT * pPort
   1446   );
   1447 
   1448 /**
   1449   Port close state 3
   1450 
   1451   This routine determines the state of the receive operations and
   1452   continues the close operation after the pending receive operations
   1453   are cancelled.
   1454 
   1455   This routine is called by
   1456   <ul>
   1457     <li>::EslIp4RxComplete</li>
   1458     <li>::EslSocketPortCloseComplete</li>
   1459     <li>::EslSocketPortCloseTxDone</li>
   1460     <li>::EslUdp4RxComplete</li>
   1461   </ul>
   1462   to determine the state of the receive operations.
   1463   See the \ref PortCloseStateMachine section.
   1464 
   1465   @param [in] pPort       Address of an ::ESL_PORT structure.
   1466 
   1467   @retval EFI_SUCCESS         The port is closed
   1468   @retval EFI_NOT_READY       The port is still closing
   1469   @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,
   1470                               most likely the routine was called already.
   1471 
   1472 **/
   1473 EFI_STATUS
   1474 EslSocketPortCloseRxDone (
   1475   IN ESL_PORT * pPort
   1476   );
   1477 
   1478 /**
   1479   Start the close operation on a port, state 1.
   1480 
   1481   This routine marks the port as closed and initiates the \ref
   1482   PortCloseStateMachine. The first step is to allow the \ref
   1483   TransmitEngine to run down.
   1484 
   1485   This routine is called by ::EslSocketCloseStart to initiate the socket
   1486   network specific close operation on the socket.
   1487 
   1488   @param [in] pPort       Address of an ::ESL_PORT structure.
   1489   @param [in] bCloseNow   Set TRUE to abort active transfers
   1490   @param [in] DebugFlags  Flags for debug messages
   1491 
   1492   @retval EFI_SUCCESS         The port is closed, not normally returned
   1493   @retval EFI_NOT_READY       The port has started the closing process
   1494   @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,
   1495                               most likely the routine was called already.
   1496 
   1497 **/
   1498 EFI_STATUS
   1499 EslSocketPortCloseStart (
   1500   IN ESL_PORT * pPort,
   1501   IN BOOLEAN bCloseNow,
   1502   IN UINTN DebugFlags
   1503   );
   1504 
   1505 /**
   1506   Port close state 2
   1507 
   1508   This routine determines the state of the transmit engine and
   1509   continue the close operation after the transmission is complete.
   1510   The next step is to stop the \ref ReceiveEngine.
   1511   See the \ref PortCloseStateMachine section.
   1512 
   1513   This routine is called by ::EslSocketPortCloseStart to determine
   1514   if the transmission is complete.
   1515 
   1516   @param [in] pPort           Address of an ::ESL_PORT structure.
   1517 
   1518   @retval EFI_SUCCESS         The port is closed, not normally returned
   1519   @retval EFI_NOT_READY       The port is still closing
   1520   @retval EFI_ALREADY_STARTED Error, the port is in the wrong state,
   1521                               most likely the routine was called already.
   1522 
   1523 **/
   1524 EFI_STATUS
   1525 EslSocketPortCloseTxDone (
   1526   IN ESL_PORT * pPort
   1527   );
   1528 
   1529 /**
   1530   Cancel the receive operations
   1531 
   1532   This routine cancels a pending receive operation.
   1533   See the \ref ReceiveEngine section.
   1534 
   1535   This routine is called by ::EslSocketShutdown when the socket
   1536   layer is being shutdown.
   1537 
   1538   @param [in] pPort     Address of an ::ESL_PORT structure
   1539   @param [in] pIo       Address of an ::ESL_IO_MGMT structure
   1540 
   1541  **/
   1542 VOID
   1543 EslSocketRxCancel (
   1544   IN ESL_PORT * pPort,
   1545   IN ESL_IO_MGMT * pIo
   1546   );
   1547 
   1548 /**
   1549   Process the receive completion
   1550 
   1551   This routine queues the data in FIFO order in either the urgent
   1552   or normal data queues depending upon the type of data received.
   1553   See the \ref ReceiveEngine section.
   1554 
   1555   This routine is called when some data is received by:
   1556   <ul>
   1557     <li>::EslIp4RxComplete</li>
   1558     <li>::EslTcp4RxComplete</li>
   1559     <li>::EslUdp4RxComplete</li>
   1560   </ul>
   1561 
   1562   @param [in] pIo           Address of an ::ESL_IO_MGMT structure
   1563   @param [in] Status        Receive status
   1564   @param [in] LengthInBytes Length of the receive data
   1565   @param [in] bUrgent       TRUE if urgent data is received and FALSE
   1566                             for normal data.
   1567 
   1568 **/
   1569 VOID
   1570 EslSocketRxComplete (
   1571   IN ESL_IO_MGMT * pIo,
   1572   IN EFI_STATUS Status,
   1573   IN UINTN LengthInBytes,
   1574   IN BOOLEAN bUrgent
   1575   );
   1576 
   1577 /**
   1578   Poll a socket for pending receive activity.
   1579 
   1580   This routine is called at elivated TPL and extends the idle
   1581   loop which polls a socket down into the LAN driver layer to
   1582   determine if there is any receive activity.
   1583 
   1584   The ::EslSocketPoll, ::EslSocketReceive and ::EslSocketTransmit
   1585   routines call this routine when there is nothing to do.
   1586 
   1587   @param [in] pSocket   Address of an ::EFI_SOCKET structure.
   1588 
   1589  **/
   1590 VOID
   1591 EslSocketRxPoll (
   1592   IN ESL_SOCKET * pSocket
   1593   );
   1594 
   1595 /**
   1596   Start a receive operation
   1597 
   1598   This routine posts a receive buffer to the network adapter.
   1599   See the \ref ReceiveEngine section.
   1600 
   1601   This support routine is called by:
   1602   <ul>
   1603     <li>::EslIp4Receive to restart the receive engine to release flow control.</li>
   1604     <li>::EslIp4RxComplete to continue the operation of the receive engine if flow control is not being applied.</li>
   1605     <li>::EslIp4SocketIsConfigured to start the recevie engine for the new socket.</li>
   1606     <li>::EslTcp4ListenComplete to start the recevie engine for the new socket.</li>
   1607     <li>::EslTcp4Receive to restart the receive engine to release flow control.</li>
   1608     <li>::EslTcp4RxComplete to continue the operation of the receive engine if flow control is not being applied.</li>
   1609     <li>::EslUdp4Receive to restart the receive engine to release flow control.</li>
   1610     <li>::EslUdp4RxComplete to continue the operation of the receive engine if flow control is not being applied.</li>
   1611     <li>::EslUdp4SocketIsConfigured to start the recevie engine for the new socket.</li>
   1612   </ul>
   1613 
   1614   @param [in] pPort       Address of an ::ESL_PORT structure.
   1615 
   1616  **/
   1617 VOID
   1618 EslSocketRxStart (
   1619   IN ESL_PORT * pPort
   1620   );
   1621 
   1622 /**
   1623   Complete the transmit operation
   1624 
   1625   This support routine handles the transmit completion processing for
   1626   the various network layers.  It frees the ::ESL_IO_MGMT structure
   1627   and and frees packet resources by calling ::EslSocketPacketFree.
   1628   Transmit errors are logged in ESL_SOCKET::TxError.
   1629   See the \ref TransmitEngine section.
   1630 
   1631   This routine is called by:
   1632   <ul>
   1633     <li>::EslIp4TxComplete</li>
   1634     <li>::EslTcp4TxComplete</li>
   1635     <li>::EslTcp4TxOobComplete</li>
   1636     <li>::EslUdp4TxComplete</li>
   1637   </ul>
   1638 
   1639   @param [in] pIo             Address of an ::ESL_IO_MGMT structure
   1640   @param [in] LengthInBytes   Length of the data in bytes
   1641   @param [in] Status          Transmit operation status
   1642   @param [in] pQueueType      Zero terminated string describing queue type
   1643   @param [in] ppQueueHead     Transmit queue head address
   1644   @param [in] ppQueueTail     Transmit queue tail address
   1645   @param [in] ppActive        Active transmit queue address
   1646   @param [in] ppFree          Free transmit queue address
   1647 
   1648  **/
   1649 VOID
   1650 EslSocketTxComplete (
   1651   IN ESL_IO_MGMT * pIo,
   1652   IN UINT32 LengthInBytes,
   1653   IN EFI_STATUS Status,
   1654   IN CONST CHAR8 * pQueueType,
   1655   IN ESL_PACKET ** ppQueueHead,
   1656   IN ESL_PACKET ** ppQueueTail,
   1657   IN ESL_IO_MGMT ** ppActive,
   1658   IN ESL_IO_MGMT ** ppFree
   1659   );
   1660 
   1661 /**
   1662   Transmit data using a network connection.
   1663 
   1664   This support routine starts a transmit operation on the
   1665   underlying network layer.
   1666 
   1667   The network specific code calls this routine to start a
   1668   transmit operation.  See the \ref TransmitEngine section.
   1669 
   1670   @param [in] pPort           Address of an ::ESL_PORT structure
   1671   @param [in] ppQueueHead     Transmit queue head address
   1672   @param [in] ppQueueTail     Transmit queue tail address
   1673   @param [in] ppActive        Active transmit queue address
   1674   @param [in] ppFree          Free transmit queue address
   1675 
   1676  **/
   1677 VOID
   1678 EslSocketTxStart (
   1679   IN ESL_PORT * pPort,
   1680   IN ESL_PACKET ** ppQueueHead,
   1681   IN ESL_PACKET ** ppQueueTail,
   1682   IN ESL_IO_MGMT ** ppActive,
   1683   IN ESL_IO_MGMT ** ppFree
   1684   );
   1685 
   1686 //------------------------------------------------------------------------------
   1687 
   1688 #endif  //  _SOCKET_H_
   1689