[ipoib 6] Bug fixes to the driver.
authortzachid <tzachid@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Wed, 21 Oct 2009 10:10:40 +0000 (10:10 +0000)
committertzachid <tzachid@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Wed, 21 Oct 2009 10:10:40 +0000 (10:10 +0000)
git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@2491 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

ulp/ipoib_NDIS6_CM/kernel/SOURCES
ulp/ipoib_NDIS6_CM/kernel/ipoib_adapter.h
ulp/ipoib_NDIS6_CM/kernel/ipoib_driver.cpp
ulp/ipoib_NDIS6_CM/kernel/ipoib_port.cpp
ulp/ipoib_NDIS6_CM/kernel/ipoib_port.h
ulp/ipoib_NDIS6_CM/kernel/makefile

index fa67f4d..86d0d9b 100644 (file)
@@ -25,7 +25,8 @@ SOURCES=      ipoib_log.mc \
                ipoib_port.cpp \\r
                ipoib_ibat.cpp \\r
 #              ipoib_cm.cpp    \\r
-               ipoib_xfr_mgr.cpp\r
+               ipoib_xfr_mgr.cpp \\r
+               ipoib_stat.cpp\r
 \r
 INCLUDES=..;..\..\..\inc;..\..\..\inc\kernel;\r
 \r
index 59c8857..2976993 100644 (file)
@@ -46,6 +46,7 @@
 #include <complib/cl_vector.h>\r
 #include <ip_packet.h>\r
 #include "ip_stats.h"\r
+#include "ipoib_stat.h"\r
 \r
 \r
 /*\r
@@ -74,6 +75,14 @@ typedef enum _ipoib_state
     IPOIB_RUNNING\r
 } ipoib_state_t;\r
 \r
+typedef struct _ipoib_offloads_cap_ {\r
+       boolean_t       lso;\r
+       boolean_t       send_chksum_offload;\r
+       boolean_t       recv_chksum_offload;\r
+}\r
+ipoib_offloads_cap_t;\r
+\r
+\r
 typedef struct _ipoib_params\r
 {\r
        int32_t         rq_depth;\r
@@ -110,7 +119,7 @@ typedef struct _ipoib_params
 *      send_chksum_offload\r
 *      recv_chksum_offload\r
 *              Flags to indicate whether to offload send/recv checksums.\r
-*              0 - No hardware cheksum\r
+*              0 - No hardware checksum\r
 *              1 - Try to offload if the device support it\r
 *              2 - Always report success (checksum bypass)\r
 *\r
@@ -195,6 +204,7 @@ typedef struct _ipoib_adapter
        uint32_t                                port_rate;\r
 \r
        ipoib_params_t                  params;\r
+       ipoib_offloads_cap_t    offload_cap;\r
        cl_spinlock_t                   recv_stat_lock;\r
        ip_stats_t                              recv_stats;\r
        cl_spinlock_t                   send_stat_lock;\r
@@ -222,6 +232,7 @@ typedef struct _ipoib_adapter
        ib_al_ifc_t                             *p_ifc;\r
 \r
        ULONG                                   sg_list_size;\r
+       PIPOIB_ST_DEVICE                p_stat;\r
 \r
 }      ipoib_adapter_t;\r
 /*\r
index 2f9117e..671950e 100644 (file)
@@ -241,8 +241,8 @@ static const NDIS_OID SUPPORTED_OIDS[] =
     OID_GEN_XMIT_ERROR,\r
     OID_GEN_RCV_ERROR,\r
     OID_GEN_RCV_NO_BUFFER,\r
-    OID_GEN_RCV_CRC_ERROR,\r
-    OID_GEN_TRANSMIT_QUEUE_LENGTH,\r
+    //OID_GEN_RCV_CRC_ERROR,\r
+    //OID_GEN_TRANSMIT_QUEUE_LENGTH,\r
     OID_802_3_PERMANENT_ADDRESS,\r
     OID_802_3_CURRENT_ADDRESS,\r
     OID_802_3_MULTICAST_LIST,\r
@@ -250,13 +250,13 @@ static const NDIS_OID SUPPORTED_OIDS[] =
     OID_802_3_RCV_ERROR_ALIGNMENT,\r
     OID_802_3_XMIT_ONE_COLLISION,\r
     OID_802_3_XMIT_MORE_COLLISIONS,\r
-    OID_802_3_XMIT_DEFERRED,\r
-    OID_802_3_XMIT_MAX_COLLISIONS,\r
-    OID_802_3_RCV_OVERRUN,\r
-    OID_802_3_XMIT_UNDERRUN,\r
-    OID_802_3_XMIT_HEARTBEAT_FAILURE,\r
-    OID_802_3_XMIT_TIMES_CRS_LOST,\r
-    OID_802_3_XMIT_LATE_COLLISIONS,\r
+    //OID_802_3_XMIT_DEFERRED,\r
+    //OID_802_3_XMIT_MAX_COLLISIONS,\r
+    //OID_802_3_RCV_OVERRUN,\r
+    //OID_802_3_XMIT_UNDERRUN,\r
+    //OID_802_3_XMIT_HEARTBEAT_FAILURE,\r
+    //OID_802_3_XMIT_TIMES_CRS_LOST,\r
+    //OID_802_3_XMIT_LATE_COLLISIONS,\r
 \r
 #if !BUILD_W2K\r
     OID_GEN_PHYSICAL_MEDIUM,\r
@@ -339,14 +339,6 @@ ULONG                      g_ipoib_send_SG_real = 0;
 ULONG                  g_ipoib_send_SG_failed = 0;\r
 \r
 \r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
 typedef struct _IPOIB_REG_ENTRY\r
 {\r
        NDIS_STRING RegName;                // variable name text\r
@@ -436,15 +428,6 @@ ipoib_initialize_ex(
     IN                                 NDIS_HANDLE             config_context,\r
     IN PNDIS_MINIPORT_INIT_PARAMETERS  MiniportInitParameters);\r
 \r
-NDIS_STATUS \r
-MPInitializeTest(\r
-    IN  NDIS_HANDLE                        MiniportAdapterHandle,\r
-    IN  NDIS_HANDLE                        MiniportDriverContext,\r
-    IN  PNDIS_MINIPORT_INIT_PARAMETERS     MiniportInitParameters\r
-    );\r
-\r
-\r
-\r
 BOOLEAN\r
 ipoib_check_for_hang(\r
        IN                              NDIS_HANDLE                                     adapter_context );\r
@@ -606,6 +589,8 @@ DriverEntry(
        \r
        KeInitializeSpinLock( &g_ipoib.lock );\r
        cl_qlist_init( &g_ipoib.adapter_list );\r
+       ipoib_st_init();\r
+       g_stat.drv.obj = p_drv_obj;\r
 \r
     NdisZeroMemory(&characteristics, sizeof(characteristics));\r
 \r
@@ -621,7 +606,7 @@ DriverEntry(
 \r
        characteristics.CheckForHangHandlerEx           = ipoib_check_for_hang;\r
        characteristics.HaltHandlerEx                           = ipoib_halt_ex;\r
-       characteristics.InitializeHandlerEx             = ipoib_initialize_ex;// MPInitializeTest\r
+       characteristics.InitializeHandlerEx             = ipoib_initialize_ex;\r
        characteristics.OidRequestHandler                       = ipoib_oid_handler;\r
        characteristics.CancelOidRequestHandler         = ipoib_cancel_oid_request;\r
        characteristics.ResetHandlerEx                          = ipoib_reset;\r
@@ -636,8 +621,6 @@ DriverEntry(
        characteristics.CancelSendHandler                       = ipoib_cancel_xmit;\r
        characteristics.ShutdownHandlerEx                       = ipoib_shutdown_ex;\r
 \r
-\r
-\r
        status = NdisMRegisterMiniportDriver(\r
                p_drv_obj, p_registry_path,(PNDIS_HANDLE)&g_IpoibDriverContext, &characteristics,&g_IpoibMiniportDriverHandle );\r
        if( status != NDIS_STATUS_SUCCESS )\r
@@ -1369,14 +1352,19 @@ OffloadConfig(
                p_offload->LsoV2.IPv4.Encapsulation = ulEncapsulation;\r
                p_offload->LsoV2.IPv4.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
                p_offload->LsoV2.IPv4.MinSegmentCount = LSO_MIN_SEG_COUNT;\r
-\r
+#if 0\r
                p_offload->LsoV2.IPv6.Encapsulation = ulEncapsulation;\r
                p_offload->LsoV2.IPv6.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
                p_offload->LsoV2.IPv6.MinSegmentCount = LSO_MIN_SEG_COUNT;\r
+#endif \r
 \r
-               p_offload->LsoV2.IPv6.IpExtensionHeadersSupported = NDIS_OFFLOAD_NOT_SUPPORTED;\r
-               p_offload->LsoV2.IPv6.TcpOptionsSupported = NDIS_OFFLOAD_SUPPORTED;\r
+       } else {\r
+               p_offload->LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_NOT_SUPPORTED;\r
+               p_offload->LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_NOT_SUPPORTED;\r
        }\r
+       \r
+       p_offload->LsoV2.IPv6.IpExtensionHeadersSupported = NDIS_OFFLOAD_NOT_SUPPORTED;\r
+       p_offload->LsoV2.IPv6.TcpOptionsSupported = NDIS_OFFLOAD_NOT_SUPPORTED;\r
 \r
 }\r
 \r
@@ -1397,6 +1385,7 @@ Return Value:
 static\r
 void\r
 OffloadCapabilities(\r
+       ipoib_adapter_t *p_adapter,\r
        NDIS_OFFLOAD    *p_offload\r
        )\r
 { \r
@@ -1408,18 +1397,18 @@ OffloadCapabilities(
        p_offload->Header.Size = NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1;\r
 \r
        p_offload->Checksum.IPv4Transmit.Encapsulation = ulEncapsulation;\r
-       p_offload->Checksum.IPv4Transmit.IpOptionsSupported = TRUE;\r
-       p_offload->Checksum.IPv4Transmit.TcpOptionsSupported = TRUE;\r
-       p_offload->Checksum.IPv4Transmit.TcpChecksum = TRUE;\r
-       p_offload->Checksum.IPv4Transmit.UdpChecksum = TRUE;\r
-       p_offload->Checksum.IPv4Transmit.IpChecksum = TRUE;\r
+       p_offload->Checksum.IPv4Transmit.IpOptionsSupported = \r
+       p_offload->Checksum.IPv4Transmit.TcpOptionsSupported = \r
+       p_offload->Checksum.IPv4Transmit.TcpChecksum = \r
+       p_offload->Checksum.IPv4Transmit.UdpChecksum = \r
+       p_offload->Checksum.IPv4Transmit.IpChecksum = p_adapter->offload_cap.send_chksum_offload;\r
 \r
        p_offload->Checksum.IPv4Receive.Encapsulation = ulEncapsulation;\r
-       p_offload->Checksum.IPv4Receive.IpOptionsSupported = TRUE;\r
-       p_offload->Checksum.IPv4Receive.TcpOptionsSupported = TRUE;\r
-       p_offload->Checksum.IPv4Receive.TcpChecksum = TRUE;\r
-       p_offload->Checksum.IPv4Receive.UdpChecksum = TRUE; \r
-       p_offload->Checksum.IPv4Receive.IpChecksum = TRUE;\r
+       p_offload->Checksum.IPv4Receive.IpOptionsSupported = \r
+       p_offload->Checksum.IPv4Receive.TcpOptionsSupported = \r
+       p_offload->Checksum.IPv4Receive.TcpChecksum = \r
+       p_offload->Checksum.IPv4Receive.UdpChecksum = \r
+       p_offload->Checksum.IPv4Receive.IpChecksum = p_adapter->offload_cap.recv_chksum_offload;\r
 \r
 \r
        //\r
@@ -1428,36 +1417,44 @@ OffloadCapabilities(
        //  IPv6 Extension Headers -> we set IpExtensionHeadersSupported to TRUE\r
        //\r
        p_offload->Checksum.IPv6Transmit.Encapsulation = ulEncapsulation;\r
-       p_offload->Checksum.IPv6Transmit.IpExtensionHeadersSupported = TRUE;\r
-       p_offload->Checksum.IPv6Transmit.TcpOptionsSupported = TRUE;\r
-       p_offload->Checksum.IPv6Transmit.TcpChecksum = TRUE;\r
-       p_offload->Checksum.IPv6Transmit.UdpChecksum = TRUE;\r
+       p_offload->Checksum.IPv6Transmit.IpExtensionHeadersSupported = \r
+       p_offload->Checksum.IPv6Transmit.TcpOptionsSupported = \r
+       p_offload->Checksum.IPv6Transmit.TcpChecksum = \r
+       p_offload->Checksum.IPv6Transmit.UdpChecksum = FALSE;\r
 \r
 \r
        p_offload->Checksum.IPv6Receive.Encapsulation = ulEncapsulation;\r
-       p_offload->Checksum.IPv6Receive.IpExtensionHeadersSupported = TRUE;\r
-       p_offload->Checksum.IPv6Receive.TcpOptionsSupported = TRUE;\r
-       p_offload->Checksum.IPv6Receive.TcpChecksum = TRUE;\r
-       p_offload->Checksum.IPv6Receive.UdpChecksum = TRUE;\r
-\r
-       p_offload->LsoV1.IPv4.Encapsulation = ulEncapsulation;\r
-       p_offload->LsoV1.IPv4.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
-       p_offload->LsoV1.IPv4.MinSegmentCount = 2;\r
-       p_offload->LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_SUPPORTED;\r
-       p_offload->LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_SUPPORTED;\r
-\r
-       p_offload->LsoV2.IPv4.Encapsulation = ulEncapsulation;\r
-       p_offload->LsoV2.IPv4.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
-       p_offload->LsoV2.IPv4.MinSegmentCount = 2;\r
-\r
-       p_offload->LsoV2.IPv6.Encapsulation = ulEncapsulation;\r
+       p_offload->Checksum.IPv6Receive.IpExtensionHeadersSupported = \r
+       p_offload->Checksum.IPv6Receive.TcpOptionsSupported = \r
+       p_offload->Checksum.IPv6Receive.TcpChecksum = \r
+       p_offload->Checksum.IPv6Receive.UdpChecksum = FALSE;\r
+\r
+       if (p_adapter->offload_cap.lso) {\r
+\r
+               p_offload->LsoV1.IPv4.Encapsulation = ulEncapsulation;\r
+               p_offload->LsoV1.IPv4.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
+               p_offload->LsoV1.IPv4.MinSegmentCount = 2;\r
+               p_offload->LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_SUPPORTED;\r
+               p_offload->LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_SUPPORTED;\r
+\r
+               p_offload->LsoV2.IPv4.Encapsulation = ulEncapsulation;\r
+               p_offload->LsoV2.IPv4.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
+               p_offload->LsoV2.IPv4.MinSegmentCount = 2;\r
+\r
+       } else {\r
+               p_offload->LsoV1.IPv4.TcpOptions = NDIS_OFFLOAD_NOT_SUPPORTED;\r
+               p_offload->LsoV1.IPv4.IpOptions = NDIS_OFFLOAD_NOT_SUPPORTED;\r
+               \r
+       }\r
+\r
+       /*p_offload->LsoV2.IPv6.Encapsulation = ulEncapsulation;\r
        p_offload->LsoV2.IPv6.MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE;\r
-       p_offload->LsoV2.IPv6.MinSegmentCount = 2;\r
+       p_offload->LsoV2.IPv6.MinSegmentCount = 2;*/\r
 \r
        p_offload->LsoV2.IPv6.IpExtensionHeadersSupported = NDIS_OFFLOAD_NOT_SUPPORTED;\r
-       p_offload->LsoV2.IPv6.TcpOptionsSupported = NDIS_OFFLOAD_SUPPORTED;\r
+       p_offload->LsoV2.IPv6.TcpOptionsSupported = NDIS_OFFLOAD_NOT_SUPPORTED;\r
 \r
-       }\r
+}\r
 \r
 \r
 /*++\r
@@ -1496,7 +1493,7 @@ SetOffloadAttributes(
        OffloadConfig(p_adapter, &offload);\r
 \r
 \r
-       OffloadCapabilities(&hwOffload);\r
+       OffloadCapabilities(p_adapter, &hwOffload);\r
 \r
        oat.DefaultOffloadConfiguration = &offload;\r
        oat.HardwareOffloadCapabilities = &hwOffload;\r
@@ -1536,8 +1533,8 @@ Note:
     Should be called in PASSIVE_LEVEL\r
     \r
 --*/\r
-       NDIS_STATUS\r
-       SetAttributes(\r
+NDIS_STATUS\r
+SetAttributes(\r
        ipoib_adapter_t *p_adapter,\r
        NDIS_HANDLE     h_adapter\r
        )\r
@@ -1560,12 +1557,7 @@ Note:
                return Status;\r
        }\r
 \r
-       Status = SetOffloadAttributes(p_adapter, h_adapter);\r
-       if (Status != NDIS_STATUS_SUCCESS)\r
-       {\r
-               //ETH_PRINT(TRACE_LEVEL_ERROR, ETH_INIT, "Set OFFLOAD attributes failed Error=0x%x\n", Status);\r
-               return Status;\r
-       }\r
+       \r
        \r
 #if 0\r
        if(!pPort->Config.fWHQL)\r
@@ -1589,6 +1581,317 @@ Note:
        return Status;\r
 }\r
 \r
