]> git.openfabrics.org - ~shefty/rdma-win.git/commitdiff
[ipoib] CM updated to the trunk rev. 1515
authoraestrin <aestrin@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Fri, 5 Sep 2008 18:22:51 +0000 (18:22 +0000)
committeraestrin <aestrin@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Fri, 5 Sep 2008 18:22:51 +0000 (18:22 +0000)
git-svn-id: svn://openib.tc.cornell.edu/gen1@1555 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

branches/ipoib_cm/kernel/ipoib_adapter.h
branches/ipoib_cm/kernel/ipoib_driver.c
branches/ipoib_cm/kernel/ipoib_endpoint.c
branches/ipoib_cm/kernel/ipoib_endpoint.h
branches/ipoib_cm/kernel/ipoib_port.c
branches/ipoib_cm/kernel/ipoib_port.h

index 5428f651ea5e2a866c3f04e4f0c0d2c9de102d67..7e80aaa62034c12c2d66a0b8a2d89d6ebd2daf2b 100644 (file)
@@ -73,6 +73,7 @@ typedef struct _ipoib_params
        uint32_t        sa_retry_cnt;\r
        uint32_t        recv_pool_ratio;\r
        uint32_t        payload_mtu;\r
+       boolean_t       lso;\r
        uint32_t        xfer_block_size;\r
        mac_addr_t      conf_mac;\r
        uint32_t        mc_leave_rescan;\r
@@ -123,6 +124,15 @@ typedef struct _ipoib_params
 *              powers of 2, excluding 1.  When zero, grows only when the pool is\r
 *              exhausted.  Other values indicate fractional values\r
 *              (i.e. 2 indicates 1/2, 4 indicates 1/4, etc.)\r
+*\r
+*      payload_mtu\r
+*              The maximum available size of IPoIB transfer unit.\r
+*              It should be lower by size of IPoIB header (==4B)\r
+*              For example, if the HCA support 4K MTU, \r
+*              upper threshold for payload mtu is 4092B and not 4096B\r
+*      lso\r
+*      It indicates if there's a support for hardware large/giant send offload\r
+*              \r
 *********/\r
 \r
 \r
index bf2d6d0d0cbb6051656e2b00823645535a4ce89b..128d6c9eed896b526438969fd6ddbd470c96bab0 100644 (file)
@@ -50,6 +50,8 @@
 #include <iba/ipoib_ifc.h>\r
 #include "ntstrsafe.h"\r
 #include "strsafe.h"\r
+#include <offload.h>\r
+\r
 \r
 \r
 \r
@@ -153,7 +155,8 @@ IPOIB_REG_ENTRY HCARegTable[] = {
        {NDIS_STRING_CONST("SaTimeout"),        1, IPOIB_OFFSET(sa_timeout),            IPOIB_SIZE(sa_timeout),         1000,       250,    UINT_MAX},\r
        {NDIS_STRING_CONST("SaRetries"),        1, IPOIB_OFFSET(sa_retry_cnt),          IPOIB_SIZE(sa_retry_cnt),       10,         1,      UINT_MAX},\r
        {NDIS_STRING_CONST("RecvRatio"),        1, IPOIB_OFFSET(recv_pool_ratio),       IPOIB_SIZE(recv_pool_ratio),    1,          1,      10},\r
-       {NDIS_STRING_CONST("PayloadMtu"),       1, IPOIB_OFFSET(payload_mtu),           IPOIB_SIZE(payload_mtu),        2044,       60,   4092},\r
+       {NDIS_STRING_CONST("PayloadMtu"),       1, IPOIB_OFFSET(payload_mtu),           IPOIB_SIZE(payload_mtu),        2044,       60,   MAX_CM_PAYLOAD_MTU},\r
+       {NDIS_STRING_CONST("lso"),              0, IPOIB_OFFSET(lso),                   IPOIB_SIZE(lso),                0,          0,      1},\r
        {NDIS_STRING_CONST("MCLeaveRescan"),    1, IPOIB_OFFSET(mc_leave_rescan),       IPOIB_SIZE(mc_leave_rescan),    260,        1,    3600},\r
        {NDIS_STRING_CONST("CmEnabled"),        1, IPOIB_OFFSET(cm_enabled),            IPOIB_SIZE(cm_enabled),         0,          0,      1}\r
 };  \r
