#include <iba/ipoib_ifc.h>\r
#include "ntstrsafe.h"\r
#include "strsafe.h"\r
+#include <offload.h>\r
+\r
\r
\r
\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("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
}; \r
\r
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
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
\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
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
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
#endif\r
#include "ipoib_port.tmh"\r
#endif\r
+#include <offload.h>\r
\r
\r
/* Amount of physical memory to register. */\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_desc_t* const p_desc,\r
+ IN INT lso_data_index);\r
\r
static NDIS_STATUS\r
__send_mgr_filter_ip(\r
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
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
* 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
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
* 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
}\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
{\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
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
\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
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
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
{\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
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
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
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
IPOIB_EXIT( IPOIB_DBG_MCAST );\r
}\r
\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