+BOOLEAN\r
+IsValidOffloadConfig(ipoib_adapter_t *p_adapter, PNDIS_OFFLOAD_PARAMETERS pOffloadParam)\r
+{\r
+    BOOLEAN bRet = TRUE;\r
+\r
+    UCHAR CheckSumConfig[5]={0};\r
+    CheckSumConfig[0] = pOffloadParam->IPv4Checksum;\r
+    CheckSumConfig[1] = pOffloadParam->TCPIPv4Checksum;\r
+    CheckSumConfig[2] = pOffloadParam->UDPIPv4Checksum;\r
+    CheckSumConfig[3] = pOffloadParam->TCPIPv6Checksum;\r
+    CheckSumConfig[4] = pOffloadParam->UDPIPv6Checksum;\r
+\r
+    for(int i=0 ; i<5 ; i++)\r
+    {\r
+        if(CheckSumConfig[i] != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE)\r
+        {\r
+               switch (CheckSumConfig[i]) {\r
+                               //return FALSE in any case when NDIS tries to set unsupported value\r
+                               case NDIS_OFFLOAD_PARAMETERS_TX_ENABLED_RX_DISABLED:\r
+                                       bRet = (BOOLEAN) p_adapter->offload_cap.send_chksum_offload;\r
+                                       break;\r
+                               case NDIS_OFFLOAD_PARAMETERS_RX_ENABLED_TX_DISABLED:\r
+                                       bRet = (BOOLEAN) p_adapter->offload_cap.recv_chksum_offload;\r
+                                       break;\r
+                               case NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED:\r
+                                       bRet = (BOOLEAN) (p_adapter->offload_cap.send_chksum_offload && \r
+                                                        p_adapter->offload_cap.recv_chksum_offload);\r
+                                       break;\r
+                               default:\r
+                                       ASSERT (FALSE);\r
+               }\r
+               \r
+                       if (!bRet) \r
+                               return FALSE;\r
+                                       \r
+                                       \r
+            for(int j=0 ; j<5 ; j++)\r
+            {\r
+                if( (CheckSumConfig[j] != 0) && (CheckSumConfig[j] != CheckSumConfig[i])  )\r
+                {\r
+                   bRet = FALSE;\r
+                   goto Exit;\r
+                }\r
+            }            \r
+        }\r
+    }\r
+\r
+\r
+    UCHAR OffloadConfig[3]={0};\r
+    OffloadConfig[0] = pOffloadParam->LsoV1;\r
+    OffloadConfig[1] = pOffloadParam->LsoV2IPv4;\r
+    OffloadConfig[2] = pOffloadParam->LsoV2IPv6;\r
+\r
+       if (!p_adapter->offload_cap.lso) {\r
+               if ((pOffloadParam->LsoV1 == NDIS_OFFLOAD_PARAMETERS_LSOV1_ENABLED) ||\r
+                       (pOffloadParam->LsoV2IPv4 == NDIS_OFFLOAD_PARAMETERS_LSOV1_ENABLED))\r
+               {\r
+                       return FALSE;\r
+               }\r
+       }\r
+       \r
+       pOffloadParam->LsoV1;\r
+    OffloadConfig[1] = pOffloadParam->LsoV2IPv4;\r
+\r
+    for(int i=0 ; i<3 ; i++)\r
+    {\r
+        if(OffloadConfig[i] != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE)\r
+        {\r
+            for(int j=0 ; j<3 ; j++)\r
+            {\r
+                if( (OffloadConfig[j] != 0) && (OffloadConfig[j] != OffloadConfig[i])  )\r
+                {\r
+                   bRet = FALSE;\r
+                   goto Exit;\r
+                }\r
+            }            \r
+        }        \r
+    }\r
+   \r
+Exit:\r
+    return bRet;        \r
+}\r
+\r
+static\r
+NDIS_STATUS \r
+SetOffloadParameters(\r
+    ipoib_adapter_t * p_adapter,\r
+    void* const pBuf,\r
+    ULONG len \r
+    )\r
+{\r
+    IPOIB_ENTER(IPOIB_DBG_OID);\r
+\r
+    ASSERT(pBuf != NULL); \r
+    \r
+    PNDIS_OFFLOAD_PARAMETERS pOffloadParam = NULL;\r
+    PNDIS_OBJECT_HEADER pOffloadHeader = NULL;\r
+    NDIS_STATUS Status = NDIS_STATUS_SUCCESS;\r
+    bool StatusIndicationFlag = FALSE;\r
\r
+    if (len != NDIS_SIZEOF_OFFLOAD_PARAMETERS_REVISION_1)\r
+    {\r
+        ASSERT(FALSE);\r
+        IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_OID, ("Buffer is too small. offloading task requirs %d but the buffer size is: %d \n", NDIS_SIZEOF_OFFLOAD_PARAMETERS_REVISION_1, len));\r
+        Status =  NDIS_STATUS_INVALID_LENGTH;\r
+        goto Exit;\r
+    }\r
+\r
+    IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_OID, ("received set for OID_TCP_TASK_OFFLOAD\n"));\r
+\r
+    pOffloadParam = (PNDIS_OFFLOAD_PARAMETERS) pBuf;\r
+    pOffloadHeader = &(pOffloadParam->Header);\r
+    \r
+    if((pOffloadHeader->Type != NDIS_OBJECT_TYPE_DEFAULT) ||\r
+       (pOffloadHeader->Revision != NDIS_OFFLOAD_PARAMETERS_REVISION_1) ||\r
+       (pOffloadHeader->Size != NDIS_SIZEOF_OFFLOAD_PARAMETERS_REVISION_1))\r
+    {       \r
+        ASSERT(FALSE);\r
+        IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_OID, ("Set offloading task Illegal header\n"));\r
+        Status = NDIS_STATUS_INVALID_DATA;\r
+        goto Exit;\r
+    }\r
+\r
+    if ((pOffloadParam->IPsecV1 != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE) ||\r
+        (pOffloadParam->TcpConnectionIPv4 != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE) ||\r
+        (pOffloadParam->TcpConnectionIPv6 != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE) ||\r
+        (pOffloadParam->Flags != 0))\r
+    {\r
+        Status = NDIS_STATUS_NOT_SUPPORTED;\r
+        goto Exit;\r
+    }\r
+\r
+       //Eliminate currently unsupported statistic\r
+       if ((pOffloadParam->TCPIPv6Checksum != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE) ||\r
+               (pOffloadParam->UDPIPv6Checksum != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE) ||\r
+               (pOffloadParam->LsoV2IPv6               != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE))\r
+       {\r
+               Status = NDIS_STATUS_NOT_SUPPORTED;\r
+        goto Exit;\r
+       }\r
+               \r
+\r
+    BOOLEAN bRet = IsValidOffloadConfig(p_adapter, pOffloadParam);\r
+    if(bRet == FALSE)\r
+    {\r
+        //ASSERT(FALSE);\r
+        Status = NDIS_STATUS_NOT_SUPPORTED;\r
+        goto Exit;        \r
+    }\r
+\r
+       // Set current offload configuration capabilites\r
+       if ((pOffloadParam->IPv4Checksum ==     NDIS_OFFLOAD_PARAMETERS_TX_ENABLED_RX_DISABLED) ||\r
+               (pOffloadParam->TCPIPv4Checksum ==      NDIS_OFFLOAD_PARAMETERS_TX_ENABLED_RX_DISABLED) ||\r
+               (pOffloadParam->UDPIPv4Checksum ==      NDIS_OFFLOAD_PARAMETERS_TX_ENABLED_RX_DISABLED))\r
+       {\r
+               p_adapter->params.send_chksum_offload = CSUM_ENABLED;\r
+               p_adapter->params.recv_chksum_offload = CSUM_DISABLED;\r
+               StatusIndicationFlag = TRUE;\r
+       }\r
+\r
+       else if ((pOffloadParam->IPv4Checksum ==        NDIS_OFFLOAD_PARAMETERS_RX_ENABLED_TX_DISABLED) ||\r
+               (pOffloadParam->TCPIPv4Checksum ==      NDIS_OFFLOAD_PARAMETERS_RX_ENABLED_TX_DISABLED) ||\r
+               (pOffloadParam->UDPIPv4Checksum ==      NDIS_OFFLOAD_PARAMETERS_RX_ENABLED_TX_DISABLED))\r
+       {\r
+               p_adapter->params.recv_chksum_offload = CSUM_ENABLED;\r
+               p_adapter->params.send_chksum_offload = CSUM_DISABLED;\r
+               StatusIndicationFlag = TRUE;\r
+       }\r
+\r
+       else if ((pOffloadParam->IPv4Checksum ==        NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED ) ||\r
+               (pOffloadParam->TCPIPv4Checksum ==      NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED ) ||\r
+               (pOffloadParam->UDPIPv4Checksum ==      NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED ))\r
+       {\r
+               p_adapter->params.send_chksum_offload = CSUM_ENABLED;\r
+               p_adapter->params.recv_chksum_offload = CSUM_ENABLED;\r
+               StatusIndicationFlag = TRUE;\r
+       }\r
+       else if ((pOffloadParam->IPv4Checksum ==        NDIS_OFFLOAD_PARAMETERS_TX_RX_DISABLED ) ||\r
+                       (pOffloadParam->TCPIPv4Checksum ==      NDIS_OFFLOAD_PARAMETERS_TX_RX_DISABLED ) ||\r
+                       (pOffloadParam->UDPIPv4Checksum ==      NDIS_OFFLOAD_PARAMETERS_TX_RX_DISABLED ))\r
+       {\r
+               p_adapter->params.send_chksum_offload = CSUM_DISABLED;\r
+               p_adapter->params.recv_chksum_offload = CSUM_DISABLED;\r
+               StatusIndicationFlag = TRUE;\r
+       }\r
+       \r
+               \r
+\r
+ #if 0  \r
+    if(pOffloadParam->TCPIPv6Checksum != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE)\r
+    {\r
+        UpdateOffloadSeeting(pOffloadParam->TCPIPv6Checksum, pPort->Config.TCPUDPIPv4Chksum);        \r
+        StatusIndicationFlag = TRUE;\r
+    }\r
+    \r
+    if(pOffloadParam->UDPIPv6Checksum != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE)\r
+    {\r
+        UpdateOffloadSeeting(pOffloadParam->UDPIPv6Checksum, pPort->Config.TCPUDPIPv4Chksum);        \r
+        StatusIndicationFlag = TRUE;\r
+    }\r
+#endif\r
+\r
+   // SetCheksumOffloadingModes(pPort->Config);\r
+    \r
+    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//\r
+    \r
+    //////////////////////////// OFFLOAD OFFLOAD ////////////////////////////\r
+    if(pOffloadParam->LsoV1 != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE)\r
+    {\r
+       p_adapter->params.lso = (pOffloadParam->LsoV1 == NDIS_OFFLOAD_PARAMETERS_LSOV1_ENABLED);   \r
+        StatusIndicationFlag = TRUE;\r
+    }\r
+    \r
+    if(pOffloadParam->LsoV2IPv4 != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE)\r
+    {        \r
+        p_adapter->params.lso = (pOffloadParam->LsoV1 == NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED);\r
+        StatusIndicationFlag = TRUE;\r
+    }\r
+#if 0    \r
+    if(pOffloadParam->LsoV2IPv6 != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE)\r
+    {        \r
+        if(pOffloadParam->LsoV2IPv6 == NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED)\r
+        {\r
+            pPort->Config.LsoV2IPv6 = TRUE;            \r
+        }\r
+        else\r
+        {\r
+            pPort->Config.LsoV2IPv6 = FALSE;            \r
+        }\r
+        \r
+        StatusIndicationFlag = TRUE;\r
+    }\r
+#endif\r
+\r
+   \r
+    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//    \r
+\r
+\r
+    if(StatusIndicationFlag)\r
+    {        \r
+        NDIS_OFFLOAD CurrentOffloadCapapilities;\r
+        NDIS_STATUS_INDICATION StatusIndication;                \r
+\r
+        OffloadConfig(p_adapter, &CurrentOffloadCapapilities);\r
+\r
+                 \r
+        IPOIB_INIT_NDIS_STATUS_INDICATION(&StatusIndication,\r
+                                       p_adapter->h_adapter,\r
+                                       NDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG ,\r
+                                       (PVOID)&CurrentOffloadCapapilities,\r
+                                       sizeof(CurrentOffloadCapapilities));\r
+                                       \r
+        NdisMIndicateStatusEx(p_adapter->h_adapter, &StatusIndication);        \r
+    }\r
+                \r
+Exit:   \r
+    IPOIB_EXIT(IPOIB_DBG_OID);\r
+    return Status;   \r
+}\r
+\r
+/*++\r
+\r
+Routine Description:\r
+    The routine handles setting of OID_GEN_INTERRUPT_MODERATION.\r
+\r
+Arguments:\r
+    InformationBuffer - Pointer to the buffer that contains the data\r
+    InformationBufferLength - data length\r
+    \r
+Return Value:\r
+    NDIS_STAUS\r
+    \r
+--*/\r
+static \r
+NDIS_STATUS\r
+SetInterruptModeration(\r
+    PVOID InformationBuffer,\r
+    ULONG InformationBufferLength\r
+)\r
+{\r
+    IPOIB_ENTER(IPOIB_DBG_OID);\r
+    \r
+    NDIS_STATUS Status = NDIS_STATUS_SUCCESS;\r
+    \r
+    if (InformationBufferLength != sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS))\r
+    {\r
+        Status = NDIS_STATUS_INVALID_LENGTH;\r
+        goto Exit;\r
+    }\r
+    \r
+    PNDIS_INTERRUPT_MODERATION_PARAMETERS pInteruptModerationParam =\r
+                    (PNDIS_INTERRUPT_MODERATION_PARAMETERS)InformationBuffer;\r
+    \r
+    if ((pInteruptModerationParam->Header.Type != NDIS_OBJECT_TYPE_DEFAULT) ||\r
+        (pInteruptModerationParam->Header.Revision != NDIS_INTERRUPT_MODERATION_PARAMETERS_REVISION_1) ||\r
+        (pInteruptModerationParam->Header.Size != NDIS_SIZEOF_INTERRUPT_MODERATION_PARAMETERS_REVISION_1))\r
+    {\r
+        Status = NDIS_STATUS_INVALID_DATA;\r
+        goto Exit;\r
+    }\r
+    //\r
+    // BUGBUG: Need to handle disabling of interrupt moderation \r
+    //                          UH, 4-Jun-2008\r
+    //\r
+//    ASSERT(pInteruptModerationParam->Flags == NDIS_INTERRUPT_MODERATION_CHANGE_NEEDS_RESET);\r
+//    ASSERT(pInteruptModerationParam->InterruptModeration == NdisInterruptModerationEnabled);\r
+\r
+Exit:\r
+    IPOIB_EXIT(IPOIB_DBG_OID);\r
+    return Status;\r
+}\r
 \r
 \r
 NDIS_STATUS\r
@@ -1609,6 +1912,7 @@ InitNdisScatterGatherDma(
        //\r
        // Even if offload is enabled, the packet size for mapping shouldn't change\r
        //\r
+       //TODO bug ?\r
        DmaDescription.MaximumPhysicalMapping = LARGE_SEND_OFFLOAD_SIZE + LSO_MAX_HEADER;\r
 \r
        DmaDescription.ProcessSGListHandler = ipoib_process_sg_list;\r
@@ -1629,10 +1933,9 @@ InitNdisScatterGatherDma(
 \r
        if( status != NDIS_STATUS_SUCCESS )\r
        {\r
-               ipoib_destroy_adapter( p_adapter );\r
                IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
                                                 ("NdisMRegisterScatterGatherDma returned 0x%.8x.\n", status) );\r
-               //ASSERT(FALSE);\r
+               return status;\r
                \r
        }\r
        //NDIS sets this value before it returns from NdisMRegisterScatterGatherDma. \r
@@ -1698,9 +2001,11 @@ if(cl_get_time_stamp_sec() < 30) {
                        return NDIS_STATUS_FAILURE;\r
                }\r
                p_adapter->ipoib_state = IPOIB_PAUSED;\r
+               \r
                status  = SetAttributes(p_adapter, h_adapter);\r
                if (status != NDIS_STATUS_SUCCESS) {\r
                        //ASSERT(FALSE);\r
+                       ipoib_destroy_adapter( p_adapter );\r
                        return NDIS_STATUS_FAILURE;\r
                }\r
 \r
@@ -1717,6 +2022,8 @@ if(cl_get_time_stamp_sec() < 30) {
 \r
 #endif\r
 \r
+               \r
+\r
                /* Create the adapter adapter */\r
                ib_status = ipoib_start_adapter( p_adapter );\r
                if( ib_status != IB_SUCCESS )\r
@@ -1732,7 +2039,23 @@ if(cl_get_time_stamp_sec() < 30) {
                                ("ipoib_start_adapter returned status %d.\n", ib_status ) );\r
                        return NDIS_STATUS_FAILURE;\r
                }\r
-       \r
+               \r
+               status = SetOffloadAttributes(p_adapter, h_adapter);\r
+               if (status != NDIS_STATUS_SUCCESS)\r
+               {\r
+#if  IPOIB_USE_DMA\r
+                       NdisMDeregisterScatterGatherDma(p_adapter->NdisMiniportDmaHandle);\r
+#endif\r
+                       ipoib_destroy_adapter( p_adapter );\r
+                       IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                               ("SetOffloadAttributes returned status 0x%.8x.\n", status ) );\r
+                       return NDIS_STATUS_FAILURE;\r
+               }\r
+\r
+               p_adapter->p_stat = ipoib_st_dev_add();\r
+               if ( p_adapter->p_stat ) \r
+                       p_adapter->p_stat->p_adapter = p_adapter;\r
+\r
                ipoib_ref_ibat();\r
        \r
                IPOIB_EXIT( IPOIB_DBG_INIT );\r
@@ -1774,7 +2097,10 @@ ipoib_halt_ex(
                p_adapter->NdisMiniportDmaHandle = NULL;\r
        }\r
 #endif\r
+\r
+       PIPOIB_ST_DEVICE p_stat = p_adapter->p_stat;\r
        ipoib_destroy_adapter( p_adapter );\r
+       ipoib_st_dev_rmv( p_stat );\r
 \r
        IPOIB_EXIT( IPOIB_DBG_INIT );\r
 }\r
@@ -1895,7 +2221,7 @@ __ipoib_get_offload_config(
 NDIS_STATUS_INVALID_LENGTH, NDIS_STATUS_NOT_ACCEPTED, NDIS_STATUS_NOT_SUPPORTED,\r
 NDIS_STATUS_RESOURCES\r
 */\r
-       NDIS_STATUS\r
+NDIS_STATUS\r
 ipoib_query_info(\r
        IN                              NDIS_HANDLE                                     adapter_context,\r
        IN                              NDIS_OID                                        oid,\r
@@ -1906,12 +2232,15 @@ ipoib_query_info(
        {\r
                ipoib_adapter_t         *p_adapter;\r
                NDIS_STATUS             status;\r
-               USHORT                          version;\r
+               ULONG                           version;\r
                ULONG                           info;\r
                PVOID                           src_buf;\r
                ULONG                           buf_len;\r
                pending_oid_t           oid_info;\r
                uint8_t                         port_num;\r
+               NDIS_OFFLOAD        offload;\r
+\r
+               NDIS_INTERRUPT_MODERATION_PARAMETERS InterruptModerationParam;\r
 \r
                \r
                IPOIB_ENTER( IPOIB_DBG_OID );\r
@@ -2070,14 +2399,14 @@ ipoib_query_info(
                        IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
                                ("Port %d received query for OID_GEN_VENDOR_ID\n", port_num) );\r
                        src_buf = (void*)VENDOR_ID;\r
-               buf_len = sizeof(VENDOR_ID);\r
+                       buf_len = sizeof(VENDOR_ID);\r
                        break;\r
        \r
                case OID_GEN_VENDOR_DESCRIPTION:\r
                        IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID, \r
                                ("Port %d received query for OID_GEN_VENDOR_DESCRIPTION\n", port_num) );\r
                        src_buf = VENDOR_DESCRIPTION;\r
-               buf_len = sizeof(VENDOR_DESCRIPTION);\r
+                       buf_len = sizeof(VENDOR_DESCRIPTION);\r
                        break;\r
        \r
                case OID_GEN_VENDOR_DRIVER_VERSION:\r
@@ -2105,7 +2434,7 @@ ipoib_query_info(
                        IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
                                ("Port %d received query for OID_GEN_DRIVER_VERSION\n", port_num) );\r
                        src_buf = &version;\r
-               buf_len = sizeof(version);\r
+                       buf_len = sizeof(version);\r
                        version = MAJOR_NDIS_VERSION << 8 | MINOR_NDIS_VERSION;\r
                        break;\r
        \r
@@ -2345,13 +2674,26 @@ ipoib_query_info(
                                "OID_802_3_XMIT_MORE_COLLISIONS\n", port_num) );\r
                        info = 0;\r
                        break;\r
-       \r
-               case OID_TCP_TASK_OFFLOAD:\r
-                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
-                               ("Port %d received query for OID_TCP_TASK_OFFLOAD\n", port_num) );\r
-                       src_buf = NULL;\r
-                       status = __ipoib_get_tcp_task_offload( p_adapter, &oid_info );\r
-                       break;\r
+               case OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES:\r
+            buf_len = sizeof(NDIS_OFFLOAD);\r
+            if (buf_len < info_buf_len)\r
+            {\r
+                *p_bytes_needed = buf_len;\r
+                               return NDIS_STATUS_BUFFER_TOO_SHORT;\r
+            }\r
+\r
+            OffloadCapabilities(p_adapter, &offload);\r
+            src_buf = &offload;\r
+            break;                     \r
+               case OID_GEN_INTERRUPT_MODERATION:\r
+            InterruptModerationParam.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;\r
+            InterruptModerationParam.Header.Revision = NDIS_INTERRUPT_MODERATION_PARAMETERS_REVISION_1;\r
+            InterruptModerationParam.Header.Size = NDIS_SIZEOF_INTERRUPT_MODERATION_PARAMETERS_REVISION_1;\r
+            InterruptModerationParam.Flags = NDIS_INTERRUPT_MODERATION_CHANGE_NEEDS_RESET ;\r
+            InterruptModerationParam.InterruptModeration = NdisInterruptModerationNotSupported ;       \r
+            buf_len = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS);\r
+            src_buf = (PVOID) &InterruptModerationParam;  \r
+            break;\r
        \r
                /* Optional General */\r
                case OID_GEN_SUPPORTED_GUIDS:\r
