4, // RX buffers\r
4, // TX buffers\r
4 }, // TX Oob buffers\r
+ { L"Tcp6",\r
+ &gEfiTcp6ServiceBindingProtocolGuid,\r
+ &gEfiTcp6ProtocolGuid,\r
+ &mEslTcp6ServiceGuid,\r
+ OFFSET_OF ( ESL_LAYER, pTcp6List ),\r
+ 4, // RX buffers\r
+ 4, // TX buffers\r
+ 4 }, // TX Oob buffers\r
{ L"Udp4",\r
&gEfiUdp4ServiceBindingProtocolGuid,\r
&gEfiUdp4ProtocolGuid,\r
OFFSET_OF ( ESL_LAYER, pUdp4List ),\r
4, // RX buffers\r
4, // TX buffers\r
+ 0 }, // TX Oob buffers\r
+ { L"Udp6",\r
+ &gEfiUdp6ServiceBindingProtocolGuid,\r
+ &gEfiUdp6ProtocolGuid,\r
+ &mEslUdp6ServiceGuid,\r
+ OFFSET_OF ( ESL_LAYER, pUdp6List ),\r
+ 4, // RX buffers\r
+ 4, // TX buffers\r
0 } // TX Oob buffers\r
};\r
\r
**/\r
CONST ESL_PROTOCOL_API * cEslAfInet6Api[] = {\r
NULL, // 0\r
- NULL, // SOCK_STREAM\r
- NULL, // SOCK_DGRAM\r
+ &cEslTcp6Api, // SOCK_STREAM\r
+ &cEslUdp6Api, // SOCK_DGRAM\r
NULL, // SOCK_RAW\r
NULL, // SOCK_RDM\r
- NULL // SOCK_SEQPACKET\r
+ &cEslTcp6Api // SOCK_SEQPACKET\r
};\r
\r
/**\r
// Validate the domain value\r
//\r
if (( AF_INET != domain )\r
+ && ( AF_INET6 != domain )\r
&& ( AF_LOCAL != domain )) {\r
DEBUG (( DEBUG_ERROR | DEBUG_SOCKET,\r
"ERROR - Invalid domain value\r\n" ));\r
//\r
// Verify that at least one network connection was found\r
//\r
- if ( NULL == pSocket->pPortList ) {\r
+ if ( NULL != pSocket->pPortList ) {\r
+ Status = EFI_SUCCESS;\r
+ }\r
+ else {\r
if ( EADDRNOTAVAIL == pSocket->errno ) {\r
DEBUG (( DEBUG_BIND | DEBUG_POOL | DEBUG_INIT,\r
"ERROR - Socket address is not available!\r\n" ));\r
if ( EFI_NOT_READY != Status ) {\r
if ( !EFI_ERROR ( Status )) {\r
pSocket->State = SOCKET_STATE_CONNECTED;\r
+\r
+ //\r
+ // Start the receive operations\r
+ //\r
+ EslSocketRxStart ( pSocket->pPortList );\r
}\r
else {\r
pSocket->State = SOCKET_STATE_BOUND;\r
//\r
// Verify the socket state\r
//\r
- Status = EslSocketIsConfigured ( pSocket );\r
- if ( !EFI_ERROR ( Status )) {\r
+ EslSocketIsConfigured ( pSocket );\r
+ if ( pSocket->bAddressSet ) {\r
//\r
// Verify the address buffer and length address\r
//\r
if (( NULL != pAddress ) && ( NULL != pAddressLength )) {\r
//\r
- // Verify the socket state\r
+ // Verify the API\r
//\r
- if ( SOCKET_STATE_CONNECTED == pSocket->State ) {\r
+ if ( NULL == pSocket->pApi->pfnLocalAddrGet ) {\r
+ Status = EFI_UNSUPPORTED;\r
+ pSocket->errno = ENOTSUP;\r
+ }\r
+ else {\r
//\r
- // Verify the API\r
+ // Synchronize with the socket layer\r
//\r
- if ( NULL == pSocket->pApi->pfnLocalAddrGet ) {\r
- Status = EFI_UNSUPPORTED;\r
- pSocket->errno = ENOTSUP;\r
- }\r
- else {\r
- //\r
- // Synchronize with the socket layer\r
- //\r
- RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
+ RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
\r
+ //\r
+ // Verify that there is just a single connection\r
+ //\r
+ pPort = pSocket->pPortList;\r
+ if ( NULL != pPort ) {\r
//\r
- // Verify that there is just a single connection\r
+ // Verify the address length\r
//\r
- pPort = pSocket->pPortList;\r
- if (( NULL != pPort ) && ( NULL == pPort->pLinkSocket )) {\r
+ LengthInBytes = pSocket->pApi->AddressLength;\r
+ if (( LengthInBytes <= *pAddressLength ) \r
+ && ( 255 >= LengthInBytes )) {\r
//\r
- // Verify the address length\r
+ // Return the local address and address length\r
//\r
- LengthInBytes = pSocket->pApi->AddressLength;\r
- if (( LengthInBytes <= *pAddressLength ) \r
- && ( 255 >= LengthInBytes )) {\r
- //\r
- // Return the local address and address length\r
- //\r
- ZeroMem ( pAddress, LengthInBytes );\r
- pAddress->sa_len = (uint8_t)LengthInBytes;\r
- *pAddressLength = pAddress->sa_len;\r
- pSocket->pApi->pfnLocalAddrGet ( pPort, pAddress );\r
- pSocket->errno = 0;\r
- Status = EFI_SUCCESS;\r
- }\r
- else {\r
- pSocket->errno = EINVAL;\r
- Status = EFI_INVALID_PARAMETER;\r
- }\r
+ ZeroMem ( pAddress, LengthInBytes );\r
+ pAddress->sa_len = (uint8_t)LengthInBytes;\r
+ *pAddressLength = pAddress->sa_len;\r
+ pSocket->pApi->pfnLocalAddrGet ( pPort, pAddress );\r
+ pSocket->errno = 0;\r
+ Status = EFI_SUCCESS;\r
}\r
else {\r
- pSocket->errno = ENOTCONN;\r
- Status = EFI_NOT_STARTED;\r
+ pSocket->errno = EINVAL;\r
+ Status = EFI_INVALID_PARAMETER;\r
}\r
- \r
- //\r
- // Release the socket layer synchronization\r
- //\r
- RESTORE_TPL ( TplPrevious );\r
}\r
- }\r
- else {\r
- pSocket->errno = ENOTCONN;\r
- Status = EFI_NOT_STARTED;\r
+ else {\r
+ pSocket->errno = ENOTCONN;\r
+ Status = EFI_NOT_STARTED;\r
+ }\r
+ \r
+ //\r
+ // Release the socket layer synchronization\r
+ //\r
+ RESTORE_TPL ( TplPrevious );\r
}\r
}\r
else {\r
Status = EFI_INVALID_PARAMETER;\r
}\r
}\r
+ else {\r
+ //\r
+ // Address not set\r
+ //\r
+ Status = EFI_NOT_STARTED;\r
+ pSocket->errno = EADDRNOTAVAIL;\r
+ }\r
}\r
\r
//\r
// Create the event for SocketAccept completion\r
//\r
Status = gBS->CreateEvent ( 0,\r
- TplPrevious,\r
+ TPL_SOCKETS,\r
NULL,\r
NULL,\r
&pSocket->WaitAccept );\r
LengthInBytes = sizeof ( pSocket->MaxRxBuf );\r
break;\r
\r
+ case SO_REUSEADDR:\r
+ //\r
+ // Return the address reuse flag\r
+ //\r
+ pOptionData = (UINT8 *)&pSocket->bReUseAddr;\r
+ LengthInBytes = sizeof ( pSocket->bReUseAddr );\r
+ break;\r
+ \r
case SO_SNDBUF:\r
//\r
// Return the maximum transmit buffer size\r
LengthInBytes = sizeof ( pSocket->MaxRxBuf );\r
break;\r
\r
+ case SO_REUSEADDR:\r
+ //\r
+ // Return the address reuse flag\r
+ //\r
+ pOptionData = (UINT8 *)&pSocket->bReUseAddr;\r
+ LengthInBytes = sizeof ( pSocket->bReUseAddr );\r
+ break;\r
+\r
case SO_SNDBUF:\r
//\r
// Send buffer size\r
LengthInBytes,\r
(VOID **)&pPacket );\r
if ( !EFI_ERROR ( Status )) {\r
- DEBUG (( DebugFlags | DEBUG_POOL | DEBUG_INIT,\r
+ DEBUG (( DebugFlags | DEBUG_POOL,\r
"0x%08x: Allocate pPacket, %d bytes\r\n",\r
pPacket,\r
LengthInBytes ));\r
DBG_ENTER ( );\r
\r
//\r
- // Allocate a packet structure\r
+ // Free a packet structure\r
//\r
LengthInBytes = pPacket->PacketSize;\r
Status = gBS->FreePool ( pPacket );\r
short DetectedEvents;\r
ESL_SOCKET * pSocket;\r
EFI_STATUS Status;\r
+ EFI_TPL TplPrevious;\r
short ValidEvents;\r
\r
DEBUG (( DEBUG_POLL, "Entering SocketPoll\r\n" ));\r
Events & ( ~ValidEvents )));\r
}\r
else {\r
+ //\r
+ // Synchronize with the socket layer\r
+ //\r
+ RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
+ \r
+ //\r
+ // Increase the network performance by extending the\r
+ // polling (idle) loop down into the LAN driver\r
+ //\r
+ EslSocketRxPoll ( pSocket );\r
+ \r
+ //\r
+ // Release the socket layer synchronization\r
+ //\r
+ RESTORE_TPL ( TplPrevious );\r
+\r
//\r
// Check for pending connections\r
//\r
// Verify that the socket is connected\r
//\r
if ( SOCKET_STATE_CONNECTED == pSocket->State ) {\r
+ //\r
+ // Poll the network to increase performance\r
+ //\r
+ EslSocketRxPoll ( pSocket );\r
+\r
//\r
// Locate the port\r
//\r
}\r
\r
\r
+/**\r
+ Poll a socket for pending receive activity.\r
+\r
+ This routine is called at elivated TPL and extends the idle\r
+ loop which polls a socket down into the LAN driver layer to\r
+ determine if there is any receive activity.\r
+\r
+ The ::EslSocketPoll, ::EslSocketReceive and ::EslSocketTransmit\r
+ routines call this routine when there is nothing to do.\r
+\r
+ @param [in] pSocket Address of an ::EFI_SOCKET structure.\r
+\r
+ **/\r
+VOID\r
+EslSocketRxPoll (\r
+ IN ESL_SOCKET * pSocket\r
+ )\r
+{\r
+ ESL_PORT * pPort;\r
+\r
+ DEBUG (( DEBUG_POLL, "Entering EslSocketRxPoll\r\n" ));\r
+\r
+ //\r
+ // Increase the network performance by extending the\r
+ // polling (idle) loop down into the LAN driver\r
+ //\r
+ pPort = pSocket->pPortList;\r
+ while ( NULL != pPort ) {\r
+ //\r
+ // Poll the LAN adapter\r
+ //\r
+ pPort->pfnRxPoll ( pPort->pProtocol.v );\r
+\r
+ //\r
+ // Locate the next LAN adapter\r
+ //\r
+ pPort = pPort->pLinkSocket;\r
+ }\r
+\r
+ DEBUG (( DEBUG_POLL, "Exiting EslSocketRxPoll\r\n" ));\r
+}\r
+\r
+\r
/**\r
Start a receive operation\r
\r
//\r
RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
\r
+ //\r
+ // Poll the network to increase performance\r
+ //\r
+ EslSocketRxPoll ( pSocket );\r
+\r
//\r
// Attempt to buffer the packet for transmission\r
//\r