@@ -856,6 +859,9 @@ ipoib_check_for_hang(
                IPOIB_EXIT( IPOIB_DBG_INIT );\r
                return FALSE;\r
        }\r
+       if (p_adapter->hung) {\r
+               ipoib_resume_oids(p_adapter);\r
+       }\r
 \r
        IPOIB_EXIT( IPOIB_DBG_INIT );\r
        return (p_adapter->hung? TRUE:FALSE);\r
@@ -1422,6 +1428,8 @@ __ipoib_get_tcp_task_offload(
        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
@@ -1430,7 +1438,10 @@ __ipoib_get_tcp_task_offload(
 \r
        buf_len = sizeof(NDIS_TASK_OFFLOAD_HEADER) +\r
                offsetof( NDIS_TASK_OFFLOAD, TaskBuffer ) +\r
-               sizeof(NDIS_TASK_TCP_IP_CHECKSUM);\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
        *(p_oid_info->p_bytes_needed) = buf_len;\r
 \r
@@ -1489,6 +1500,33 @@ __ipoib_get_tcp_task_offload(
        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
+\r
        *(p_oid_info->p_bytes_used) = buf_len;\r
 \r
        return NDIS_STATUS_SUCCESS;\r
@@ -1895,7 +1933,7 @@ ipoib_send_packets(
                for( packet_num = 0; packet_num < num_packets; ++packet_num )\r
                {\r
                        ipoib_inc_send_stat( p_adapter, IP_STAT_DROPPED, 0 );\r
-                       NdisMSendComplete( p_adapter->h_adapter,\r
+                       NdisMSendCompleteX( p_adapter->h_adapter,\r
                                packet_array[packet_num], NDIS_STATUS_ADAPTER_NOT_READY );\r
                }\r
                IPOIB_EXIT( IPOIB_DBG_SEND );\r
index 8be2fb762c419eaa96264c3090fc8f83c24083bd..a184bf244b54c89ad1bc8e08581d65168e87bee4 100644 (file)
@@ -43,7 +43,6 @@
 #include "ipoib_endpoint.tmh"\r
 #endif\r
 #include <complib/cl_atomic.h>\r
-#include <complib/cl_math.h>\r
 \r
 \r
 static void\r
index ce35554c4b7e3a63ab5e2c7b4a52c7a870d4a76f..4c4f4d767c2b0a90986e33ea97a3a81dafbc01c7 100644 (file)
@@ -46,7 +46,6 @@
 #include "ipoib_debug.h"\r
 \r
 \r
-\r
 typedef struct _endpt_buf_mgr\r
 {\r
        cl_qpool_t                      recv_pool;\r
index 0e9d9f17c3474d1d9af6746012a9bc234b540966..599dbeb1403a4712106afc9c38fff734c99edc4f 100644 (file)
@@ -43,6 +43,7 @@
 #endif\r
 #include "ipoib_port.tmh"\r
 #endif\r
+#include <offload.h>\r
 \r
 \r
 ib_gid_t       bcast_mgid_template = {\r
@@ -282,7 +283,8 @@ __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_desc_t* const        p_desc,\r
+       IN                              INT                                             lso_data_index);\r
 \r
 static NDIS_STATUS\r
 __send_mgr_filter_ip(\r
@@ -335,6 +337,14 @@ __send_cb(
        IN              const   ib_cq_handle_t                          h_cq,\r
        IN                              void                                            *cq_context );\r
 \r
+static NDIS_STATUS GetLsoHeaderSize(\r
+       IN      ipoib_port_t* const pPort,\r
+       IN      PNDIS_BUFFER  CurrBuffer,\r
+       IN      LsoData *pLsoData,\r
+       OUT     uint16_t *pSize,\r
+       OUT     INT  *IndexOfData,\r
+       IN              ipoib_hdr_t *ipoib_hdr\r
+       );\r
 \r
 /******************************************************************************\r
 *\r
@@ -2031,7 +2041,7 @@ __recv_get_endpts(
 \r
        if( *pp_src && *pp_dst )\r
        {\r
-               IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_RECV,\r
+               IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_RECV,\r
                        ("Recv:\n"\r
                        "\tsrc MAC: %02X-%02X-%02X-%02X-%02X-%02X\n"\r
                        "\tdst MAC: %02X-%02X-%02X-%02X-%02X-%02X\n",\r
@@ -2089,7 +2099,7 @@ __recv_mgr_filter(
                        }\r
                        else\r
                        {\r
-                               IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_RECV,\r
+                               IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_RECV,\r
                                        ("Flushed completion %s\n",\r
                                        p_port->p_adapter->p_ifc->get_wc_status_str( p_wc->status )) );\r
                                ipoib_inc_recv_stat( p_port->p_adapter, IP_STAT_DROPPED, 0, 0 );\r
@@ -2902,7 +2912,7 @@ __pending_list_destroy(
                p_item = cl_qlist_remove_head( &p_port->send_mgr.pending_list ) )\r
        {\r
                p_packet = IPOIB_PACKET_FROM_LIST_ITEM( p_item );\r
-               NdisMSendComplete( p_port->p_adapter->h_adapter, p_packet,\r
+               NdisMSendCompleteX( p_port->p_adapter->h_adapter, p_packet,\r
                        NDIS_STATUS_RESET_IN_PROGRESS );\r
        }\r
        cl_spinlock_release( &p_port->send_lock );\r
@@ -2963,7 +2973,7 @@ __send_mgr_filter(
                 * Just send the payload and hope for the best.\r
                 */\r
                cl_perf_start( SendGen );\r
-               status = __send_gen( p_port, p_desc );\r
+               status = __send_gen( p_port, p_desc, 0 );\r
                cl_perf_stop( &p_port->p_adapter->perf, SendGen );\r
                break;\r
        }\r
@@ -3190,7 +3200,8 @@ __send_gen(
 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_desc_t* const        p_desc,\r
+       IN                              INT lso_data_index)\r
 {\r
        ib_api_status_t                 status;\r
        SCATTER_GATHER_LIST             *p_sgl;\r
@@ -3211,8 +3222,10 @@ __send_gen(
        }\r
 \r
        /* Remember that one of the DS entries is reserved for the IPoIB header. */\r
-       if( ( p_sgl->NumberOfElements > MAX_SEND_SGE ||\r
-                 p_sgl->Elements[0].Length < sizeof(eth_hdr_t)) )\r
+       if( ( p_sgl->NumberOfElements >= MAX_SEND_SGE &&\r
+               p_sgl->Elements[0].Length > sizeof(eth_hdr_t)) ||\r
+               ( p_sgl->NumberOfElements > MAX_SEND_SGE &&\r
+               p_sgl->Elements[0].Length <= sizeof(eth_hdr_t)) )\r
        {\r
 \r
                IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_SEND,\r
@@ -3235,9 +3248,13 @@ __send_gen(
         * or part of it.\r
         */\r
        i = 0;\r
-       while( offset )\r
+       if (lso_data_index) { //we have an LSO packet\r
+               i = lso_data_index;\r
+               j = 0;\r
+       }\r
+       else while( offset )\r
        {\r
-               if( p_sgl->Elements[i].Length <= sizeof(eth_hdr_t) )\r
+               if( p_sgl->Elements[i].Length <= offset )\r
                {\r
                        offset -= p_sgl->Elements[i++].Length;\r
                }\r
@@ -3356,7 +3373,7 @@ __send_mgr_filter_ip(
                }\r
                /* Not a UDP packet. */\r
                cl_perf_start( SendTcp );\r
-               status = __send_gen( p_port, p_desc );\r
+               status = __send_gen( p_port, p_desc,0 );\r
                cl_perf_stop( &p_port->p_adapter->perf, SendTcp );\r
                IPOIB_EXIT( IPOIB_DBG_SEND );\r
                return status;\r
@@ -3555,7 +3572,7 @@ __send_mgr_filter_udp(
        {\r
                /* Not a DHCP packet. */\r
                cl_perf_start( SendUdp );\r
-               status = __send_gen( p_port, p_desc );\r
+               status = __send_gen( p_port, p_desc,0 );\r
                cl_perf_stop( &p_port->p_adapter->perf, SendUdp );\r
                IPOIB_EXIT( IPOIB_DBG_SEND );\r
                return status;\r
@@ -3981,7 +3998,7 @@ __send_mgr_get_eth_hdr(
                return NDIS_STATUS_BUFFER_TOO_SHORT;\r
        }\r
 \r
-       IPOIB_PRINT_EXIT( TRACE_LEVEL_VERBOSE, IPOIB_DBG_SEND,\r
+       IPOIB_PRINT_EXIT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_SEND,\r
                ("Ethernet header:\n"\r
                "\tsrc MAC: %02X-%02X-%02X-%02X-%02X-%02X\n"\r
                "\tdst MAC: %02X-%02X-%02X-%02X-%02X-%02X\n"\r
@@ -4067,6 +4084,14 @@ __build_send_desc(
        int32_t                         hdr_idx;\r
        PNDIS_PACKET_EXTENSION                          PktExt;\r
        PNDIS_TCP_IP_CHECKSUM_PACKET_INFO       pChecksumPktInfo; //NDIS 5.1\r
+       ULONG                                                           mss;\r
+       LsoData                                                         TheLsoData;\r
+       INT                                                                     IndexOfData = 0;\r
+       ULONG                                                           PhysBufCount;\r
+       ULONG                                                           PacketLength;\r
+       PNDIS_BUFFER                                            FirstBuffer;\r
+       uint16_t                                                        lso_header_size;\r
+\r
 \r
        PERF_DECLARE( SendMgrFilter );\r
 \r
@@ -4074,15 +4099,12 @@ __build_send_desc(
 \r
        /* Format the send descriptor. */\r
        cl_perf_start( SendMgrFilter );\r
-       status = __send_mgr_filter(\r
-               p_port, p_eth_hdr, p_buf, buf_len, p_desc );\r
-       cl_perf_stop( &p_port->p_adapter->perf, SendMgrFilter );\r
-       if( status != NDIS_STATUS_SUCCESS )\r
-       {\r
-               IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
-                       ("__send_mgr_filter returned 0x%08X.\n", status) );\r
-               return status;\r
-       }\r
+\r
+       PktExt = NDIS_PACKET_EXTENSION_FROM_PACKET(p_desc->p_pkt);\r
+       pChecksumPktInfo = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&PktExt->NdisPacketInfo[TcpIpChecksumPacketInfo];\r
+       mss = PtrToUlong(PktExt->NdisPacketInfo[TcpLargeSendPacketInfo]);\r
+       //TODO: optimization: we already got total length from NdisGetFirstBufferFromPacketSafe before\r
+       NdisQueryPacket(p_desc->p_pkt, (PUINT)&PhysBufCount, NULL, &FirstBuffer,(PUINT)&PacketLength);\r
 \r
        /* Format the send descriptor. */\r
        hdr_idx = cl_atomic_inc( &p_port->hdr_idx );\r
@@ -4091,19 +4113,66 @@ __build_send_desc(
        p_port->hdr[hdr_idx].type = p_eth_hdr->type;\r
        p_port->hdr[hdr_idx].resv = 0;\r
 \r
-       /* Setup the first local data segment (used for the IPoIB header). */\r
-       p_desc->local_ds[0].vaddr = cl_get_physaddr( &p_port->hdr[hdr_idx] );\r
-       p_desc->local_ds[0].length = sizeof(ipoib_hdr_t);\r
-       p_desc->local_ds[0].lkey = p_port->ib_mgr.lkey;\r
+       if (mss)\r
+       {\r
+               memset(&TheLsoData, 0, sizeof TheLsoData );\r
+               status = GetLsoHeaderSize(\r
+                       p_port,\r
+                       FirstBuffer, \r
+                       &TheLsoData, \r
+                       &lso_header_size,\r
+                       &IndexOfData,\r
+                       &p_port->hdr[hdr_idx]\r
+                       \r
+               );\r
+               if ((status != NDIS_STATUS_SUCCESS ) || \r
+                       (TheLsoData.FullBuffers != TheLsoData.UsedBuffers)) {\r
+                       ASSERT(FALSE);\r
+\r
+                       IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, ("<-- Throwing this packet\n"));\r
+\r
+                       //NdisReleaseSpinLock(&Port->SendLock);\r
+                       //MP_ASSERT_NDIS_PACKET_TYPE(Packet);\r
+                       //SendComplete(Port, Packet, NDIS_STATUS_INVALID_PACKET);\r
+                       //NdisAcquireSpinLock(&Port->SendLock);\r
+                       //IPOIB_PRINT_EXIT\r
+                       return status;\r
+               }\r
+               ASSERT(lso_header_size > 0);\r
+               p_desc->wr.dgrm.ud.mss = mss;\r
+               p_desc->wr.dgrm.ud.header = TheLsoData.LsoBuffers[0].pData;\r
+               p_desc->wr.dgrm.ud.hlen = lso_header_size; \r
+               // Tell NDIS how much we will send.\r
+               PktExt->NdisPacketInfo[TcpLargeSendPacketInfo] = UlongToPtr(PacketLength);\r
+               p_desc->wr.send_opt |= (IB_SEND_OPT_TX_IP_CSUM | IB_SEND_OPT_TX_TCP_UDP_CSUM);\r
+               __send_gen(p_port, p_desc, IndexOfData);\r
+               p_desc->wr.wr_type = ( WR_LSO | IB_SEND_OPT_SIGNALED);\r
+       } else {\r
+\r
+               /* Setup the first local data segment (used for the IPoIB header). */\r
+               p_desc->local_ds[0].vaddr = cl_get_physaddr( &p_port->hdr[hdr_idx] );\r
+               p_desc->local_ds[0].length = sizeof(ipoib_hdr_t);\r
+               p_desc->local_ds[0].lkey = p_port->ib_mgr.lkey;\r
+\r
+               status = __send_mgr_filter(\r
+                       p_port, p_eth_hdr, p_buf, buf_len, p_desc);\r
+               cl_perf_stop( &p_port->p_adapter->perf, SendMgrFilter );\r
+               if( status != NDIS_STATUS_SUCCESS )\r
+               {\r
+                       IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                               ("__send_mgr_filter returned 0x%08X.\n", status) );\r
+                       return status;\r
+               }\r
+               p_desc->wr.wr_type = WR_SEND;\r
+               p_desc->wr.send_opt = IB_SEND_OPT_SIGNALED;\r
+       }\r
+\r
+\r
 \r
        /* Setup the work request. */\r
        p_desc->wr.p_next = NULL;\r
        p_desc->wr.wr_id = (uintn_t)p_desc->p_pkt;\r
-       p_desc->wr.wr_type = WR_SEND;\r
-       p_desc->wr.send_opt = IB_SEND_OPT_SIGNALED;\r
-       \r
-       PktExt = NDIS_PACKET_EXTENSION_FROM_PACKET(p_desc->p_pkt);\r
-       pChecksumPktInfo = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&PktExt->NdisPacketInfo[TcpIpChecksumPacketInfo];\r
+\r
        if(p_port->p_adapter->params.send_chksum_offload & \r
                (pChecksumPktInfo->Transmit.NdisPacketChecksumV4 || pChecksumPktInfo->Transmit.NdisPacketChecksumV6))\r
        {\r
@@ -4154,7 +4223,7 @@ __process_failed_send(
        IPOIB_ENTER( IPOIB_DBG_SEND );\r
 \r
        /* Complete the packet. */\r
-       NdisMSendComplete( p_port->p_adapter->h_adapter,\r
+       NdisMSendCompleteX( p_port->p_adapter->h_adapter,\r
                p_desc->p_pkt, status );\r
        ipoib_inc_send_stat( p_port->p_adapter, IP_STAT_ERROR, 0 );\r
        /* Deref the endpoint. */\r
@@ -4203,7 +4272,7 @@ ipoib_port_send(
                {\r
                        ipoib_inc_send_stat( p_port->p_adapter, IP_STAT_DROPPED, 0 );\r
                        /* Complete the packet. */\r
-                       NdisMSendComplete( p_port->p_adapter->h_adapter,\r
+                       NdisMSendCompleteX( p_port->p_adapter->h_adapter,\r
                                p_packet_array[i], NDIS_STATUS_ADAPTER_NOT_READY );\r
                        \r
                }\r
@@ -4535,7 +4604,9 @@ __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 \r
+                                                                       || p_wc->wc_type == IB_WC_SEND\r
+                                                                       || p_wc->wc_type == IB_WC_LSO);\r
                        p_packet = (NDIS_PACKET*)(uintn_t)p_wc->wr_id;\r
                        CL_ASSERT( p_packet );\r
                        CL_ASSERT( IPOIB_PORT_FROM_PACKET( p_packet ) == p_port );\r
@@ -4573,7 +4644,7 @@ __send_cb(
                                IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_SEND,\r
                                        ("Flushed send completion.\n") );\r
                                ipoib_inc_send_stat( p_port->p_adapter, IP_STAT_DROPPED, 0 );\r
-                               NdisMSendComplete( p_port->p_adapter->h_adapter,\r
+                               NdisMSendCompleteX( p_port->p_adapter->h_adapter,\r
                                        p_packet, NDIS_STATUS_RESET_IN_PROGRESS );\r
                                break;\r
 \r
@@ -4583,7 +4654,7 @@ __send_cb(
                                        p_port->p_adapter->p_ifc->get_wc_status_str( p_wc->status ),\r
                                        (int)p_wc->vendor_specific) );\r
                                ipoib_inc_send_stat( p_port->p_adapter, IP_STAT_ERROR, 0 );\r
-                               NdisMSendComplete( p_port->p_adapter->h_adapter,\r
+                               NdisMSendCompleteX( p_port->p_adapter->h_adapter,\r
                                        p_packet, NDIS_STATUS_FAILURE );\r
                                break;\r
                        }\r
@@ -5047,7 +5118,7 @@ __endpt_mgr_ref(
 \r
        cl_obj_lock( &p_port->obj );\r
 \r
-       IPOIB_PRINT( TRACE_LEVEL_VERBOSE, IPOIB_DBG_ENDPT,\r
+       IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_ENDPT,\r
                ("Look for :\t  MAC: %02X-%02X-%02X-%02X-%02X-%02X\n",\r
                mac.addr[0], mac.addr[1], mac.addr[2],\r
                mac.addr[3], mac.addr[4], mac.addr[5]) );\r
@@ -6471,6 +6542,8 @@ ipoib_leave_mcast_cb(
        IPOIB_EXIT( IPOIB_DBG_MCAST );\r
 }\r
 \r
+\r
+\r
 void\r
 __leave_error_mcast_cb(\r
        IN                              void                            *context )\r
@@ -6488,8 +6561,160 @@ __leave_error_mcast_cb(
        IPOIB_EXIT( IPOIB_DBG_MCAST );\r
 }\r
 \r
-static void\r
-__port_do_mcast_garbage(ipoib_port_t* const    p_port)\r
+\r
+NDIS_STATUS GetLsoHeaderSize(\r
+       IN      ipoib_port_t* const pPort,\r
+       IN      PNDIS_BUFFER  CurrBuffer,\r
+       IN      LsoData *pLsoData,\r
+       OUT     uint16_t *pSize,\r
+       OUT     INT  *IndexOfData,\r
+       IN              ipoib_hdr_t *ipoib_hdr\r
+       )\r
+       {\r
+       UINT    CurrLength;\r
+       PUCHAR  pSrc;\r
+       PUCHAR  pCopiedData = pLsoData->coppied_data;\r
+       ip_hdr_t UNALIGNED  *IpHdr;\r
+       tcp_hdr_t UNALIGNED *TcpHdr;\r
+       uint16_t                 TcpHeaderLen;\r
+       uint16_t                 IpHeaderLen;\r
+       uint16_t IpOffset;\r
+       INT                 FullBuffers = 0;\r
+       NDIS_STATUS         status = NDIS_STATUS_INVALID_PACKET;    \r
+       //\r
+       // This Flag indicates the way we gets the headers\r
+       // RegularFlow = we get the headers (ETH+IP+TCP) in the same Buffer \r
+       // in sequence.\r
+       //\r
+#define IP_OFFSET 14;\r
+       boolean_t                       IsRegularFlow = TRUE;\r
+       const uint16_t ETH_OFFSET = IP_OFFSET; \r
+       *pSize = 0;\r
+       UNUSED_PARAM(pPort);\r
+       IpOffset = IP_OFFSET; //(uint16_t)pPort->EncapsulationFormat.EncapsulationHeaderSize;\r
+       *IndexOfData = 0;\r
+       NdisQueryBufferSafe( CurrBuffer, &pSrc, &CurrLength, NormalPagePriority );    \r
+       if (pSrc == NULL) {\r
+               IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, ("Error processing packets\n"));\r
+               return status;\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
+       //*pSize = *pSize + ETH_OFFSET;\r
+       if (CurrLength == ETH_OFFSET) {        \r
+               ASSERT(FALSE);\r
+               IsRegularFlow = FALSE;        \r
+               memcpy(pCopiedData, pSrc, ETH_OFFSET);\r
+               pCopiedData += ETH_OFFSET;        \r
+               FullBuffers++;\r
+               // First buffer was only ethernet\r
+               NdisGetNextBuffer( CurrBuffer, &CurrBuffer);\r
+               NdisQueryBufferSafe( CurrBuffer, &pSrc, &CurrLength, NormalPagePriority );\r
+               if (pSrc == NULL) {\r
+                       IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_ERROR, ("Error porcessing packets\n"));\r
+                       return status;\r
+           }\r
+       } else {\r
+               // This is ETH + IP together (at least)\r
+               pLsoData->LsoBuffers[0].pData = pSrc + (ETH_OFFSET - sizeof (ipoib_hdr_t));\r
+               memcpy (pLsoData->LsoBuffers[0].pData, ipoib_hdr, sizeof (ipoib_hdr_t));\r
+               CurrLength -= ETH_OFFSET;\r
+               pSrc = pSrc + ETH_OFFSET;\r
+               *pSize = *pSize + sizeof (ipoib_hdr_t);\r
+       }\r
+       // we should now be having at least the size of ethernet data\r
+       if (CurrLength < sizeof (ip_hdr_t)) {\r
+               IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_ERROR, ("Error porcessing packets\n"));\r
+               return status;\r
+       }\r
+       IpHdr = (ip_hdr_t UNALIGNED*)pSrc;\r
+       IpHeaderLen = (uint16_t)IP_HEADER_LENGTH(IpHdr);\r
+       ASSERT(IpHdr->prot == PROTOCOL_TCP);\r
+       if (CurrLength < IpHeaderLen) {\r
+               IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_ERROR, ("Error processing packets\n"));\r
+               return status;\r
+       }\r
+       *pSize = *pSize + IpHeaderLen;\r
+       // We now start to find where the TCP header starts\r
+       if (CurrLength == IpHeaderLen) {\r
+               ASSERT(FALSE);\r
+               // two options : \r
+               // if(IsRegularFlow = FALSE) ==> ETH and IP seperated in two buffers\r
+               // if(IsRegularFlow = TRUE ) ==> ETH and IP in the same buffer \r
+               // TCP will start at next buffer\r
+               if(IsRegularFlow){\r
+                       memcpy(pCopiedData, pSrc-ETH_OFFSET ,ETH_OFFSET+IpHeaderLen);\r
+                       pCopiedData += (ETH_OFFSET + IpHeaderLen);\r
+               } else {\r
+                       memcpy(pCopiedData, pSrc,IpHeaderLen);\r
+                       pCopiedData += IpHeaderLen;\r
+               }\r
+           \r
+               FullBuffers++;\r
+               IsRegularFlow = FALSE;\r
+               NdisGetNextBuffer( CurrBuffer, &CurrBuffer);\r
+               NdisQueryBufferSafe( CurrBuffer, &pSrc, &CurrLength, NormalPagePriority );\r
+\r
+               if (pSrc == NULL) {\r
+                       IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_ERROR, ("Error porcessing packets\n"));\r
+                       return status;\r
+               }\r
+       } else {\r
+               // if(IsRegularFlow = TRUE ) ==> the ETH and IP and TCP in the same buffer       \r
+               // if(IsRegularFlow = FLASE ) ==> ETH in one buffer , IP+TCP together in the same buffer\r
+               if (IsRegularFlow) {            \r
+                       pLsoData->LsoBuffers[0].Len += IpHeaderLen;\r
+               } else {            \r
+                       memcpy(pCopiedData, pSrc, IpHeaderLen);\r
+                       pCopiedData += IpHeaderLen;\r
+               }\r
+\r
+               CurrLength -= IpHeaderLen;\r
+               pSrc = pSrc + IpHeaderLen;\r
+       }\r
+       if (CurrLength < sizeof (tcp_hdr_t)) {\r
+               IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_ERROR, ("Error porcessing packets\n"));\r
+               return status;\r
+       }\r
+       // We have finaly found the TCP header\r
+       TcpHdr = (tcp_hdr_t UNALIGNED *)pSrc;\r
+       TcpHeaderLen = TCP_HEADER_LENGTH(TcpHdr);\r
+\r
+       ASSERT(TcpHeaderLen == 20);\r
+       \r
+       if (CurrLength < TcpHeaderLen) {\r
+               //IPOIB_PRINT(TRACE_LEVEL_VERBOSE, ETH, ("Error porcessing packets\n"));\r
+               return status;\r
+       }\r
+       *pSize =  *pSize + TcpHeaderLen;\r
+       if(IsRegularFlow){\r
+               pLsoData->LsoBuffers[0].Len += TcpHeaderLen;            \r
+       }\r
+       else{\r
+               memcpy(pCopiedData, pSrc, TcpHeaderLen);                    \r
+               pCopiedData += TcpHeaderLen;                  \r
+       }         \r
+       if (CurrLength == TcpHeaderLen) {        \r
+               FullBuffers++;\r
+               pLsoData->UsedBuffers = FullBuffers;\r
+               *IndexOfData = FullBuffers ;\r
+       } else {\r
+               pLsoData->UsedBuffers = FullBuffers + 1;\r
+               *IndexOfData = FullBuffers - 1;\r
+       }\r
+       pLsoData->FullBuffers = FullBuffers; \r
+       if (!IsRegularFlow){\r
+               pLsoData->LsoBuffers[0].pData = pLsoData->coppied_data;\r
+               pLsoData->LsoBuffers[0].Len = ETH_OFFSET + IpHeaderLen + TcpHeaderLen;\r
+               ASSERT(pLsoData->LsoBuffers[0].Len <= LSO_MAX_HEADER);\r
+       }\r
+       return NDIS_STATUS_SUCCESS;\r
+}\r
+\r
+static void __port_do_mcast_garbage(ipoib_port_t* const        p_port)\r
 {\r
     const mac_addr_t DEFAULT_MCAST_GROUP = {0x01, 0x00, 0x5E, 0x00, 0x00, 0x01};\r
        /* Do garbage collecting... */\r
@@ -6557,8 +6782,7 @@ __port_do_mcast_garbage(ipoib_port_t* const       p_port)
        }\r
 }\r
 \r
-static void\r
-__port_mcast_garbage_dpc(KDPC *p_gc_dpc,void *context,void *s_arg1, void *s_arg2)\r
+static void __port_mcast_garbage_dpc(KDPC *p_gc_dpc,void *context,void *s_arg1, void *s_arg2)\r
 {\r
        ipoib_port_t *p_port = context;\r
 \r
index c9efb00ea0002d9fd37c10ae57b1c91731e756c2..dfd567662e4dd459b33d950716926cb1fd851be2 100644 (file)
@@ -640,6 +640,22 @@ inline void ipoib_port_deref(
        IN                              ipoib_port_t *                          p_port,\r
        IN                              int                                             type);\r
 \r
+#if DBG\r
+// This function is only used to monitor send failures\r
+static inline VOID NdisMSendCompleteX(\r
+       IN NDIS_HANDLE  MiniportAdapterHandle,\r
+       IN PNDIS_PACKET  Packet,\r
+       IN NDIS_STATUS  Status\r
+       ) {\r
+       if (Status != NDIS_STATUS_SUCCESS) {\r
+               IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+                       ("Sending status other than Success to NDIS\n"));\r
+       }\r
+       NdisMSendComplete(MiniportAdapterHandle,Packet,Status);\r
+}\r
+#else\r
+#define NdisMSendCompleteX NdisMSendComplete\r
+#endif\r
 ipoib_endpt_t*\r
 ipoib_endpt_get_by_gid(\r
        IN                              ipoib_port_t* const                     p_port,\r