@@ -2401,13 +2743,13 @@ ipoib_query_info(
                                //ulBytesAvailable = ulInfoLen = sizeof(NDIS_OFFLOAD);\r
                                if (info_buf_len <  sizeof(NDIS_OFFLOAD))\r
                                {\r
-                                       status = NDIS_STATUS_BUFFER_TOO_SHORT;\r
+                                       \r
                                        *p_bytes_needed = sizeof(NDIS_OFFLOAD) ;\r
-                                       break;\r
+                                       return NDIS_STATUS_BUFFER_TOO_SHORT;\r
                                }\r
        \r
-                               //ipoib_offload_config(pPort, &offload);\r
-                               //pInfo = &offload;\r
+                               OffloadConfig( p_adapter, &offload);\r
+                               src_buf = &offload;\r
                                break;\r
        \r
                default:\r
@@ -2493,195 +2835,59 @@ ipoib_complete_query(
        \r
 }\r
 \r
-\r
-static NDIS_STATUS\r
-__ipoib_get_tcp_task_offload(\r
-       IN                              ipoib_adapter_t*                        p_adapter,\r
-       OUT                             pending_oid_t                           *pNdisRequest )\r
+static\r
+NDIS_STATUS \r
+SetOffloadEncapsulation(\r
+    void* const pBuf,\r
+    ULONG len \r
+    )\r
 {\r
-#ifndef NDIS60_MINIPORT\r
-       NDIS_TASK_OFFLOAD_HEADER        *p_offload_hdr;\r
-       NDIS_TASK_OFFLOAD                       *p_offload_task;\r
-       NDIS_TASK_TCP_IP_CHECKSUM       *p_offload_chksum;\r
-\r
-       NDIS_TASK_TCP_LARGE_SEND        *p_offload_lso;\r
-       ULONG                                           buf_len;\r
-\r
-       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
-               ("Port %d received query for OID_TCP_TASK_OFFLOAD\n",\r
-               p_adapter->guids.port_num) );\r
-\r
-       buf_len = sizeof(NDIS_TASK_OFFLOAD_HEADER) +\r
-               offsetof( NDIS_TASK_OFFLOAD, TaskBuffer ) +\r
-               sizeof(NDIS_TASK_TCP_IP_CHECKSUM) +\r
-               (p_adapter->params.lso  ? \r
-                       sizeof(NDIS_TASK_OFFLOAD) + sizeof(NDIS_TASK_TCP_LARGE_SEND)\r
-                       : 0);\r
-\r
-       pNdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = buf_len;\r
-\r
-       if( pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength < buf_len )\r
-               return NDIS_STATUS_INVALID_LENGTH;\r
-\r
-       p_offload_hdr = (NDIS_TASK_OFFLOAD_HEADER*)pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer;\r
-       if( p_offload_hdr->Version != NDIS_TASK_OFFLOAD_VERSION )\r
-               return NDIS_STATUS_INVALID_DATA;\r
-\r
-       if( p_offload_hdr->EncapsulationFormat.Encapsulation !=\r
-               IEEE_802_3_Encapsulation )\r
-       {\r
-               return NDIS_STATUS_INVALID_DATA;\r
-       }\r
+    ASSERT(pBuf != NULL);\r
+    \r
+    PNDIS_OFFLOAD_ENCAPSULATION pOffload;\r
+    PNDIS_OBJECT_HEADER pOffloadHeader;\r
 \r
-       p_offload_hdr->OffsetFirstTask = sizeof(NDIS_TASK_OFFLOAD_HEADER);\r
-       p_offload_task = (NDIS_TASK_OFFLOAD*)(p_offload_hdr + 1);\r
-       p_offload_task->Version = NDIS_TASK_OFFLOAD_VERSION;\r
-       p_offload_task->Size = sizeof(NDIS_TASK_OFFLOAD);\r
-       p_offload_task->Task = TcpIpChecksumNdisTask;\r
-       p_offload_task->OffsetNextTask = 0;\r
-       p_offload_task->TaskBufferLength = sizeof(NDIS_TASK_TCP_IP_CHECKSUM);\r
-       p_offload_chksum =\r
-               (NDIS_TASK_TCP_IP_CHECKSUM*)p_offload_task->TaskBuffer;\r
-       \r
-       p_offload_chksum->V4Transmit.IpOptionsSupported =\r
-       p_offload_chksum->V4Transmit.TcpOptionsSupported =\r
-       p_offload_chksum->V4Transmit.TcpChecksum =\r
-       p_offload_chksum->V4Transmit.UdpChecksum =\r
-       p_offload_chksum->V4Transmit.IpChecksum =\r
-               !!(p_adapter->params.send_chksum_offload);\r
-\r
-       p_offload_chksum->V4Receive.IpOptionsSupported =\r
-       p_offload_chksum->V4Receive.TcpOptionsSupported =\r
-       p_offload_chksum->V4Receive.TcpChecksum =\r
-       p_offload_chksum->V4Receive.UdpChecksum =\r
-       p_offload_chksum->V4Receive.IpChecksum =\r
-               !!(p_adapter->params.recv_chksum_offload);\r
-\r
-       p_offload_chksum->V6Transmit.IpOptionsSupported = FALSE;\r
-       p_offload_chksum->V6Transmit.TcpOptionsSupported = FALSE;\r
-       p_offload_chksum->V6Transmit.TcpChecksum = FALSE;\r
-       p_offload_chksum->V6Transmit.UdpChecksum = FALSE;\r
-\r
-       p_offload_chksum->V6Receive.IpOptionsSupported = FALSE;\r
-       p_offload_chksum->V6Receive.TcpOptionsSupported = FALSE;\r
-       p_offload_chksum->V6Receive.TcpChecksum = FALSE;\r
-       p_offload_chksum->V6Receive.UdpChecksum = FALSE;\r
-\r
-\r
-       if (p_adapter->params.lso) {\r
-               // set the previous pointer to the correct place\r
-               p_offload_task->OffsetNextTask = FIELD_OFFSET(NDIS_TASK_OFFLOAD, TaskBuffer) +\r
-                                               p_offload_task->TaskBufferLength;\r
-               // set the LSO packet\r
-               p_offload_task = (PNDIS_TASK_OFFLOAD)\r
-                                               ((PUCHAR)p_offload_task + p_offload_task->OffsetNextTask);\r
-\r
-               p_offload_task->Version = NDIS_TASK_OFFLOAD_VERSION;\r
-               p_offload_task->Size = sizeof(NDIS_TASK_OFFLOAD);\r
-               p_offload_task->Task = TcpLargeSendNdisTask;\r
-               p_offload_task->OffsetNextTask = 0;\r
-               p_offload_task->TaskBufferLength = sizeof(NDIS_TASK_TCP_LARGE_SEND);\r
-\r
-               p_offload_lso = (PNDIS_TASK_TCP_LARGE_SEND) p_offload_task->TaskBuffer;\r
-\r
-               p_offload_lso->Version = 0;\r
-               //TODO optimal size: 60000, 64000 or 65536\r
-               //TODO LSO_MIN_SEG_COUNT to be 1\r
-               p_offload_lso->MaxOffLoadSize = LARGE_SEND_OFFLOAD_SIZE; \r
-#define LSO_MIN_SEG_COUNT 2\r
-               p_offload_lso->MinSegmentCount = LSO_MIN_SEG_COUNT;\r
-               p_offload_lso->TcpOptions = TRUE;\r
-               p_offload_lso->IpOptions = TRUE;\r
-       }\r
+    if (len != sizeof(NDIS_OFFLOAD_ENCAPSULATION))\r
+    {\r
+        ASSERT(FALSE);\r
+        IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_OID, ("Buffer is too small. offloading task requirs %d but the buffer size is: %d \n", sizeof(NDIS_OFFLOAD_ENCAPSULATION), len));\r
+        return  NDIS_STATUS_INVALID_DATA;\r
+    } \r
 \r
-               pNdisRequest->DATA.QUERY_INFORMATION.BytesWritten = buf_len\r
+    pOffload= (PNDIS_OFFLOAD_ENCAPSULATION) pBuf;\r
+    pOffloadHeader = &(pOffload->Header);\r
 \r
-       return NDIS_STATUS_SUCCESS;\r
-#endif\r
-       UNUSED_PARAM(p_adapter);\r
-       UNUSED_PARAM(pNdisRequest);\r
-       return NDIS_STATUS_NOT_SUPPORTED;\r
+    if((pOffloadHeader->Type != NDIS_OBJECT_TYPE_OFFLOAD_ENCAPSULATION) ||\r
+       (pOffloadHeader->Revision != NDIS_OFFLOAD_ENCAPSULATION_REVISION_1) ||\r
+       (pOffloadHeader->Size != NDIS_SIZEOF_OFFLOAD_ENCAPSULATION_REVISION_1))\r
+    {       \r
+        ASSERT(FALSE);\r
+        IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_OID, ("Set offloading task Illegal header\n"));\r
+        return NDIS_STATUS_INVALID_DATA;\r
+    }\r
 \r
+    //\r
+    // BUGBUG: Need to handle the offload parameter setting\r
+    //\r
+    return NDIS_STATUS_SUCCESS;\r
 }\r
 \r
-\r
+#if 0\r
 static NDIS_STATUS\r
 __ipoib_set_tcp_task_offload(\r
        IN                              ipoib_adapter_t*                        p_adapter,\r
        IN                              void* const                                     p_info_buf,\r
        IN                              ULONG* const                            p_info_len )\r
 {\r
-#ifndef NDIS60_MINIPORT\r
-       NDIS_TASK_OFFLOAD_HEADER        *p_offload_hdr;\r
-       NDIS_TASK_OFFLOAD                       *p_offload_task;\r
-       NDIS_TASK_TCP_IP_CHECKSUM       *p_offload_chksum;\r
 \r
-       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
-               ("Port %d received set for OID_TCP_TASK_OFFLOAD\n",\r
-               p_adapter->guids.port_num) );\r
-\r
-       p_offload_hdr = (NDIS_TASK_OFFLOAD_HEADER*)p_info_buf;\r
-\r
-       if( *p_info_len < sizeof(NDIS_TASK_OFFLOAD_HEADER) )\r
-               return NDIS_STATUS_INVALID_LENGTH;\r
-\r
-       if( p_offload_hdr->Version != NDIS_TASK_OFFLOAD_VERSION )\r
-               return NDIS_STATUS_INVALID_DATA;\r
-\r
-       if( p_offload_hdr->Size != sizeof(NDIS_TASK_OFFLOAD_HEADER) )\r
-               return NDIS_STATUS_INVALID_LENGTH;\r
-\r
-       if( !p_offload_hdr->OffsetFirstTask )\r
-               return NDIS_STATUS_SUCCESS;\r
-\r
-       if( p_offload_hdr->EncapsulationFormat.Encapsulation !=\r
-               IEEE_802_3_Encapsulation )\r
-       {\r
-               return NDIS_STATUS_INVALID_DATA;\r
-       }\r
-\r
-       p_offload_task = (NDIS_TASK_OFFLOAD*)\r
-               (((UCHAR*)p_offload_hdr) + p_offload_hdr->OffsetFirstTask);\r
+       return NDIS_STATUS_SUCCESS;\r
 \r
-       if( *p_info_len < sizeof(NDIS_TASK_OFFLOAD_HEADER) +\r
-               offsetof( NDIS_TASK_OFFLOAD, TaskBuffer ) +\r
-               sizeof(NDIS_TASK_TCP_IP_CHECKSUM) )\r
-       {\r
-               return NDIS_STATUS_INVALID_LENGTH;\r
-       }\r
+       \r
+}\r
+#endif\r
 \r
-       if( p_offload_task->Version != NDIS_TASK_OFFLOAD_VERSION )\r
-               return NDIS_STATUS_INVALID_DATA;\r
-       p_offload_chksum =\r
-               (NDIS_TASK_TCP_IP_CHECKSUM*)p_offload_task->TaskBuffer;\r
-\r
-       if( !p_adapter->params.send_chksum_offload &&\r
-               (p_offload_chksum->V4Transmit.IpOptionsSupported ||\r
-               p_offload_chksum->V4Transmit.TcpOptionsSupported ||\r
-               p_offload_chksum->V4Transmit.TcpChecksum ||\r
-               p_offload_chksum->V4Transmit.UdpChecksum ||\r
-               p_offload_chksum->V4Transmit.IpChecksum) )\r
-       {\r
-               return NDIS_STATUS_NOT_SUPPORTED;\r
-       }\r
 \r
-       if( !p_adapter->params.recv_chksum_offload &&\r
-               (p_offload_chksum->V4Receive.IpOptionsSupported ||\r
-               p_offload_chksum->V4Receive.TcpOptionsSupported ||\r
-               p_offload_chksum->V4Receive.TcpChecksum ||\r
-               p_offload_chksum->V4Receive.UdpChecksum ||\r
-               p_offload_chksum->V4Receive.IpChecksum) )\r
-       {\r
-               return NDIS_STATUS_NOT_SUPPORTED;\r
-       }\r
 \r
-       return NDIS_STATUS_SUCCESS;\r
-#endif \r
-       UNUSED_PARAM(p_adapter);\r
-       UNUSED_PARAM(p_info_buf);\r
-       UNUSED_PARAM(p_info_len);\r
-       return NDIS_STATUS_NOT_SUPPORTED;\r
-}\r
 \r
 \r
 //! Issues a hardware reset to the NIC and/or resets the driver's software state.\r
@@ -2918,230 +3124,21 @@ ipoib_set_info(
                break;\r
 \r
        case OID_TCP_TASK_OFFLOAD:\r
-               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+               ASSERT (FALSE);\r
+               IPOIB_PRINT( TRACE_LEVEL_ERROR,IPOIB_DBG_ERROR,\r
                        ("Port %d received set for OID_TCP_TASK_OFFLOAD\n", port_num) );\r
 \r
                buf_len = info_buf_len;\r
-               status =\r
-                       __ipoib_set_tcp_task_offload( p_adapter, info_buf, &buf_len );\r
-               break;\r
-\r
-       /* Optional General */\r
-       case OID_GEN_TRANSPORT_HEADER_OFFSET:\r
-#ifdef NDIS51_MINIPORT\r
-       case OID_GEN_RNDIS_CONFIG_PARAMETER:\r
-       case OID_GEN_VLAN_ID:\r
-#endif\r
-               status = NDIS_STATUS_NOT_SUPPORTED;\r
-               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
-                       ("Port %d received an unsupported oid of 0x%.8X!\n", port_num, oid));\r
-               break;\r
-\r
-       case OID_GEN_SUPPORTED_LIST:\r
-       case OID_GEN_HARDWARE_STATUS:\r
-       case OID_GEN_MEDIA_SUPPORTED:\r
-       case OID_GEN_MEDIA_IN_USE:\r
-       case OID_GEN_MAXIMUM_FRAME_SIZE:\r
-       case OID_GEN_LINK_SPEED:\r
-       case OID_GEN_TRANSMIT_BUFFER_SPACE:\r
-       case OID_GEN_RECEIVE_BUFFER_SPACE:\r
-       case OID_GEN_MAXIMUM_LOOKAHEAD:\r
-       case OID_GEN_TRANSMIT_BLOCK_SIZE:\r
-       case OID_GEN_RECEIVE_BLOCK_SIZE:\r
-       case OID_GEN_MAXIMUM_TOTAL_SIZE:\r
-       case OID_GEN_VENDOR_ID:\r
-       case OID_GEN_VENDOR_DESCRIPTION:\r
-       case OID_GEN_VENDOR_DRIVER_VERSION:\r
-       case OID_GEN_DRIVER_VERSION:\r
-       case OID_GEN_MAC_OPTIONS:\r
-       case OID_GEN_MEDIA_CONNECT_STATUS:\r
-       case OID_GEN_MAXIMUM_SEND_PACKETS:\r
-       case OID_GEN_SUPPORTED_GUIDS:\r
-       case OID_GEN_PHYSICAL_MEDIUM:\r
-       default:\r
-               status = NDIS_STATUS_INVALID_OID;\r
-               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
-                       ("Port %d received an invalid oid of 0x%.8X!\n", port_num, oid));\r
-               break;\r
-       }\r
-\r
-       if( status == NDIS_STATUS_SUCCESS )\r
-       {\r
-               *p_bytes_read = buf_len;\r
-       }\r
-       else\r
-       {\r
-               if( status == NDIS_STATUS_INVALID_LENGTH )\r
-               {\r
-                       if ( !*p_bytes_needed )\r
-                       {\r
-                               *p_bytes_needed = buf_len;\r
-                       }\r
-               }\r
-\r
-               *p_bytes_read = 0;\r
-       }\r
-\r
-       IPOIB_EXIT( IPOIB_DBG_OID );\r
-       return status;\r
-}\r
-\r
-#ifdef NNN\r
-NDIS_STATUS\r
-ipoib_set_info(\r
-       ipoib_adapter_t*           p_adapter,\r
-       IN PNDIS_OID_REQUEST   pNdisRequest)\r
-{\r
-       NDIS_STATUS                     status;\r
-       NDIS_OID            oid;\r
-       UINT                            info_buf_len;\r
-       UINT                            buf_len;\r
-       uint8_t                         port_num;\r
-       PVOID                           info_buf;\r
-       UINT                            *p_bytes_needed;\r
-       KLOCK_QUEUE_HANDLE      hdl;\r
-\r
-       IPOIB_ENTER( IPOIB_DBG_OID );\r
-\r
-    oid                        = pNdisRequest->DATA.SET_INFORMATION.Oid;\r
-    info_buf           = pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer;\r
-    info_buf_len       = pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength;\r
-       p_bytes_needed  = &pNdisRequest->DATA.QUERY_INFORMATION.BytesNeeded;\r
-       status = NDIS_STATUS_SUCCESS;\r
-\r
-       buf_len = sizeof(UINT);\r
-       port_num = p_adapter->guids.port_num;\r
-\r
-       switch( oid )\r
-       {\r
-       /* Required General */\r
-       case OID_GEN_CURRENT_PACKET_FILTER:\r
-               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
-                       ("Port %d received set for OID_GEN_CURRENT_PACKET_FILTER\n", port_num));\r
-               if( info_buf_len < sizeof(p_adapter->packet_filter) )\r
-               {\r
-                       status = NDIS_STATUS_INVALID_LENGTH;\r
-               }\r
-               else if( !info_buf )\r
-               {\r
-                       status = NDIS_STATUS_INVALID_DATA;\r
-               }\r
-               else\r
-               {\r
-                       KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );\r
-                       cl_obj_lock( &p_adapter->obj );\r
-                       switch( p_adapter->state )\r
-                       {\r
-                       case IB_PNP_PORT_ADD:\r
-                               p_adapter->p_oid_request = pNdisRequest;\r
-                               status = NDIS_STATUS_PENDING;\r
-                               break;\r
-\r
-                       case IB_PNP_PORT_REMOVE:\r
-                               status = NDIS_STATUS_NOT_ACCEPTED;\r
-                               break;\r
-\r
-                       default:\r
-                               if( !p_adapter->packet_filter && (*(uint32_t*)info_buf) )\r
-                               {\r
-                                       cl_qlist_insert_tail(\r
-                                               &g_ipoib.adapter_list, &p_adapter->entry );\r
-\r
-                                       /*\r
-                                        * Filter was zero, now non-zero.  Register IP addresses\r
-                                        * with SA.\r
-                                        */\r
-                                       ipoib_reg_addrs( p_adapter );\r
-                               }\r
-                               else if( p_adapter->packet_filter && !(*(uint32_t*)info_buf) )\r
-                               {\r
-                                       /*\r
-                                        * Filter was non-zero, now zero.  Deregister IP addresses.\r
-                                        */\r
-                                       ipoib_dereg_addrs( p_adapter );\r
-\r
-                                       ASSERT( cl_qlist_count( &g_ipoib.adapter_list ) );\r
-                                       cl_qlist_remove_item(\r
-                                               &g_ipoib.adapter_list, &p_adapter->entry );\r
-                               }\r
-\r
-                               p_adapter->packet_filter = *(uint32_t*)info_buf;\r
-                       }\r
-                       cl_obj_unlock( &p_adapter->obj );\r
-                       KeReleaseInStackQueuedSpinLock( &hdl );\r
-               }\r
-               break;\r
-\r
-       case OID_GEN_CURRENT_LOOKAHEAD:\r
-               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
-                       ("Port %d received set for OID_GEN_CURRENT_LOOKAHEAD\n", port_num));\r
-               if( info_buf_len < buf_len )\r
-                       status = NDIS_STATUS_INVALID_LENGTH;\r
-               break;\r
-\r
-       case OID_GEN_PROTOCOL_OPTIONS:\r
-               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
-                       ("Port %d received set for OID_GEN_PROTOCOL_OPTIONS\n", port_num));\r
-               if( info_buf_len < buf_len )\r
-                       status = NDIS_STATUS_INVALID_LENGTH;\r
-               break;\r
-\r
-       case OID_GEN_NETWORK_LAYER_ADDRESSES:\r
-               status = __ipoib_set_net_addr( p_adapter, pNdisRequest);\r
-               break;\r
-\r
-       case OID_GEN_MACHINE_NAME:\r
-               IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_OID,\r
-                       ("Port %d received set for OID_GEN_MACHINE_NAME\n", port_num) );\r
+               //status =\r
+               //      __ipoib_set_tcp_task_offload( p_adapter, info_buf, &buf_len );\r
                break;\r
 \r
 \r
