]> git.proxmox.com Git - mirror_edk2.git/blobdiff - StdLib/EfiSocketLib/Ip4.c
StdLib: Remove EfiSocketLib and Ip4Config Protocol dependency.
[mirror_edk2.git] / StdLib / EfiSocketLib / Ip4.c
index a245e6847e25a0fba58445f7b99f2b278bde2c19..d3531b89288d8786c570068e784da0369ef9f236 100644 (file)
@@ -1,22 +1,19 @@
 /** @file\r
   Implement the IP4 driver support for the socket layer.\r
 \r
 /** @file\r
   Implement the IP4 driver support for the socket layer.\r
 \r
-  Copyright (c) 2011, Intel Corporation\r
-  All rights reserved. This program and the accompanying materials\r
-  are licensed and made available under the terms and conditions of the BSD License\r
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
+  Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials are licensed and made available\r
+  under the terms and conditions of the BSD License which accompanies this\r
+  distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
 \r
   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
 **/\r
 **/\r
-\r
 #include "Socket.h"\r
 \r
 \r
 #include "Socket.h"\r
 \r
 \r
-/**\r
-  Get the local socket address\r
+/** Get the local socket address.\r
 \r
   This routine returns the IPv4 address associated with the local\r
   socket.\r
 \r
   This routine returns the IPv4 address associated with the local\r
   socket.\r
@@ -25,9 +22,7 @@
   network address for the SOCK_RAW socket.\r
 \r
   @param [in] pPort       Address of an ::ESL_PORT structure.\r
   network address for the SOCK_RAW socket.\r
 \r
   @param [in] pPort       Address of an ::ESL_PORT structure.\r
-\r
   @param [out] pAddress   Network address to receive the local system address\r
   @param [out] pAddress   Network address to receive the local system address\r
-\r
 **/\r
 VOID\r
 EslIp4LocalAddressGet (\r
 **/\r
 VOID\r
 EslIp4LocalAddressGet (\r
@@ -40,9 +35,7 @@ EslIp4LocalAddressGet (
 \r
   DBG_ENTER ( );\r
 \r
 \r
   DBG_ENTER ( );\r
 \r
-  //\r
   //  Return the local address\r
   //  Return the local address\r
-  //\r
   pIp4 = &pPort->Context.Ip4;\r
   pLocalAddress = (struct sockaddr_in *)pAddress;\r
   pLocalAddress->sin_family = AF_INET;\r
   pIp4 = &pPort->Context.Ip4;\r
   pLocalAddress = (struct sockaddr_in *)pAddress;\r
   pLocalAddress->sin_family = AF_INET;\r
@@ -54,8 +47,7 @@ EslIp4LocalAddressGet (
 }\r
 \r
 \r
 }\r
 \r
 \r
-/**\r
-  Set the local port address.\r
+/** Set the local port address.\r
 \r
   This routine sets the local port address.\r
 \r
 \r
   This routine sets the local port address.\r
 \r
@@ -75,7 +67,6 @@ EslIp4LocalAddressGet (
   @param [in] bBindTest   TRUE = run bind testing\r
 \r
   @retval EFI_SUCCESS     The operation was successful\r
   @param [in] bBindTest   TRUE = run bind testing\r
 \r
   @retval EFI_SUCCESS     The operation was successful\r
-\r
  **/\r
 EFI_STATUS\r
 EslIp4LocalAddressSet (\r
  **/\r
 EFI_STATUS\r
 EslIp4LocalAddressSet (\r
@@ -91,23 +82,17 @@ EslIp4LocalAddressSet (
 \r
   DBG_ENTER ( );\r
 \r
 \r
   DBG_ENTER ( );\r
 \r
-  //\r
   //  Validate the address\r
   //  Validate the address\r
-  //\r
   pIpAddress = (struct sockaddr_in *)pSockAddr;\r
   if ( INADDR_BROADCAST == pIpAddress->sin_addr.s_addr ) {\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
     //  The local address must not be the broadcast address\r
-    //\r
     Status = EFI_INVALID_PARAMETER;\r
     pPort->pSocket->errno = EADDRNOTAVAIL;\r
   }\r
   else {\r
     Status = EFI_SUCCESS;\r
 \r
     Status = EFI_INVALID_PARAMETER;\r
     pPort->pSocket->errno = EADDRNOTAVAIL;\r
   }\r
   else {\r
     Status = EFI_SUCCESS;\r
 \r
-    //\r
     //  Set the local address\r
     //  Set the local address\r
-    //\r
     pIpAddress = (struct sockaddr_in *)pSockAddr;\r
     pIpv4Address = (UINT8 *)&pIpAddress->sin_addr.s_addr;\r
     pConfig = &pPort->Context.Ip4.ModeData.ConfigData;\r
     pIpAddress = (struct sockaddr_in *)pSockAddr;\r
     pIpv4Address = (UINT8 *)&pIpAddress->sin_addr.s_addr;\r
     pConfig = &pPort->Context.Ip4.ModeData.ConfigData;\r
@@ -116,14 +101,10 @@ EslIp4LocalAddressSet (
     pConfig->StationAddress.Addr[2] = pIpv4Address[2];\r
     pConfig->StationAddress.Addr[3] = pIpv4Address[3];\r
 \r
     pConfig->StationAddress.Addr[2] = pIpv4Address[2];\r
     pConfig->StationAddress.Addr[3] = pIpv4Address[3];\r
 \r
-    //\r
     //  Determine if the default address is used\r
     //  Determine if the default address is used\r
-    //\r
     pConfig->UseDefaultAddress = (BOOLEAN)( 0 == pIpAddress->sin_addr.s_addr );\r
 \r
     pConfig->UseDefaultAddress = (BOOLEAN)( 0 == pIpAddress->sin_addr.s_addr );\r
 \r
-    //\r
     //  Display the local address\r
     //  Display the local address\r
-    //\r
     DEBUG (( DEBUG_BIND,\r
               "0x%08x: Port, Local IP4 Address: %d.%d.%d.%d\r\n",\r
               pPort,\r
     DEBUG (( DEBUG_BIND,\r
               "0x%08x: Port, Local IP4 Address: %d.%d.%d.%d\r\n",\r
               pPort,\r
@@ -132,9 +113,7 @@ EslIp4LocalAddressSet (
               pConfig->StationAddress.Addr[2],\r
               pConfig->StationAddress.Addr[3]));\r
 \r
               pConfig->StationAddress.Addr[2],\r
               pConfig->StationAddress.Addr[3]));\r
 \r
-    //\r
     //  Set the subnet mask\r
     //  Set the subnet mask\r
-    //\r
     if ( pConfig->UseDefaultAddress ) {\r
       pConfig->SubnetMask.Addr[0] = 0;\r
       pConfig->SubnetMask.Addr[1] = 0;\r
     if ( pConfig->UseDefaultAddress ) {\r
       pConfig->SubnetMask.Addr[0] = 0;\r
       pConfig->SubnetMask.Addr[1] = 0;\r
@@ -148,17 +127,13 @@ EslIp4LocalAddressSet (
       pConfig->SubnetMask.Addr[3] = ( 224 <= pConfig->StationAddress.Addr[0]) ? 0xff : 0;\r
     }\r
   }\r
       pConfig->SubnetMask.Addr[3] = ( 224 <= pConfig->StationAddress.Addr[0]) ? 0xff : 0;\r
     }\r
   }\r
-\r
-  //\r
   //  Return the operation status\r
   //  Return the operation status\r
-  //\r
   DBG_EXIT_STATUS ( Status );\r
   return Status;\r
 }\r
 \r
 \r
   DBG_EXIT_STATUS ( Status );\r
   return Status;\r
 }\r
 \r
 \r
-/**\r
-  Get the option value\r
+/** Get the option value.\r
 \r
   This routine handles the IPv4 level options.\r
 \r
 \r
   This routine handles the IPv4 level options.\r
 \r
@@ -171,7 +146,6 @@ EslIp4LocalAddressSet (
   @param [out] pOptionLength    Buffer to receive the option length\r
 \r
   @retval EFI_SUCCESS - Socket data successfully received\r
   @param [out] pOptionLength    Buffer to receive the option length\r
 \r
   @retval EFI_SUCCESS - Socket data successfully received\r
-\r
  **/\r
 EFI_STATUS\r
 EslIp4OptionGet (\r
  **/\r
 EFI_STATUS\r
 EslIp4OptionGet (\r
@@ -185,20 +159,14 @@ EslIp4OptionGet (
 \r
   DBG_ENTER ( );\r
 \r
 \r
   DBG_ENTER ( );\r
 \r
-  //\r
   //  Assume success\r
   //  Assume success\r
-  //\r
   pSocket->errno = 0;\r
   Status = EFI_SUCCESS;\r
 \r
   pSocket->errno = 0;\r
   Status = EFI_SUCCESS;\r
 \r
-  //\r
   //  Attempt to get the option\r
   //  Attempt to get the option\r
-  //\r
   switch ( OptionName ) {\r
   default:\r
   switch ( OptionName ) {\r
   default:\r
-    //\r
     //  Option not supported\r
     //  Option not supported\r
-    //\r
     pSocket->errno = ENOPROTOOPT;\r
     Status = EFI_INVALID_PARAMETER;\r
     break;\r
     pSocket->errno = ENOPROTOOPT;\r
     Status = EFI_INVALID_PARAMETER;\r
     break;\r
@@ -208,17 +176,13 @@ EslIp4OptionGet (
     *pOptionLength = sizeof ( pSocket->bIncludeHeader );\r
     break;\r
   }\r
     *pOptionLength = sizeof ( pSocket->bIncludeHeader );\r
     break;\r
   }\r
-\r
-  //\r
   //  Return the operation status\r
   //  Return the operation status\r
-  //\r
   DBG_EXIT_STATUS ( Status );\r
   return Status;\r
 }\r
 \r
 \r
   DBG_EXIT_STATUS ( Status );\r
   return Status;\r
 }\r
 \r
 \r
-/**\r
-  Set the option value\r
+/** Set the option value.\r
 \r
   This routine handles the IPv4 level options.\r
 \r
 \r
   This routine handles the IPv4 level options.\r
 \r
@@ -231,7 +195,6 @@ EslIp4OptionGet (
   @param [in] OptionLength    Length of the buffer in bytes\r
 \r
   @retval EFI_SUCCESS - Option successfully set\r
   @param [in] OptionLength    Length of the buffer in bytes\r
 \r
   @retval EFI_SUCCESS - Option successfully set\r
-\r
  **/\r
 EFI_STATUS\r
 EslIp4OptionSet (\r
  **/\r
 EFI_STATUS\r
 EslIp4OptionSet (\r
@@ -242,28 +205,22 @@ EslIp4OptionSet (
   )\r
 {\r
   BOOLEAN bTrueFalse;\r
   )\r
 {\r
   BOOLEAN bTrueFalse;\r
-  socklen_t LengthInBytes;\r
-  UINT8 * pOptionData;\r
+  //socklen_t LengthInBytes;\r
+  //UINT8 * pOptionData;\r
   EFI_STATUS Status;\r
 \r
   DBG_ENTER ( );\r
 \r
   EFI_STATUS Status;\r
 \r
   DBG_ENTER ( );\r
 \r
-  //\r
   //  Assume success\r
   //  Assume success\r
-  //\r
   pSocket->errno = 0;\r
   Status = EFI_SUCCESS;\r
 \r
   pSocket->errno = 0;\r
   Status = EFI_SUCCESS;\r
 \r
-  //\r
   //  Determine if the option protocol matches\r
   //  Determine if the option protocol matches\r
-  //\r
-  LengthInBytes = 0;\r
-  pOptionData = NULL;\r
+  //LengthInBytes = 0;\r
+  //pOptionData = NULL;\r
   switch ( OptionName ) {\r
   default:\r
   switch ( OptionName ) {\r
   default:\r
-    //\r
     //  Protocol level not supported\r
     //  Protocol level not supported\r
-    //\r
     DEBUG (( DEBUG_INFO | DEBUG_OPTION, "ERROR - Invalid protocol option\r\n" ));\r
     pSocket->errno = ENOTSUP;\r
     Status = EFI_UNSUPPORTED;\r
     DEBUG (( DEBUG_INFO | DEBUG_OPTION, "ERROR - Invalid protocol option\r\n" ));\r
     pSocket->errno = ENOTSUP;\r
     Status = EFI_UNSUPPORTED;\r
@@ -271,31 +228,22 @@ EslIp4OptionSet (
 \r
   case IP_HDRINCL:\r
 \r
 \r
   case IP_HDRINCL:\r
 \r
-    //\r
     //  Validate the option length\r
     //  Validate the option length\r
-    //\r
     if ( sizeof ( UINT32 ) == OptionLength ) {\r
     if ( sizeof ( UINT32 ) == OptionLength ) {\r
-      //\r
       //  Restrict the input to TRUE or FALSE\r
       //  Restrict the input to TRUE or FALSE\r
-      //\r
       bTrueFalse = TRUE;\r
       if ( 0 == *(UINT32 *)pOptionValue ) {\r
         bTrueFalse = FALSE;\r
       }\r
       pOptionValue = &bTrueFalse;\r
 \r
       bTrueFalse = TRUE;\r
       if ( 0 == *(UINT32 *)pOptionValue ) {\r
         bTrueFalse = FALSE;\r
       }\r
       pOptionValue = &bTrueFalse;\r
 \r
-      //\r
       //  Set the option value\r
       //  Set the option value\r
-      //\r
-      pOptionData = (UINT8 *)&pSocket->bIncludeHeader;\r
-      LengthInBytes = sizeof ( pSocket->bIncludeHeader );\r
+      //pOptionData = (UINT8 *)&pSocket->bIncludeHeader;\r
+      //LengthInBytes = sizeof ( pSocket->bIncludeHeader );\r
     }\r
     break;\r
   }\r
     }\r
     break;\r
   }\r
-\r
-  //\r
   //  Return the operation status\r
   //  Return the operation status\r
-  //\r
   DBG_EXIT_STATUS ( Status );\r
   return Status;\r
 }\r
   DBG_EXIT_STATUS ( Status );\r
   return Status;\r
 }\r
@@ -430,13 +378,13 @@ EslIp4PortAllocate (
   @param [in] pPort           Address of an ::ESL_PORT structure.\r
 \r
   @param [in] pPacket         Address of an ::ESL_PACKET structure.\r
   @param [in] pPort           Address of an ::ESL_PORT structure.\r
 \r
   @param [in] pPacket         Address of an ::ESL_PACKET structure.\r
-  \r
+\r
   @param [in] pbConsumePacket Address of a BOOLEAN indicating if the packet is to be consumed\r
   @param [in] pbConsumePacket Address of a BOOLEAN indicating if the packet is to be consumed\r
-  \r
+\r
   @param [in] BufferLength    Length of the the buffer\r
   @param [in] BufferLength    Length of the the buffer\r
-  \r
+\r
   @param [in] pBuffer         Address of a buffer to receive the data.\r
   @param [in] pBuffer         Address of a buffer to receive the data.\r
-  \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
   @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
@@ -653,17 +601,15 @@ EslIp4RxComplete (
   )\r
 {\r
   size_t LengthInBytes;\r
   )\r
 {\r
   size_t LengthInBytes;\r
-  ESL_PORT * pPort;\r
   ESL_PACKET * pPacket;\r
   EFI_IP4_RECEIVE_DATA * pRxData;\r
   EFI_STATUS Status;\r
   ESL_PACKET * pPacket;\r
   EFI_IP4_RECEIVE_DATA * pRxData;\r
   EFI_STATUS Status;\r
-  \r
+\r
   DBG_ENTER ( );\r
   DBG_ENTER ( );\r
-  \r
+\r
   //\r
   //  Get the operation status.\r
   //\r
   //\r
   //  Get the operation status.\r
   //\r
-  pPort = pIo->pPort;\r
   Status = pIo->Token.Ip4Rx.Status;\r
 \r
   //\r
   Status = pIo->Token.Ip4Rx.Status;\r
 \r
   //\r
@@ -672,7 +618,7 @@ EslIp4RxComplete (
   pRxData = pIo->Token.Ip4Rx.Packet.RxData;\r
   LengthInBytes = pRxData->HeaderLength + pRxData->DataLength;\r
 \r
   pRxData = pIo->Token.Ip4Rx.Packet.RxData;\r
   LengthInBytes = pRxData->HeaderLength + pRxData->DataLength;\r
 \r
-  //\r
+  //{{\r
   //      +--------------------+   +----------------------+\r
   //      | ESL_IO_MGMT        |   |      Data Buffer     |\r
   //      |                    |   |     (Driver owned)   |\r
   //      +--------------------+   +----------------------+\r
   //      | ESL_IO_MGMT        |   |      Data Buffer     |\r
   //      |                    |   |     (Driver owned)   |\r
@@ -692,7 +638,7 @@ EslIp4RxComplete (
   //\r
   //\r
   //  Save the data in the packet\r
   //\r
   //\r
   //  Save the data in the packet\r
-  //\r
+  //}}\r
   pPacket = pIo->pPacket;\r
   pPacket->Op.Ip4Rx.pRxData = pRxData;\r
 \r
   pPacket = pIo->pPacket;\r
   pPacket->Op.Ip4Rx.pRxData = pRxData;\r
 \r
@@ -717,7 +663,7 @@ EslIp4RxComplete (
   that the socket is configured.\r
 \r
   @param [in] pSocket         Address of an ::ESL_SOCKET structure\r
   that the socket is configured.\r
 \r
   @param [in] pSocket         Address of an ::ESL_SOCKET structure\r
-  \r
+\r
   @retval EFI_SUCCESS - The port is connected\r
   @retval EFI_NOT_STARTED - The port is not connected\r
 \r
   @retval EFI_SUCCESS - The port is connected\r
   @retval EFI_NOT_STARTED - The port is not connected\r
 \r
@@ -904,7 +850,7 @@ EslIp4RxComplete (
   //  Determine the socket configuration status\r
   //\r
   Status = pSocket->bConfigured ? EFI_SUCCESS : EFI_NOT_STARTED;\r
   //  Determine the socket configuration status\r
   //\r
   Status = pSocket->bConfigured ? EFI_SUCCESS : EFI_NOT_STARTED;\r
-  \r
+\r
   //\r
   //  Return the port connected state.\r
   //\r
   //\r
   //  Return the port connected state.\r
   //\r
@@ -985,21 +931,21 @@ EslIp4TxBuffer (
   //\r
   if ( SOCKET_STATE_CONNECTED == pSocket->State ) {\r
     //\r
   //\r
   if ( SOCKET_STATE_CONNECTED == pSocket->State ) {\r
     //\r
-    //  Locate the port\r
+    //  Verify that there is enough room to buffer another\r
+    //  transmit operation\r
     //\r
     //\r
-    pPort = pSocket->pPortList;\r
-    if ( NULL != pPort ) {\r
+    pTxBytes = &pSocket->TxBytes;\r
+    if ( pSocket->MaxTxBuf > *pTxBytes ) {\r
       //\r
       //\r
-      //  Determine the queue head\r
+      //  Locate the port\r
       //\r
       //\r
-      pIp4 = &pPort->Context.Ip4;\r
-      pTxBytes = &pSocket->TxBytes;\r
+      pPort = pSocket->pPortList;\r
+      while ( NULL != pPort ) {\r
+        //\r
+        //  Determine the queue head\r
+        //\r
+        pIp4 = &pPort->Context.Ip4;\r
 \r
 \r
-      //\r
-      //  Verify that there is enough room to buffer another\r
-      //  transmit operation\r
-      //\r
-      if ( pSocket->MaxTxBuf > *pTxBytes ) {\r
         //\r
         //  Attempt to allocate the packet\r
         //\r
         //\r
         //  Attempt to allocate the packet\r
         //\r
@@ -1067,70 +1013,64 @@ EslIp4TxBuffer (
           RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
 \r
           //\r
           RAISE_TPL ( TplPrevious, TPL_SOCKETS );\r
 \r
           //\r
-          //  Stop transmission after an error\r
+          //  Display the request\r
           //\r
           //\r
-          if ( !EFI_ERROR ( pSocket->TxError )) {\r
-            //\r
-            //  Display the request\r
-            //\r
-            DEBUG (( DEBUG_TX,\r
-                      "Send %d bytes from 0x%08x, %d.%d.%d.%d --> %d.%d.%d.%d\r\n",\r
-                      BufferLength,\r
-                      pBuffer,\r
-                      pIp4->ModeData.ConfigData.StationAddress.Addr[0],\r
-                      pIp4->ModeData.ConfigData.StationAddress.Addr[1],\r
-                      pIp4->ModeData.ConfigData.StationAddress.Addr[2],\r
-                      pIp4->ModeData.ConfigData.StationAddress.Addr[3],\r
-                      pTxData->TxData.DestinationAddress.Addr[0],\r
-                      pTxData->TxData.DestinationAddress.Addr[1],\r
-                      pTxData->TxData.DestinationAddress.Addr[2],\r
-                      pTxData->TxData.DestinationAddress.Addr[3]));\r
-\r
-            //\r
-            //  Queue the data for transmission\r
-            //\r
-            pPacket->pNext = NULL;\r
-            pPreviousPacket = pSocket->pTxPacketListTail;\r
-            if ( NULL == pPreviousPacket ) {\r
-              pSocket->pTxPacketListHead = pPacket;\r
-            }\r
-            else {\r
-              pPreviousPacket->pNext = pPacket;\r
-            }\r
-            pSocket->pTxPacketListTail = pPacket;\r
-            DEBUG (( DEBUG_TX,\r
-                      "0x%08x: Packet on transmit list\r\n",\r
-                      pPacket ));\r
-\r
-            //\r
-            //  Account for the buffered data\r
-            //\r
-            *pTxBytes += BufferLength;\r
-            *pDataLength = BufferLength;\r
+          DEBUG (( DEBUG_TX,\r
+                    "Send %d bytes from 0x%08x, %d.%d.%d.%d --> %d.%d.%d.%d\r\n",\r
+                    BufferLength,\r
+                    pBuffer,\r
+                    pIp4->ModeData.ConfigData.StationAddress.Addr[0],\r
+                    pIp4->ModeData.ConfigData.StationAddress.Addr[1],\r
+                    pIp4->ModeData.ConfigData.StationAddress.Addr[2],\r
+                    pIp4->ModeData.ConfigData.StationAddress.Addr[3],\r
+                    pTxData->TxData.DestinationAddress.Addr[0],\r
+                    pTxData->TxData.DestinationAddress.Addr[1],\r
+                    pTxData->TxData.DestinationAddress.Addr[2],\r
+                    pTxData->TxData.DestinationAddress.Addr[3]));\r
 \r
 \r
-            //\r
-            //  Start the transmit engine if it is idle\r
-            //\r
-            if ( NULL != pPort->pTxFree ) {\r
-              EslSocketTxStart ( pPort,\r
-                                 &pSocket->pTxPacketListHead,\r
-                                 &pSocket->pTxPacketListTail,\r
-                                 &pPort->pTxActive,\r
-                                 &pPort->pTxFree );\r
-            }\r
+          //\r
+          //  Queue the data for transmission\r
+          //\r
+          pPacket->pNext = NULL;\r
+          pPreviousPacket = pSocket->pTxPacketListTail;\r
+          if ( NULL == pPreviousPacket ) {\r
+            pSocket->pTxPacketListHead = pPacket;\r
           }\r
           else {\r
           }\r
           else {\r
-            //\r
-            //  Previous transmit error\r
-            //  Stop transmission\r
-            //\r
-            Status = pSocket->TxError;\r
-            pSocket->errno = EIO;\r
+            pPreviousPacket->pNext = pPacket;\r
+          }\r
+          pSocket->pTxPacketListTail = pPacket;\r
+          DEBUG (( DEBUG_TX,\r
+                    "0x%08x: Packet on transmit list\r\n",\r
+                    pPacket ));\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 != pPort->pTxFree ) {\r
+            EslSocketTxStart ( pPort,\r
+                               &pSocket->pTxPacketListHead,\r
+                               &pSocket->pTxPacketListTail,\r
+                               &pPort->pTxActive,\r
+                               &pPort->pTxFree );\r
 \r
             //\r
 \r
             //\r
-            //  Free the packet\r
+            //  Ignore any transmit error\r
             //\r
             //\r
-            EslSocketPacketFree ( pPacket, DEBUG_TX );\r
+            if ( EFI_ERROR ( pSocket->TxError )) {\r
+              DEBUG (( DEBUG_TX,\r
+                       "0x%08x: Transmit error, Packet: 0x%08x, Status: %r\r\n",\r
+                       pPort,\r
+                       pPacket,\r
+                       pSocket->TxError ));\r
+            }\r
+            pSocket->TxError = EFI_SUCCESS;\r
           }\r
 \r
           //\r
           }\r
 \r
           //\r
@@ -1143,16 +1083,22 @@ EslIp4TxBuffer (
           //  Packet allocation failed\r
           //\r
           pSocket->errno = ENOMEM;\r
           //  Packet allocation failed\r
           //\r
           pSocket->errno = ENOMEM;\r
+          break;\r
         }\r
         }\r
-      }\r
-      else {\r
+\r
         //\r
         //\r
-        //  Not enough buffer space available\r
+        //  Set the next port\r
         //\r
         //\r
-        pSocket->errno = EAGAIN;\r
-        Status = EFI_NOT_READY;\r
+        pPort = pPort->pLinkSocket;\r
       }\r
     }\r
       }\r
     }\r
+    else {\r
+      //\r
+      //  Not enough buffer space available\r
+      //\r
+      pSocket->errno = EAGAIN;\r
+      Status = EFI_NOT_READY;\r
+    }\r
   }\r
 \r
   //\r
   }\r
 \r
   //\r
@@ -1188,9 +1134,9 @@ EslIp4TxComplete (
   ESL_PACKET * pPacket;\r
   ESL_SOCKET * pSocket;\r
   EFI_STATUS Status;\r
   ESL_PACKET * pPacket;\r
   ESL_SOCKET * pSocket;\r
   EFI_STATUS Status;\r
-  \r
+\r
   DBG_ENTER ( );\r
   DBG_ENTER ( );\r
-  \r
+\r
   //\r
   //  Locate the active transmit packet\r
   //\r
   //\r
   //  Locate the active transmit packet\r
   //\r
@@ -1205,6 +1151,18 @@ EslIp4TxComplete (
   pSocket->TxBytes -= LengthInBytes;\r
   Status = pIo->Token.Ip4Tx.Status;\r
 \r
   pSocket->TxBytes -= LengthInBytes;\r
   Status = pIo->Token.Ip4Tx.Status;\r
 \r
+  //\r
+  //  Ignore the transmit error\r
+  //\r
+  if ( EFI_ERROR ( Status )) {\r
+    DEBUG (( DEBUG_TX,\r
+             "0x%08x: Transmit completion error, Packet: 0x%08x, Status: %r\r\n",\r
+             pPort,\r
+             pPacket,\r
+             Status ));\r
+    Status = EFI_SUCCESS;\r
+  }\r
+\r
   //\r
   //  Complete the transmit operation\r
   //\r
   //\r
   //  Complete the transmit operation\r
   //\r
@@ -1220,6 +1178,165 @@ EslIp4TxComplete (
 }\r
 \r
 \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
+EslIp4VerifyLocalIpAddress (\r
+  IN ESL_PORT * pPort,\r
+  IN EFI_IP4_CONFIG_DATA * pConfigData\r
+  )\r
+{\r
+  UINTN DataSize;\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
+    DEBUG (( DEBUG_BIND,\r
+              "UseDefaultAddress: %s\r\n",\r
+              pConfigData->UseDefaultAddress ? L"TRUE" : L"FALSE" ));\r
+    DEBUG (( DEBUG_BIND,\r
+              "Requested IP address: %d.%d.%d.%d\r\n",\r
+              pConfigData->StationAddress.Addr [ 0 ],\r
+              pConfigData->StationAddress.Addr [ 1 ],\r
+              pConfigData->StationAddress.Addr [ 2 ],\r
+              pConfigData->StationAddress.Addr [ 3 ]));\r
+    if ( pConfigData->UseDefaultAddress\r
+      || (( 0 == pConfigData->StationAddress.Addr [ 0 ])\r
+      && ( 0 == pConfigData->StationAddress.Addr [ 1 ])\r
+      && ( 0 == pConfigData->StationAddress.Addr [ 2 ])\r
+      && ( 0 == pConfigData->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 (( pConfigData->StationAddress.Addr [ 0 ] == pIfInfo->StationAddress.Addr [ 0 ])\r
+      && ( pConfigData->StationAddress.Addr [ 1 ] == pIfInfo->StationAddress.Addr [ 1 ])\r
+      && ( pConfigData->StationAddress.Addr [ 2 ] == pIfInfo->StationAddress.Addr [ 2 ])\r
+      && ( pConfigData->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_RAW sockets over IPv4.\r
 /**\r
   Interface between the socket layer and the network specific\r
   code that supports SOCK_RAW sockets over IPv4.\r
@@ -1258,5 +1375,6 @@ CONST ESL_PROTOCOL_API cEslIp4Api = {
   NULL,   //  RxStart\r
   EslIp4TxBuffer,\r
   EslIp4TxComplete,\r
   NULL,   //  RxStart\r
   EslIp4TxBuffer,\r
   EslIp4TxComplete,\r
-  NULL    //  TxOobComplete\r
+  NULL,   //  TxOobComplete\r
+  (PFN_API_VERIFY_LOCAL_IP_ADDRESS)EslIp4VerifyLocalIpAddress\r
 };\r
 };\r