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