-       /* Required Ethernet operational characteristics */\r
-       case OID_802_3_MULTICAST_LIST:\r
-               IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_OID,\r
-                       ("Port %d received set for OID_802_3_MULTICAST_LIST\n", port_num) );\r
-               if( info_buf_len > MAX_MCAST * sizeof(mac_addr_t) )\r
-               {\r
-                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
-                               ("Port %d OID_802_3_MULTICAST_LIST - Multicast list full.\n", port_num) );\r
-                       status = NDIS_STATUS_MULTICAST_FULL;\r
-                       *p_bytes_needed = MAX_MCAST * sizeof(mac_addr_t);\r
-               }\r
-               else if( info_buf_len % sizeof(mac_addr_t) )\r
-               {\r
-                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
-                               ("Port %d OID_802_3_MULTICAST_LIST - Invalid input buffer.\n", port_num) );\r
-                       status = NDIS_STATUS_INVALID_DATA;\r
-               }\r
-               else if( !info_buf && info_buf_len )\r
-               {\r
-                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
-                               ("Port %d OID_802_3_MULTICAST_LIST - Invalid input buffer.\n", port_num) );\r
-                       status = NDIS_STATUS_INVALID_DATA;\r
-               }\r
-               else\r
-               {\r
-                       ipoib_refresh_mcast( p_adapter, (mac_addr_t*)info_buf,\r
-                               (uint8_t)(info_buf_len / sizeof(mac_addr_t)) );\r
-\r
-                       buf_len = info_buf_len;\r
-                       /*\r
-                        * Note that we don't return pending.  It will likely take longer\r
-                        * for our SA transactions to complete than NDIS will give us\r
-                        * before reseting the adapter.  If an SA failure is encountered,\r
-                        * the adapter will be marked as hung and we will get reset.\r
-                        */\r
-                       status = NDIS_STATUS_SUCCESS;\r
-               }\r
-               break;\r
-\r
-       case OID_TCP_TASK_OFFLOAD:\r
+       case OID_TCP_OFFLOAD_PARAMETERS:\r
                IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
-                       ("Port %d received set for OID_TCP_TASK_OFFLOAD\n", port_num) );\r
-\r
+                       ("Port %d received set for OID_TCP_OFFLOAD_PARAMETERS\n", port_num) );\r
                buf_len = info_buf_len;\r
-               status =\r
-                       __ipoib_set_tcp_task_offload( p_adapter, pNdisRequest );\r
+               status = SetOffloadParameters(p_adapter, info_buf, info_buf_len);\r
                break;\r
 \r
        /* Optional General */\r
@@ -3155,8 +3152,17 @@ ipoib_set_info(
                        ("Port %d received an unsupported oid of 0x%.8X!\n", port_num, oid));\r
                break;\r
 \r
+       case OID_GEN_INTERRUPT_MODERATION:\r
+               status = SetInterruptModeration(info_buf, info_buf_len);\r
+               break;\r
+\r
+       case OID_OFFLOAD_ENCAPSULATION:\r
+                status = SetOffloadEncapsulation(info_buf, info_buf_len);\r
+                break;\r
+\r
+\r
        case OID_GEN_SUPPORTED_LIST:\r
-       case OID_GEN_HARDWARE_STATUS:\r
+       //case OID_GEN_HARDWARE_STATUS:\r
        case OID_GEN_MEDIA_SUPPORTED:\r
        case OID_GEN_MEDIA_IN_USE:\r
        case OID_GEN_MAXIMUM_FRAME_SIZE:\r
@@ -3176,16 +3182,17 @@ ipoib_set_info(
        case OID_GEN_MAXIMUM_SEND_PACKETS:\r
        case OID_GEN_SUPPORTED_GUIDS:\r
        case OID_GEN_PHYSICAL_MEDIUM:\r
+               \r
        default:\r
                status = NDIS_STATUS_INVALID_OID;\r
-               IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,\r
+               IPOIB_PRINT( TRACE_LEVEL_ERROR,IPOIB_DBG_ERROR,\r
                        ("Port %d received an invalid oid of 0x%.8X!\n", port_num, oid));\r
                break;\r
        }\r
 \r
        if( status == NDIS_STATUS_SUCCESS )\r
        {\r
-               pNdisRequest->DATA.SET_INFORMATION.BytesRead = buf_len;\r
+               *p_bytes_read = buf_len;\r
        }\r
        else\r
        {\r
@@ -3197,13 +3204,14 @@ ipoib_set_info(
                        }\r
                }\r
 \r
-               pNdisRequest->DATA.SET_INFORMATION.BytesRead = 0;\r
+               *p_bytes_read = 0;\r
        }\r
 \r
        IPOIB_EXIT( IPOIB_DBG_OID );\r
        return status;\r
 }\r
-#endif\r
+\r
+\r
 static NDIS_STATUS\r
 ipoib_oid_handler(\r
     IN  NDIS_HANDLE         adapter_context,\r
@@ -3383,7 +3391,10 @@ ipoib_pnp_notify(
                cl_obj_unlock( &p_adapter->obj );\r
 \r
                ipoib_resume_oids( p_adapter );\r
+               p_adapter->p_stat->n_pnp_irps++;\r
        }\r
+       else \r
+               p_adapter->p_stat->n_power_irps++;\r
 \r
        IPOIB_EXIT( IPOIB_DBG_PNP );\r
 }\r
index f73f263..273e86f 100644 (file)
@@ -77,7 +77,7 @@ static void __port_do_mcast_garbage(ipoib_port_t* const       p_port );
 \r
 static void __recv_cb_dpc(KDPC *p_gc_dpc,void *context,void *s_arg1, void *s_arg2);\r
 \r
-\r
+#if 0\r
 #ifndef _IPOIB_DEBUG_NDIS6\r
 #define _IPOIB_DEBUG_NDIS6\r
 CL_INLINE void CL_API\r
@@ -102,7 +102,7 @@ cl_qlist_check_validity(
        return;\r
 }\r
 #endif\r
-\r
+#endif\r
 /******************************************************************************\r
 *\r
 * Declarations\r
@@ -328,10 +328,11 @@ __send_mgr_destroy(
 static NDIS_STATUS\r
 __send_gen(\r
        IN                              ipoib_port_t* const                     p_port,\r
-       IN                              ipoib_send_desc_t* const        p_desc,\r
+       IN                              ipoib_send_NB_SG *                      s_buf,\r
        IN                              SCATTER_GATHER_LIST                     *p_sgl,\r
        IN                              INT                                             lso_data_index,\r
-       IN                              NET_BUFFER                                      *p_netbuf);\r
+       IN                              NET_BUFFER                                      *p_netbuf,\r
+       IN                              UINT                                            lso_header_size OPTIONAL);\r
 \r
 static NDIS_STATUS\r
 __send_mgr_filter_ip(\r
@@ -340,7 +341,7 @@ __send_mgr_filter_ip(
        IN                              MDL*                                            p_mdl,\r
        IN                              size_t                                          buf_len,\r
        IN                              SCATTER_GATHER_LIST                     *p_sgl,\r
-       IN      OUT                     ipoib_send_desc_t* const        p_desc,\r
+       IN      OUT                     ipoib_send_NB_SG* const         s_buf,\r
        IN                              NET_BUFFER                                      *p_netbuf);\r
 \r
 static NDIS_STATUS\r
@@ -357,7 +358,7 @@ __send_mgr_filter_udp(
        IN              const   ip_hdr_t* const                         p_ip_hdr,\r
        IN                              MDL*                                            p_mdl,\r
        IN                              size_t                                          buf_len,\r
-       IN      OUT                     ipoib_send_desc_t* const        p_desc );\r
+       IN      OUT                     ipoib_send_NB_SG* const         s_buf);\r
 \r
 static NDIS_STATUS\r
 __send_mgr_filter_dhcp(\r
@@ -365,7 +366,7 @@ __send_mgr_filter_dhcp(
        IN              const   udp_hdr_t* const                        p_udp_hdr,\r
        IN                              MDL*                                            p_mdl,\r
        IN                              size_t                                          buf_len,\r
-       IN      OUT                     ipoib_send_desc_t* const        p_desc );\r
+       IN      OUT                     ipoib_send_NB_SG* const         s_buf );\r
 \r
 static NDIS_STATUS\r
 __send_mgr_filter_arp(\r
@@ -373,14 +374,15 @@ __send_mgr_filter_arp(
        IN              const   eth_hdr_t* const                        p_eth_hdr,\r
        IN                              MDL*                                            p_mdl,\r
        IN                              size_t                                          buf_len,\r
-       IN      OUT                     ipoib_send_desc_t* const        p_desc );\r
+       IN      OUT                     ipoib_send_NB_SG* const         s_buf );\r
+\r
+static inline void \r
+__send_complete_net_buffer(\r
+       IN      ipoib_send_NB_SG        *s_buf, \r
+       IN      NDIS_STATUS             status,\r
+       IN      ULONG                           compl_flags,\r
+       IN      boolean_t                       bLock   );\r
 \r
-static void\r
-__process_failed_send(\r
-       IN                              ipoib_port_t* const                     p_port,\r
-       IN                              ipoib_send_desc_t* const        p_desc,\r
-       IN              const   NDIS_STATUS                                     status,\r
-       IN              ULONG                                           send_complete_flags );\r
 \r
 static inline NDIS_STATUS\r
 __send_mgr_queue(\r
@@ -395,7 +397,6 @@ __build_send_desc(
        IN                              MDL* const                                      p_mdl,\r
        IN              const   size_t                                          mdl_len,\r
        IN                              SCATTER_GATHER_LIST                     *p_sgl,\r
-       IN      OUT                     ipoib_send_desc_t* const        p_desc,\r
        IN                              NET_BUFFER                                      *p_netbuf,\r
        IN                              ipoib_send_NB_SG                        *s_buf);\r
 \r
@@ -416,13 +417,15 @@ GetLsoHeaderSize(
 static NDIS_STATUS\r
 __build_lso_desc(\r
        IN                              ipoib_port_t* const                     p_port,\r
-       IN      OUT                     ipoib_send_desc_t* const        p_desc,\r
        IN                              ULONG                                           mss,\r
        IN                              SCATTER_GATHER_LIST                     *p_sgl,\r
        IN                              int32_t                                         hdr_idx,\r
        IN PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO p_lso_info,\r
        IN                              NET_BUFFER                                      *p_netbuf);\r
 \r
+//TODO CM Restore\r
+#if 0\r
+\r
 static NDIS_STATUS\r
 __send_fragments(\r
        IN              ipoib_port_t* const                                     p_port,\r
@@ -432,8 +435,7 @@ __send_fragments(
        IN              uint32_t                                                        buf_len,\r
        IN              NDIS_BUFFER*                                            p_ndis_buf );\r
 \r
-//TODO CM Restore\r
-#if 0\r
+\r
 static void\r
 __update_fragment_ip_hdr(\r
 IN             ip_hdr_t* const         p_ip_hdr,\r
@@ -1087,6 +1089,19 @@ __ib_mgr_init(
                        p_port->p_adapter->params.recv_chksum_offload = CSUM_DISABLED;\r
        }\r
 \r
+\r
+       // Now, params struct contains the intersection between the user definition\r
+       // and actual HW capabilites\r
+       // Remember these values for NDIS OID requests\r
+       p_port->p_adapter->offload_cap.lso = !!(p_port->p_adapter->params.lso);\r
+       p_port->p_adapter->offload_cap.send_chksum_offload = \r
+               !! (p_port->p_adapter->params.send_chksum_offload);\r
+       p_port->p_adapter->offload_cap.recv_chksum_offload = \r
+               !! (p_port->p_adapter->params.recv_chksum_offload);\r
+       \r
+       \r
+       \r
+       \r
        qp_create.h_sq_cq = p_port->ib_mgr.h_send_cq;\r
        qp_create.sq_signaled = FALSE;\r
        status = p_port->p_adapter->p_ifc->create_qp(\r
@@ -1359,7 +1374,6 @@ __buf_mgr_construct(
                NULL, NULL, 0, MAX_XFER_BLOCK_SIZE, 'bipi', 0 );\r
 \r
        p_port->buf_mgr.h_send_pkt_pool = NULL;\r
-       p_port->buf_mgr.h_send_buf_pool = NULL;\r
 \r
        IPOIB_EXIT( IPOIB_DBG_INIT );\r
 }\r
@@ -1406,6 +1420,7 @@ __buf_mgr_init(
     pool_parameters.ContextSize = 0;\r
     pool_parameters.fAllocateNetBuffer = TRUE;\r
     pool_parameters.PoolTag = 'CRPI';\r
+       pool_parameters.DataSize = 0;\r
 \r
     p_port->buf_mgr.h_packet_pool = NdisAllocateNetBufferListPool(\r
                 p_port->p_adapter->h_adapter,\r
@@ -1419,18 +1434,7 @@ __buf_mgr_init(
                        ("NdisAllocatePacketPool returned %08X\n", (UINT)NDIS_STATUS_RESOURCES) );\r
                return IB_INSUFFICIENT_RESOURCES;\r
        }\r
-/*\r
-       NdisAllocateBufferPool( &ndis_status, &p_port->buf_mgr.h_buffer_pool,\r
-               p_params->rq_depth );\r
-       if( ndis_status != NDIS_STATUS_SUCCESS )\r
-       {\r
-               NdisWriteErrorLogEntry( p_port->p_adapter->h_adapter,\r
-                       EVENT_IPOIB_RECV_BUF_POOL, 1, ndis_status );\r
-               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
-                       ("NdisAllocateBufferPool returned %08X\n", ndis_status) );\r
-               return IB_INSUFFICIENT_RESOURCES;\r
-       }\r
-*/\r
+       \r
        /* Allocate the NET buffer list pool for send formatting. */\r
     pool_parameters.PoolTag = 'XTPI';\r
 \r
@@ -1445,18 +1449,7 @@ __buf_mgr_init(
                        ("NdisAllocatePacketPool returned %08X\n", (UINT)NDIS_STATUS_RESOURCES) );\r
                return IB_INSUFFICIENT_RESOURCES;\r
        }\r
-/*\r
-       NdisAllocateBufferPool( &ndis_status,\r
-               &p_port->buf_mgr.h_send_buf_pool, 1 );\r
-       if( ndis_status != NDIS_STATUS_SUCCESS )\r
-       {\r
-               NdisWriteErrorLogEntry( p_port->p_adapter->h_adapter,\r
-                       EVENT_IPOIB_SEND_BUF_POOL, 1, ndis_status );\r
-               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
-                       ("NdisAllocateBufferPool returned %08X\n", ndis_status) );\r
-               return IB_INSUFFICIENT_RESOURCES;\r
-       }\r
-*/\r
+\r
        IPOIB_EXIT( IPOIB_DBG_INIT );\r
        return IB_SUCCESS;\r
 }\r
@@ -3094,11 +3087,10 @@ __recv_mgr_prepare_NBL(
                break;\r
          case CSUM_BYPASS:\r
                /* Flag the checksums as having been calculated. */\r
-               chksum.Receive.TcpChecksumSucceeded = TRUE;\r
-               chksum.Receive.UdpChecksumSucceeded = TRUE;\r
+               chksum.Receive.TcpChecksumSucceeded = \r
+               chksum.Receive.UdpChecksumSucceeded = \r
                chksum.Receive.IpChecksumSucceeded = TRUE;\r
-               //NDIS60\r
-               //NDIS_PER_PACKET_INFO_FROM_PACKET( *pp_packet, TcpIpChecksumPacketInfo ) =\r
+               \r
                NET_BUFFER_LIST_INFO(*pp_net_buffer_list, TcpIpChecksumNetBufferListInfo) =\r
                (void*)(uintn_t)chksum.Value;\r
                break;\r
@@ -3210,12 +3202,27 @@ __send_mgr_init(
 \r
        CL_ASSERT( p_port );\r
 \r
-       static const size_t cPoolMaxSize(1000);\r
+       static const size_t cPoolDeltaSize(1024);\r
+       static const ULONG      MaxNumBuffers(16384);\r
        \r
        /* Allocate the pool for async NETBUF flow (process_sg_list) */\r
+       cl_status = cl_qpool_init( &p_port->send_mgr.sg_pool,\r
+               MaxNumBuffers,\r
+               0, cPoolDeltaSize, sizeof(cl_pool_item_t) + p_port->p_adapter->sg_list_size, NULL, NULL, p_port );\r
+       \r
+       if( cl_status != CL_SUCCESS )\r
+       {\r
+               NdisWriteErrorLogEntry( p_port->p_adapter->h_adapter,\r
+                       EVENT_IPOIB_RECV_POOL, 1, cl_status ); //TODO EVENT_IPOIB_SEND_POOL\r
+               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("cl_qpool_init for sends returned %#x\n",\r
+                       cl_status) );\r
+               return  IB_INSUFFICIENT_MEMORY;\r
+       }\r
+\r
        cl_status = cl_qpool_init( &p_port->send_mgr.send_pool,\r
-               cPoolMaxSize,\r
-               0, cPoolMaxSize, sizeof(ipoib_send_NB_SG), NULL, NULL, p_port );\r
+               MaxNumBuffers,\r
+               0, cPoolDeltaSize, sizeof(ipoib_send_NB_SG), NULL, NULL, p_port );\r
        \r
        if( cl_status != CL_SUCCESS )\r
        {\r
@@ -3224,6 +3231,7 @@ __send_mgr_init(
                IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
                        ("cl_qpool_init for sends returned %#x\n",\r
                        cl_status) );\r
+               cl_qpool_destroy(&p_port->send_mgr.sg_pool);\r
                return IB_INSUFFICIENT_MEMORY;\r
        }\r
 \r
@@ -3235,9 +3243,13 @@ __send_mgr_init(
                        EVENT_IPOIB_RECV_POOL, 1, CL_INSUFFICIENT_MEMORY); //TODO EVENT_IPOIB_SEND_POOL\r
                IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
                        ("Allocation of  send descriptor failed\n") );\r
+               cl_qpool_destroy(&p_port->send_mgr.send_pool);\r
+               cl_qpool_destroy(&p_port->send_mgr.sg_pool);\r
                return IB_INSUFFICIENT_MEMORY;\r
        }\r
+\r
        return IB_SUCCESS;\r
+\r
 }\r
 \r
 \r
@@ -3249,6 +3261,11 @@ __pending_list_destroy(
        ipoib_send_NB_SG        *s_buf;\r
        ULONG                           send_complete_flags = 0;\r
 \r
+       if (KeGetCurrentIrql() == DISPATCH_LEVEL)\r
+       {\r
+               NDIS_SET_SEND_COMPLETE_FLAG(send_complete_flags, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);\r
+       } \r
+\r
        cl_spinlock_acquire( &p_port->send_lock );\r
        /* Complete any pending packets. */\r
        for( p_item = cl_qlist_remove_head( &p_port->send_mgr.pending_list );\r
@@ -3263,22 +3280,7 @@ __pending_list_destroy(
                //Increase the send counter\r
                ++g_ipoib_send;\r
                \r
-               if (IPOIB_GET_NET_BUFFER_LIST_REF_COUNT(s_buf->p_nbl) == 0) {\r
-                                               \r
-                                       NET_BUFFER_LIST_STATUS(s_buf->p_nbl) = NDIS_STATUS_RESET_IN_PROGRESS;\r
-                                       cl_spinlock_release( &p_port->send_lock );\r
-                                       if (NDIS_TEST_SEND_COMPLETE_AT_DISPATCH_LEVEL(send_complete_flags))\r
-                                       {\r
-                                               //TODO Tzachid: make an assert here to validate your IRQL\r
-                                               ASSERT (KeGetCurrentIrql() == DISPATCH_LEVEL);\r
-                                               NDIS_SET_SEND_COMPLETE_FLAG(send_complete_flags, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);\r
-                                       } \r
-                                       NdisMSendNetBufferListsComplete(p_port->p_adapter->h_adapter,\r
-                                                                                                       s_buf->p_nbl,send_complete_flags);\r
-                                       cl_spinlock_acquire( &p_port->send_lock );\r
-               }\r
-               //Put back into the pool list structure allocated for the NB\r
-               cl_qpool_put(&p_port->send_mgr.send_pool, (cl_pool_item_t* )s_buf);\r
+               __send_complete_net_buffer(s_buf, NDIS_STATUS_RESET_IN_PROGRESS,send_complete_flags,TRUE);\r
 \r
        }\r
 \r
@@ -3293,15 +3295,19 @@ __send_mgr_destroy(
 {\r
        IPOIB_ENTER( IPOIB_DBG_SEND );\r
        //Destroy pending list and put all the send buffers back to pool\r
+       //The list should be already destroyed at this point\r
+       ASSERT(p_port->send_mgr.pending_list.count == 0);\r
        __pending_list_destroy(p_port);\r
 \r
        // Now, destroy the send pool\r
        cl_qpool_destroy(&p_port->send_mgr.send_pool);\r
+       cl_qpool_destroy(&p_port->send_mgr.sg_pool);\r
 \r
        //Now, free port descriptor\r
        ExFreePoolWithTag(p_port->p_desc, 'XMXA');\r
-       \r
 \r
+       //Lookaside list will be destroyed in __buf_mgr_destroy\r
+       \r
        IPOIB_EXIT( IPOIB_DBG_SEND );\r
 }\r
 \r
@@ -3313,7 +3319,7 @@ __send_mgr_filter(
        IN                              MDL* const                                      p_mdl,\r
        IN                              size_t                                          buf_len,\r
        IN                              SCATTER_GATHER_LIST                     *p_sgl,\r
-       IN      OUT                     ipoib_send_desc_t* const        p_desc,\r
+       IN      OUT                     ipoib_send_NB_SG                        *s_buf,\r
        IN                              NET_BUFFER                                      *p_netbuf)\r
 {\r
        NDIS_STATUS             status;\r
@@ -3328,6 +3334,7 @@ __send_mgr_filter(
         * We already checked the ethernet header length, so we know it's safe\r
         * to decrement the buf_len without underflowing.\r
         */\r
+       ipoib_send_desc_t *p_desc = p_port->p_desc;\r
        buf_len -= sizeof(eth_hdr_t);\r
 \r
        switch( p_eth_hdr->type )\r
@@ -3335,14 +3342,14 @@ __send_mgr_filter(
        case ETH_PROT_TYPE_IP:\r
                cl_perf_start( FilterIp );\r
                status = __send_mgr_filter_ip(\r
-                       p_port, p_eth_hdr, p_mdl, buf_len, p_sgl, p_desc, p_netbuf);\r
+                       p_port, p_eth_hdr, p_mdl, buf_len, p_sgl, s_buf, p_netbuf);\r
                cl_perf_stop( &p_port->p_adapter->perf, FilterIp );\r
                break;\r
 \r
        case ETH_PROT_TYPE_ARP:\r
                cl_perf_start( FilterArp );\r
                status = __send_mgr_filter_arp(\r
-                       p_port, p_eth_hdr, p_mdl, buf_len, p_desc );\r
+                       p_port, p_eth_hdr, p_mdl, buf_len, s_buf );\r
                p_desc->send_dir = SEND_UD_QP;\r
                cl_perf_stop( &p_port->p_adapter->perf, FilterArp );\r
                break;\r
@@ -3355,7 +3362,7 @@ __send_mgr_filter(
 \r
                p_desc->send_dir = SEND_UD_QP;\r
                cl_perf_start( SendGen );\r
-               status = __send_gen( p_port, p_desc, p_sgl, 0, p_netbuf );\r
+               status = __send_gen( p_port, s_buf, p_sgl, 0, p_netbuf,0 );\r
                cl_perf_stop( &p_port->p_adapter->perf, SendGen );\r
                break;\r
        }\r
@@ -3365,73 +3372,128 @@ __send_mgr_filter(
 }\r
 \r
 \r
+// TODO: move the p_desc to be on the send buffer\r
+\r
+ULONG \r
+CopyNetBuffer(\r
+    PNET_BUFFER NetBuffer,\r
+    PUCHAR              pDest\r
+    ) \r
+{\r
+    ULONG  BytesCopied = 0;\r
+    \r
+    IPOIB_ENTER(IPOIB_DBG_SEND);\r
+\r
+    PUCHAR pSrc = NULL;\r
+    \r
+    PMDL CurrentMdl = NET_BUFFER_CURRENT_MDL(NetBuffer);\r
+    ULONG Offset = NET_BUFFER_CURRENT_MDL_OFFSET(NetBuffer);\r
+    ULONG DataLength = NET_BUFFER_DATA_LENGTH(NetBuffer);\r
+\r
+    \r
+    while (CurrentMdl && DataLength > 0)\r
+    {\r
+        ULONG  CurrLength;\r
+        NdisQueryMdl(CurrentMdl, &pSrc, &CurrLength, NormalPagePriority);\r
+        if (pSrc == NULL)\r
+        {\r
+            BytesCopied = 0;\r
+            break;\r
+        }\r
+        // \r
+        //  Current buffer length is greater than the offset to the buffer\r
+        //  \r
+        if (CurrLength > Offset)\r
+        { \r
+            pSrc += Offset;\r
+            CurrLength -= Offset;\r
+\r
+            if (CurrLength > DataLength)\r
+            {\r
+                CurrLength = DataLength;\r
+            }\r
+            DataLength -= CurrLength;\r
+            NdisMoveMemory(pDest, pSrc, CurrLength);\r
+            BytesCopied += CurrLength;\r
+\r
+            pDest += CurrLength;\r
+            pSrc += CurrLength;\r
+            Offset = 0;\r
+        }\r
+        else\r
+        {\r
+            ASSERT(FALSE);\r
+            Offset -= CurrLength;\r
+        }\r
+        NdisGetNextMdl(CurrentMdl, &CurrentMdl);\r
+    }\r
+\r
+    if (DataLength > 0)\r
+    {   \r
+        //\r
+        // In some cases the size in MDL isn't equal to the buffer size. In such \r
+        // a case we need to copy the rest of packet\r
+        //\r
+#ifdef _WIN64\r
+        ASSERT((((uint64_t)pSrc % PAGE_SIZE) + DataLength) <= PAGE_SIZE);\r
+#else\r
+        ASSERT((((uint32_t)pSrc % PAGE_SIZE) + DataLength) <= PAGE_SIZE);\r
+#endif\r
+        NdisMoveMemory(pDest, pSrc, DataLength);\r
+        BytesCopied += DataLength;\r
+    }\r
+    \r
+#if 0\r
+    if ((BytesCopied != 0) && (BytesCopied < NIC_MIN_PACKET_SIZE))\r
+    {\r
+        NdisZeroMemory(pDest, NIC_MIN_PACKET_SIZE - BytesCopied);\r
+    }\r
+#endif\r
+    \r
+   // NdisAdjustMdlLength(pMpTxBuf->Mdl, BytesCopied);\r
+   // NdisFlushBuffer(pMpTxBuf->Mdl, TRUE);\r
+    \r
+    //ASSERT(BytesCopied <= pMpTxBuf->BufferSize);\r
+\r
+    IPOIB_EXIT(IPOIB_DBG_SEND);\r
+    return BytesCopied;\r
+}\r
+\r
+\r
 static NDIS_STATUS\r
 __send_copy(\r
        IN                              ipoib_port_t* const                     p_port,\r
-       IN                              ipoib_send_desc_t* const        p_desc )\r
+       IN                              ipoib_send_NB_SG *                      s_buf,\r
+       IN                              UINT                                            lso_header_size)\r
 {\r
-       NET_BUFFER_LIST                 *p_net_buffer_list;\r
-       NET_BUFFER                              *p_netbuffer;\r
-       MDL                                             *p_mdl;\r
-       UINT                                    tot_len = 0;\r
+       ULONG                                   tot_len = 0;\r
 \r
        IPOIB_ENTER( IPOIB_DBG_SEND );\r
 \r
-       UNREFERENCED_PARAMETER(p_port);\r
-       UNREFERENCED_PARAMETER(p_desc);\r
+       ipoib_send_desc_t *p_desc = p_port->p_desc;\r
 \r
-       p_desc->p_buf = \r
+       ASSERT(s_buf->p_send_buf == NULL);\r
+       s_buf->p_send_buf = \r
                (send_buf_t *) NdisAllocateFromNPagedLookasideList( &p_port->buf_mgr.send_buf_list );\r
-       if( !p_desc->p_buf )\r
+       if( !s_buf->p_send_buf )\r
        {\r
                IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
                        ("Failed to allocate buffer for packet copy.\n") );\r
                return NDIS_STATUS_RESOURCES;\r
        }\r
+       tot_len = CopyNetBuffer(s_buf->p_curr_nb, (PUCHAR) s_buf->p_send_buf);\r
+       ASSERT(tot_len);\r
+       ASSERT(tot_len > lso_header_size);\r
+       //TODO Do not copy the ETH header \r
+       /* Setup the work request. */\r
+       int seg_index = lso_header_size ? 0 : 1;\r
 \r
-       p_mdl = NdisAllocateMdl(p_port->p_adapter->h_adapter,\r
-                                                       p_desc->p_buf,\r
-                                                       p_port->p_adapter->params.xfer_block_size );\r
-       if( !p_mdl )\r
-       {\r
-               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
-                       ("Failed to allocate MDL\n") );\r
-               return NDIS_STATUS_RESOURCES;\r
-       }\r
-\r
-       p_net_buffer_list = NdisAllocateNetBufferAndNetBufferList(\r
-                                               p_port->buf_mgr.h_send_buf_pool,\r
-                                               0,\r
-                                               0,\r
-                                               p_mdl,\r
-                                               0,\r
-                                               0);\r
+       p_desc->send_wr[0].local_ds[seg_index].vaddr = cl_get_physaddr(\r
+               ((uint8_t*)s_buf->p_send_buf) + lso_header_size );\r
+       p_desc->send_wr[0].local_ds[seg_index].length = tot_len - lso_header_size;\r
+       p_desc->send_wr[0].local_ds[seg_index].lkey = p_port->ib_mgr.lkey;\r
+       p_desc->send_wr[0].wr.num_ds = seg_index+1;\r
 \r
-       if( !p_net_buffer_list )\r
-       {\r
-               NdisFreeMdl(p_mdl);\r
-               IPOIB_PRINT_EXIT( TRACE_LEVEL_WARNING, IPOIB_DBG_SEND,\r
-                       ("Failed to allocate NDIS_PACKET for copy.\n") );\r
-               return NDIS_STATUS_RESOURCES;\r
-       }\r
-\r
-       for (p_netbuffer = NET_BUFFER_LIST_FIRST_NB(p_net_buffer_list); \r
-                p_netbuffer != NULL;\r
-                p_netbuffer = NET_BUFFER_NEXT_NB(p_netbuffer))\r
-       {\r
-               tot_len +=NET_BUFFER_DATA_LENGTH(p_netbuffer);\r
-       }\r
-\r
-       /* Setup the work request. */\r
-       p_desc->send_wr[0].local_ds[1].vaddr = cl_get_physaddr(\r
-               ((uint8_t*)p_desc->p_buf) + sizeof(eth_hdr_t) );\r
-       p_desc->send_wr[0].local_ds[1].length = tot_len - sizeof(eth_hdr_t);\r
-       p_desc->send_wr[0].local_ds[1].lkey = p_port->ib_mgr.lkey;\r
-       p_desc->send_wr[0].wr.num_ds = 2;\r
-       \r
-       /* Free our temp packet now that the data is copied. */\r
-       NdisFreeMdl(p_mdl);\r
-       NdisFreeNetBufferList(p_net_buffer_list);\r
 \r
        IPOIB_EXIT( IPOIB_DBG_SEND );\r
        return NDIS_STATUS_SUCCESS;\r
@@ -3678,23 +3740,20 @@ ipoib_process_sg_list_real(
        p_netbuf =                      s_buf->p_curr_nb;\r
        p_port =                        s_buf->p_port;\r
 \r
-       //ASSERT(p_port->send_lock.lock == 1);\r
-\r
-\r
 \r
        IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_SEND,\r
                                ("Processing netbuffer list: %p \n", p_net_buffer_list) );\r
 \r
 \r
-\r
        //TODO Define this function as void if we are not in DBG mode\r
-       cl_qlist_check_validity(&p_port->send_mgr.pending_list);\r
+       //cl_qlist_check_validity(&p_port->send_mgr.pending_list);\r
        NDIS_SET_SEND_COMPLETE_FLAG(complete_flags, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);\r
+       CL_ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);\r
 \r
        \r
        p_port->p_desc->p_netbuf_list = p_net_buffer_list;\r
        p_port->p_desc->p_endpt = NULL;\r
-       p_port->p_desc->p_buf = NULL;\r
+       s_buf->p_send_buf = NULL;\r
        p_port->p_desc->num_wrs = 1;\r
 \r
        IPOIB_PRINT( TRACE_LEVEL_VERBOSE, IPOIB_DBG_SEND,\r
@@ -3708,17 +3767,13 @@ ipoib_process_sg_list_real(
        if( status != NDIS_STATUS_SUCCESS )\r
        {\r
                cl_perf_start( ProcessFailedSends );\r
-               /* fail  net buffer list */\r
-\r
-               //ASSERT(FALSE);\r
-               //TODO: Mark that we will not send it, and only if all netbuffers were completed complete it\r
-               // Check all __process_failed_send\r
-               cl_dbg_out("Failed send inside process SG list\n");\r
-               __process_failed_send( p_port, p_port->p_desc, status, complete_flags);\r
-               ++g_ipoib_send_SG_failed;\r
+               /* fail  net buffer */\r
+               IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,("Failed send inside process SG list\n"));\r
+               __send_complete_net_buffer(s_buf, status, complete_flags, TRUE);\r
+               \r
                cl_perf_stop( &p_port->p_adapter->perf, ProcessFailedSends );\r
                ret = true;\r
-               ++g_ipoib_send_SG_pending;\r
+               ++g_ipoib_send_SG_failed;\r
                goto send_end;\r
        }\r
        from_queue = (boolean_t)(s_buf->p_sgl != NULL);\r
@@ -3732,7 +3787,7 @@ ipoib_process_sg_list_real(
                        s_buf->p_sgl = p_sgl;\r
                        cl_qlist_insert_head( &p_port->send_mgr.pending_list,\r
                                (cl_list_item_t*)s_buf  );\r
-                       //cl_dbg_out("We insert this item back to the pending list: %x \n", p_net_buffer_list);\r
+                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_MCAST, ("We insert this item back to the pending list: %p \n", p_net_buffer_list));\r
                        ret = false;\r
                        goto send_end;\r
                }\r
@@ -3742,14 +3797,12 @@ ipoib_process_sg_list_real(
 \r
                        if( ETH_IS_MULTICAST( p_eth_hdr->dst.addr ) )\r
                        {\r
-                               cl_dbg_out("recived a mc packet (from the queue) %p\n", p_net_buffer_list);\r
+                               IPOIB_PRINT( TRACE_LEVEL_VERBOSE, IPOIB_DBG_MCAST, ("recived a mc packet (from the queue) %p\n", p_net_buffer_list));\r
                                if( ipoib_port_join_mcast( p_port, p_eth_hdr->dst,\r
                                        IB_MC_REC_STATE_FULL_MEMBER) == IB_SUCCESS )\r
                                {\r
-                                       IPOIB_PRINT_EXIT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_SEND,\r
-                                               ("Multicast Mac - trying to join ?????????????????.\n") );\r
                                        s_buf->p_sgl = p_sgl;\r
-                                       cl_dbg_out("We insert this MULTICAST item back to the pending list: %x \n", p_net_buffer_list);                                 \r
+                                       IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_MCAST,("We insert this MULTICAST item back to the pending list: %p \n", p_net_buffer_list));                                    \r
                                        cl_qlist_insert_head( &p_port->send_mgr.pending_list, (cl_list_item_t*) s_buf  );\r
                                        ret = false;\r
                                        ++g_ipoib_send_SG_pending;\r
@@ -3760,10 +3813,10 @@ ipoib_process_sg_list_real(
                         * Complete the send as if we sent it - WHQL tests don't like the\r
                         * sends to fail.\r
                         */\r
-                       cl_dbg_out("We got bad status and the packet had not been sent\n");\r
+                       IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,("We got bad status and the packet had not been sent\n"));\r
                        cl_perf_start( ProcessFailedSends );\r
-                       __process_failed_send( p_port, p_port->p_desc, NDIS_STATUS_SUCCESS,complete_flags );\r
-                       cl_perf_stop( &p_port->p_adapter->perf, ProcessFailedSends );\r
+\r
+                       __send_complete_net_buffer(s_buf, NDIS_STATUS_SUCCESS, complete_flags, TRUE);\r
                        ret = true;\r
                        goto send_end;\r
                }\r
@@ -3852,27 +3905,25 @@ mc_end:
                         * Complete the send as if we sent it - WHQL tests don't like the\r
                         * sends to fail.\r
                         */\r
+                        //TODO - check previous comment !\r
                        cl_perf_start( ProcessFailedSends );\r
 \r
-                       // TODO: Need to make sure that we are not completing one part of the send\r
-                       cl_dbg_out("Problem sending packet, got bad status\n");\r
-                       \r
-                       __process_failed_send( p_port, p_port->p_desc, NDIS_STATUS_SUCCESS, complete_flags );\r
+                       __send_complete_net_buffer(s_buf, NDIS_STATUS_SUCCESS, complete_flags, TRUE);\r
                        cl_perf_stop( &p_port->p_adapter->perf, ProcessFailedSends );\r
-                       ++g_ipoib_send_SG_failed;\r
+                       //++g_ipoib_send_SG_failed;\r
                        ret = true;\r
                        goto send_end;\r
                }\r
        }\r
        cl_perf_start( BuildSendDesc );\r
-       status = __build_send_desc( p_port, p_eth_hdr, p_mdl, mdl_len, p_sgl, p_port->p_desc, p_netbuf, s_buf );\r
+       status = __build_send_desc( p_port, p_eth_hdr, p_mdl, mdl_len, p_sgl, p_netbuf, s_buf );\r
        cl_perf_stop( &p_port->p_adapter->perf, BuildSendDesc );\r
 \r
        if( status != NDIS_STATUS_SUCCESS )\r
        {\r
                ASSERT(FALSE);\r
                cl_perf_start( ProcessFailedSends );\r
-               __process_failed_send( p_port, p_port->p_desc, status, complete_flags );\r
+               __send_complete_net_buffer(s_buf, NDIS_STATUS_FAILURE, complete_flags, TRUE);\r
                cl_perf_stop( &p_port->p_adapter->perf, ProcessFailedSends );\r
                ret = true;\r
                goto send_end;\r
@@ -3881,7 +3932,7 @@ mc_end:
        /* Post the WR. */\r
        cl_perf_start( PostSend );\r
 //     cl_dbg_out("sending packet with wr-id =0x%x\n",p_net_buffer_list );\r
-       ++g_ipoib_send;\r
+       \r
        // IF this value is NULL, this netbuffer was already sent and when working on its NBL it will be not sent again\r
        ASSERT(s_buf->p_sgl == NULL);\r
        s_buf->p_sgl = p_sgl;\r
@@ -3894,25 +3945,15 @@ mc_end:
                        ("ib_post_send returned %s\n", \r
                        p_port->p_adapter->p_ifc->get_err_str( ib_status )) );\r
                cl_perf_start( ProcessFailedSends );\r
-               __process_failed_send( p_port, p_port->p_desc, NDIS_STATUS_FAILURE, complete_flags );\r
+               __send_complete_net_buffer(s_buf, NDIS_STATUS_FAILURE, complete_flags, TRUE);\r
                cl_perf_stop( &p_port->p_adapter->perf, ProcessFailedSends );\r
                /* Flag the adapter as hung since posting is busted. */\r
                p_port->p_adapter->hung = TRUE;\r
        }\r
+       ++g_ipoib_send;\r
        cl_atomic_inc( &p_port->send_mgr.depth );\r
 \r
-send_end:\r
-       if (status != NDIS_STATUS_SUCCESS) {\r
-               //TODO Restore\r
-//             IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_SEND,\r
-       //                                      ("Free S/G List: 0x%x.\n", (UINT) (PVOID) p_sgl) );\r
-               /*NdisMFreeNetBufferSGList(\r
-                       p_port->p_adapter->NdisMiniportDmaHandle,\r
-                       p_sgl,\r
-                       p_netbuf);*/\r
-               \r
-       }\r
-                       \r
+send_end:              \r
                        \r
        IPOIB_EXIT( IPOIB_DBG_SEND );\r
 \r
@@ -3949,15 +3990,14 @@ ipoib_process_sg_list(
 }\r
 \r
 \r
-\r
 static NDIS_STATUS\r
 __send_gen(\r
        IN                              ipoib_port_t* const                     p_port,\r
-       IN                              ipoib_send_desc_t* const        p_desc,\r
+       IN                              ipoib_send_NB_SG *                      s_buf,\r
        IN                              SCATTER_GATHER_LIST                     *p_sgl,\r
        IN                              INT                                                     lso_data_index,\r
-       IN                              NET_BUFFER                                      *p_netbuf\r
-        )\r
+       IN                              NET_BUFFER                                      *p_netbuf,\r
+       IN                              UINT                                            lso_header_size OPTIONAL)\r
 {\r
        NDIS_STATUS             status;\r
        uint32_t                i, j            = 1;\r
@@ -3975,6 +4015,7 @@ __send_gen(
                        ("Failed to get SGL from packet.\n") );\r
                return NDIS_STATUS_FAILURE;\r
        }\r
+       ipoib_send_desc_t *p_desc = p_port->p_desc;\r
        \r
        /* Remember that one of the DS entries is reserved for the IPoIB header. */\r
        if( ( p_sgl->NumberOfElements >= MAX_SEND_SGE ||\r
@@ -3989,7 +4030,7 @@ __send_gen(
                if( !p_port->p_adapter->params.cm_enabled )\r
                {\r
                        cl_perf_start( SendCopy );\r
-                       status = __send_copy( p_port, p_desc );\r
+                       status = __send_copy( p_port, s_buf, lso_header_size );\r
                        cl_perf_stop( &p_port->p_adapter->perf, SendCopy );\r
                }\r
                IPOIB_EXIT( IPOIB_DBG_SEND );\r
@@ -4007,6 +4048,22 @@ __send_gen(
        { /* we have an LSO packet */\r
                i = lso_data_index;\r
                j = 0;\r
+               ASSERT( i <= p_sgl->NumberOfElements);\r
+               if (i == p_sgl->NumberOfElements) {\r
+\r
+                       /****************************\r
+                       * Handle the case when there is only one SG element !\r
+                       ****************************/\r
+                       \r
+                       p_desc->send_wr[0].local_ds[j].vaddr = \r
+                               p_sgl->Elements[0].Address.QuadPart + lso_header_size;\r
+                       p_desc->send_wr[0].local_ds[j].length = \r
+                               p_sgl->Elements[0].Length - lso_header_size;\r
+                       p_desc->send_wr[0].local_ds[j].lkey = p_port->ib_mgr.lkey;\r
+                       /* Set the number of data segments. */\r
+                       p_desc->send_wr[0].wr.num_ds = 1;\r
+                       return NDIS_STATUS_SUCCESS;\r
+               }               \r
        }\r
        else while( offset )\r
        {\r
@@ -4052,7 +4109,7 @@ __send_mgr_filter_ip(
        IN                              MDL*                                            p_mdl,\r
        IN                              size_t                                          buf_len,\r
        IN                              SCATTER_GATHER_LIST                     *p_sgl,\r
-       IN      OUT                     ipoib_send_desc_t* const        p_desc,\r
+       IN                              ipoib_send_NB_SG                        *s_buf,\r
        IN                              NET_BUFFER                                      *p_netbuf)\r
 {\r
        NDIS_STATUS             status;\r
@@ -4067,6 +4124,7 @@ __send_mgr_filter_ip(
 \r
        IPOIB_ENTER( IPOIB_DBG_SEND );\r
 \r
+       ipoib_send_desc_t *p_desc = p_port->p_desc;\r
        if( !buf_len )\r
        {\r
                cl_perf_start( QueryIp );\r
@@ -4105,7 +4163,7 @@ __send_mgr_filter_ip(
 \r
                cl_perf_start( FilterUdp );\r
                status = __send_mgr_filter_udp(\r
-                       p_port, p_ip_hdr, p_mdl, (buf_len - sizeof(ip_hdr_t)), p_desc );\r
+                       p_port, p_ip_hdr, p_mdl, (buf_len - sizeof(ip_hdr_t)), s_buf );\r
                cl_perf_stop( &p_port->p_adapter->perf, FilterUdp );\r
                if( status == NDIS_STATUS_PENDING )\r
                {  /* not DHCP packet, keep going */\r
@@ -4173,7 +4231,7 @@ __send_mgr_filter_ip(
 \r
 send_gen:\r
        cl_perf_start( SendTcp );\r
-       status = __send_gen( p_port, p_desc, p_sgl, 0, p_netbuf );\r
+       status = __send_gen( p_port, s_buf, p_sgl, 0, p_netbuf,0 );\r
        cl_perf_stop( &p_port->p_adapter->perf, SendTcp );\r
 \r
        IPOIB_EXIT( IPOIB_DBG_SEND );\r
@@ -4314,7 +4372,7 @@ __send_mgr_filter_udp(
        IN              const   ip_hdr_t* const                         p_ip_hdr,\r
        IN                              MDL*                                            p_mdl,\r
        IN                              size_t                                          buf_len,\r
-       IN      OUT                     ipoib_send_desc_t* const        p_desc )\r
+       IN      OUT                     ipoib_send_NB_SG*                       s_buf )\r
 {\r
        NDIS_STATUS                     status;\r
        udp_hdr_t                       *p_udp_hdr;\r
@@ -4375,22 +4433,22 @@ __send_mgr_filter_udp(
        buf_len -= sizeof(udp_hdr_t);\r
 \r
        /* Allocate our scratch buffer. */\r
-       p_desc->p_buf = (send_buf_t*)\r
+       s_buf->p_send_buf = (send_buf_t*)\r
                ExAllocateFromNPagedLookasideList( &p_port->buf_mgr.send_buf_list );\r
-       if( !p_desc->p_buf )\r
+       if( !s_buf->p_send_buf )\r
        {\r
                IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
                        ("Failed to query DHCP packet buffer.\n") );\r
                return NDIS_STATUS_RESOURCES;\r
        }\r
        /* Copy the IP and UDP headers. */\r
-       cl_memcpy( &p_desc->p_buf->ip.hdr, p_ip_hdr , sizeof(ip_hdr_t) );\r
+       cl_memcpy( &s_buf->p_send_buf->ip.hdr, p_ip_hdr , sizeof(ip_hdr_t) );\r
        cl_memcpy(\r
-               &p_desc->p_buf->ip.prot.udp.hdr, p_udp_hdr, sizeof(udp_hdr_t) );\r
+               &s_buf->p_send_buf->ip.prot.udp.hdr, p_udp_hdr, sizeof(udp_hdr_t) );\r
 \r
        cl_perf_start( FilterDhcp );\r
        status = __send_mgr_filter_dhcp(\r
-               p_port, p_udp_hdr, p_mdl, buf_len, p_desc );\r
+               p_port, p_udp_hdr, p_mdl, buf_len, s_buf );\r
        cl_perf_stop( &p_port->p_adapter->perf, FilterDhcp );\r
 \r
        IPOIB_EXIT( IPOIB_DBG_SEND );\r
@@ -4416,7 +4474,7 @@ __send_mgr_filter_dhcp(
        IN              const   udp_hdr_t* const                        p_udp_hdr,\r
        IN                              NDIS_BUFFER*                            p_mdl,\r
        IN                              size_t                                          buf_len,\r
-       IN      OUT                     ipoib_send_desc_t* const        p_desc )\r
+       IN      OUT                     ipoib_send_NB_SG*                       s_buf )\r
 {\r
        dhcp_pkt_t                      *p_dhcp;\r
        dhcp_pkt_t                      *p_ib_dhcp;\r
@@ -4427,6 +4485,8 @@ __send_mgr_filter_dhcp(
 \r
        IPOIB_ENTER( IPOIB_DBG_SEND );\r
 \r
+       ipoib_send_desc_t *p_desc = p_port->p_desc;\r
+       \r
        if( !buf_len )\r
        {\r
                NdisGetNextMdl( p_mdl, &p_mdl );\r
@@ -4456,7 +4516,7 @@ __send_mgr_filter_dhcp(
                return NDIS_STATUS_BUFFER_TOO_SHORT;\r
        }\r
 \r
-       p_ib_dhcp = &p_desc->p_buf->ip.prot.udp.dhcp;\r
+       p_ib_dhcp = &s_buf->p_send_buf->ip.prot.udp.dhcp;\r
        cl_memcpy( p_ib_dhcp, p_dhcp, buf_len );\r
 \r
        /* Now scan through the options looking for the client identifier. */\r
@@ -4557,14 +4617,14 @@ __send_mgr_filter_dhcp(
                p_ib_dhcp->htype = DHCP_HW_TYPE_IB;\r
 \r
                /* update lengths to include any change we made */\r
-               p_desc->p_buf->ip.hdr.length = cl_ntoh16( sizeof(ip_hdr_t) + sizeof(udp_hdr_t) + sizeof(dhcp_pkt_t) );\r
-               p_desc->p_buf->ip.prot.udp.hdr.length = cl_ntoh16( sizeof(udp_hdr_t) + sizeof(dhcp_pkt_t) );\r
+               s_buf->p_send_buf->ip.hdr.length = cl_ntoh16( sizeof(ip_hdr_t) + sizeof(udp_hdr_t) + sizeof(dhcp_pkt_t) );\r
+               s_buf->p_send_buf->ip.prot.udp.hdr.length = cl_ntoh16( sizeof(udp_hdr_t) + sizeof(dhcp_pkt_t) );\r
 \r
                /* update crc in ip header */\r
                //if( !p_port->p_adapter->params.send_chksum_offload )\r
                //{ //TODO ?\r
-               p_desc->p_buf->ip.hdr.chksum = 0;\r
-               p_desc->p_buf->ip.hdr.chksum = ipchksum((unsigned short*) &p_desc->p_buf->ip.hdr, sizeof(ip_hdr_t));\r
+               s_buf->p_send_buf->ip.hdr.chksum = 0;\r
+               s_buf->p_send_buf->ip.hdr.chksum = ipchksum((unsigned short*) &s_buf->p_send_buf->ip.hdr, sizeof(ip_hdr_t));\r
                //} TODO ??\r
                break;\r
 \r
@@ -4581,8 +4641,8 @@ __send_mgr_filter_dhcp(
                return NDIS_STATUS_INVALID_DATA;\r
        }\r
        /* no chksum for udp */\r
-       p_desc->p_buf->ip.prot.udp.hdr.chksum = 0;\r
-       p_desc->send_wr[0].local_ds[1].vaddr = cl_get_physaddr( p_desc->p_buf );\r
+       s_buf->p_send_buf->ip.prot.udp.hdr.chksum = 0;\r
+       p_desc->send_wr[0].local_ds[1].vaddr = cl_get_physaddr( s_buf->p_send_buf );\r
        p_desc->send_wr[0].local_ds[1].length = sizeof(ip_hdr_t) +      sizeof(udp_hdr_t) + sizeof(dhcp_pkt_t);\r
        p_desc->send_wr[0].local_ds[1].lkey = p_port->ib_mgr.lkey;\r
        p_desc->send_wr[0].wr.num_ds = 2;\r
@@ -4598,7 +4658,7 @@ __send_mgr_filter_arp(
        IN              const   eth_hdr_t* const                        p_eth_hdr,\r
        IN                              MDL*                                            p_mdl,\r
        IN                              size_t                                          buf_len,\r
-       IN      OUT                     ipoib_send_desc_t* const        p_desc )\r
+       IN      OUT                     ipoib_send_NB_SG*                       s_buf )\r
 {\r
        arp_pkt_t                       *p_arp;\r
        ipoib_arp_pkt_t         *p_ib_arp;\r
@@ -4606,6 +4666,8 @@ __send_mgr_filter_arp(
        mac_addr_t                      null_hw = {0};\r
 \r
        IPOIB_ENTER( IPOIB_DBG_SEND );\r
+\r
+       ipoib_send_desc_t *p_desc = p_port->p_desc;\r
        \r
        if( !buf_len )\r
        {\r
@@ -4645,15 +4707,16 @@ __send_mgr_filter_arp(
        }\r
 \r
        /* Allocate our scratch buffer. */\r
-       p_desc->p_buf = (send_buf_t*)\r
+       ASSERT(s_buf->p_send_buf == NULL);\r
+       s_buf->p_send_buf = (send_buf_t*)\r
                NdisAllocateFromNPagedLookasideList( &p_port->buf_mgr.send_buf_list );\r
-       if( !p_desc->p_buf )\r
+       if( !s_buf->p_send_buf )\r
        {\r
                IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
                        ("Failed to query ARP packet buffer.\n") );\r
                return NDIS_STATUS_RESOURCES;\r
        }\r
-       p_ib_arp = (ipoib_arp_pkt_t*)p_desc->p_buf;\r
+       p_ib_arp = (ipoib_arp_pkt_t*)s_buf->p_send_buf;\r
 \r
        /* Convert the ARP payload. */\r
        p_ib_arp->hw_type = ARP_HW_TYPE_IB;\r
@@ -4710,9 +4773,9 @@ __send_mgr_filter_arp(
                                                                                ipoib_addr_get_qpn( &p_ib_arp->dst_hw ) );\r
 \r
                                        NdisFreeToNPagedLookasideList(\r
-                                               &p_port->buf_mgr.send_buf_list, p_desc->p_buf );\r
+                                               &p_port->buf_mgr.send_buf_list, s_buf->p_send_buf );\r
                                        cl_qlist_insert_tail( &p_port->send_mgr.pending_list,\r
-                                                               IPOIB_LIST_ITEM_FROM_NBL( p_desc->p_buf ) );\r
+                                                               IPOIB_LIST_ITEM_FROM_NBL( s_buf->p_send_buf ) );\r
                                        NdisInterlockedInsertTailList( &p_port->endpt_mgr.pending_conns, \r
                                                                                                &p_desc->p_endpt->list_item, \r
                                                                                                &p_port->endpt_mgr.conn_lock );\r
@@ -4722,7 +4785,7 @@ __send_mgr_filter_arp(
                        case IPOIB_CM_CONNECT:\r
                                /* queue ARP REP packet until connected */\r
                                        NdisFreeToNPagedLookasideList(\r
-                                       &p_port->buf_mgr.send_buf_list, p_desc->p_buf );\r
+                                       &p_port->buf_mgr.send_buf_list, s_buf->p_send_buf );\r
                                        cl_qlist_insert_tail( &p_port->send_mgr.pending_list,\r
                                                                IPOIB_LIST_ITEM_FROM_NBL( p_desc->p_pkt ) );\r
                                        return NDIS_STATUS_PENDING;\r
@@ -4830,33 +4893,46 @@ __build_send_desc(
        IN                              MDL* const                                      p_mdl,\r
        IN              const   size_t                                          mdl_len,\r
        IN                              SCATTER_GATHER_LIST                     *p_sgl,\r
-       IN      OUT                     ipoib_send_desc_t* const        p_desc,\r
        IN                              NET_BUFFER                                      *p_netbuf,\r
        IN                              ipoib_send_NB_SG                        *s_buf)\r
 {\r
        NDIS_STATUS                     status;\r
        int32_t                         hdr_idx;\r
-       uint32_t                        mss = 0;\r
+       ULONG                           mss = 0;\r
 \r
-       PNDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO                      p_checksum_list_info;\r
+       PNDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO                      p_checksum_list_info = NULL;\r
        PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO       p_lso_info = NULL;\r
        PERF_DECLARE( SendMgrFilter );\r
        \r
        IPOIB_ENTER( IPOIB_DBG_SEND );\r
 \r
-       /* Format the send descriptor. */\r
-       p_checksum_list_info =\r
-               (PNDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO) NET_BUFFER_LIST_INFO( p_desc->p_netbuf_list,TcpIpChecksumNetBufferListInfo);\r
+       ipoib_send_desc_t *p_desc = p_port->p_desc;\r
 \r
+       /* Format the send descriptor. */\r
+       PVOID* ppTemp           = &NET_BUFFER_LIST_INFO(s_buf->p_nbl, TcpIpChecksumNetBufferListInfo);\r
+    p_checksum_list_info = \r
+                        (PNDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO) ((PULONG)ppTemp); \r
        // Calculate LSO\r
        if( p_port->p_adapter->params.lso ) {\r
-               p_lso_info = \r
-                       (PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO) \r
-                       NET_BUFFER_LIST_INFO( p_desc->p_netbuf_list, TcpLargeSendNetBufferListInfo );\r
+\r
+               p_lso_info =\r
+                       (PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO) (PULONG) &NET_BUFFER_LIST_INFO(s_buf->p_nbl, TcpLargeSendNetBufferListInfo);\r
                ASSERT(p_lso_info);\r
-               if (p_lso_info) {\r
-                       mss = (p_lso_info->LsoV1Transmit.MSS | p_lso_info->LsoV2Transmit.MSS);\r
+       ULONG LsoType = p_lso_info->Transmit.Type;\r
+\r
+           mss = p_lso_info->LsoV1Transmit.MSS;\r
+               ULONG PacketLength = NET_BUFFER_DATA_LENGTH(p_netbuf);\r
+               if  (PacketLength < mss) {\r
+                       ASSERT(FALSE);\r
+                       return NDIS_STATUS_INVALID_PACKET;\r
                }\r
+           if(LsoType == NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE) {\r
+               ASSERT(p_lso_info->LsoV2Transmit.Type == NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE);\r
+               ASSERT(mss == p_lso_info->LsoV2Transmit.MSS);\r
+               ASSERT(p_lso_info->LsoV1Transmit.TcpHeaderOffset == p_lso_info->LsoV2Transmit.TcpHeaderOffset);\r
+           }\r
+                       \r
+                       \r
        }\r
                        \r
        /* Format the send descriptor. */\r
@@ -4866,17 +4942,21 @@ __build_send_desc(
        p_port->hdr[hdr_idx].type = p_eth_hdr->type;\r
        p_port->hdr[hdr_idx].resv = 0;\r
 \r
+       //TODO why we enter this block for LSO ???\r
        p_desc->send_wr[0].local_ds[0].vaddr = cl_get_physaddr( &p_port->hdr[hdr_idx] );\r
        p_desc->send_wr[0].local_ds[0].length = sizeof(ipoib_hdr_t);\r
        p_desc->send_wr[0].local_ds[0].lkey = p_port->ib_mgr.lkey;\r
        p_desc->send_wr[0].wr.send_opt = 0;\r
+       //Set this value to 0\r
+       s_buf->p_send_buf = NULL;\r
 \r
        \r
                \r
-       if (mss) { //We have LSO packet\r
+       if (mss && (p_lso_info->LsoV1Transmit.TcpHeaderOffset != 0)) { //We have LSO packet\r
+               \r
                ASSERT( mss == (p_lso_info->LsoV1Transmit.MSS & p_lso_info->LsoV2Transmit.MSS));\r
-               ASSERT ( (mss & (1<<20)) == mss);\r
-               status = __build_lso_desc( p_port, p_desc, mss, p_sgl, hdr_idx, p_lso_info, p_netbuf);\r
+               //ASSERT ( (mss & (1<<20)) == mss);\r
+               status = __build_lso_desc( p_port, mss, p_sgl, hdr_idx, p_lso_info, p_netbuf);\r
                if( status != NDIS_STATUS_SUCCESS )\r
                {\r
                        IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
@@ -4890,7 +4970,7 @@ __build_send_desc(
                uint32_t        i;\r
                cl_perf_start( SendMgrFilter );\r
                status = __send_mgr_filter(\r
-               p_port, p_eth_hdr, p_mdl, mdl_len,p_sgl, p_desc, p_netbuf );\r
+               p_port, p_eth_hdr, p_mdl, mdl_len,p_sgl, s_buf, p_netbuf );\r
                cl_perf_stop( &p_port->p_adapter->perf, SendMgrFilter );\r
                if( status != NDIS_STATUS_SUCCESS )\r
                {\r
@@ -4921,7 +5001,7 @@ __build_send_desc(
                                        {\r
                                                p_desc->send_wr[i].wr.send_opt |= IB_SEND_OPT_TX_IP_CSUM;\r
                                        }\r
-                                       if( p_checksum_list_info->Transmit.TcpChecksum )\r
+                                       if( p_checksum_list_info->Transmit.TcpChecksum || p_checksum_list_info->Transmit.UdpChecksum)\r
                                        {\r
                                                p_desc->send_wr[i].wr.send_opt |= IB_SEND_OPT_TX_TCP_UDP_CSUM;\r
                                        }\r
@@ -4954,7 +5034,9 @@ __build_send_desc(
 \r
        ASSERT(s_buf == (ipoib_send_NB_SG *) IPOIB_INFO_FROM_NB(p_netbuf));\r
        s_buf->p_endpt = p_desc->p_endpt;\r
-       s_buf->p_send_buf= p_desc->p_buf;\r
+       //TODO IMPORTANT: Send buffer should not be allocated within global struct !!!\r
+       // Otherwise, the next send may override its content\r
+       //s_buf->p_send_buf= p_desc->p_buf;\r
        \r
        IPOIB_EXIT( IPOIB_DBG_SEND );\r
        return NDIS_STATUS_SUCCESS;\r
@@ -4963,7 +5045,6 @@ __build_send_desc(
 static NDIS_STATUS\r
 __build_lso_desc(\r
        IN                              ipoib_port_t* const                     p_port,\r
-       IN      OUT                     ipoib_send_desc_t* const        p_desc,\r
        IN                              ULONG                                           mss,\r
        IN                              SCATTER_GATHER_LIST                     *p_sgl,\r
        IN                              int32_t                                         hdr_idx, \r
@@ -4973,13 +5054,15 @@ __build_lso_desc(
        NDIS_STATUS                     status;\r
        LsoData                                                         TheLsoData;\r
        UINT                                                            IndexOfData = 0;\r
-       \r
-       PNET_BUFFER     FirstBuffer  = NET_BUFFER_LIST_FIRST_NB (p_desc->p_netbuf_list);\r
-       ULONG                   PacketLength = NET_BUFFER_DATA_LENGTH(FirstBuffer);\r
 \r
        IPOIB_ENTER( IPOIB_DBG_SEND );\r
 \r
+       ipoib_send_NB_SG * s_buf = IPOIB_INFO_FROM_NB(p_netbuf);\r
+       ipoib_send_desc_t *p_desc = p_port->p_desc;\r
 \r
+       //TODO What if first NB was inserted to pending list ????\r
+       PNET_BUFFER     FirstBuffer  = NET_BUFFER_LIST_FIRST_NB (s_buf->p_nbl);\r
+       ULONG                   PacketLength = NET_BUFFER_DATA_LENGTH(FirstBuffer);\r
 \r
        memset(&TheLsoData, 0, sizeof TheLsoData );\r
        status = GetLsoHeaderSize(\r
@@ -5001,10 +5084,18 @@ __build_lso_desc(
                }\r
                return status;\r
        }\r
-       ASSERT(TheLsoData.LsoHeaderSize> 0);\r
+       ASSERT(TheLsoData.LsoHeaderSize > 0);\r
        // Tell NDIS how much we will send.\r
        //PktExt->NdisPacketInfo[TcpLargeSendPacketInfo] = UlongToPtr(PacketLength);\r
-       p_lso_info->LsoV1TransmitComplete.TcpPayload = PacketLength;\r
+       //p_lso_info->LsoV1TransmitComplete.TcpPayload = PacketLength;\r
+       \r
+       // Tell NDIS how much we will send.\r
+       if(p_lso_info->LsoV1Transmit.Type == NDIS_TCP_LARGE_SEND_OFFLOAD_V1_TYPE)\r
+    {\r
+               //IPOIB_TCP_PAYLOAD_FROM_NB(p_netbuf) += PacketLength-TheLsoData.LsoHeaderSize;\r
+               s_buf->tcp_payload = PacketLength-TheLsoData.LsoHeaderSize;\r
+               \r
+       }\r
 \r
        p_desc->send_wr[0].wr.dgrm.ud.mss = mss;\r
        p_desc->send_wr[0].wr.dgrm.ud.header = TheLsoData.LsoBuffers[0].pData;\r
@@ -5015,8 +5106,7 @@ __build_lso_desc(
        p_desc->send_wr[0].wr.dgrm.ud.pkey_index = p_port->pkey_index;\r
        p_desc->send_wr[0].wr.dgrm.ud.rsvd = NULL;\r
 \r
-       //TODO: Should be NBL or p_desc SHOULD be s_buf\r
-       p_desc->send_wr[0].wr.wr_id = (uintn_t)p_desc->p_netbuf_list;\r
+       p_desc->send_wr[0].wr.wr_id = (uintn_t)s_buf;\r
        p_desc->send_wr[0].wr.ds_array = p_desc->send_wr[0].local_ds;\r
        p_desc->send_wr[0].wr.wr_type = WR_LSO;\r
        p_desc->send_wr[0].wr.send_opt = \r
@@ -5025,50 +5115,12 @@ __build_lso_desc(
        p_desc->send_wr[0].wr.p_next = NULL;\r
        p_desc->send_qp = p_port->ib_mgr.h_qp;\r
        p_desc->send_dir = SEND_UD_QP;\r
-       status = __send_gen(p_port, p_desc, p_sgl, IndexOfData, p_netbuf);\r
+       status = __send_gen(p_port, s_buf, p_sgl, IndexOfData, p_netbuf, TheLsoData.LsoHeaderSize);\r
 \r
        IPOIB_EXIT( IPOIB_DBG_SEND );\r
        return status;\r
 }\r
 \r
-static inline void\r
-__process_failed_send(\r
-       IN                              ipoib_port_t* const                     p_port,\r
-       IN                              ipoib_send_desc_t* const        p_desc,\r
-       IN              const   NDIS_STATUS                                     status,\r
-       IN                              ULONG                                           compl_flags)\r
-{\r
-\r
-       cl_dbg_out("__process_failed_send called, chechk that things are ok\n");\r
-\r
-       IPOIB_ENTER( IPOIB_DBG_SEND );\r
-       PNET_BUFFER_LIST p_nbl  = p_desc->p_netbuf_list;\r
-\r
-       /* Complete the packet. */\r
-       NET_BUFFER_LIST_NEXT_NBL(p_desc->p_netbuf_list) = NULL;\r
-       NET_BUFFER_LIST_STATUS(p_desc->p_netbuf_list) = status;\r
-       \r
-       IPOIB_DEC_NET_BUFFER_LIST_REF_COUNT(p_nbl);\r
-       if (IPOIB_GET_NET_BUFFER_LIST_REF_COUNT(p_nbl) == 0) {\r
-               cl_spinlock_release( &p_port->send_lock );\r
-               NdisMSendNetBufferListsComplete( p_port->p_adapter->h_adapter,\r
-                       p_nbl, compl_flags );\r
-               cl_spinlock_acquire( &p_port->send_lock );\r
-       }\r
-       \r
-       ipoib_inc_send_stat( p_port->p_adapter, IP_STAT_ERROR, 0 );\r
-       /* Deref the endpoint. */\r
-       if( p_desc->p_endpt )\r
-               ipoib_endpt_deref( p_desc->p_endpt );\r
-\r
-       if( p_desc->p_buf )\r
-       {\r
-               NdisFreeToNPagedLookasideList(\r
-                       &p_port->buf_mgr.send_buf_list, p_desc->p_buf );\r
-       }\r
-\r
-       IPOIB_EXIT( IPOIB_DBG_SEND );\r
-}\r
 \r
 // max number of physical fragmented buffers \r
 #define MAX_PHYS_BUF_FRAG_ELEMENTS      0x29\r
@@ -5091,7 +5143,7 @@ CreateFragList(
     PMP_FRAG_LIST pFragList\r
     )\r
 {\r
-//    ETH_ENTER(ETH_SND);\r
+\r
 \r
     ULONG i = 0;\r
        int j=0;\r
@@ -5250,7 +5302,6 @@ ipoib_port_send(
        NDIS_STATUS                     status;\r
        PNET_BUFFER                     p_netbuf, p_next_netbuf = NULL;\r
        UINT                            buf_cnt = 0;\r
-       //ipoib_send_desc_t     *p_desc;\r
        ULONG                           send_complete_flags = 0;\r
        \r
        KIRQL                           old_irql;\r
@@ -5299,6 +5350,11 @@ ipoib_port_send(
        cl_spinlock_acquire( &p_port->send_lock );\r
        // You are already here at dispatch\r
 \r
+       // We need to init the status here\r
+       // When completing the send, we will set the status NDIS_STATUS_FAILURE if AT LEAST\r
+       // one of NBs will fail.\r
+       // That is, status can't be updated back to SUCCESS if it previosly was set to FAILURE\r
+       NET_BUFFER_LIST_STATUS(p_net_buffer_list) = NDIS_STATUS_SUCCESS;\r
 \r
        for (p_netbuf = NET_BUFFER_LIST_FIRST_NB(p_net_buffer_list);\r
                 p_netbuf != NULL; \r
@@ -5322,7 +5378,16 @@ ipoib_port_send(
                p_next_netbuf = NET_BUFFER_NEXT_NB(p_netbuf);\r
 \r
                ipoib_send_NB_SG * s_buf = (ipoib_send_NB_SG*) (PVOID) (cl_qpool_get(&p_port->send_mgr.send_pool));\r
-               ASSERT(s_buf != NULL);// TODO: replace assert\r
+               if (s_buf == NULL) {\r
+                       ASSERT(FALSE);\r
+                       NET_BUFFER_LIST_STATUS(p_net_buffer_list) = NDIS_STATUS_RESOURCES;\r
+                       NdisMSendNetBufferListsComplete(\r
+                               p_port->p_adapter->h_adapter,\r
+                               p_net_buffer_list,\r
+                               send_complete_flags);   \r
+                               break;\r
+               }\r
+                       \r
 \r
                //Set all the data needed for process_sg_list\r
                s_buf->p_port = p_port;\r
@@ -5330,8 +5395,13 @@ ipoib_port_send(
                s_buf->p_nbl = p_net_buffer_list;\r
                s_buf->p_curr_nb = p_netbuf;\r
 \r
-               IPOIB_INFO_FROM_NB(p_netbuf) = s_buf;\r
+               //We can also define p_sg_buf as a static member of send_buf,\r
+               // But the problem is that we don't know it's size\r
+               if (s_buf->p_sg_buf == NULL) {\r
+                       s_buf->p_sg_buf = (PVOID) cl_qpool_get(&p_port->send_mgr.sg_pool);\r
+               }\r
                \r
+               IPOIB_INFO_FROM_NB(p_netbuf) = s_buf;\r
                \r
                IPOIB_PRINT( TRACE_LEVEL_VERBOSE, IPOIB_DBG_SEND,\r
                                ("Netbuf to send = %p\n", p_netbuf) );\r
@@ -5358,17 +5428,18 @@ ipoib_port_send(
 \r
 \r
                        ++g_ipoib_send_SW_in_loop;\r
-                       //TODO use preallocated SG pool\r
+\r
+                       ASSERT(s_buf->p_sg_buf);\r
                        status = NdisMAllocateNetBufferSGList(\r
                                                                        p_port->p_adapter->NdisMiniportDmaHandle,\r
                                                                        p_netbuf,\r
                                                                        s_buf,\r
                                                                        NDIS_SG_LIST_WRITE_TO_DEVICE,\r
-                                                                       NULL,\r
-                                                                       0);\r
+                                                                       (PUCHAR )s_buf->p_sg_buf + sizeof(cl_pool_item_t),\r
+                                                                       p_port->p_adapter->sg_list_size);\r
                        \r
-                       cl_spinlock_acquire( &p_port->send_lock );\r
-                       //cl_qlist_check_validity(&p_port->send_mgr.pending_list);\r
+               \r
+                       cl_spinlock_acquire( &p_port->send_lock );              \r
 #endif\r
 //             }\r
        \r
@@ -5394,6 +5465,102 @@ ipoib_port_send(
        NDIS_LOWER_IRQL(old_irql, DISPATCH_LEVEL);\r
 }\r
 \r
+static inline void \r
+__send_complete_net_buffer(\r
+       IN      ipoib_send_NB_SG        *s_buf, \r
+       IN      NDIS_STATUS             status,\r
+       IN      ULONG                           compl_flags,\r
+       IN      boolean_t                       bLock   ) \r
+{\r
+\r
+       CL_ASSERT( s_buf );\r
+       \r
+       \r
+       IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_SEND,\r
+               ("Processing send completion for NBL=0x%p .\n",  s_buf->p_nbl ));\r
+       \r
+       \r
+       //Free SGL element allocated by NDIS\r
+       NdisMFreeNetBufferSGList(\r
+                                                       s_buf->p_port->p_adapter->NdisMiniportDmaHandle,\r
+                                                       s_buf->p_sgl,\r
+                                                       s_buf->p_curr_nb);\r
+                                                       \r
+       if( s_buf->p_send_buf )\r
+       {\r
+               cl_perf_start( FreeSendBuf );\r
+               NdisFreeToNPagedLookasideList( &s_buf->p_port->buf_mgr.send_buf_list,\r
+                       s_buf->p_send_buf );\r
+               cl_perf_stop( &p_port->p_adapter->perf, FreeSendBuf );\r
+       }       \r
+       \r
+       /* Dereference the enpoint used for the transfer. */\r
+       if( s_buf->p_endpt ) {\r
+               ipoib_endpt_deref( s_buf->p_endpt );\r
+       }\r
+\r
+       \r
+       // No need to delete p_sg_buf at this state, we will destroy the whole list at the end of the execution\r
+       //NET_BUFFER_LIST_NEXT_NBL(p_desc->p_netbuf_list) = NULL;\r
+       if (NET_BUFFER_LIST_STATUS(s_buf->p_nbl) != NDIS_STATUS_FAILURE) {\r
+               //TODO what about other statuses ?????\r
+               NET_BUFFER_LIST_STATUS(s_buf->p_nbl) = status;\r
+       }\r
+\r
+\r
+               \r
+       IPOIB_DEC_NET_BUFFER_LIST_REF_COUNT(s_buf->p_nbl);\r
+       /* Complete the NBL */\r
+       if (IPOIB_GET_NET_BUFFER_LIST_REF_COUNT(s_buf->p_nbl) == 0) {\r
+               NET_BUFFER_LIST_STATUS(s_buf->p_nbl) = status;\r
+               PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO pLsoInfo =    \r
+                       (PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO) (PULONG)&NET_BUFFER_LIST_INFO(s_buf->p_nbl, TcpLargeSendNetBufferListInfo);\r
+        if(pLsoInfo->Transmit.Type == NDIS_TCP_LARGE_SEND_OFFLOAD_V1_TYPE)\r
+        {            \r
+            UINT TcpPayLoad = 0;\r
+                       //TODO optimize this code during MSS/LSO building\r
+            for (PNET_BUFFER NetBuffer = NET_BUFFER_LIST_FIRST_NB(s_buf->p_nbl);\r
+                 NetBuffer != NULL ; \r
+                 NetBuffer = NET_BUFFER_NEXT_NB(NetBuffer))\r
+            {\r
+                //TcpPayLoad += IPOIB_TCP_PAYLOAD_FROM_NB(NetBuffer);           \r
+                TcpPayLoad += s_buf->tcp_payload;\r
+            }\r
+            pLsoInfo->LsoV1TransmitComplete.TcpPayload = TcpPayLoad;            \r
+        }\r
+        else if (pLsoInfo->Transmit.Type == NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE)\r
+        {\r
+            pLsoInfo->LsoV2TransmitComplete.Reserved = 0;\r
+            pLsoInfo->LsoV2TransmitComplete.Type = NDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE;\r
+        }\r
+               \r
+               if (bLock) {\r
+                       cl_spinlock_release( &s_buf->p_port->send_lock );\r
+                       NdisMSendNetBufferListsComplete( s_buf->p_port->p_adapter->h_adapter,\r
+                               s_buf->p_nbl, compl_flags );\r
+                       cl_spinlock_acquire( &s_buf->p_port->send_lock );  \r
+               } else {\r
+                       NdisMSendNetBufferListsComplete( s_buf->p_port->p_adapter->h_adapter,\r
+                               s_buf->p_nbl, compl_flags );\r
+               }\r
+       }\r
+\r
+#if 0  \r
+       if (status == NDIS_STATUS_SUCCESS) {\r
+               //++g_ipoib_send_SG_real;\r
+               ipoib_inc_send_stat( p_port->p_adapter, IP_STAT_SUCCESS, 0 );\r
+       } else {\r
+               ++g_ipoib_send_SG_failed;\r
+               ipoib_inc_send_stat( p_port->p_adapter, IP_STAT_ERROR, 0 );\r
+       }\r
+#endif\r
+       //Put back into the pool list structure allocated for the NB\r
+       cl_qpool_put(&s_buf->p_port->send_mgr.send_pool, (cl_pool_item_t* )s_buf);\r
+       \r
+       cl_perf_stop( &p_port->p_adapter->perf, SendComp );\r
+}\r
+\r
+\r
 \r
 void\r
 ipoib_port_resume(\r
@@ -5402,6 +5569,7 @@ ipoib_port_resume(
 {\r
        cl_list_item_t          *p_item;\r
        ipoib_send_NB_SG        *s_buf = NULL;\r
+       boolean_t                       b_good_port_state = TRUE;\r
        \r
        PERF_DECLARE( GetEndpt );\r
        PERF_DECLARE( BuildSendDesc );\r
@@ -5411,16 +5579,16 @@ ipoib_port_resume(
        IPOIB_ENTER( IPOIB_DBG_SEND );\r
 \r
        UNUSED_PARAM(b_pending);\r
+\r
+       ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);\r
        \r
        cl_obj_lock( &p_port->obj );\r
        if( p_port->state != IB_QPS_RTS )\r
        {\r
-               // TODO: If there are packets that are not handeled, how will they get out of the\r
-               // queues\r
                IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_SEND,\r
-                       ("Invalid state - Aborting.\n") );\r
-               cl_obj_unlock( &p_port->obj );\r
-               return;\r
+                       ("Invalid port state =%d - Flushing the penging list\n", p_port->state) );\r
+               b_good_port_state = FALSE;\r
+\r
        }\r
        cl_obj_unlock( &p_port->obj );\r
 \r
@@ -5428,7 +5596,6 @@ ipoib_port_resume(
        if (p_port->send_mgr.pending_list.count <= 0) {\r
                return;\r
        };\r
-\r
        p_item =  cl_qlist_remove_head( &p_port->send_mgr.pending_list );\r
        while (p_item != cl_qlist_end(&p_port->send_mgr.pending_list))\r
        {\r
@@ -5444,10 +5611,18 @@ ipoib_port_resume(
                }\r
 \r
                s_buf = (ipoib_send_NB_SG*) (PVOID) p_item; // TODO: Check this casting\r
+\r
+               if (!b_good_port_state) {\r
+                       ipoib_inc_send_stat( p_port->p_adapter, IP_STAT_DROPPED, 0 );\r
+                       __send_complete_net_buffer(\r
+                               s_buf, NDIS_STATUS_FAILURE, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL, FALSE);\r
+       \r
+                       continue;\r
+               }\r
                        \r
                bool continue_sending = ipoib_process_sg_list_real(NULL, NULL, (PSCATTER_GATHER_LIST) s_buf->p_sgl, s_buf);\r
 \r
-               cl_qlist_check_validity(&p_port->send_mgr.pending_list);\r
+               //cl_qlist_check_validity(&p_port->send_mgr.pending_list);\r
 \r
                if (!continue_sending) {\r
                        ASSERT (cl_is_item_in_qlist(&p_port->send_mgr.pending_list, (cl_list_item_t*)(PVOID)s_buf));\r
@@ -5472,9 +5647,7 @@ __send_cb(
        ib_api_status_t         status;\r
        ib_wc_t                         wc[MAX_SEND_WC], *p_wc, *p_free;\r
        cl_qlist_t                      done_list;\r
-       uint32_t                        length;\r
        ipoib_endpt_t           *p_endpt;\r
-       send_buf_t                      *p_send_buf;\r
        ip_stat_sel_t           type;\r
        size_t                          i;\r
        NET_BUFFER                      *p_netbuffer = NULL;\r
@@ -5505,7 +5678,7 @@ __send_cb(
 \r
        p_port = (ipoib_port_t*)cq_context;\r
        cl_spinlock_acquire( &p_port->send_lock );\r
-       cl_qlist_check_validity(&p_port->send_mgr.pending_list);\r
+       //cl_qlist_check_validity(&p_port->send_mgr.pending_list);\r
        ipoib_port_ref( p_port, ref_send_cb );\r
 \r
        for( i = 0; i < MAX_SEND_WC; i++ )\r
@@ -5523,7 +5696,7 @@ __send_cb(
                while( p_wc )\r
                {\r
                        cl_perf_start( SendComp );\r
-                       CL_ASSERT( p_wc->status != IB_WCS_SUCCESS || p_wc->wc_type == IB_WC_SEND );\r
+                       CL_ASSERT( p_wc->status != IB_WCS_SUCCESS || p_wc->wc_type == IB_WC_SEND || p_wc->wc_type == IB_WC_LSO);\r
                        s_buf = (ipoib_send_NB_SG*)(uintn_t)p_wc->wr_id;\r
                        IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_SEND,\r
                                ("Successfull send completion for NBL=0x%p .\n",  s_buf->p_nbl ));\r
@@ -5531,17 +5704,7 @@ __send_cb(
 \r
 \r
                        ++g_ipoib_send_ack;\r
-                       length = 0;\r
                        p_endpt = s_buf->p_endpt;\r
-                       p_send_buf = s_buf->p_send_buf;\r
-\r
-                       //Free SGL element allocated by NDIS\r
-                       //TODO free SGL also each time we decide not to send (before post_send)\r
-\r
-                       NdisMFreeNetBufferSGList(\r
-                                                                       p_port->p_adapter->NdisMiniportDmaHandle,\r
-                                                                       s_buf->p_sgl,\r
-                                                                       s_buf->p_curr_nb);\r
 \r
                        NDIS_STATUS status = NDIS_STATUS_FAILURE;\r
                        switch( p_wc->status )\r
@@ -5590,32 +5753,9 @@ __send_cb(
                        \r
                                break;\r
                        }\r
-                       IPOIB_DEC_NET_BUFFER_LIST_REF_COUNT(s_buf->p_nbl);\r
-                       if (IPOIB_GET_NET_BUFFER_LIST_REF_COUNT(s_buf->p_nbl) == 0) {\r
-                                               \r
-\r
-                                       NET_BUFFER_LIST_STATUS(s_buf->p_nbl) = status;\r
-                                       NdisMSendNetBufferListsComplete(p_port->p_adapter->h_adapter,\r
-                                                                                                       s_buf->p_nbl,\r
-                                                                                                       NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);  \r
-                       }\r
                        \r
-                       //Put back into the pool list structure allocated for the NB\r
-                       cl_qpool_put(&p_port->send_mgr.send_pool, (cl_pool_item_t* )s_buf);\r
+                       __send_complete_net_buffer(s_buf, status, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL, FALSE);\r
                        \r
-                       cl_perf_stop( &p_port->p_adapter->perf, SendComp );\r
-                       /* Dereference the enpoint used for the transfer. */\r
-                       ipoib_endpt_deref( p_endpt );\r
-\r
-                       if( p_send_buf )\r
-                       {\r
-                       //TODO restore \r
-                               cl_perf_start( FreeSendBuf );\r
-                               NdisFreeToNPagedLookasideList( &p_port->buf_mgr.send_buf_list,\r
-                                       p_send_buf );\r
-                       cl_perf_stop( &p_port->p_adapter->perf, FreeSendBuf );\r
-                       }\r
-\r
                        cl_atomic_dec( &p_port->send_mgr.depth );\r
 \r
                        p_wc = p_wc->p_next;\r
@@ -5636,18 +5776,18 @@ __send_cb(
        cl_perf_stop( &p_port->p_adapter->perf, RearmSend );\r
        CL_ASSERT( status == IB_SUCCESS );\r
 \r
-       \r
        ipoib_port_deref( p_port, ref_send_cb );\r
 \r
        cl_perf_stop( &p_port->p_adapter->perf, SendCb );\r
        cl_perf_update_ctr( &p_port->p_adapter->perf, SendCompBundle );\r
-       cl_qlist_check_validity(&p_port->send_mgr.pending_list);\r
+       //cl_qlist_check_validity(&p_port->send_mgr.pending_list);\r
        cl_spinlock_release( &p_port->send_lock );\r
        IPOIB_EXIT( IPOIB_DBG_SEND );\r
        \r
 }\r
 \r
 \r
+\r
 /******************************************************************************\r
 *\r
 * Endpoint manager implementation\r
@@ -7581,7 +7721,7 @@ __mcast_cb(
        \r
        /* Try to send all pending sends. */\r
        cl_spinlock_acquire( &p_port->send_lock );\r
-       cl_dbg_out("Calling ipoib_port_resume from mcast_cb\n");\r
+       //cl_dbg_out("Calling ipoib_port_resume from mcast_cb\n");\r
        ipoib_port_resume(p_port , FALSE);\r
        cl_spinlock_release( &p_port->send_lock );\r
 \r
@@ -7604,6 +7744,8 @@ ipoib_leave_mcast_cb(
        IPOIB_PRINT( TRACE_LEVEL_VERBOSE, IPOIB_DBG_MCAST,("p_port->mcast_cnt = %d\n", p_port->mcast_cnt));\r
        \r
        ipoib_port_deref( p_port, ref_leave_mcast);\r
+       //It happens\r
+       //ASSERT(p_port->mcast_cnt > 0);\r
        cl_atomic_dec( &p_port->mcast_cnt);\r
        \r
        if(0 == p_port->mcast_cnt)\r
@@ -7690,16 +7832,22 @@ NDIS_STATUS GetLsoHeaderSize(
 \r
        pMDL = NET_BUFFER_CURRENT_MDL(pNetBuffer);\r
        NdisQueryMdl(pMDL, &pSrc, &CurrLength, NormalPagePriority);\r
-       //NdisQueryBufferSafe( CurrBuffer, &pSrc, &CurrLength, NormalPagePriority );\r
+       \r
        if (pSrc == NULL) {\r
                IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, ("Error processing packets\n"));\r
                return status;\r
        }\r
+       \r
+       ULONG DataOffset = NET_BUFFER_CURRENT_MDL_OFFSET(pNetBuffer);\r
+       pSrc += DataOffset;\r
+       CurrLength -= DataOffset;\r
+\r
        // We start by looking for the ethernet and the IP\r
        if (CurrLength < ETH_OFFSET) {\r
                IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, ("Error porcessing packets\n"));\r
                return status;\r
        }\r
+       \r
        //pLsoData->LsoHeaderSize = pLsoData->LsoHeaderSize + ETH_OFFSET;\r
        if (CurrLength == ETH_OFFSET) {        \r
                ASSERT(FALSE);\r
@@ -7717,7 +7865,10 @@ NDIS_STATUS GetLsoHeaderSize(
        } else {\r
                // This is ETH + IP together (at least)\r
                pLsoData->LsoBuffers[0].pData = pSrc + (ETH_OFFSET - sizeof (ipoib_hdr_t));\r
+               \r
+               //IMPORTANT: we de-facto replace ETH header by IPoIB header here\r
                memcpy (pLsoData->LsoBuffers[0].pData, ipoib_hdr, sizeof (ipoib_hdr_t));\r
+               \r
                CurrLength -= ETH_OFFSET;\r
                pSrc = pSrc + ETH_OFFSET;\r
                pLsoData->LsoHeaderSize = pLsoData->LsoHeaderSize + sizeof (ipoib_hdr_t);\r
@@ -7731,7 +7882,7 @@ NDIS_STATUS GetLsoHeaderSize(
        IpHeaderLen = (uint16_t)IP_HEADER_LENGTH(IpHdr);\r
        ASSERT(IpHdr->prot == IP_PROT_TCP);\r
        if (CurrLength < IpHeaderLen) {\r
-               IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_ERROR, ("Error processing packets\n"));\r
+               IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, ("Error processing packets\n"));\r
                return status;\r
        }\r
        pLsoData->LsoHeaderSize = pLsoData->LsoHeaderSize + IpHeaderLen;\r
@@ -7933,7 +8084,6 @@ ipoib_port_cancel_xmit(
        ipoib_send_NB_SG        *s_buf;\r
        PVOID                   nbl_id;\r
        cl_qlist_t              cancel_list;\r
-       ULONG                   send_complete_flags = 0;\r
        IPOIB_ENTER( IPOIB_DBG_SEND );\r
 \r
        cl_qlist_init( &cancel_list );\r
@@ -7967,21 +8117,15 @@ ipoib_port_cancel_xmit(
                {\r
                        s_buf = (ipoib_send_NB_SG*) (PVOID) p_item;\r
                        IPOIB_DEC_NET_BUFFER_LIST_REF_COUNT(s_buf->p_nbl);\r
-                       if (IPOIB_GET_NET_BUFFER_LIST_REF_COUNT(s_buf->p_nbl) == 0) {\r
-                                               \r
-                                       NET_BUFFER_LIST_STATUS(s_buf->p_nbl) = NDIS_STATUS_SEND_ABORTED;\r
-                                       send_complete_flags = 0;\r
-                                       if (NDIS_CURRENT_IRQL() == DISPATCH_LEVEL)\r
-                                       {\r
-                                               NDIS_SET_SEND_COMPLETE_FLAG(send_complete_flags, NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);\r
-                                       }\r
-                                                       NdisMSendNetBufferListsComplete(p_port->p_adapter->h_adapter,\r
-                                                                                                                       s_buf->p_nbl, send_complete_flags);\r
-                                                                                                               \r
-                               }\r
+\r
+                       \r
+                       //TODO don't use DISPATCH LEVEL\r
+                       __send_complete_net_buffer(\r
+                               s_buf, NDIS_STATUS_SEND_ABORTED ,NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL, TRUE);\r
                }\r
+                       \r
        }\r
-       //TODO free send buffers !\r
+\r
        IPOIB_EXIT( IPOIB_DBG_SEND );\r
 }\r
 \r
@@ -8043,7 +8187,7 @@ IN                NDIS_BUFFER*                            p_ndis_buf )
                        ("Failed to allocate lookaside buffer.\n") );\r
                return NDIS_STATUS_RESOURCES;\r
        }\r
-       p_desc->p_buf = (send_buf_t*)p_buf;\r
+       s_buf->p_send_buf = (send_buf_t*)p_buf;\r
 \r
        if( buf_len < ip_hdr_len )\r
        {       /* ip options in a separate buffer */\r
index 47dded0..9a5dfc4 100644 (file)
 #define IPOIB_INFO_FROM_NB( P )        \\r
        (((ipoib_send_NB_SG **)NET_BUFFER_MINIPORT_RESERVED(P))[0])\r
 \r
+//#define IPOIB_TCP_PAYLOAD_FROM_NB( P )       \\r
+//     (((UINT *)NET_BUFFER_MINIPORT_RESERVED(P))[1])\r
+\r
+\r
 //Used in SEND flow\r
 #define IPOIB_GET_NET_BUFFER_LIST_REF_COUNT(_NetBufferList)    ((_NetBufferList)->MiniportReserved[0])\r
 #define IPOIB_DEC_NET_BUFFER_LIST_REF_COUNT(_NetBufferList)    (*(PULONG)&(_NetBufferList)->MiniportReserved[0])--\r
@@ -304,7 +308,7 @@ typedef struct _ipoib_buf_mgr
 \r
        NPAGED_LOOKASIDE_LIST   send_buf_list;\r
        NDIS_HANDLE                     h_send_pkt_pool;\r
-       NDIS_HANDLE                     h_send_buf_pool;\r
+\r
 \r
 }      ipoib_buf_mgr_t;\r
 /*\r
@@ -410,7 +414,7 @@ typedef struct _ipoib_send_desc
 {\r
        PNET_BUFFER_LIST    p_netbuf_list;\r
        ipoib_endpt_t           *p_endpt;\r
-       send_buf_t                      *p_buf;\r
+       //send_buf_t                    *p_buf; // This field migrated to ipoib_send_NB_SG class\r
        ib_qp_handle_t          send_qp;\r
        send_dir_t                      send_dir;\r
        uint32_t                        num_wrs;\r
@@ -530,6 +534,7 @@ typedef struct _ipoib_send_mgr
        cl_qlist_t                      pending_list;\r
        ipoib_send_desc_t       desc;\r
        cl_qpool_t                      send_pool;\r
+       cl_qpool_t                      sg_pool;\r
 \r
 }      ipoib_send_mgr_t;\r
 \r
@@ -688,6 +693,8 @@ typedef struct ipoib_send_NB_SG_t {
        ipoib_endpt_t                   *p_endpt;\r
        send_buf_t                              *p_send_buf;\r
        PSCATTER_GATHER_LIST    p_sgl;\r
+       UINT                                    tcp_payload;\r
+       PVOID                                   p_sg_buf;\r
 } ipoib_send_NB_SG;\r
 \r
 ib_api_status_t\r
index 47e99a3..72fbf96 100644 (file)
@@ -4,6 +4,10 @@
 # that is shared by all the driver components of the OpenIB Windows project.\r
 #\r
 \r
+#\r
+# prevent the Build utility from building the driver for an earlier \r
+# version of the operating system than vista/Win 2008. \r
+#\r
 MINIMUM_NT_TARGET_VERSION=0x600\r
 \r
 !INCLUDE ..\..\..\inc\openib.def\r