<HTML dir=ltr><HEAD>
<META http-equiv=Content-Type content="text/html; charset=unicode">
<META content="MSHTML 6.00.2900.3395" name=GENERATOR></HEAD>
<BODY>
<P><FONT face=Arial color=#000000 size=2>Hello,</FONT></P>
<P><FONT face=Arial color=#000000 size=2>Attached are IPoIB Connected Mode changes.</FONT></P>
<P><FONT face=Arial size=2>Here is a reviewed key implementation info from previous emails with some recent changes:</FONT></P>
<P><FONT face=Arial color=#000000 size=2>Connection:<BR>        Listening CEP associated with local endpoint.<BR>        Connection established per endpoint. CM Active side, QP creation/destroy is offloaded to a system thread.<BR>        CREQ sent along with unicast ARP reply to the endpoint if that endpoint reported it's C/M capabilities in ARP request.<BR></FONT><FONT face=Arial color=#000000 size=2>Host can accept CREQ from the same endpoint. As a result one or two RC QPs will be created per connection (that matches linux behavior).<BR>Both QPs are created bidirectional so the first established connection will be used for transmission.<BR>Max payload MTU is set to 65520 (to match Linux ipoib cm MTU size).<BR>Since there is no HW support for RC QP yet, checksum offload flags were forced to set: Send - disabled, receive - bypass.<BR><BR>Send path:</FONT></P>
<P><FONT face=Arial color=#000000 size=2>        Unicast TCP and UDP packets go through RC QP.</FONT><FONT face=Arial color=#000000 size=2> </FONT></P>
<P><FONT face=Arial color=#000000 size=2>        ARP, ICMP, multicast go through UD QP, if necessary IP packet fragmented and fit into a chain of WRs.</FONT></P>
<P><FONT color=#000000><FONT face=Arial size=2>Recv path:<BR>        endpoint recv queue attached to SRQ.<BR>        SRQ is created per port, SRQ queue size calculated using data from ca attributes query (might need to come up with better scalable value).<BR>        introduced new descriptor type that extends layout of UD receive descriptor.<BR>        implemented simple ARP filter (will go away).<BR>        reused existing filter for UDP/DHCP packets.<BR><BR>Common code changes: </FONT></FONT></P>
<P><FONT color=#000000><FONT face=Arial size=2>ipoib_cm.c <BR>-</FONT></FONT><FONT color=#000000><FONT face=Arial size=2>new file. Most of IB CM related code was put there.</FONT></FONT></P>
<P><FONT face=Arial size=2>ipoib_endpoint.c</FONT></P>
<P><FONT face=Arial size=2> Most receive buffers management functions implemented there.</FONT></P>
<P><FONT color=#000000><FONT face=Arial size=2>ipoib_port.c</FONT></FONT></P>
<P><FONT color=#000000><FONT face=Arial size=2>__build_send_desc() and __send_mgr_filter_ip() were reworked to handle RC/UD redirection and IP fragmentation logic. <BR> LSO WR formatting was repackaged as a separate function.<BR>R</FONT></FONT><FONT color=#000000><FONT face=Arial size=2>ecv statistics update was optimized a bit for RC path. </FONT></FONT></P>
<P><FONT color=#000000><FONT face=Arial size=2>inc\kernel\ip_packet.h  <BR></FONT></FONT><FONT color=#000000><FONT face=Arial size=2>- added a few macros for IP header fragment flags handling.</FONT></FONT></P>
<P><FONT face=Arial size=2>ipoib_xfr_mgr.h</FONT></P>
<P><FONT color=#000000><FONT face=Arial size=2>        fixed and put to use ipoib hw addr fields handling routines.</FONT></FONT></P>
<P><FONT color=#000000><FONT face=Arial size=2>ipoib_driver.h.</P></FONT></FONT>
<P><FONT color=#000000><FONT face=Arial size=2>        most global definitions moved here.</FONT></FONT></P>
<P><FONT color=#000000><FONT face=Arial size=2>Some other changes:</FONT></FONT></P>
<P><FONT color=#000000><FONT face=Arial size=2>        added MiniportCancelSendPackets routine.<BR>        added ErrorLog messages for success/failed C/M initialization.<BR>        reduced some debug print noise by moving statistic OIDs and few other to higher level.<BR>        some minor code format, while tried to maintain consistent project coding style.</FONT></FONT></P>
<P><FONT face=Arial size=2>Please review.</FONT></P>
<P><FONT color=#000000><FONT face=Arial size=2>Known issues and limitations:<BR>C/M is forced to stay disabled if LSO is enabled ( not sure how to merge it together since LSO is tied to UD ).<BR>SID is misformatted (IETF bit) to match Linux implementation. (Linux PR was opened).<BR>IP fragmentation of packets > 30k will fail.</FONT></FONT><FONT color=#000000><FONT face=Arial size=2><BR></FONT></FONT><FONT face=Arial size=2>Code was tested on 2003 x86, x64 and with Linux OFED 1.3.1<BR></P></FONT>
<P><FONT face=Arial size=2>Thanks,</FONT></P>
<P><FONT face=Arial size=2>Alex.</FONT></P>
<P>Index: inc/kernel/ip_packet.h<BR>===================================================================<BR>--- inc/kernel/ip_packet.h (revision 1776)<BR>+++ inc/kernel/ip_packet.h (working copy)<BR>@@ -197,6 +197,7 @@<BR> #define IP_PROT_TCP   6<BR> #define IP_PROT_UDP   17<BR> #define IP_PROT_IGMP  2<BR>+#define IP_PROT_ICMP  1<BR> <BR> <BR> #include <complib/cl_packon.h><BR>@@ -359,12 +360,26 @@<BR> #define IP_HEADER_LENGTH(pIpHdr)   \<BR>         ( (ULONG)((pIpHdr->ver_hl & 0x0F) << 2) )<BR> <BR>+#define IP_FRAGMENT_OFFSET(p_ip_hdr) \<BR>+  ( cl_ntoh16( p_ip_hdr->offset & CL_HTON16(0x1fff) ) )<BR>+<BR>+#define IP_DONT_FRAGMENT(p_ip_hdr) \<BR>+  ( (BOOLEAN)( p_ip_hdr->offset & CL_HTON16(0x4000 ) ) )<BR>+  <BR>+#define IP_MORE_FRAGMENTS( p_ip_hdr ) \<BR>+  ( (BOOLEAN)( p_ip_hdr->offset & CL_HTON16(0x2000) ) )<BR>+<BR>+#define IP_SET_MORE_FRAGMENTS( p_ip_hdr ) \<BR>+  ( p_ip_hdr->offset |= CL_HTON16(0x2000) )<BR>+<BR>+#define IP_SET_LAST_FRAGMENT( p_ip_hdr ) \<BR>+  ( p_ip_hdr->offset &= (CL_HTON16(~0x2000) ) )<BR>+<BR> #define TCP_HEADER_LENGTH(pTcpHdr) \<BR>   ((pTcpHdr->offset & 0xF0) >> 2)<BR> <BR>-#define PROTOCOL_TCP         6<BR>+#define PROTOCOL_TCP         IP_PROT_TCP<BR> <BR>-<BR> #define IGMP_V2_MEMBERSHIP_QUERY 0x11<BR> #define IGMP_V2_MEMBERSHIP_REPORT 0x16<BR> #define IGMP_V1_MEMBERSHIP_REPORT 0x12 // for backward compatibility with IGMPv1<BR>Index: ulp/ipoib/kernel/ipoib_adapter.c<BR>===================================================================<BR>--- ulp/ipoib/kernel/ipoib_adapter.c (revision 1776)<BR>+++ ulp/ipoib/kernel/ipoib_adapter.c (working copy)<BR>@@ -1287,7 +1287,8 @@<BR> ipoib_inc_recv_stat(<BR>  IN    ipoib_adapter_t* const  p_adapter,<BR>  IN  const ip_stat_sel_t    stat_sel,<BR>- IN  const size_t      bytes OPTIONAL )<BR>+ IN  const size_t      bytes OPTIONAL,<BR>+ IN  const size_t      packets OPTIONAL )<BR> {<BR>  IPOIB_ENTER( IPOIB_DBG_STAT );<BR> <BR>@@ -1305,21 +1306,21 @@<BR>  case IP_STAT_UCAST_BYTES:<BR>  case IP_STAT_UCAST_FRAMES:<BR>   p_adapter->recv_stats.comp.success++;<BR>-  p_adapter->recv_stats.ucast.frames++;<BR>+  p_adapter->recv_stats.ucast.frames += packets;<BR>   p_adapter->recv_stats.ucast.bytes += bytes;<BR>   break;<BR> <BR>  case IP_STAT_BCAST_BYTES:<BR>  case IP_STAT_BCAST_FRAMES:<BR>   p_adapter->recv_stats.comp.success++;<BR>-  p_adapter->recv_stats.bcast.frames++;<BR>+  p_adapter->recv_stats.bcast.frames += packets;<BR>   p_adapter->recv_stats.bcast.bytes += bytes;<BR>   break;<BR> <BR>  case IP_STAT_MCAST_BYTES:<BR>  case IP_STAT_MCAST_FRAMES:<BR>   p_adapter->recv_stats.comp.success++;<BR>-  p_adapter->recv_stats.mcast.frames++;<BR>+  p_adapter->recv_stats.mcast.frames += packets;<BR>   p_adapter->recv_stats.mcast.bytes += bytes;<BR>   break;<BR> <BR>Index: ulp/ipoib/kernel/ipoib_adapter.h<BR>===================================================================<BR>--- ulp/ipoib/kernel/ipoib_adapter.h (revision 1776)<BR>+++ ulp/ipoib/kernel/ipoib_adapter.h (working copy)<BR>@@ -60,15 +60,20 @@<BR> /*<BR>  * Macros<BR>  */<BR>-typedef enum {CSUM_DISABLED = 0, CSUM_ENABLED, CSUM_BYPASS} tCsumTypeEn;<BR>+typedef enum <BR>+{<BR>+ CSUM_DISABLED = 0, <BR>+ CSUM_ENABLED, <BR>+ CSUM_BYPASS<BR>+} csum_flag_t;<BR> <BR> typedef struct _ipoib_params<BR> {<BR>  int32_t  rq_depth;<BR>  int32_t  rq_low_watermark;<BR>  int32_t  sq_depth;<BR>- int32_t  send_chksum_offload;  //is actually of type tCsumTypeEn<BR>- int32_t  recv_chksum_offload; //is actually of type tCsumTypeEn<BR>+ csum_flag_t send_chksum_offload;<BR>+ csum_flag_t recv_chksum_offload;<BR>  uint32_t sa_timeout;<BR>  uint32_t sa_retry_cnt;<BR>  uint32_t recv_pool_ratio;<BR>@@ -79,6 +84,9 @@<BR>  uint32_t mc_leave_rescan;<BR>  uint32_t guid_mask;<BR>  uint32_t bc_join_retry;<BR>+ boolean_t cm_enabled;<BR>+ uint32_t cm_payload_mtu;<BR>+ uint32_t cm_xfer_block_size;<BR> } ipoib_params_t;<BR> /*<BR> * FIELDS<BR>@@ -389,7 +397,8 @@<BR> ipoib_inc_recv_stat(<BR>  IN    ipoib_adapter_t* const  p_adapter,<BR>  IN  const ip_stat_sel_t    stat_sel,<BR>- IN  const size_t      bytes OPTIONAL );<BR>+ IN  const size_t      bytes OPTIONAL,<BR>+ IN  const size_t      packets OPTIONAL );<BR> <BR> <BR> NDIS_STATUS<BR>Index: ulp/ipoib/kernel/ipoib_debug.h<BR>===================================================================<BR>--- ulp/ipoib/kernel/ipoib_debug.h (revision 1776)<BR>+++ ulp/ipoib/kernel/ipoib_debug.h (working copy)<BR>@@ -34,6 +34,9 @@<BR> #ifndef _IPOIB_DEBUG_H_<BR> #define _IPOIB_DEBUG_H_<BR> <BR>+#if defined __MODULE__<BR>+#undef __MODULE__<BR>+#endif<BR> <BR> #define __MODULE__ "[IPoIB]"<BR> <BR>Index: ulp/ipoib/kernel/ipoib_driver.c<BR>===================================================================<BR>--- ulp/ipoib/kernel/ipoib_driver.c (revision 1776)<BR>+++ ulp/ipoib/kernel/ipoib_driver.c (working copy)<BR>@@ -160,11 +160,12 @@<BR>  {NDIS_STRING_CONST("SaTimeout"),        1, IPOIB_OFFSET(sa_timeout),            IPOIB_SIZE(sa_timeout),         1000,       250,    UINT_MAX},<BR>  {NDIS_STRING_CONST("SaRetries"),        1, IPOIB_OFFSET(sa_retry_cnt),          IPOIB_SIZE(sa_retry_cnt),       10,         1,      UINT_MAX},<BR>  {NDIS_STRING_CONST("RecvRatio"),        1, IPOIB_OFFSET(recv_pool_ratio),       IPOIB_SIZE(recv_pool_ratio),    1,          1,      10},<BR>- {NDIS_STRING_CONST("PayloadMtu"),       1, IPOIB_OFFSET(payload_mtu),           IPOIB_SIZE(payload_mtu),        2044,       512,    4092},<BR>+ {NDIS_STRING_CONST("PayloadMtu"),       1, IPOIB_OFFSET(payload_mtu),           IPOIB_SIZE(payload_mtu),        2044,       512,   MAX_CM_PAYLOAD_MTU},<BR>  {NDIS_STRING_CONST("lso"),              0, IPOIB_OFFSET(lso),                   IPOIB_SIZE(lso),                0,          0,      1},<BR>  {NDIS_STRING_CONST("MCLeaveRescan"),    1, IPOIB_OFFSET(mc_leave_rescan),       IPOIB_SIZE(mc_leave_rescan),    260,        1,    3600},<BR>- {NDIS_STRING_CONST("BCJoinRetry"),     1, IPOIB_OFFSET(bc_join_retry),      IPOIB_SIZE(bc_join_retry),      50,         0,    1000}<BR>- <BR>+ {NDIS_STRING_CONST("BCJoinRetry"),     1, IPOIB_OFFSET(bc_join_retry),      IPOIB_SIZE(bc_join_retry),      50,         0,    1000},<BR>+ {NDIS_STRING_CONST("CmEnabled"),        0, IPOIB_OFFSET(cm_enabled),            IPOIB_SIZE(cm_enabled),         FALSE,     FALSE, TRUE}<BR>+<BR> };  <BR> <BR> #define IPOIB_NUM_REG_PARAMS (sizeof (HCARegTable) / sizeof(IPOIB_REG_ENTRY))<BR>@@ -275,6 +276,11 @@<BR> ipoib_shutdown(<BR>  IN    PVOID      adapter_context );<BR> <BR>+void<BR>+ipoib_cancel_xmit(<BR>+ IN    NDIS_HANDLE     adapter_context,<BR>+ IN    PVOID      cancel_id );<BR>+<BR> static void<BR> ipoib_complete_query(<BR>  IN    ipoib_adapter_t* const  p_adapter,<BR>@@ -370,7 +376,7 @@<BR> <BR>  characteristics.ReturnPacketHandler  = ipoib_return_packet;<BR>  characteristics.SendPacketsHandler  = ipoib_send_packets;<BR>-<BR>+ characteristics.CancelSendPacketsHandler = ipoib_cancel_xmit;<BR> #ifdef NDIS51_MINIPORT<BR>  characteristics.PnPEventNotifyHandler = ipoib_pnp_notify;<BR>  characteristics.AdapterShutdownHandler = ipoib_shutdown;<BR>@@ -597,7 +603,23 @@<BR>  // Adjusting the low watermark parameter<BR>  p_adapter->params.rq_low_watermark =<BR>    p_adapter->params.rq_depth / p_adapter->params.rq_low_watermark;<BR>-<BR>+ <BR>+ /* disable CM if LSO is active */<BR>+ if( p_adapter->params.cm_enabled )<BR>+ {<BR>+  p_adapter->params.cm_enabled = !p_adapter->params.lso;<BR>+  if( !p_adapter->params.cm_enabled )<BR>+  {<BR>+   NdisWriteErrorLogEntry( p_adapter->h_adapter,<BR>+    EVENT_IPOIB_CONNECTED_MODE_ERR, 1, 0xbadc0de0 );<BR>+  }<BR>+ }<BR>+ p_adapter->params.cm_payload_mtu =<BR>+   min( MAX_CM_PAYLOAD_MTU, p_adapter->params.payload_mtu );<BR>+ p_adapter->params.cm_xfer_block_size = <BR>+   p_adapter->params.cm_payload_mtu + sizeof(eth_hdr_t);<BR>+ p_adapter->params.payload_mtu = <BR>+   min( DEFAULT_PAYLOAD_MTU, p_adapter->params.payload_mtu);<BR>  p_adapter->params.xfer_block_size = (sizeof(eth_hdr_t) + p_adapter->params.payload_mtu);<BR>  NdisReadNetworkAddress( &status, p_mac, p_len, h_config );<BR> <BR>@@ -717,7 +739,9 @@<BR>  ib_api_status_t  ib_status;<BR>  UINT    medium_index;<BR>  ipoib_adapter_t  *p_adapter;<BR>-<BR>+#if IPOIB_USE_DMA<BR>+ ULONG max_phys_mapping;<BR>+#endif<BR>  IPOIB_ENTER( IPOIB_DBG_INIT );<BR> <BR> #ifdef _DEBUG_<BR>@@ -760,8 +784,13 @@<BR>   NdisInterfacePNPBus );<BR> <BR> #if IPOIB_USE_DMA<BR>+ max_phys_mapping = p_adapter->params.cm_enabled ? <BR>+  p_adapter->params.cm_xfer_block_size: p_adapter->params.xfer_block_size;<BR>+ max_phys_mapping = p_adapter->params.lso ? <BR>+  max(LARGE_SEND_OFFLOAD_SIZE, max_phys_mapping): max_phys_mapping;<BR>  status =<BR>-  NdisMInitializeScatterGatherDma( h_adapter, TRUE, p_adapter->params.xfer_block_size );<BR>+  NdisMInitializeScatterGatherDma( h_adapter, TRUE, max_phys_mapping );<BR>+<BR>  if( status != NDIS_STATUS_SUCCESS )<BR>  {<BR>   ipoib_destroy_adapter( p_adapter );<BR>@@ -948,11 +977,18 @@<BR>  case OID_GEN_MAXIMUM_FRAME_SIZE:<BR>   IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_GEN_MAXIMUM_FRAME_SIZE\n", port_num) );<BR>-  info = p_adapter->params.payload_mtu;<BR>+  if( p_adapter->params.cm_enabled )<BR>+  {<BR>+   info = p_adapter->params.cm_payload_mtu;<BR>+  }<BR>+  else<BR>+  {<BR>+   info = p_adapter->params.payload_mtu;<BR>+  }<BR>   break;<BR> <BR>  case OID_GEN_LINK_SPEED:<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_GEN_LINK_SPEED\n", port_num) );<BR>   cl_obj_lock( &p_adapter->obj );<BR>   info = p_adapter->port_rate;<BR>@@ -962,14 +998,20 @@<BR>  case OID_GEN_TRANSMIT_BUFFER_SPACE:<BR>   IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_GEN_TRANSMIT_BUFFER_SPACE\n", port_num) );<BR>-  info = p_adapter->params.sq_depth * p_adapter->params.xfer_block_size;<BR>+  if( p_adapter->params.cm_enabled )<BR>+   info = p_adapter->params.sq_depth * p_adapter->params.cm_xfer_block_size;<BR>+  else<BR>+   info = p_adapter->params.sq_depth * p_adapter->params.xfer_block_size;<BR>   break;<BR> <BR>  case OID_GEN_RECEIVE_BUFFER_SPACE:<BR>   IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_GEN_TRANSMIT_BUFFER_SPACE "<BR>    "or OID_GEN_RECEIVE_BUFFER_SPACE\n", port_num) );<BR>-  info = p_adapter->params.rq_depth * p_adapter->params.xfer_block_size;<BR>+  if( p_adapter->params.cm_enabled )<BR>+   info = p_adapter->params.rq_depth * p_adapter->params.cm_xfer_block_size;<BR>+  else<BR>+   info = p_adapter->params.rq_depth * p_adapter->params.xfer_block_size;<BR>   break;<BR> <BR>  case OID_GEN_MAXIMUM_LOOKAHEAD:<BR>@@ -983,7 +1025,10 @@<BR>    "OID_GEN_TRANSMIT_BLOCK_SIZE or "<BR>    "OID_GEN_RECEIVE_BLOCK_SIZE or "<BR>    "OID_GEN_MAXIMUM_TOTAL_SIZE\n", port_num) );<BR>-  info = p_adapter->params.xfer_block_size;<BR>+  if( p_adapter->params.cm_enabled )<BR>+   info = p_adapter->params.cm_xfer_block_size;<BR>+  else<BR>+   info = p_adapter->params.xfer_block_size;<BR>   break;<BR> <BR>  case OID_GEN_VENDOR_ID:<BR>@@ -1044,7 +1089,7 @@<BR>   break;<BR> <BR>  case OID_GEN_MEDIA_CONNECT_STATUS:<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_GEN_MEDIA_CONNECT_STATUS\n", port_num) );<BR>   cl_obj_lock( &p_adapter->obj );<BR>   switch( p_adapter->state )<BR>@@ -1064,7 +1109,7 @@<BR>    break;<BR> <BR>   case IB_PNP_PORT_ACTIVE:<BR>-   IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+   IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>     ("Port %d returning NdisMediaStateConnected\n", port_num) );<BR>    info = NdisMediaStateConnected;<BR>    break;<BR>@@ -1091,119 +1136,119 @@<BR> <BR>  /* Required General Statistics */<BR>  case OID_GEN_XMIT_OK:<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_GEN_XMIT_OK\n", port_num) );<BR>   src_buf = NULL;<BR>   status = ipoib_get_send_stat( p_adapter, IP_STAT_SUCCESS, &oid_info );<BR>   break;<BR> <BR>  case OID_GEN_RCV_OK:<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_GEN_RCV_OK\n", port_num) );<BR>   src_buf = NULL;<BR>   status = ipoib_get_recv_stat( p_adapter, IP_STAT_SUCCESS, &oid_info );<BR>   break;<BR> <BR>  case OID_GEN_XMIT_ERROR:<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_GEN_XMIT_ERROR\n", port_num) );<BR>   src_buf = NULL;<BR>   status = ipoib_get_send_stat( p_adapter, IP_STAT_ERROR, &oid_info );<BR>   break;<BR> <BR>  case OID_GEN_RCV_ERROR:<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_GEN_RCV_ERROR\n", port_num) );<BR>   src_buf = NULL;<BR>   status = ipoib_get_recv_stat( p_adapter, IP_STAT_ERROR, &oid_info );<BR>   break;<BR> <BR>  case OID_GEN_RCV_NO_BUFFER:<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_GEN_RCV_NO_BUFFER\n", port_num) );<BR>   src_buf = NULL;<BR>   status = ipoib_get_recv_stat( p_adapter, IP_STAT_DROPPED, &oid_info );<BR>   break;<BR> <BR>  case OID_GEN_DIRECTED_BYTES_XMIT:<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_GEN_DIRECTED_BYTES_XMIT\n", port_num) );<BR>   src_buf = NULL;<BR>   status = ipoib_get_send_stat( p_adapter, IP_STAT_UCAST_BYTES, &oid_info );<BR>   break;<BR> <BR>  case OID_GEN_DIRECTED_FRAMES_XMIT:<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_GEN_DIRECTED_FRAMES_XMIT\n", port_num) );<BR>   src_buf = NULL;<BR>   status = ipoib_get_send_stat( p_adapter, IP_STAT_UCAST_FRAMES, &oid_info );<BR>   break;<BR> <BR>  case OID_GEN_MULTICAST_BYTES_XMIT:<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_GEN_MULTICAST_BYTES_XMIT\n", port_num) );<BR>   src_buf = NULL;<BR>   status = ipoib_get_send_stat( p_adapter, IP_STAT_MCAST_BYTES, &oid_info );<BR>   break;<BR> <BR>  case OID_GEN_MULTICAST_FRAMES_XMIT:<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_GEN_MULTICAST_FRAMES_XMIT\n", port_num) );<BR>   src_buf = NULL;<BR>   status = ipoib_get_send_stat( p_adapter, IP_STAT_MCAST_FRAMES, &oid_info );<BR>   break;<BR> <BR>  case OID_GEN_BROADCAST_BYTES_XMIT:<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_GEN_BROADCAST_BYTES_XMIT\n", port_num) );<BR>   src_buf = NULL;<BR>   status = ipoib_get_send_stat( p_adapter, IP_STAT_BCAST_BYTES, &oid_info );<BR>   break;<BR> <BR>  case OID_GEN_BROADCAST_FRAMES_XMIT:<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_GEN_BROADCAST_FRAMES_XMIT\n", port_num) );<BR>   src_buf = NULL;<BR>   status = ipoib_get_send_stat( p_adapter, IP_STAT_BCAST_FRAMES, &oid_info );<BR>   break;<BR> <BR>  case OID_GEN_DIRECTED_BYTES_RCV:<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_GEN_DIRECTED_BYTES_RCV\n", port_num) );<BR>   src_buf = NULL;<BR>   status = ipoib_get_recv_stat( p_adapter, IP_STAT_UCAST_BYTES, &oid_info );<BR>   break;<BR> <BR>  case OID_GEN_DIRECTED_FRAMES_RCV:<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_GEN_DIRECTED_FRAMES_RCV\n", port_num) );<BR>   src_buf = NULL;<BR>   status = ipoib_get_recv_stat( p_adapter, IP_STAT_UCAST_FRAMES, &oid_info );<BR>   break;<BR> <BR>  case OID_GEN_MULTICAST_BYTES_RCV:<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_GEN_MULTICAST_BYTES_RCV\n", port_num) );<BR>   src_buf = NULL;<BR>   status = ipoib_get_recv_stat( p_adapter, IP_STAT_MCAST_BYTES, &oid_info );<BR>   break;<BR> <BR>  case OID_GEN_MULTICAST_FRAMES_RCV:<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_GEN_MULTICAST_FRAMES_RCV\n", port_num) );<BR>   src_buf = NULL;<BR>   status = ipoib_get_recv_stat( p_adapter, IP_STAT_MCAST_FRAMES, &oid_info );<BR>   break;<BR> <BR>  case OID_GEN_BROADCAST_BYTES_RCV:<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_GEN_BROADCAST_BYTES_RCV\n", port_num) );<BR>   src_buf = NULL;<BR>   status = ipoib_get_recv_stat( p_adapter, IP_STAT_BCAST_BYTES, &oid_info );<BR>   break;<BR> <BR>  case OID_GEN_BROADCAST_FRAMES_RCV:<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_GEN_BROADCAST_FRAMES_RCV\n", port_num) );<BR>   src_buf = NULL;<BR>   status = ipoib_get_recv_stat( p_adapter, IP_STAT_BCAST_FRAMES, &oid_info );<BR>@@ -1211,34 +1256,34 @@<BR> <BR>  /* Required Ethernet operational characteristics */<BR>  case OID_802_3_PERMANENT_ADDRESS:<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_802_3_PERMANENT_ADDRESS\n", port_num) );<BR>   src_buf = &p_adapter->mac;<BR>   buf_len = sizeof(p_adapter->mac);<BR>   break;<BR> <BR>  case OID_802_3_CURRENT_ADDRESS:<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_802_3_CURRENT_ADDRESS\n", port_num) );<BR>   src_buf = &p_adapter->params.conf_mac;<BR>   buf_len = sizeof(p_adapter->params.conf_mac);<BR>   break;<BR> <BR>  case OID_802_3_MULTICAST_LIST:<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_802_3_MULTICAST_LIST\n", port_num) );<BR>   src_buf = p_adapter->mcast_array;<BR>   buf_len = p_adapter->mcast_array_size * sizeof(mac_addr_t);<BR>   break;<BR> <BR>  case OID_802_3_MAXIMUM_LIST_SIZE:<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_802_3_MAXIMUM_LIST_SIZE\n", port_num) );<BR>   info = MAX_MCAST;<BR>   break;<BR> <BR>  case OID_802_3_MAC_OPTIONS:<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received query for OID_802_3_MAC_OPTIONS\n", port_num) );<BR>   info = 0;<BR>   break;<BR>@@ -1279,7 +1324,7 @@<BR>  case OID_802_3_XMIT_LATE_COLLISIONS:<BR>  case OID_PNP_CAPABILITIES:<BR>   status = NDIS_STATUS_NOT_SUPPORTED;<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received an unsupported oid of 0x%.8X!\n", port_num, oid) );<BR>   break;<BR> <BR>@@ -1292,7 +1337,7 @@<BR> #endif<BR>  default:<BR>   status = NDIS_STATUS_INVALID_OID;<BR>-  IPOIB_PRINT( TRACE_LEVEL_INFORMATION,IPOIB_DBG_OID,<BR>+  IPOIB_PRINT( TRACE_LEVEL_VERBOSE,IPOIB_DBG_OID,<BR>    ("Port %d received an invalid oid of 0x%.8X!\n", port_num, oid) );<BR>   break;<BR>  }<BR>@@ -1638,7 +1683,18 @@<BR>  buf_len = sizeof(ULONG);<BR> <BR>  port_num = p_adapter->guids.port_num;<BR>+ <BR>+ cl_obj_lock( &p_adapter->obj );<BR> <BR>+ if( p_adapter->state == IB_PNP_PORT_REMOVE )<BR>+ {<BR>+  *p_bytes_read = 0;<BR>+  cl_obj_unlock( &p_adapter->obj );<BR>+  return NDIS_STATUS_NOT_ACCEPTED;<BR>+ }<BR>+<BR>+ cl_obj_unlock( &p_adapter->obj );<BR>+<BR>  switch( oid )<BR>  {<BR>  /* Required General */<BR>@@ -2520,7 +2576,20 @@<BR>  IPOIB_EXIT( IPOIB_DBG_OID );<BR> }<BR> <BR>+void<BR>+ipoib_cancel_xmit(<BR>+ IN    NDIS_HANDLE  adapter_context,<BR>+ IN    PVOID   cancel_id )<BR>+{<BR>+ ipoib_adapter_t* const p_adapter =<BR>+  (ipoib_adapter_t* const )adapter_context;<BR> <BR>+ if( p_adapter && p_adapter->p_port )<BR>+ {<BR>+  ipoib_port_cancel_xmit( p_adapter->p_port, cancel_id );<BR>+ }<BR>+}<BR>+<BR> static void<BR> __ipoib_ats_reg_cb(<BR>  IN    ib_reg_svc_rec_t   *p_reg_svc_rec )<BR>Index: ulp/ipoib/kernel/ipoib_driver.h<BR>===================================================================<BR>--- ulp/ipoib/kernel/ipoib_driver.h (revision 1776)<BR>+++ ulp/ipoib/kernel/ipoib_driver.h (working copy)<BR>@@ -48,23 +48,39 @@<BR> #define MAX_BUNDLE_ID_LENGTH 32<BR> <BR> /* MLX4 supports 4K MTU */<BR>-#define IB_MTU   4096<BR>+#define MAX_IB_MTU   4096<BR>+#define DEFAULT_MTU   2048<BR> /*<BR>  * Header length as defined by IPoIB spec:<BR>  * <A href="http://www.ietf.org/internet-drafts/draft-ietf-ipoib-ip-over-infiniband-04.txt">http://www.ietf.org/internet-drafts/draft-ietf-ipoib-ip-over-infiniband-04.txt</A><BR>  */<BR>  <BR>-#define MAX_PAYLOAD_MTU  (IB_MTU - sizeof(ipoib_hdr_t))<BR>-<BR>+#define MAX_UD_PAYLOAD_MTU  (MAX_IB_MTU - sizeof(ipoib_hdr_t))<BR>+#define DEFAULT_PAYLOAD_MTU  (DEFAULT_MTU - sizeof(ipoib_hdr_t))<BR>+#define MAX_CM_PAYLOAD_MTU  (65520)<BR>+#define MAX_WRS_PER_MSG   (MAX_CM_PAYLOAD_MTU/MAX_UD_PAYLOAD_MTU)<BR> /*<BR>  * Only the protocol type is sent as part of the UD payload<BR>  * since the rest of the Ethernet header is encapsulated in the<BR>  * various IB headers.  We report out buffer space as if we<BR>  * transmit the ethernet headers.<BR>  */<BR>-#define MAX_XFER_BLOCK_SIZE  (sizeof(eth_hdr_t) + MAX_PAYLOAD_MTU)<BR>+#define MAX_XFER_BLOCK_SIZE  (sizeof(eth_hdr_t) + MAX_UD_PAYLOAD_MTU)<BR>+#define DATA_OFFSET    (sizeof(eth_hdr_t) - sizeof(ipoib_hdr_t))<BR> <BR>+#define IPOIB_CM_FLAG_RC  (0x80)<BR>+#define IPOIB_CM_FLAG_UC  (0x40)<BR>+#define IPOIB_CM_FLAG_SVCID  (0x10) // OFED set IETF bit this way ( open OFED PR 1121 )<BR> <BR>+#define MAX_SEND_SGE   (30)<BR>+<BR>+/* Amount of physical memory to register. */<BR>+#define MEM_REG_SIZE 0xFFFFFFFFFFFFFFFF<BR>+<BR>+/* Number of work completions to chain for send and receive polling. */<BR>+#define MAX_SEND_WC  8<BR>+#define MAX_RECV_WC  16<BR>+<BR> typedef struct _ipoib_globals<BR> {<BR>  KSPIN_LOCK  lock;<BR>Index: ulp/ipoib/kernel/ipoib_endpoint.c<BR>===================================================================<BR>--- ulp/ipoib/kernel/ipoib_endpoint.c (revision 1776)<BR>+++ ulp/ipoib/kernel/ipoib_endpoint.c (working copy)<BR>@@ -43,6 +43,7 @@<BR> #include "ipoib_endpoint.tmh"<BR> #endif<BR> #include <complib/cl_atomic.h><BR>+#include <complib/cl_math.h><BR> <BR> <BR> static void<BR>@@ -76,7 +77,73 @@<BR> __endpt_resolve(<BR>  IN    ipoib_endpt_t* const  p_endpt );<BR> <BR>+static void<BR>+__endpt_cm_send_cb(<BR>+ IN  const ib_cq_handle_t   h_cq,<BR>+ IN    void     *cq_context );<BR>+static void<BR>+__endpt_cm_recv_cb(<BR>+ IN  const ib_cq_handle_t   h_cq,<BR>+ IN    void     *cq_context );<BR> <BR>+static void<BR>+__endpt_cm_buf_mgr_construct(<BR>+ IN  endpt_buf_mgr_t * const  p_buf_mgr );<BR>+static void<BR>+__conn_reply_cb(<BR>+ IN  ib_cm_rep_rec_t   *p_cm_rep );<BR>+<BR>+static void<BR>+__conn_mra_cb(<BR>+ IN  ib_cm_mra_rec_t   *p_mra_rec );<BR>+<BR>+static void<BR>+__conn_rej_cb(<BR>+ IN  ib_cm_rej_rec_t   *p_rej_rec );<BR>+<BR>+static void<BR>+__conn_dreq_cb(<BR>+  IN ib_cm_dreq_rec_t   *p_dreq_rec );<BR>+<BR>+static cl_status_t<BR>+__cm_recv_desc_ctor(<BR>+ IN  void* const     p_object,<BR>+ IN  void*      context,<BR>+ OUT  cl_pool_item_t** const  pp_pool_item );<BR>+<BR>+static void<BR>+__cm_recv_desc_dtor(<BR>+ IN  const cl_pool_item_t* const  p_pool_item,<BR>+ IN    void      *context );<BR>+<BR>+static NDIS_PACKET*<BR>+__endpt_cm_get_ndis_pkt(<BR>+ IN  ipoib_port_t* const   p_port,<BR>+ IN  ipoib_cm_desc_t* const  p_desc );<BR>+<BR>+static inline ipoib_cm_desc_t*<BR>+__endpt_cm_buf_mgr_get_recv(<BR>+ IN  endpt_buf_mgr_t * const  p_buf_mgr );<BR>+<BR>+static boolean_t<BR>+__cm_recv_is_dhcp(<BR>+ IN  const ipoib_pkt_t* const p_ipoib );<BR>+<BR>+static ib_api_status_t<BR>+__endpt_cm_recv_arp(<BR>+ IN  ipoib_port_t* const   p_port,<BR>+ IN  const ipoib_pkt_t* const p_ipoib,<BR>+ OUT  eth_pkt_t* const   p_eth,<BR>+ IN  ipoib_endpt_t* const  p_src_endpt );<BR>+<BR>+static ib_api_status_t<BR>+__endpt_cm_recv_udp(<BR>+ IN  ipoib_port_t* const   p_port,<BR>+ IN  ib_wc_t* const    p_wc,<BR>+ IN  const ipoib_pkt_t* const p_ipoib,<BR>+ OUT  eth_pkt_t* const   p_eth,<BR>+ IN  ipoib_endpt_t* const  p_src_endpt );<BR>+<BR> ipoib_endpt_t*<BR> ipoib_endpt_create(<BR>  IN  const ib_gid_t* const    p_dgid,<BR>@@ -102,6 +169,10 @@<BR>  status = cl_obj_init( &p_endpt->obj, CL_DESTROY_ASYNC,<BR>   __endpt_destroying, __endpt_cleanup, __endpt_free );<BR> <BR>+ IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_ENDPT,<BR>+  ("Created endpoint: [ %p ] DLID: %#x QPN: %#x \n", <BR>+  p_endpt, cl_ntoh16(dlid), cl_ntoh32(qpn) ) );<BR>+<BR>  p_endpt->dgid = *p_dgid;<BR>  p_endpt->dlid = dlid;<BR>  p_endpt->qpn = qpn;<BR>@@ -218,7 +289,12 @@<BR>   ipoib_port_ref(p_port, ref_leave_mcast);<BR>   p_port->p_adapter->p_ifc->leave_mcast( p_endpt->h_mcast, ipoib_leave_mcast_cb );<BR>  }<BR>- <BR>+ else if( p_port->p_adapter->params.cm_enabled )<BR>+ {<BR>+  p_endpt->cm_flag = 0;<BR>+  CL_ASSERT( endpt_cm_get_state( p_endpt ) == IPOIB_CM_DISCONNECTED );<BR>+ }<BR>+<BR>  cl_obj_unlock( p_obj );<BR>  <BR>  IPOIB_EXIT( IPOIB_DBG_ENDPT );<BR>@@ -269,6 +345,12 @@<BR>  return PARENT_STRUCT( p_endpt->rel.p_parent_obj, ipoib_port_t, obj );<BR> }<BR> <BR>+ipoib_port_t*<BR>+ipoib_endpt_parent(<BR>+ IN    ipoib_endpt_t* const  p_endpt )<BR>+{<BR>+ return __endpt_parent( p_endpt );<BR>+}<BR> <BR> /*<BR>  * This function is called with the port object's send lock held and<BR>@@ -356,3 +438,706 @@<BR>  IPOIB_EXIT( IPOIB_DBG_ENDPT );<BR>  return NDIS_STATUS_SUCCESS;<BR> }<BR>+<BR>+<BR>+static void<BR>+__endpt_cm_buf_mgr_construct(<BR>+ IN  endpt_buf_mgr_t * const  p_buf_mgr )<BR>+{<BR>+ IPOIB_ENTER( IPOIB_DBG_INIT );<BR>+<BR>+ cl_qpool_construct( &p_buf_mgr->recv_pool );<BR>+<BR>+ p_buf_mgr->h_packet_pool = NULL;<BR>+ p_buf_mgr->h_buffer_pool = NULL;<BR>+<BR>+ IPOIB_EXIT( IPOIB_DBG_INIT );<BR>+}<BR>+<BR>+ib_api_status_t<BR>+endpt_cm_buf_mgr_init(<BR>+ IN    ipoib_port_t* const    p_port )<BR>+{<BR>+ cl_status_t  cl_status;<BR>+ NDIS_STATUS  ndis_status;<BR>+ ib_api_status_t ib_status = IB_SUCCESS;<BR>+<BR>+ IPOIB_ENTER( IPOIB_DBG_INIT );<BR>+<BR>+ if( p_port->cm_buf_mgr.pool_init )<BR>+  return ib_status;<BR>+<BR>+ cl_qlist_init( &p_port->cm_buf_mgr.posted_list );<BR>+<BR>+ __endpt_cm_buf_mgr_construct( &p_port->cm_buf_mgr );<BR>+ p_port->cm_recv_mgr.rq_depth = <BR>+  min( (uint32_t)p_port->p_adapter->params.rq_depth * 8,<BR>+    p_port->p_ca_attrs->max_srq_wrs/2 );<BR>+ p_port->cm_recv_mgr.depth = 0;<BR>+ /* Allocate the receive descriptors pool */<BR>+ cl_status = cl_qpool_init( &p_port->cm_buf_mgr.recv_pool,<BR>+  p_port->cm_recv_mgr.rq_depth ,<BR>+  0,<BR>+  0,<BR>+  sizeof( ipoib_cm_desc_t ),<BR>+  __cm_recv_desc_ctor,<BR>+  __cm_recv_desc_dtor,<BR>+  p_port );<BR>+<BR>+ if( cl_status != CL_SUCCESS )<BR>+ {<BR>+  NdisWriteErrorLogEntry( p_port->p_adapter->h_adapter,<BR>+   EVENT_IPOIB_RECV_POOL, 1, cl_status );<BR>+  <BR>+  IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+   ("cl_qpool_init for cm recvs returned %#x\n", cl_status) );<BR>+  <BR>+  return IB_INSUFFICIENT_MEMORY;<BR>+ }<BR>+<BR>+ /* Allocate the NDIS buffer and packet pools for receive indication. */<BR>+ NdisAllocatePacketPool( &ndis_status, <BR>+       &p_port->cm_buf_mgr.h_packet_pool,<BR>+       p_port->cm_recv_mgr.rq_depth, <BR>+       PROTOCOL_RESERVED_SIZE_IN_PACKET );<BR>+ if( ndis_status != NDIS_STATUS_SUCCESS )<BR>+ {<BR>+  NdisWriteErrorLogEntry( p_port->p_adapter->h_adapter,<BR>+   EVENT_IPOIB_RECV_PKT_POOL, 1, ndis_status );<BR>+<BR>+  IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+   ("NdisAllocatePacketPool returned %08X\n", ndis_status) );<BR>+  <BR>+  ib_status = IB_INSUFFICIENT_RESOURCES;<BR>+  goto pkt_pool_failed;<BR>+ }<BR>+<BR>+ NdisAllocateBufferPool( &ndis_status, <BR>+       &p_port->cm_buf_mgr.h_buffer_pool,<BR>+       p_port->cm_recv_mgr.rq_depth );<BR>+ if( ndis_status != NDIS_STATUS_SUCCESS )<BR>+ {<BR>+  NdisWriteErrorLogEntry( p_port->p_adapter->h_adapter,<BR>+   EVENT_IPOIB_RECV_BUF_POOL, 1, ndis_status );<BR>+  <BR>+  IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+   ("NdisAllocateBufferPool returned %08X\n", ndis_status) );<BR>+  <BR>+  ib_status = IB_INSUFFICIENT_RESOURCES;<BR>+  goto buf_pool_failed;<BR>+ }<BR>+ p_port->cm_recv_mgr.recv_pkt_array = <BR>+  cl_zalloc( sizeof(NDIS_PACKET*) * p_port->cm_recv_mgr.rq_depth );<BR>+<BR>+ if( !p_port->cm_recv_mgr.recv_pkt_array )<BR>+ {<BR>+  IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+   ("cl_zalloc for PNDIS_PACKET array failed.\n") );<BR>+  <BR>+  ib_status = IB_INSUFFICIENT_MEMORY;<BR>+  goto pkt_array_failed;<BR>+ }<BR>+<BR>+ p_port->cm_buf_mgr.pool_init = TRUE;<BR>+ return IB_SUCCESS;<BR>+<BR>+pkt_array_failed:<BR>+ if( p_port->cm_buf_mgr.h_buffer_pool )<BR>+  NdisFreeBufferPool( p_port->cm_buf_mgr.h_buffer_pool );<BR>+buf_pool_failed:<BR>+ if( p_port->cm_buf_mgr.h_packet_pool )<BR>+  NdisFreePacketPool( p_port->cm_buf_mgr.h_packet_pool );<BR>+pkt_pool_failed:<BR>+  cl_qpool_destroy( &p_port->cm_buf_mgr.recv_pool );<BR>+<BR>+ IPOIB_EXIT( IPOIB_DBG_INIT );<BR>+ return ib_status;<BR>+}<BR>+<BR>+void<BR>+endpt_cm_buf_mgr_reset(<BR>+ IN  ipoib_port_t* const  p_port )<BR>+{<BR>+ cl_list_item_t  *p_item;<BR>+<BR>+ if( !p_port->cm_buf_mgr.pool_init )<BR>+  return;<BR>+<BR>+ if( cl_qlist_count( &p_port->cm_buf_mgr.posted_list ) )<BR>+ {<BR>+  for( p_item = cl_qlist_remove_head( &p_port->cm_buf_mgr.posted_list );<BR>+   p_item != cl_qlist_end( &p_port->cm_buf_mgr.posted_list );<BR>+   p_item =  cl_qlist_remove_head( &p_port->cm_buf_mgr.posted_list ) )<BR>+  {<BR>+   cl_qpool_put( &p_port->cm_buf_mgr.recv_pool, <BR>+    &( PARENT_STRUCT( p_item, ipoib_cm_desc_t, list_item ))->item );<BR>+  }<BR>+ }<BR>+}<BR>+<BR>+void<BR>+endpt_cm_buf_mgr_destroy(<BR>+ IN  ipoib_port_t* const  p_port )<BR>+{<BR>+<BR>+ IPOIB_ENTER(IPOIB_DBG_INIT );<BR>+<BR>+ CL_ASSERT( p_port );<BR>+ <BR>+ /* Free the receive descriptors. */<BR>+ if( !p_port->cm_buf_mgr.pool_init )<BR>+  return;<BR>+<BR>+ endpt_cm_buf_mgr_reset( p_port );<BR>+<BR>+ p_port->cm_buf_mgr.pool_init = FALSE;<BR>+ <BR>+ if( p_port->cm_recv_mgr.recv_pkt_array )<BR>+ {<BR>+  cl_free( p_port->cm_recv_mgr.recv_pkt_array );<BR>+ }<BR>+<BR>+ /* Destroy the receive packet and buffer pools. */<BR>+ if( p_port->cm_buf_mgr.h_buffer_pool )<BR>+  NdisFreeBufferPool( p_port->cm_buf_mgr.h_buffer_pool );<BR>+ if( p_port->cm_buf_mgr.h_packet_pool )<BR>+  NdisFreePacketPool( p_port->cm_buf_mgr.h_packet_pool );<BR>+<BR>+ cl_qpool_destroy( &p_port->cm_buf_mgr.recv_pool );<BR>+ <BR>+ IPOIB_EXIT(  IPOIB_DBG_INIT );<BR>+}<BR>+<BR>+static cl_status_t<BR>+__cm_recv_desc_ctor(<BR>+ IN    void* const     p_object,<BR>+ IN    void*      context,<BR>+  OUT   cl_pool_item_t** const  pp_pool_item )<BR>+{<BR>+ ipoib_cm_desc_t* p_desc;<BR>+ ipoib_port_t*  p_port;<BR>+ ib_mr_create_t  create_mr;<BR>+ net32_t    rkey;<BR>+<BR>+ CL_ASSERT( p_object );<BR>+ CL_ASSERT( context );<BR>+<BR>+ p_desc = (ipoib_cm_desc_t*)p_object;<BR>+ p_port = (ipoib_port_t*)context;<BR>+<BR>+#define BUF_ALIGN  (16)<BR>+<BR>+ p_desc->alloc_buf_size = <BR>+  ROUNDUP( p_port->p_adapter->params.cm_xfer_block_size, BUF_ALIGN );<BR>+ <BR>+ p_desc->p_alloc_buf = (uint8_t *)ExAllocatePoolWithTag( <BR>+  NonPagedPool, p_desc->alloc_buf_size, 'DOMC' );<BR>+<BR>+ if( p_desc->p_alloc_buf == NULL )<BR>+ {<BR>+  IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+   ("Failed to allocate receive buffer size %d bytes.\n", p_desc->alloc_buf_size ) );<BR>+  return CL_INSUFFICIENT_MEMORY;<BR>+ }<BR>+<BR>+ create_mr.vaddr  = p_desc->p_alloc_buf;<BR>+ create_mr.length  = p_desc->alloc_buf_size;<BR>+ create_mr.access_ctrl = IB_AC_LOCAL_WRITE;<BR>+<BR>+ <BR>+ if( p_port->p_adapter->p_ifc->reg_mem( <BR>+       p_port->ib_mgr.h_pd,<BR>+       &create_mr,<BR>+       &p_desc->lkey,<BR>+       &rkey,<BR>+       &p_desc->h_mr ) != IB_SUCCESS )<BR>+ {<BR>+  IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+   ("Failed to create Memory Region size %d bytes.\n", p_desc->alloc_buf_size ) );<BR>+  goto ctor_failed;<BR>+ }<BR>+ p_desc->p_buf = p_desc->p_alloc_buf + (BUF_ALIGN - sizeof( ipoib_hdr_t));<BR>+ p_desc->buf_size = p_desc->alloc_buf_size - (BUF_ALIGN - sizeof( ipoib_hdr_t));<BR>+<BR>+ /* Setup the local data segment. */<BR>+ p_desc->local_ds[0].vaddr = (uint64_t)(uintn_t)p_desc->p_buf;<BR>+ p_desc->local_ds[0].length = p_desc->buf_size;<BR>+ p_desc->local_ds[0].lkey = p_desc->lkey;<BR>+<BR>+ /* Setup the work request. */<BR>+ p_desc->wr.wr_id = (uintn_t)p_desc;<BR>+ p_desc->wr.ds_array = p_desc->local_ds;<BR>+ p_desc->wr.num_ds = 1;<BR>+ p_desc->type = PKT_TYPE_CM_UCAST;<BR>+ <BR>+ *pp_pool_item = &p_desc->item;<BR>+ return CL_SUCCESS;<BR>+<BR>+ctor_failed:<BR>+ ExFreePoolWithTag( p_desc->p_alloc_buf, 'DOMC' );<BR>+ return CL_INSUFFICIENT_MEMORY;<BR>+}<BR>+<BR>+static void<BR>+__cm_recv_desc_dtor(<BR>+ IN  const cl_pool_item_t* const  p_pool_item,<BR>+ IN    void      *context )<BR>+{<BR>+ ipoib_cm_desc_t *p_desc;<BR>+ ipoib_port_t* p_port;<BR>+<BR>+ if( p_pool_item == NULL || context == NULL )<BR>+  return;<BR>+<BR>+ p_port = (ipoib_port_t*)context;<BR>+ p_desc = PARENT_STRUCT( p_pool_item, ipoib_cm_desc_t, item );<BR>+<BR>+ if( p_desc->h_mr )<BR>+  p_port->p_adapter->p_ifc->dereg_mr( p_desc->h_mr );<BR>+<BR>+ if( p_desc->p_alloc_buf )<BR>+  ExFreePoolWithTag( p_desc->p_alloc_buf, 'DOMC' );<BR>+}<BR>+<BR>+static NDIS_PACKET*<BR>+__endpt_cm_get_ndis_pkt(<BR>+ IN  ipoib_port_t* const   p_port,<BR>+ IN  ipoib_cm_desc_t* const p_desc )<BR>+{<BR>+ NDIS_STATUS    status;<BR>+ NDIS_PACKET    *p_packet;<BR>+ NDIS_BUFFER    *p_buffer;<BR>+ <BR>+ IPOIB_ENTER(  IPOIB_DBG_RECV );<BR>+<BR>+ NdisDprAllocatePacketNonInterlocked( &status, &p_packet,<BR>+   p_port->cm_buf_mgr.h_packet_pool );<BR>+ if( status != NDIS_STATUS_SUCCESS )<BR>+ {<BR>+  IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+   ("Failed to allocate NDIS_PACKET: %08x\n", status) );<BR>+  return NULL;<BR>+ }<BR>+<BR>+ IPOIB_PORT_FROM_PACKET( p_packet ) = p_port;<BR>+ IPOIB_RECV_FROM_PACKET( p_packet ) = p_desc;<BR>+<BR>+ NdisAllocateBuffer( <BR>+   &status, <BR>+   &p_buffer,<BR>+   p_port->cm_buf_mgr.h_buffer_pool, <BR>+   (void *)(p_desc->p_buf - DATA_OFFSET),<BR>+   p_desc->len + DATA_OFFSET );<BR>+<BR>+ if( status != NDIS_STATUS_SUCCESS )<BR>+ {<BR>+  IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+   ("Failed to allocate NDIS_BUFFER: %08x\n", status) );<BR>+  NdisDprFreePacketNonInterlocked( p_packet );<BR>+  return NULL;<BR>+ }<BR>+<BR>+ NdisChainBufferAtFront( p_packet, p_buffer );<BR>+ NDIS_SET_PACKET_HEADER_SIZE( p_packet, sizeof(eth_hdr_t) );<BR>+<BR>+ IPOIB_EXIT(  IPOIB_DBG_RECV );<BR>+ return p_packet;<BR>+}<BR>+<BR>+static inline ipoib_cm_desc_t*<BR>+__endpt_cm_buf_mgr_get_recv(<BR>+ IN  endpt_buf_mgr_t * const  p_buf_mgr )<BR>+{<BR>+ ipoib_cm_desc_t *p_desc;<BR>+<BR>+ p_desc = (ipoib_cm_desc_t*)cl_qpool_get( &p_buf_mgr->recv_pool );<BR>+ if( p_desc )<BR>+  cl_qlist_insert_tail( &p_buf_mgr->posted_list, &p_desc->list_item );<BR>+<BR>+ return p_desc;<BR>+}<BR>+<BR>+void<BR>+endpt_cm_buf_mgr_put_recv(<BR>+ IN  endpt_buf_mgr_t * const  p_buf_mgr,<BR>+ IN  ipoib_cm_desc_t* const p_desc )<BR>+{<BR>+<BR>+ IPOIB_ENTER(IPOIB_DBG_RECV );<BR>+<BR>+ /* Return the descriptor to it's pool. */<BR>+ cl_qlist_remove_item( &p_buf_mgr->posted_list, &p_desc->list_item );<BR>+ cl_qpool_put( &p_buf_mgr->recv_pool, &p_desc->item );<BR>+<BR>+ IPOIB_EXIT(  IPOIB_DBG_RECV );<BR>+}<BR>+<BR>+void<BR>+endpt_cm_buf_mgr_put_recv_list(<BR>+ IN  endpt_buf_mgr_t * const  p_buf_mgr,<BR>+ IN  cl_qlist_t* const   p_list )<BR>+{<BR>+ cl_qpool_put_list( &p_buf_mgr->recv_pool, p_list );<BR>+}<BR>+<BR>+uint32_t<BR>+endpt_cm_recv_mgr_build_pkt_array(<BR>+ IN   ipoib_port_t* const   p_port,<BR>+ IN   ipoib_endpt_t* const  p_endpt,<BR>+ IN   cl_qlist_t* const   p_done_list,<BR>+ IN OUT  uint32_t*     p_bytes_recv )<BR>+{<BR>+ cl_list_item_t   *p_item;<BR>+ ipoib_cm_desc_t  *p_desc;<BR>+ uint32_t    i = 0;<BR>+ NDIS_PACKET    *p_packet;<BR>+<BR>+ IPOIB_ENTER( IPOIB_DBG_RECV );<BR>+ UNUSED_PARAM( p_endpt );<BR>+<BR>+ p_item = cl_qlist_remove_head( p_done_list );<BR>+ <BR>+ *p_bytes_recv = 0;<BR>+<BR>+ for( p_item; p_item != cl_qlist_end( p_done_list );<BR>+  p_item = cl_qlist_remove_head( p_done_list ) )<BR>+ {<BR>+  p_desc = (ipoib_cm_desc_t*)p_item;<BR>+<BR>+  p_packet = __endpt_cm_get_ndis_pkt( p_port, p_desc );<BR>+  if( !p_packet )<BR>+  {<BR>+   IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+    ("Failed to get Packet from descriptor\n" ) );<BR>+   endpt_cm_buf_mgr_put_recv( &p_port->cm_buf_mgr, p_desc );<BR>+   p_port->cm_recv_mgr.depth--;<BR>+   continue;<BR>+  }<BR>+  p_desc->ndis_csum.Value = 0;<BR>+  p_desc->ndis_csum.Receive.NdisPacketTcpChecksumSucceeded = TRUE;<BR>+  p_desc->ndis_csum.Receive.NdisPacketUdpChecksumSucceeded = TRUE;<BR>+  p_desc->ndis_csum.Receive.NdisPacketIpChecksumSucceeded = TRUE;<BR>+  NDIS_PER_PACKET_INFO_FROM_PACKET( p_packet, TcpIpChecksumPacketInfo ) =<BR>+             (void*)(uintn_t)p_desc->ndis_csum.Value;<BR>+<BR>+  NDIS_SET_PACKET_STATUS( p_packet, NDIS_STATUS_SUCCESS );<BR>+  p_port->cm_recv_mgr.recv_pkt_array[i] = p_packet;<BR>+  i++;  <BR>+  *p_bytes_recv += p_desc->len;<BR>+ }<BR>+<BR>+ IPOIB_EXIT( IPOIB_DBG_RECV );<BR>+ return i;<BR>+}<BR>+void<BR>+endpt_cm_flush_recv(<BR>+ IN    ipoib_port_t* const  p_port,<BR>+ IN    ipoib_endpt_t* const p_endpt )<BR>+{<BR>+ ib_api_status_t  ib_status = IB_SUCCESS;<BR>+ ib_qp_mod_t   mod_attr;<BR>+ ib_wc_t    wc[MAX_RECV_WC];<BR>+ ib_wc_t    *p_free_wc;<BR>+ ib_wc_t    *p_done_wc;<BR>+ ib_wc_t    *p_wc;<BR>+ ipoib_cm_desc_t  *p_desc;<BR>+ size_t    i;<BR>+<BR>+ IPOIB_ENTER( IPOIB_DBG_RECV );<BR>+<BR>+ CL_ASSERT( p_endpt );<BR>+<BR>+ if( p_endpt->conn.h_recv_qp )<BR>+ {<BR>+  cl_memclr( &mod_attr, sizeof( mod_attr ) );<BR>+  mod_attr.req_state = IB_QPS_ERROR;<BR>+  p_port->p_adapter->p_ifc->modify_qp( p_endpt->conn.h_send_qp, &mod_attr );<BR>+  p_port->p_adapter->p_ifc->modify_qp( p_endpt->conn.h_recv_qp, &mod_attr );<BR>+<BR>+  for( i = 0; i < MAX_RECV_WC; i++ )<BR>+   wc[i].p_next = &wc[i + 1];<BR>+  wc[MAX_RECV_WC - 1].p_next = NULL;<BR>+<BR>+  do<BR>+  {<BR>+   p_free_wc = wc;<BR>+   ib_status = <BR>+    p_port->p_adapter->p_ifc->poll_cq( p_endpt->conn.h_recv_cq, <BR>+    &p_free_wc, &p_done_wc );<BR>+   if( ib_status != IB_SUCCESS && <BR>+    ib_status != IB_NOT_FOUND )<BR>+   {<BR>+    /* connection CQ failed */<BR>+    IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+     ("Poll Recv CQ failed status %#x\n", ib_status ) );<BR>+    break;<BR>+   }<BR>+   cl_spinlock_acquire( &p_port->recv_lock );<BR>+   for( p_wc = p_done_wc; p_wc; p_wc = p_wc->p_next )<BR>+   {<BR>+    p_desc = (ipoib_cm_desc_t *)(uintn_t)p_wc->wr_id;<BR>+    endpt_cm_buf_mgr_put_recv( &p_port->cm_buf_mgr, p_desc );<BR>+    p_port->cm_recv_mgr.depth--;<BR>+   }<BR>+   cl_spinlock_release( &p_port->recv_lock );<BR>+  } while( !p_free_wc );<BR>+<BR>+  ib_status = p_port->p_adapter->p_ifc->destroy_qp( p_endpt->conn.h_recv_qp, NULL );<BR>+  if( ib_status != IB_SUCCESS )<BR>+  {<BR>+   IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+    ("Destroy Recv QP failed status %#x\n", ib_status ) );<BR>+  }<BR>+  p_endpt->conn.h_recv_qp = NULL;<BR>+ }<BR>+<BR>+ if( p_endpt->conn.h_send_qp )<BR>+ {<BR>+  ib_status = p_port->p_adapter->p_ifc->destroy_qp( p_endpt->conn.h_send_qp, NULL );<BR>+  if( ib_status != IB_SUCCESS )<BR>+  {<BR>+   IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+    ("Destroy Send QP failed status %#x\n", ib_status ) );<BR>+  }<BR>+  p_endpt->conn.h_send_qp = NULL;<BR>+ }<BR>+<BR>+ IPOIB_EXIT( IPOIB_DBG_RECV );<BR>+}<BR>+<BR>+int32_t<BR>+endpt_cm_recv_mgr_filter(<BR>+ IN  ipoib_endpt_t* const  p_endpt,<BR>+ IN  ib_wc_t* const    p_done_wc_list,<BR>+ OUT  cl_qlist_t* const   p_done_list,<BR>+ OUT  cl_qlist_t* const   p_bad_list )<BR>+{<BR>+ ib_api_status_t   ib_status;<BR>+ ipoib_cm_desc_t   *p_desc;<BR>+ ib_wc_t     *p_wc;<BR>+ ipoib_pkt_t    *p_ipoib;<BR>+ eth_pkt_t    *p_eth;<BR>+ ipoib_port_t*   p_port;<BR>+ int32_t     recv_cnt;<BR>+<BR>+ IPOIB_ENTER( IPOIB_DBG_RECV );<BR>+<BR>+ p_port = ipoib_endpt_parent( p_endpt );<BR>+<BR>+ for( p_wc = p_done_wc_list, recv_cnt = 0; p_wc; p_wc = p_wc->p_next )<BR>+ {<BR>+  p_desc = (ipoib_cm_desc_t *)(uintn_t)p_wc->wr_id;<BR>+  recv_cnt++;<BR>+  if(  p_wc->status != IB_WCS_SUCCESS )<BR>+  {<BR>+   if( p_wc->status != IB_WCS_WR_FLUSHED_ERR )<BR>+   {<BR>+    <BR>+    IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+     ("Failed completion %s  (vendor specific %#x)\n",<BR>+     p_port->p_adapter->p_ifc->get_wc_status_str( p_wc->status ),<BR>+     (int)p_wc->vendor_specific) );<BR>+   }<BR>+   else<BR>+   {<BR>+    IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_RECV,<BR>+     ("Flushed completion %s\n",<BR>+     p_port->p_adapter->p_ifc->get_wc_status_str( p_wc->status )) );<BR>+   }<BR>+   <BR>+   ipoib_inc_recv_stat( p_port->p_adapter, IP_STAT_ERROR, 0, 0 );<BR>+<BR>+   cl_qlist_remove_item( &p_port->cm_buf_mgr.posted_list,&p_desc->list_item );<BR>+   cl_qlist_insert_tail( p_bad_list, &p_desc->item.list_item );<BR>+   continue;<BR>+  }<BR>+<BR>+  /* Successful completion  <BR>+   Setup the ethernet/ip/arp header and queue descriptor for report. */<BR>+  ib_status = IB_SUCCESS;<BR>+  p_ipoib = (ipoib_pkt_t *)((uint8_t*)p_desc->p_buf );<BR>+  p_eth = (eth_pkt_t *)((uint8_t*)p_desc->p_buf - DATA_OFFSET );<BR>+  <BR>+  switch( p_ipoib->hdr.type )<BR>+  {<BR>+  case ETH_PROT_TYPE_ARP:<BR>+   if( p_wc->length < (sizeof(ipoib_hdr_t) + sizeof(ipoib_arp_pkt_t)) )<BR>+   {<BR>+    IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+    ("Received ARP packet too short\n") );<BR>+    ib_status = IB_ERROR;<BR>+    break;<BR>+   }<BR>+   ib_status = <BR>+    __endpt_cm_recv_arp( p_port, p_ipoib, p_eth, p_endpt );<BR>+   break;<BR>+  case ETH_PROT_TYPE_IP:<BR>+   if( p_wc->length < (sizeof(ipoib_hdr_t) + sizeof(ip_hdr_t)) )<BR>+   {<BR>+    IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+     ("Received IP packet too short\n") );<BR>+    ib_status = IB_ERROR;<BR>+    break;<BR>+   }<BR>+   if( p_ipoib->type.ip.hdr.prot == IP_PROT_UDP )<BR>+   {<BR>+    ib_status = <BR>+     __endpt_cm_recv_udp( p_port, p_wc, p_ipoib, p_eth, p_endpt );<BR>+   }<BR>+  <BR>+   break;<BR>+  }<BR>+<BR>+  if( ib_status != IB_SUCCESS )<BR>+  {<BR>+   ipoib_inc_recv_stat( p_port->p_adapter, IP_STAT_ERROR, 0, 0 );<BR>+   cl_qlist_insert_tail( p_bad_list, &p_desc->item.list_item );<BR>+   continue;<BR>+  }<BR>+<BR>+  p_eth->hdr.type = p_ipoib->hdr.type;<BR>+  p_eth->hdr.src = p_endpt->mac;<BR>+  p_eth->hdr.dst = p_port->p_adapter->mac;<BR>+<BR>+  /* save payload length */<BR>+  p_desc->len = p_wc->length;<BR>+  <BR>+  cl_qlist_insert_tail( p_done_list, &p_desc->item.list_item );<BR>+ }<BR>+<BR>+ IPOIB_EXIT( IPOIB_DBG_RECV );<BR>+ return recv_cnt;<BR>+}<BR>+<BR>+ib_api_status_t<BR>+endpt_cm_post_recv(<BR>+ IN  ipoib_port_t* const   p_port )<BR>+{<BR>+ ib_api_status_t  ib_status = IB_SUCCESS;<BR>+ ipoib_cm_desc_t  *p_head_desc = NULL;<BR>+ ipoib_cm_desc_t  *p_tail_desc = NULL;<BR>+ ipoib_cm_desc_t  *p_next_desc;<BR>+ ib_recv_wr_t  *p_failed_wc = NULL;<BR>+<BR>+ IPOIB_ENTER( IPOIB_DBG_RECV );<BR>+<BR>+ while( cl_qpool_count( &p_port->cm_buf_mgr.recv_pool )  > 1  )<BR>+ {<BR>+   /* Pull receives out of the pool and chain them up. */<BR>+  p_next_desc = __endpt_cm_buf_mgr_get_recv( <BR>+         &p_port->cm_buf_mgr );<BR>+  if( !p_next_desc )<BR>+  {<BR>+   IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_RECV,<BR>+    ("Out of receive descriptors! Endpt recv queue depth 0x%x\n",<BR>+    p_port->cm_recv_mgr.depth ) );<BR>+   break;<BR>+  }<BR>+<BR>+  if( !p_tail_desc )<BR>+  {<BR>+   p_tail_desc = p_next_desc;<BR>+   p_next_desc->wr.p_next = NULL;<BR>+  }<BR>+  else<BR>+  {<BR>+   p_next_desc->wr.p_next = &p_head_desc->wr;<BR>+  }<BR>+<BR>+  p_head_desc = p_next_desc;<BR>+<BR>+  p_port->cm_recv_mgr.depth++;<BR>+ }<BR>+<BR>+ if( p_head_desc )<BR>+ {<BR>+  ib_status = p_port->p_adapter->p_ifc->post_srq_recv(<BR>+   p_port->ib_mgr.h_srq, &p_head_desc->wr, &p_failed_wc );<BR>+<BR>+  if( ib_status != IB_SUCCESS )<BR>+  {<BR>+   IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+    ("ip_post_recv returned %s\n", <BR>+    p_port->p_adapter->p_ifc->get_err_str( ib_status )) );<BR>+   <BR>+   /* put descriptors back to the pool */<BR>+   while( p_failed_wc )<BR>+   {<BR>+    p_head_desc = PARENT_STRUCT( p_failed_wc, ipoib_cm_desc_t, wr );<BR>+    p_failed_wc = p_failed_wc->p_next;<BR>+    endpt_cm_buf_mgr_put_recv( &p_port->cm_buf_mgr, p_head_desc );<BR>+    p_port->cm_recv_mgr.depth--;<BR>+   }<BR>+  }<BR>+ }<BR>+<BR>+<BR>+ IPOIB_EXIT( IPOIB_DBG_RECV );<BR>+ return( ib_status );<BR>+}<BR>+<BR>+static ib_api_status_t<BR>+__endpt_cm_recv_arp(<BR>+ IN  ipoib_port_t* const    p_port,<BR>+ IN  const ipoib_pkt_t* const  p_ipoib,<BR>+ OUT  eth_pkt_t* const    p_eth,<BR>+ IN  ipoib_endpt_t* const   p_src_endpt )<BR>+{<BR>+ const ipoib_arp_pkt_t *p_ib_arp;<BR>+ arp_pkt_t    *p_arp;<BR>+ <BR>+ p_ib_arp = &p_ipoib->type.arp;<BR>+ p_arp = &p_eth->type.arp;<BR>+ <BR>+ if( p_ib_arp->hw_type != ARP_HW_TYPE_IB ||<BR>+  p_ib_arp->hw_size != sizeof(ipoib_hw_addr_t) ||<BR>+  p_ib_arp->prot_type != ETH_PROT_TYPE_IP )<BR>+ {<BR>+  return IB_ERROR;<BR>+ }<BR>+ <BR>+ p_arp->hw_type = ARP_HW_TYPE_ETH;<BR>+ p_arp->hw_size = sizeof(mac_addr_t);<BR>+ p_arp->src_hw = p_src_endpt->mac;<BR>+ p_arp->src_ip = p_ib_arp->src_ip;<BR>+ p_arp->dst_hw = p_port->p_local_endpt->mac;<BR>+ p_arp->dst_ip = p_ib_arp->dst_ip;<BR>+<BR>+ return IB_SUCCESS; <BR>+}<BR>+<BR>+static ib_api_status_t<BR>+__endpt_cm_recv_udp(<BR>+ IN ipoib_port_t* const p_port,<BR>+ IN   ib_wc_t* const    p_wc,<BR>+ IN  const ipoib_pkt_t* const  p_ipoib,<BR>+ OUT   eth_pkt_t* const   p_eth,<BR>+ IN   ipoib_endpt_t* const  p_src_endpt )<BR>+{<BR>+ ib_api_status_t   ib_status = IB_SUCCESS;<BR>+<BR>+ if( p_wc->length <<BR>+  (sizeof(ipoib_hdr_t) + sizeof(ip_hdr_t) + sizeof(udp_hdr_t)) )<BR>+ {<BR>+  IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+   ("Received UDP packet too short\n") );<BR>+  return IB_ERROR;<BR>+ }<BR>+ if( __cm_recv_is_dhcp( p_ipoib ) )<BR>+ {<BR>+  ib_status = ipoib_recv_dhcp(<BR>+   p_port, p_ipoib, p_eth, p_src_endpt, p_port->p_local_endpt );<BR>+ }<BR>+<BR>+ return ib_status;<BR>+}<BR>+<BR>+static boolean_t<BR>+__cm_recv_is_dhcp(<BR>+ IN const ipoib_pkt_t* const p_ipoib )<BR>+{<BR>+ return( (p_ipoib->type.ip.prot.udp.hdr.dst_port == DHCP_PORT_SERVER &&<BR>+    p_ipoib->type.ip.prot.udp.hdr.src_port == DHCP_PORT_CLIENT) ||<BR>+    (p_ipoib->type.ip.prot.udp.hdr.dst_port == DHCP_PORT_CLIENT &&<BR>+    p_ipoib->type.ip.prot.udp.hdr.src_port == DHCP_PORT_SERVER) );<BR>+}<BR>Index: ulp/ipoib/kernel/ipoib_endpoint.h<BR>===================================================================<BR>--- ulp/ipoib/kernel/ipoib_endpoint.h (revision 1776)<BR>+++ ulp/ipoib/kernel/ipoib_endpoint.h (working copy)<BR>@@ -46,6 +46,57 @@<BR> #include "ipoib_debug.h"<BR> <BR> <BR>+typedef struct _endpt_buf_mgr<BR>+{<BR>+ cl_qpool_t   recv_pool;<BR>+ NDIS_HANDLE   h_packet_pool;<BR>+ NDIS_HANDLE   h_buffer_pool;<BR>+ cl_qlist_t   posted_list;<BR>+ boolean_t   pool_init;<BR>+} endpt_buf_mgr_t;<BR>+<BR>+typedef struct _endpt_recv_mgr<BR>+{<BR>+ int32_t   depth;<BR>+ int32_t   rq_depth;<BR>+ NDIS_PACKET  **recv_pkt_array;<BR>+<BR>+} endpt_recv_mgr_t;<BR>+<BR>+<BR>+typedef enum _cm_state <BR>+{<BR>+ IPOIB_CM_DISCONNECTED,<BR>+ IPOIB_CM_INIT,<BR>+ IPOIB_CM_CONNECT,<BR>+ IPOIB_CM_CONNECTED,<BR>+ IPOIB_CM_LISTEN,<BR>+ IPOIB_CM_DREP_SENT,<BR>+ IPOIB_CM_DREQ_SENT,<BR>+ IPOIB_CM_REJ_RECVD,<BR>+ IPOIB_CM_DESTROY<BR>+} cm_state_t;<BR>+<BR>+typedef struct _cm_private_data <BR>+{<BR>+ ib_net32_t  ud_qpn;<BR>+ ib_net32_t  recv_mtu;<BR>+} cm_private_data_t;<BR>+<BR>+typedef struct _endpt_conn <BR>+{<BR>+ ib_net64_t   service_id;<BR>+ cm_private_data_t private_data;<BR>+ ib_qp_handle_t  h_send_qp;<BR>+ ib_qp_handle_t  h_recv_qp;<BR>+ ib_qp_handle_t  h_work_qp;<BR>+ ib_cq_handle_t  h_send_cq;<BR>+ ib_cq_handle_t  h_recv_cq;<BR>+ ib_listen_handle_t  h_cm_listen;<BR>+ cm_state_t   state;<BR>+<BR>+} endpt_conn_t;<BR>+<BR> typedef struct _ipoib_endpt<BR> {<BR>  cl_obj_t    obj;<BR>@@ -53,13 +104,18 @@<BR>  cl_map_item_t   mac_item;<BR>  cl_fmap_item_t   gid_item;<BR>  cl_map_item_t   lid_item;<BR>+ cl_fmap_item_t   conn_item;<BR>+ LIST_ENTRY    list_item;<BR>  ib_query_handle_t  h_query;<BR>  ib_mcast_handle_t  h_mcast;<BR>  mac_addr_t    mac;<BR>  ib_gid_t    dgid;<BR>  net16_t     dlid;<BR>  net32_t     qpn;<BR>+ uint8_t     cm_flag;<BR>  ib_av_handle_t   h_av;<BR>+ endpt_conn_t   conn;<BR>+<BR>  ib_al_ifc_t    *p_ifc;<BR>  boolean_t       is_in_use;<BR>  boolean_t    is_mcast_listener;<BR>@@ -103,6 +159,9 @@<BR> * expired<BR> *  Flag to indicate that the endpoint should be flushed.<BR> *<BR>+* connection<BR>+*  for connected mode endpoints<BR>+*<BR> * p_ifc<BR> *  Reference to transport functions, can be used<BR> *  while endpoint is not attached to port yet.<BR>@@ -154,5 +213,43 @@<BR> ipoib_endpt_queue(<BR>  IN    ipoib_endpt_t* const  p_endpt );<BR> <BR>+struct _ipoib_port *<BR>+ipoib_endpt_parent(<BR>+ IN  ipoib_endpt_t* const  p_endpt );<BR> <BR>+inline cm_state_t<BR>+endpt_cm_set_state(<BR>+ IN  ipoib_endpt_t* const  p_endpt,<BR>+ IN  cm_state_t     state )<BR>+{<BR>+ return(cm_state_t)InterlockedExchange( <BR>+    (volatile LONG *)&p_endpt->conn.state, <BR>+    (LONG)state );<BR>+}<BR>+<BR>+inline cm_state_t<BR>+endpt_cm_get_state(<BR>+ IN  ipoib_endpt_t* const  p_endpt )<BR>+{<BR>+ return( cm_state_t )InterlockedCompareExchange( <BR>+    (volatile LONG *)&p_endpt->conn.state, <BR>+    IPOIB_CM_DISCONNECTED, IPOIB_CM_DISCONNECTED );<BR>+}<BR>+<BR>+ib_api_status_t<BR>+endpt_cm_create_qp( <BR>+ IN  ipoib_endpt_t* const p_endpt,<BR>+ IN  ib_qp_handle_t* const p_h_qp );<BR>+<BR>+ib_api_status_t<BR>+ipoib_endpt_connect(<BR>+ IN  ipoib_endpt_t* const  p_endpt );<BR>+<BR>+int32_t<BR>+endpt_cm_recv_mgr_filter(<BR>+ IN  ipoib_endpt_t* const  p_endpt,<BR>+ IN  ib_wc_t* const    p_done_wc_list,<BR>+ OUT  cl_qlist_t* const   p_done_list,<BR>+ OUT  cl_qlist_t* const   p_bad_list );<BR>+<BR> #endif /* _IPOIB_ENDPOINT_H_ */<BR>Index: ulp/ipoib/kernel/ipoib_log.mc<BR>===================================================================<BR>--- ulp/ipoib/kernel/ipoib_log.mc (revision 1776)<BR>+++ ulp/ipoib/kernel/ipoib_log.mc (working copy)<BR>@@ -316,3 +316,19 @@<BR> %2: Pkey index not found for partition , change switch pkey configuration.<BR> .<BR> <BR>+MessageId=0x005C<BR>+Facility=IPoIB<BR>+Severity=Error<BR>+SymbolicName=EVENT_IPOIB_CONNECTED_MODE_ERR<BR>+Language=English<BR>+%2: Connected Mode failed to initialize, disabled. Interface will use default UD QP transport.<BR>+.<BR>+<BR>+MessageId=0x005D<BR>+Facility=IPoIB<BR>+Severity=Informational<BR>+SymbolicName=EVENT_IPOIB_CONNECTED_MODE_UP<BR>+Language=English<BR>+%2: Connected Mode initialized and operational.<BR>+.<BR>+<BR>Index: ulp/ipoib/kernel/ipoib_port.c<BR>===================================================================<BR>--- ulp/ipoib/kernel/ipoib_port.c (revision 1776)<BR>+++ ulp/ipoib/kernel/ipoib_port.c (working copy)<BR>@@ -33,6 +33,7 @@<BR> <BR> <BR> <BR>+#include "ipoib_endpoint.h"<BR> #include "ipoib_port.h"<BR> #include "ipoib_adapter.h"<BR> #include "ipoib_debug.h"<BR>@@ -45,14 +46,6 @@<BR> #include <offload.h><BR> <BR> <BR>-/* Amount of physical memory to register. */<BR>-#define MEM_REG_SIZE 0xFFFFFFFFFFFFFFFF<BR>-<BR>-/* Number of work completions to chain for send and receive polling. */<BR>-#define MAX_SEND_WC  8<BR>-#define MAX_RECV_WC  16<BR>-<BR>-<BR> ib_gid_t bcast_mgid_template = {<BR>  0xff,        /* multicast field */<BR>  0x12,        /* scope (to be filled in) */<BR>@@ -102,7 +95,15 @@<BR> __port_free(<BR>  IN    cl_obj_t* const    p_obj );<BR> <BR>+static ib_api_status_t<BR>+__port_query_ca_attrs( <BR>+ IN  ipoib_port_t* const     p_port,<BR>+ IN  ib_ca_attr_t**      pp_ca_attrs );<BR> <BR>+static void<BR>+__srq_async_event_cb(<BR>+IN   ib_async_event_rec_t  *p_event_rec );<BR>+<BR> /******************************************************************************<BR> *<BR> * IB resource manager operations<BR>@@ -341,15 +342,44 @@<BR>  IN  const ib_cq_handle_t    h_cq,<BR>  IN    void      *cq_context );<BR> <BR>-static NDIS_STATUS GetLsoHeaderSize(<BR>- IN      ipoib_port_t* const pPort,<BR>- IN      PNDIS_BUFFER  CurrBuffer,<BR>- IN      LsoData *pLsoData,<BR>- OUT     uint16_t *pSize,<BR>- OUT     INT  *IndexOfData,<BR>- IN  ipoib_hdr_t *ipoib_hdr<BR>- );<BR>+static NDIS_STATUS<BR>+GetLsoHeaderSize(<BR>+ IN      ipoib_port_t* const     pPort,<BR>+ IN      PNDIS_BUFFER      CurrBuffer,<BR>+ IN      LsoData        *pLsoData,<BR>+ OUT     uint16_t       *pSize,<BR>+ OUT     INT         *IndexOfData,<BR>+ IN  ipoib_hdr_t       *ipoib_hdr );<BR> <BR>+static NDIS_STATUS<BR>+__build_lso_desc(<BR>+ IN    ipoib_port_t* const   p_port,<BR>+ IN OUT   ipoib_send_desc_t* const p_desc,<BR>+ IN    ULONG      mss,<BR>+ IN    int32_t      hdr_idx );<BR>+<BR>+static NDIS_STATUS<BR>+__send_fragments(<BR>+ IN  ipoib_port_t* const     p_port,<BR>+ IN  ipoib_send_desc_t* const   p_desc,<BR>+ IN  eth_hdr_t* const     p_eth_hdr,<BR>+ IN  ip_hdr_t* const      p_ip_hdr,<BR>+ IN  uint32_t       buf_len,<BR>+ IN  NDIS_BUFFER*      p_ndis_buf );<BR>+<BR>+static void<BR>+__update_fragment_ip_hdr(<BR>+IN  ip_hdr_t* const  p_ip_hdr,<BR>+IN  uint16_t   fragment_size, <BR>+IN  uint16_t   fragment_offset, <BR>+IN  BOOLEAN    more_fragments );<BR>+<BR>+static void<BR>+__copy_ip_options(<BR>+IN  uint8_t*   p_buf,<BR>+IN  uint8_t*   p_options,<BR>+IN  uint32_t   options_len,<BR>+IN  BOOLEAN    copy_all );<BR> /******************************************************************************<BR> *<BR> * Endpoint manager operations<BR>@@ -516,7 +546,7 @@<BR> */<BR> static void* GetIpPayloadPtr(const ip_hdr_t* const p_ip_hdr)<BR> {<BR>- return (void*)((uint8_t*)p_ip_hdr + 4*(p_ip_hdr->ver_hl & 0xf));<BR>+ return (void*)((uint8_t*)p_ip_hdr + IP_HEADER_LENGTH(p_ip_hdr));<BR> }<BR> <BR> /******************************************************************************<BR>@@ -742,6 +772,14 @@<BR> <BR>  __endpt_mgr_remove_all( p_port );<BR> <BR>+ if( p_port->p_adapter->params.cm_enabled )<BR>+ {<BR>+  endpt_cm_buf_mgr_destroy(  p_port );<BR>+  ipoib_port_srq_destroy( p_port );<BR>+  p_port->endpt_mgr.thread_is_done = 1;<BR>+  cl_event_signal( &p_port->endpt_mgr.event );<BR>+ }<BR>+<BR>  ipoib_port_resume( p_port );<BR> <BR>  IPOIB_EXIT( IPOIB_DBG_INIT );<BR>@@ -794,7 +832,10 @@<BR>  cl_spinlock_destroy( &p_port->recv_lock );<BR> <BR>  cl_obj_deinit( p_obj );<BR>-<BR>+ if( p_port->p_ca_attrs )<BR>+ {<BR>+  cl_free ( p_port->p_ca_attrs );<BR>+ }<BR>  cl_free( p_port );<BR> <BR>  IPOIB_EXIT( IPOIB_DBG_INIT );<BR>@@ -831,8 +872,6 @@<BR>  uint64_t   vaddr;<BR>  net32_t    rkey;<BR>  ib_qp_attr_t  qp_attr;<BR>- ib_ca_attr_t *  p_ca_attr;<BR>- uint32_t   attr_size;<BR> <BR>  IPOIB_ENTER( IPOIB_DBG_INIT );<BR> <BR>@@ -850,6 +889,13 @@<BR>   return status;<BR>  }<BR> <BR>+ status = __port_query_ca_attrs( p_port, &p_port->p_ca_attrs );<BR>+ if( status != IB_SUCCESS )<BR>+ {<BR>+  IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+   ("Query CA attributes failed\n" ) );<BR>+  return status;<BR>+ }<BR>  /* Allocate the PD. */<BR>  status = p_port->p_adapter->p_ifc->alloc_pd(<BR>   p_port->ib_mgr.h_ca, IB_PDT_UD, p_port, &p_port->ib_mgr.h_pd );<BR>@@ -905,50 +951,22 @@<BR>  qp_create.rq_sge = 2; /* To support buffers spanning pages. */<BR>  qp_create.h_rq_cq = p_port->ib_mgr.h_recv_cq;<BR>  qp_create.sq_depth = p_port->p_adapter->params.sq_depth;<BR>- <BR>- //Figure out the right number of SGE entries for sends.<BR>- /* Get the size of the CA attribute structure. */<BR>- status = p_port->p_adapter->p_ifc->query_ca( p_port->ib_mgr.h_ca, NULL, &attr_size );<BR>- if( status != IB_INSUFFICIENT_MEMORY )<BR>- {<BR>-  IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>-   ("ib_query_ca failed with status %s.\n", p_port->p_adapter->p_ifc->get_err_str(status)) );<BR>-  return status;<BR>- }<BR> <BR>- /* Allocate enough space to store the attribute structure. */<BR>- p_ca_attr = cl_malloc( attr_size );<BR>- if( !p_ca_attr )<BR>- {<BR>-  IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>-   ("cl_malloc failed to allocate p_ca_attr!\n") );<BR>-  return IB_INSUFFICIENT_RESOURCES;<BR>- }<BR>-<BR>- /* Query the CA attributes. */<BR>- status = p_port->p_adapter->p_ifc->query_ca(p_port->ib_mgr.h_ca, p_ca_attr, &attr_size );<BR>- if( status != IB_SUCCESS )<BR>- {<BR>-  cl_free( p_ca_attr );<BR>-<BR>-  IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>-   ("ib_query_ca failed with status %s.\n", p_port->p_adapter->p_ifc->get_err_str(status)) );<BR>-  return status;<BR>- }<BR> #define UD_QP_USED_SGE 3<BR>- qp_create.sq_sge = MAX_SEND_SGE < p_ca_attr->max_sges ? MAX_SEND_SGE  : (p_ca_attr->max_sges - UD_QP_USED_SGE);<BR>- if (!p_ca_attr->ipoib_csum) { <BR>-  //checksum is not supported by device<BR>-  //user must specify BYPASS to explicitly cancel checksum calculation<BR>+ qp_create.sq_sge = MAX_SEND_SGE < p_port->p_ca_attrs->max_sges ? <BR>+   MAX_SEND_SGE  : ( p_port->p_ca_attrs->max_sges - UD_QP_USED_SGE );<BR>+ if ( !p_port->p_ca_attrs->ipoib_csum ) <BR>+ { <BR>+  /* checksum is not supported by device<BR>+  user must specify BYPASS to explicitly cancel checksum calculation */<BR>   if (p_port->p_adapter->params.send_chksum_offload == CSUM_ENABLED)<BR>    p_port->p_adapter->params.send_chksum_offload = CSUM_DISABLED;<BR>   if (p_port->p_adapter->params.recv_chksum_offload == CSUM_ENABLED)<BR>    p_port->p_adapter->params.recv_chksum_offload = CSUM_DISABLED;<BR>  }<BR>- cl_free( p_ca_attr );<BR>- <BR>+<BR>  qp_create.h_sq_cq = p_port->ib_mgr.h_send_cq;<BR>- qp_create.sq_signaled = TRUE;<BR>+ qp_create.sq_signaled = FALSE;<BR>  status = p_port->p_adapter->p_ifc->create_qp(<BR>   p_port->ib_mgr.h_pd, &qp_create, p_port,<BR>   __qp_event, &p_port->ib_mgr.h_qp );<BR>@@ -998,11 +1016,185 @@<BR>   return status;<BR>  }<BR> <BR>+ status = ipoib_port_srq_init( p_port );<BR>+ if( status != IB_SUCCESS )<BR>+ {<BR>+  IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+   ("ipoib_port_srq_init failed %s\n",<BR>+   p_port->p_adapter->p_ifc->get_err_str( status )) );<BR>+  /* disable further CM initialization */<BR>+  p_port->p_adapter->params.cm_enabled = FALSE;<BR>+<BR>+  NdisWriteErrorLogEntry( p_port->p_adapter->h_adapter,<BR>+    EVENT_IPOIB_CONNECTED_MODE_ERR, 1, 0xbadc0de1 );<BR>+<BR>+ }<BR>+ if( p_port->p_adapter->params.cm_enabled )<BR>+ {<BR>+  status = endpt_cm_buf_mgr_init( p_port );<BR>+  if( status != IB_SUCCESS )<BR>+  {<BR>+   IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+    ("CM Init buf mgr failed status %#x\n", status ) );<BR>+   ipoib_port_srq_destroy( p_port );<BR>+   p_port->p_adapter->params.cm_enabled = FALSE;<BR>+<BR>+   NdisWriteErrorLogEntry( p_port->p_adapter->h_adapter,<BR>+    EVENT_IPOIB_CONNECTED_MODE_ERR, 1, 0xbadc0de2 );<BR>+  }<BR>+  else <BR>+  {<BR>+   /* now we can adjust csum capabilities */<BR>+   p_port->p_adapter->params.send_chksum_offload = CSUM_DISABLED;<BR>+   p_port->p_adapter->params.recv_chksum_offload = CSUM_BYPASS;<BR>+  }<BR>+<BR>+ }<BR>  IPOIB_EXIT( IPOIB_DBG_INIT );<BR>  return IB_SUCCESS;<BR> }<BR> <BR>+static void<BR>+__srq_async_event_cb(<BR>+IN   ib_async_event_rec_t  *p_event_rec )<BR>+{<BR>+ ipoib_port_t* p_port = <BR>+  (ipoib_port_t *)p_event_rec->context;<BR> <BR>+ switch( p_event_rec->code )<BR>+ {<BR>+ case IB_AE_SRQ_LIMIT_REACHED:<BR>+    IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+   ("SRQ ASYNC EVENT CODE %d: %s\n", <BR>+   p_event_rec->code, "IB_AE_SRQ_LIMIT_REACHED" ) );<BR>+   break;<BR>+ case IB_AE_SRQ_CATAS_ERROR:<BR>+   IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+    ("SRQ ASYNC EVENT CODE %d: %s\n", <BR>+    p_event_rec->code, "IB_AE_SRQ_CATAS_ERROR" ) );<BR>+   /*SRQ is in err state, must reinitialize */<BR>+   p_port->p_adapter->hung = TRUE;<BR>+   break;<BR>+ case IB_AE_SRQ_QP_LAST_WQE_REACHED:<BR>+   IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+    ("SRQ ASYNC EVENT CODE %d: %s\n", <BR>+    p_event_rec->code, "IB_AE_SRQ_QP_LAST_WQE_REACHED" ) );<BR>+   /*SRQ is in err state, must reinitialize */<BR>+   p_port->p_adapter->hung = TRUE;<BR>+   break;<BR>+ default:<BR>+   IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+    ("ASYNC EVENT CODE ARRIVED %d(%#x)\n", <BR>+    p_event_rec->code, p_event_rec->code ) );<BR>+ }<BR>+}<BR>+<BR>+ib_api_status_t<BR>+ipoib_port_srq_init(<BR>+ IN    ipoib_port_t* const   p_port )<BR>+{<BR>+ ib_api_status_t  ib_status;<BR>+ ib_srq_handle_t  h_srq;<BR>+ ib_srq_attr_t  srq_attr;<BR>+<BR>+ IPOIB_ENTER( IPOIB_DBG_INIT );<BR>+ <BR>+ if( !p_port->p_adapter->params.cm_enabled )<BR>+  return IB_SUCCESS;<BR>+<BR>+ srq_attr.max_sge = min( 2, p_port->p_ca_attrs->max_srq_sges );<BR>+ srq_attr.srq_limit = 10;<BR>+ srq_attr.max_wr = <BR>+  min( (uint32_t)p_port->p_adapter->params.rq_depth * 8,<BR>+    p_port->p_ca_attrs->max_srq_wrs/2 );<BR>+<BR>+ ib_status = p_port->p_adapter->p_ifc->create_srq( <BR>+        p_port->ib_mgr.h_pd, <BR>+        &srq_attr, <BR>+        p_port, <BR>+        __srq_async_event_cb, <BR>+        &h_srq );<BR>+ if( ib_status != IB_SUCCESS )<BR>+ {<BR>+  NdisWriteErrorLogEntry( p_port->p_adapter->h_adapter,<BR>+   EVENT_IPOIB_CREATE_QP, 1, ib_status );<BR>+  IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+   ("ib_create_srq failed status %s\n", <BR>+   p_port->p_adapter->p_ifc->get_err_str( ib_status )) );<BR>+  return ib_status;<BR>+ }<BR>+ p_port->ib_mgr.h_srq = h_srq;<BR>+<BR>+ IPOIB_EXIT( IPOIB_DBG_INIT );<BR>+<BR>+ return ib_status;<BR>+}<BR>+<BR>+/*  __port_query_ca_attrs() <BR>+ *  returns a pointer to allocated memory.<BR>+ *  must be released by caller.<BR>+ */<BR>+static ib_api_status_t<BR>+__port_query_ca_attrs( <BR>+ IN  ipoib_port_t* const  p_port,<BR>+ IN  ib_ca_attr_t**   pp_ca_attrs )<BR>+{<BR>+ ib_api_status_t  ib_status;<BR>+ uint32_t   attr_size;<BR>+ ib_ca_attr_t*  p_ca_attrs;<BR>+<BR>+ *pp_ca_attrs = NULL;<BR>+<BR>+ ib_status = <BR>+  p_port->p_adapter->p_ifc->query_ca( p_port->ib_mgr.h_ca, NULL , &attr_size );<BR>+ if( ib_status != IB_INSUFFICIENT_MEMORY )<BR>+ {<BR>+  IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+   ("ib_query_ca failed status %s\n",<BR>+   p_port->p_adapter->p_ifc->get_err_str( ib_status )) );<BR>+  goto done;<BR>+ }<BR>+ CL_ASSERT( attr_size );<BR>+<BR>+ p_ca_attrs = cl_zalloc( attr_size );<BR>+ if ( p_ca_attrs == NULL )<BR>+ {<BR>+  IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+   ("Allocate %d bytes failed for CA Attributes\n", attr_size ));<BR>+  ib_status = IB_INSUFFICIENT_MEMORY;<BR>+  goto done;<BR>+ }<BR>+<BR>+ ib_status = <BR>+  p_port->p_adapter->p_ifc->query_ca( p_port->ib_mgr.h_ca, p_ca_attrs , &attr_size );<BR>+ if ( ib_status != IB_SUCCESS )<BR>+ {<BR>+  IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+   ("CA attributes query failed\n") );<BR>+  cl_free ( p_ca_attrs );<BR>+  goto done;<BR>+ }<BR>+<BR>+ *pp_ca_attrs = p_ca_attrs;<BR>+done:<BR>+ return ib_status;<BR>+}<BR>+<BR>+void<BR>+ipoib_port_srq_destroy( <BR>+ IN    ipoib_port_t* const   p_port )<BR>+{<BR>+ ib_api_status_t status;<BR>+<BR>+ if( p_port->ib_mgr.h_srq )<BR>+ {<BR>+  status =<BR>+   p_port->p_adapter->p_ifc->destroy_srq( p_port->ib_mgr.h_srq, NULL );<BR>+  CL_ASSERT( status == IB_SUCCESS );<BR>+  p_port->ib_mgr.h_srq = NULL;<BR>+ }<BR>+}<BR>+<BR> static void<BR> __ib_mgr_destroy(<BR>  IN    ipoib_port_t* const   p_port )<BR>@@ -1172,7 +1364,10 @@<BR> {<BR>  ipoib_recv_desc_t *p_desc;<BR>  ipoib_port_t  *p_port;<BR>+<BR>+#if IPOIB_INLINE_RECV<BR>  uint32_t   ds0_len;<BR>+#endif<BR> <BR>  IPOIB_ENTER( IPOIB_DBG_ALLOC );<BR> <BR>@@ -1231,6 +1426,7 @@<BR>  p_desc->local_ds[0].vaddr = cl_get_physaddr( p_desc->p_buf );<BR>  p_desc->local_ds[0].length = sizeof(ipoib_pkt_t) + sizeof(ib_grh_t);<BR>  p_desc->local_ds[0].lkey = p_port->ib_mgr.lkey;<BR>+ p_desc->wr.num_ds = 1;<BR> #endif /* IPOIB_INLINE_RECV */<BR> <BR>  *pp_pool_item = &p_desc->item;<BR>@@ -1472,8 +1668,8 @@<BR>   cl_perf_stop( &p_port->p_adapter->perf, GetRecv );<BR>   if( !p_next )<BR>   {<BR>-   IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_RECV,<BR>-    ("Out of receive descriptors! recv queue depath 0x%x\n",p_port->recv_mgr.depth) );<BR>+   IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_RECV,<BR>+    ("Out of receive descriptors! recv queue depth 0x%x\n",p_port->recv_mgr.depth) );<BR>    break;<BR>   }<BR> <BR>@@ -1547,10 +1743,33 @@<BR> <BR>  /* Get the port and descriptor from the packet. */<BR>  p_port = IPOIB_PORT_FROM_PACKET( p_packet );<BR>- p_desc = IPOIB_RECV_FROM_PACKET( p_packet );<BR>+ p_desc = (ipoib_recv_desc_t *)IPOIB_RECV_FROM_PACKET( p_packet );<BR> <BR>  cl_spinlock_acquire( &p_port->recv_lock );<BR> <BR>+ /* Get descriptor from the packet. */<BR>+ if( p_desc->type == PKT_TYPE_CM_UCAST )<BR>+ {<BR>+  NDIS_BUFFER  *p_buf;<BR>+<BR>+  /* Unchain the NDIS buffer. */<BR>+  NdisUnchainBufferAtFront( p_packet, &p_buf );<BR>+  CL_ASSERT( p_buf );<BR>+  /* Return the NDIS packet and NDIS buffer to their pools. */<BR>+  NdisDprFreePacketNonInterlocked( p_packet );<BR>+  NdisFreeBuffer( p_buf );<BR>+<BR>+  endpt_cm_buf_mgr_put_recv( &p_port->cm_buf_mgr, (ipoib_cm_desc_t *)p_desc );<BR>+  status = endpt_cm_post_recv( p_port );<BR>+  if(  status != IB_SUCCESS )<BR>+  {<BR>+   IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+    ("Post Recv QP failed\n" ) );<BR>+  }<BR>+  cl_spinlock_release( &p_port->recv_lock );<BR>+  return;<BR>+ }<BR>+<BR>  cl_perf_start( ReturnPutRecv );<BR>  __buf_mgr_put_recv( p_port, p_desc, p_packet );<BR>  cl_perf_stop( &p_port->p_adapter->perf, ReturnPutRecv );<BR>@@ -1754,7 +1973,7 @@<BR>    while( shortage-- > 1 )<BR>    {<BR>     __buf_mgr_put_recv( p_port,<BR>-     IPOIB_RECV_FROM_PACKET( p_port->recv_mgr.recv_pkt_array[shortage] ),<BR>+     (ipoib_recv_desc_t *)IPOIB_RECV_FROM_PACKET( p_port->recv_mgr.recv_pkt_array[shortage] ),<BR>      p_port->recv_mgr.recv_pkt_array[shortage] );<BR>    }<BR>    cl_spinlock_release( &p_port->recv_lock );<BR>@@ -1909,12 +2128,12 @@<BR>    (*pp_src )->mac.addr[0], (*pp_src )->mac.addr[1],<BR>    (*pp_src )->mac.addr[2], (*pp_src )->mac.addr[3],<BR>    (*pp_src )->mac.addr[4], (*pp_src )->mac.addr[5]) );<BR>-  (*pp_src)->qpn = p_wc->recv.ud.remote_qp;<BR>+//  (*pp_src)->qpn = p_wc->recv.ud.remote_qp;<BR>  }<BR> <BR>  if( *pp_src && *pp_dst )<BR>  {<BR>-  IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_RECV,<BR>+  IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_RECV,<BR>    ("Recv:\n"<BR>    "\tsrc MAC: %02X-%02X-%02X-%02X-%02X-%02X\n"<BR>    "\tdst MAC: %02X-%02X-%02X-%02X-%02X-%02X\n",<BR>@@ -1968,14 +2187,14 @@<BR>      ("Failed completion %s  (vendor specific %#x)\n",<BR>      p_port->p_adapter->p_ifc->get_wc_status_str( p_wc->status ),<BR>      (int)p_wc->vendor_specific) );<BR>-    ipoib_inc_recv_stat( p_port->p_adapter, IP_STAT_ERROR, 0 );<BR>+    ipoib_inc_recv_stat( p_port->p_adapter, IP_STAT_ERROR, 0, 0 );<BR>    }<BR>    else<BR>    {<BR>-    IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_RECV,<BR>+    IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_RECV,<BR>      ("Flushed completion %s\n",<BR>      p_port->p_adapter->p_ifc->get_wc_status_str( p_wc->status )) );<BR>-    ipoib_inc_recv_stat( p_port->p_adapter, IP_STAT_DROPPED, 0 );<BR>+    ipoib_inc_recv_stat( p_port->p_adapter, IP_STAT_DROPPED, 0, 0 );<BR>    }<BR>    cl_qlist_insert_tail( p_bad_list, &p_desc->item.list_item );<BR>    /* Dereference the port object on behalf of the failed receive. */<BR>@@ -1989,7 +2208,7 @@<BR>   {<BR>    IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>     ("Received ETH packet < min size\n") );<BR>-   ipoib_inc_recv_stat( p_port->p_adapter, IP_STAT_ERROR, 0 );<BR>+   ipoib_inc_recv_stat( p_port->p_adapter, IP_STAT_ERROR, 0, 0 );<BR>    cl_qlist_insert_tail( p_bad_list, &p_desc->item.list_item );<BR>    ipoib_port_deref( p_port, ref_recv_inv_len );<BR>    continue;<BR>@@ -1998,16 +2217,17 @@<BR>   if((len - sizeof(ipoib_hdr_t)) > p_port->p_adapter->params.payload_mtu)<BR>   {<BR>    IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>-    ("Received ETH packet > payload MTU (%d)\n",<BR>+    ("Received ETH packet len %d > payload MTU (%d)\n",<BR>+    (len - sizeof(ipoib_hdr_t)),<BR>     p_port->p_adapter->params.payload_mtu) );<BR>-   ipoib_inc_recv_stat( p_port->p_adapter, IP_STAT_ERROR, 0 );<BR>+   ipoib_inc_recv_stat( p_port->p_adapter, IP_STAT_ERROR, 0, 0 );<BR>    cl_qlist_insert_tail( p_bad_list, &p_desc->item.list_item );<BR>    ipoib_port_deref( p_port, ref_recv_inv_len );<BR>    continue;<BR>    <BR>   }<BR>   /* Successful completion.  Get the receive information. */<BR>-  p_desc->ndis_csum.Value = ( (p_wc->recv.ud.recv_opt & IB_RECV_OPT_CSUM_MASK ) >> 8 );<BR>+  p_desc->ndis_csum.Value = ( ( p_wc->recv.ud.recv_opt & IB_RECV_OPT_CSUM_MASK ) >> 8 );<BR>   cl_perf_start( GetRecvEndpts );<BR>   __recv_get_endpts( p_port, p_desc, p_wc, &p_src, &p_dst );<BR>   cl_perf_stop( &p_port->p_adapter->perf, GetRecvEndpts );<BR>@@ -2125,7 +2345,7 @@<BR>   if( status != IB_SUCCESS )<BR>   {<BR>    /* Update stats. */<BR>-   ipoib_inc_recv_stat( p_port->p_adapter, IP_STAT_ERROR, 0 );<BR>+   ipoib_inc_recv_stat( p_port->p_adapter, IP_STAT_ERROR, 0, 0 );<BR>    cl_qlist_insert_tail( p_bad_list, &p_desc->item.list_item );<BR>    /* Dereference the port object on behalf of the failed receive. */<BR>    ipoib_port_deref( p_port, ref_recv_filter );<BR>@@ -2158,7 +2378,7 @@<BR>     <BR>    }<BR>    cl_qlist_insert_tail( p_done_list, &p_desc->item.list_item );<BR>-   ipoib_inc_recv_stat( p_port->p_adapter,ip_stat , len );  <BR>+   ipoib_inc_recv_stat( p_port->p_adapter, ip_stat, len, 1 );  <BR>   }<BR>  }<BR> <BR>@@ -2373,6 +2593,7 @@<BR>  ib_gid_t    gid;<BR>  mac_addr_t    mac;<BR>  ipoib_hw_addr_t   null_hw = {0};<BR>+ uint8_t     cm_capable = 0;<BR> <BR>  IPOIB_ENTER( IPOIB_DBG_RECV );<BR> <BR>@@ -2407,6 +2628,8 @@<BR>   return IB_INVALID_SETTING;<BR>  }<BR> <BR>+ cm_capable = ipoib_addr_get_flags( &p_ib_arp->src_hw );<BR>+<BR>  /*<BR>   * If we don't have a source, lookup the endpoint specified in the payload.<BR>   */<BR>@@ -2442,10 +2665,8 @@<BR>   }<BR>   else if( ipoib_is_voltaire_router_gid( &(*pp_src)->dgid ) )<BR>   {<BR>-   if( (*pp_src)->qpn !=<BR>-    (p_ib_arp->src_hw.flags_qpn & CL_HTON32(0x00FFFFFF)) &&<BR>-    p_wc->recv.ud.remote_qp !=<BR>-    (p_ib_arp->src_hw.flags_qpn & CL_HTON32(0x00FFFFFF)) )<BR>+   if( (*pp_src)->qpn != ipoib_addr_get_qpn( &p_ib_arp->src_hw ) &&<BR>+     p_wc->recv.ud.remote_qp != ipoib_addr_get_qpn( &p_ib_arp->src_hw ) )<BR>    {<BR>     /* Out of date!  Destroy the endpoint and replace it. */<BR>     __endpt_mgr_remove( p_port, *pp_src );<BR>@@ -2483,7 +2704,7 @@<BR>    * Create the endpoint.<BR>    */<BR>   *pp_src = ipoib_endpt_create( &p_ib_arp->src_hw.gid,<BR>-   p_wc->recv.ud.remote_lid, (p_ib_arp->src_hw.flags_qpn & CL_HTON32(0x00FFFFFF)) );<BR>+   p_wc->recv.ud.remote_lid, ipoib_addr_get_qpn( &p_ib_arp->src_hw ) );<BR> <BR>   if( !*pp_src )<BR>   {<BR>@@ -2506,11 +2727,44 @@<BR>   cl_obj_unlock( &p_port->obj );<BR>  }<BR> <BR>+ (*pp_src)->cm_flag = cm_capable;<BR>+<BR>  CL_ASSERT( !cl_memcmp(<BR>   &(*pp_src)->dgid, &p_ib_arp->src_hw.gid, sizeof(ib_gid_t) ) );<BR>  CL_ASSERT( ipoib_is_voltaire_router_gid( &(*pp_src)->dgid ) ||<BR>-  (*pp_src)->qpn ==<BR>-  (p_ib_arp->src_hw.flags_qpn & CL_HTON32(0x00FFFFFF)) );<BR>+  (*pp_src)->qpn == ipoib_addr_get_qpn( &p_ib_arp->src_hw ) );<BR>+<BR>+ if( p_port->p_adapter->params.cm_enabled &&<BR>+  p_ib_arp->op == ARP_OP_REQ &&<BR>+  cm_capable == IPOIB_CM_FLAG_RC )<BR>+ {<BR>+  /* if we've got ARP request and RC flag is set, <BR>+  save SID for connect REQ to be sent in ARP reply<BR>+  when requestor's path get resolved */<BR>+  if( endpt_cm_get_state( (*pp_src) ) == IPOIB_CM_DISCONNECTED )<BR>+  {<BR>+   (*pp_src)->cm_flag = cm_capable;<BR>+   ipoib_addr_set_sid( <BR>+    &(*pp_src)->conn.service_id,<BR>+    ipoib_addr_get_qpn( &p_ib_arp->src_hw ) );<BR>+  }<BR>+ }<BR>+<BR>+#if DBG<BR>+ if( p_port->p_adapter->params.cm_enabled )<BR>+ {<BR>+  IPOIB_PRINT_EXIT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,<BR>+   (" ARP %s from ENDPT[%p] state %d CM cap: %d QPN: %#x MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",<BR>+   ((p_ib_arp->op == ARP_OP_REQ )? "REQUEST" : "REPLY"),<BR>+   *pp_src, endpt_cm_get_state( *pp_src ), <BR>+   ((cm_capable == IPOIB_CM_FLAG_RC)? 1: 0),<BR>+   cl_ntoh32( ipoib_addr_get_qpn( &p_ib_arp->src_hw ) ),<BR>+   (*pp_src)->mac.addr[0], (*pp_src)->mac.addr[1],<BR>+   (*pp_src)->mac.addr[2], (*pp_src)->mac.addr[3],<BR>+   (*pp_src)->mac.addr[4], (*pp_src)->mac.addr[5] ));<BR>+ }<BR>+#endif<BR>+<BR>  /* Now swizzle the data. */<BR>  p_arp->hw_type = ARP_HW_TYPE_ETH;<BR>  p_arp->hw_size = sizeof(mac_addr_t);<BR>@@ -2549,8 +2803,7 @@<BR>   {<BR>    p_arp->dst_hw = p_dst->mac;<BR>    p_arp->dst_ip = p_ib_arp->dst_ip;<BR>-   CL_ASSERT( p_dst->qpn == <BR>-    (p_ib_arp->dst_hw.flags_qpn & CL_HTON32(0x00FFFFFF)) );<BR>+   CL_ASSERT( p_dst->qpn == ipoib_addr_get_qpn( &p_ib_arp->dst_hw ) );<BR>   }<BR>  }<BR>  else /* we got ARP reqeust */<BR>@@ -2646,7 +2899,7 @@<BR> <BR>  if( status != NDIS_STATUS_SUCCESS )<BR>  {<BR>-  ipoib_inc_recv_stat( p_port->p_adapter, type, 0 );<BR>+  ipoib_inc_recv_stat( p_port->p_adapter, type, 0, 0 );<BR>   /* Return the receive descriptor to the pool. */<BR>   __buf_mgr_put_recv( p_port, p_desc, NULL );<BR>   IPOIB_PRINT_EXIT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_RECV,<BR>@@ -2669,7 +2922,10 @@<BR>  }<BR> <BR>  chksum.Value = 0;<BR>- switch (p_port->p_adapter->params.recv_chksum_offload) {<BR>+ switch( p_port->p_adapter->params.recv_chksum_offload )<BR>+ {<BR>+   default:<BR>+  CL_ASSERT( FALSE );<BR>    case CSUM_DISABLED:<BR>   NDIS_PER_PACKET_INFO_FROM_PACKET( *pp_packet, TcpIpChecksumPacketInfo ) =<BR>   (void*)(uintn_t)chksum.Value;<BR>@@ -2689,12 +2945,8 @@<BR>   NDIS_PER_PACKET_INFO_FROM_PACKET( *pp_packet, TcpIpChecksumPacketInfo ) =<BR>   (void*)(uintn_t)chksum.Value;<BR>   break;<BR>-   default:<BR>-  ASSERT(FALSE);<BR>-  NDIS_PER_PACKET_INFO_FROM_PACKET( *pp_packet, TcpIpChecksumPacketInfo ) =<BR>-  (void*)(uintn_t)chksum.Value;<BR>  }<BR>- ipoib_inc_recv_stat( p_port->p_adapter, type, p_desc->len );<BR>+ ipoib_inc_recv_stat( p_port->p_adapter, type, p_desc->len, 1 );<BR> <BR>  IPOIB_EXIT( IPOIB_DBG_RECV );<BR>  return IB_SUCCESS;<BR>@@ -2851,6 +3103,7 @@<BR>   cl_perf_start( FilterArp );<BR>   status = __send_mgr_filter_arp(<BR>    p_port, p_eth_hdr, p_buf, buf_len, p_desc );<BR>+  p_desc->send_dir = SEND_UD_QP;<BR>   cl_perf_stop( &p_port->p_adapter->perf, FilterArp );<BR>   break;<BR> <BR>@@ -2859,6 +3112,8 @@<BR>    * The IPoIB spec doesn't define how to send non IP or ARP packets.<BR>    * Just send the payload and hope for the best.<BR>    */<BR>+<BR>+  p_desc->send_dir = SEND_UD_QP;<BR>   cl_perf_start( SendGen );<BR>   status = __send_gen( p_port, p_desc, 0 );<BR>   cl_perf_stop( &p_port->p_adapter->perf, SendGen );<BR>@@ -2914,11 +3169,11 @@<BR>  NdisQueryPacketLength( p_desc->p_pkt, &tot_len );<BR> <BR>  /* Setup the work request. */<BR>- p_desc->local_ds[1].vaddr = cl_get_physaddr(<BR>+ p_desc->send_wr[0].local_ds[1].vaddr = cl_get_physaddr(<BR>   ((uint8_t*)p_desc->p_buf) + sizeof(eth_hdr_t) );<BR>- p_desc->local_ds[1].length = tot_len - sizeof(eth_hdr_t);<BR>- p_desc->local_ds[1].lkey = p_port->ib_mgr.lkey;<BR>- p_desc->wr.num_ds = 2;<BR>+ p_desc->send_wr[0].local_ds[1].length = tot_len - sizeof(eth_hdr_t);<BR>+ p_desc->send_wr[0].local_ds[1].lkey = p_port->ib_mgr.lkey;<BR>+ p_desc->send_wr[0].wr.num_ds = 2;<BR> <BR>  /* Copy the packet. */<BR>  NdisCopyFromPacketToPacketSafe( p_packet, bytes_copied, tot_len,<BR>@@ -3010,18 +3265,18 @@<BR>     CL_ASSERT( i == 0 );<BR>     if( offset < PAGE_SIZE )<BR>     {<BR>-     p_desc->local_ds[j].lkey = p_port->ib_mgr.lkey;<BR>-     p_desc->local_ds[j].vaddr = (page_array[i] << PAGE_SHIFT);<BR>+     p_desc->send_wr[0].local_ds[j].lkey = p_port->ib_mgr.lkey;<BR>+     p_desc->send_wr[0].local_ds[j].vaddr = (page_array[i] << PAGE_SHIFT);<BR>      /* Add the byte offset since we're on the 1st page. */<BR>-     p_desc->local_ds[j].vaddr += offset;<BR>+     p_desc->send_wr[0].local_ds[j].vaddr += offset;<BR>      if( offset + buf_len > PAGE_SIZE )<BR>      {<BR>-      p_desc->local_ds[j].length = PAGE_SIZE - offset;<BR>-      buf_len -= p_desc->local_ds[j].length;<BR>+      p_desc->send_wr[0].local_ds[j].length = PAGE_SIZE - offset;<BR>+      buf_len -= p_desc->send_wr[0].local_ds[j].length;<BR>      }<BR>      else<BR>      {<BR>-      p_desc->local_ds[j].length = buf_len;<BR>+      p_desc->send_wr[0].local_ds[j].length = buf_len;<BR>       buf_len = 0;<BR>      }<BR>      /* This data segment is done.  Move to the next. */<BR>@@ -3037,25 +3292,25 @@<BR>   /* Finish this MDL */<BR>   while( buf_len )<BR>   {<BR>-   p_desc->local_ds[j].lkey = p_port->ib_mgr.lkey;<BR>-   p_desc->local_ds[j].vaddr = (page_array[i] << PAGE_SHIFT);<BR>+   p_desc->send_wr[0].local_ds[j].lkey = p_port->ib_mgr.lkey;<BR>+   p_desc->send_wr[0].local_ds[j].vaddr = (page_array[i] << PAGE_SHIFT);<BR>    /* Add the first page's offset if we're on the first page. */<BR>    if( i == 0 )<BR>-    p_desc->local_ds[j].vaddr += MmGetMdlByteOffset( p_mdl );<BR>+    p_desc->send_wr[0].local_ds[j].vaddr += MmGetMdlByteOffset( p_mdl );<BR> <BR>    if( i == 0 && (MmGetMdlByteOffset( p_mdl ) + buf_len) > PAGE_SIZE )<BR>    {<BR>     /* Buffers spans pages. */<BR>-    p_desc->local_ds[j].length =<BR>+    p_desc->send_wr[0].local_ds[j].length =<BR>      PAGE_SIZE - MmGetMdlByteOffset( p_mdl );<BR>-    buf_len -= p_desc->local_ds[j].length;<BR>+    buf_len -= p_desc->send_wr[0].local_ds[j].length;<BR>     /* This page is done.  Move to the next. */<BR>     i++;<BR>    }<BR>    else<BR>    {<BR>     /* Last page of the buffer. */<BR>-    p_desc->local_ds[j].length = buf_len;<BR>+    p_desc->send_wr[0].local_ds[j].length = buf_len;<BR>     buf_len = 0;<BR>    }<BR>    /* This data segment is done.  Move to the next. */<BR>@@ -3076,7 +3331,7 @@<BR>  }<BR> <BR>  /* Set the number of data segments. */<BR>- p_desc->wr.num_ds = j;<BR>+ p_desc->send_wr[0].wr.num_ds = j;<BR> <BR>  IPOIB_EXIT( IPOIB_DBG_SEND );<BR>  return IB_SUCCESS;<BR>@@ -3088,7 +3343,7 @@<BR> __send_gen(<BR>  IN    ipoib_port_t* const   p_port,<BR>  IN    ipoib_send_desc_t* const p_desc,<BR>- IN    INT lso_data_index)<BR>+ IN    INT       lso_data_index )<BR> {<BR>  ib_api_status_t   status;<BR>  SCATTER_GATHER_LIST  *p_sgl;<BR>@@ -3109,16 +3364,21 @@<BR>  }<BR> <BR>  /* Remember that one of the DS entries is reserved for the IPoIB header. */<BR>- if( ( p_sgl->NumberOfElements >= MAX_SEND_SGE &&<BR>-  p_sgl->Elements[0].Length > sizeof(eth_hdr_t)) ||<BR>-  ( p_sgl->NumberOfElements > MAX_SEND_SGE &&<BR>-  p_sgl->Elements[0].Length <= sizeof(eth_hdr_t)) )<BR>+ if( ( p_sgl->NumberOfElements >= MAX_SEND_SGE ||<BR>+  p_sgl->Elements[0].Length < sizeof(eth_hdr_t)) )<BR>  {<BR>-  IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_SEND,<BR>-   ("Too many buffers to fit in WR ds_array.  Copying data.\n") );<BR>-  cl_perf_start( SendCopy );<BR>-  status = __send_copy( p_port, p_desc );<BR>-  cl_perf_stop( &p_port->p_adapter->perf, SendCopy );<BR>+<BR>+  IPOIB_PRINT( TRACE_LEVEL_WARNING, IPOIB_DBG_SEND,<BR>+   ("Too many buffers %d to fit in WR ds_array[%d] \<BR>+    Or buffer[0] length %d < Eth header. Copying data.\n",<BR>+   p_sgl->NumberOfElements, MAX_SEND_SGE, p_sgl->Elements[0].Length ) );<BR>+  status = NDIS_STATUS_RESOURCES;<BR>+  if( !p_port->p_adapter->params.cm_enabled )<BR>+  {<BR>+   cl_perf_start( SendCopy );<BR>+   status = __send_copy( p_port, p_desc );<BR>+   cl_perf_stop( &p_port->p_adapter->perf, SendCopy );<BR>+  }<BR>   IPOIB_EXIT( IPOIB_DBG_SEND );<BR>   return status;<BR>  }<BR>@@ -3128,7 +3388,8 @@<BR>   * or part of it.<BR>   */<BR>  i = 0;<BR>- if (lso_data_index) { //we have an LSO packet<BR>+ if( lso_data_index )<BR>+ { /* we have an LSO packet */<BR>   i = lso_data_index;<BR>   j = 0;<BR>  }<BR>@@ -3140,11 +3401,11 @@<BR>   }<BR>   else<BR>   {<BR>-   p_desc->local_ds[j].vaddr =<BR>+   p_desc->send_wr[0].local_ds[j].vaddr =<BR>     p_sgl->Elements[i].Address.QuadPart + offset;<BR>-   p_desc->local_ds[j].length =<BR>+   p_desc->send_wr[0].local_ds[j].length =<BR>     p_sgl->Elements[i].Length - offset;<BR>-   p_desc->local_ds[j].lkey = p_port->ib_mgr.lkey;<BR>+   p_desc->send_wr[0].local_ds[j].lkey = p_port->ib_mgr.lkey;<BR>    i++;<BR>    j++;<BR>    break;<BR>@@ -3153,15 +3414,15 @@<BR>  /* Now fill in the rest of the local data segments. */<BR>  while( i < p_sgl->NumberOfElements )<BR>  {<BR>-  p_desc->local_ds[j].vaddr = p_sgl->Elements[i].Address.QuadPart;<BR>-  p_desc->local_ds[j].length = p_sgl->Elements[i].Length;<BR>-  p_desc->local_ds[j].lkey = p_port->ib_mgr.lkey;<BR>+  p_desc->send_wr[0].local_ds[j].vaddr = p_sgl->Elements[i].Address.QuadPart;<BR>+  p_desc->send_wr[0].local_ds[j].length = p_sgl->Elements[i].Length;<BR>+  p_desc->send_wr[0].local_ds[j].lkey = p_port->ib_mgr.lkey;<BR>   i++;<BR>   j++;<BR>  }<BR> <BR>  /* Set the number of data segments. */<BR>- p_desc->wr.num_ds = j;<BR>+ p_desc->send_wr[0].wr.num_ds = j;<BR> <BR>  IPOIB_EXIT( IPOIB_DBG_SEND );<BR>  return NDIS_STATUS_SUCCESS;<BR>@@ -3179,6 +3440,7 @@<BR> {<BR>  NDIS_STATUS  status;<BR>  ip_hdr_t  *p_ip_hdr;<BR>+ uint32_t  ip_packet_len;<BR> <BR>  PERF_DECLARE( QueryIp );<BR>  PERF_DECLARE( SendTcp );<BR>@@ -3217,43 +3479,76 @@<BR>   return NDIS_STATUS_BUFFER_TOO_SHORT;<BR>  }<BR> <BR>- if( p_ip_hdr->offset ||<BR>-  p_ip_hdr->prot != IP_PROT_UDP )<BR>+ switch( p_ip_hdr->prot )<BR>  {<BR>-  /* Check if this packet is IGMP */<BR>-  if ( p_ip_hdr->prot == IP_PROT_IGMP ) <BR>-  {<BR>-   /*<BR>-       In igmp packet I saw that iph arrive in 2 NDIS_BUFFERs:<BR>-    1. iph<BR>-    2. ip options<BR>-    So to get the IGMP packet we need to skip the ip options NDIS_BUFFER<BR>-   */<BR>-   size_t iph_size_in_bytes = (p_ip_hdr->ver_hl & 0xf) * 4;<BR>-   size_t iph_options_size = iph_size_in_bytes - buf_len;<BR>-   buf_len -= sizeof(ip_hdr_t);//without ipheader<BR>+ case IP_PROT_UDP:<BR> <BR>-   /*<BR>-       Could be a case that arrived igmp packet not from type IGMPv2 ,<BR>-    but IGMPv1 or IGMPv3.<BR>-    We anyway pass it to __send_mgr_filter_igmp_v2().<BR>-   */<BR>-   __send_mgr_filter_igmp_v2(p_port, p_ip_hdr, iph_options_size, p_buf, buf_len);<BR>+  cl_perf_start( FilterUdp );<BR>+  status = __send_mgr_filter_udp(<BR>+   p_port, p_ip_hdr, p_buf, (buf_len - sizeof(ip_hdr_t)), p_desc );<BR>+  cl_perf_stop( &p_port->p_adapter->perf, FilterUdp );<BR>+  if( status == NDIS_STATUS_PENDING )<BR>+  {  /* not DHCP packet, keep going */<BR>+   if( ETH_IS_MULTICAST( p_eth_hdr->dst.addr ) )<BR>+    p_desc->send_dir = SEND_UD_QP;<BR>+   else<BR>+    p_desc->send_dir = SEND_RC_QP;<BR>+   break;<BR>   }<BR>-  /* Not a UDP packet. */<BR>-  cl_perf_start( SendTcp );<BR>-  status = __send_gen( p_port, p_desc,0 );<BR>-  cl_perf_stop( &p_port->p_adapter->perf, SendTcp );<BR>-  IPOIB_EXIT( IPOIB_DBG_SEND );<BR>   return status;<BR>+ <BR>+ case IP_PROT_TCP:<BR>+  p_desc->send_dir = SEND_RC_QP;<BR>+  break;<BR>+ case IP_PROT_IGMP:<BR>+  /*<BR>+  In igmp packet I saw that iph arrive in 2 NDIS_BUFFERs:<BR>+  1. iph<BR>+  2. ip options<BR>+  So to get the IGMP packet we need to skip the ip options NDIS_BUFFER.<BR>+  Could be a case that arrived igmp packet not from type IGMPv2 ,<BR>+  but IGMPv1 or IGMPv3.<BR>+  We anyway pass it to __send_mgr_filter_igmp_v2().<BR>+  */<BR>+  status =<BR>+   __send_mgr_filter_igmp_v2(p_port, p_ip_hdr,<BR>+    (size_t)( IP_HEADER_LENGTH(p_ip_hdr) - buf_len ),<BR>+    p_buf, (buf_len - sizeof(ip_hdr_t)) );<BR>+  if( status != NDIS_STATUS_SUCCESS )<BR>+   return status;<BR>+  p_desc->send_dir = SEND_UD_QP;<BR>+  break;<BR>+ case IP_PROT_ICMP:<BR>+  p_desc->send_dir = SEND_UD_QP;<BR>+ default:<BR>+  break;<BR>  }<BR>+ <BR>+ if( !p_port->p_adapter->params.cm_enabled )<BR>+ {<BR>+  p_desc->send_dir = SEND_UD_QP;<BR>+  goto send_gen;<BR>+ }<BR>+ else if( endpt_cm_get_state( p_desc->p_endpt ) != IPOIB_CM_CONNECTED )<BR>+ {<BR>+  p_desc->send_dir = SEND_UD_QP;<BR>+ }<BR> <BR>- buf_len -= sizeof(ip_hdr_t);<BR>+ if( p_desc->send_dir == SEND_UD_QP )<BR>+ {<BR>+  ip_packet_len = cl_ntoh16( p_ip_hdr->length );<BR>+  if( ip_packet_len  > p_port->p_adapter->params.payload_mtu )<BR>+  {<BR>+   status = __send_fragments( p_port, p_desc, (eth_hdr_t* const)p_eth_hdr,<BR>+      (ip_hdr_t* const)p_ip_hdr, (uint32_t)buf_len, p_buf );<BR>+   return status;<BR>+  }<BR>+ }<BR> <BR>- cl_perf_start( FilterUdp );<BR>- status = __send_mgr_filter_udp(<BR>-  p_port, p_ip_hdr, p_buf, buf_len, p_desc );<BR>- cl_perf_stop( &p_port->p_adapter->perf, FilterUdp );<BR>+send_gen:<BR>+ cl_perf_start( SendTcp );<BR>+ status = __send_gen( p_port, p_desc,0 );<BR>+ cl_perf_stop( &p_port->p_adapter->perf, SendTcp );<BR> <BR>  IPOIB_EXIT( IPOIB_DBG_SEND );<BR>  return status;<BR>@@ -3440,11 +3735,7 @@<BR>   p_udp_hdr->dst_port != DHCP_PORT_CLIENT) )<BR>  {<BR>   /* Not a DHCP packet. */<BR>-  cl_perf_start( SendUdp );<BR>-  status = __send_gen( p_port, p_desc,0 );<BR>-  cl_perf_stop( &p_port->p_adapter->perf, SendUdp );<BR>-  IPOIB_EXIT( IPOIB_DBG_SEND );<BR>-  return status;<BR>+  return NDIS_STATUS_PENDING;<BR>  }<BR> <BR>  buf_len -= sizeof(udp_hdr_t);<BR>@@ -3654,10 +3945,11 @@<BR>  }<BR>  /* no chksum for udp */<BR>  p_desc->p_buf->ip.prot.udp.hdr.chksum = 0;<BR>- p_desc->local_ds[1].vaddr = cl_get_physaddr( p_desc->p_buf );<BR>- p_desc->local_ds[1].length = sizeof(ip_hdr_t) + sizeof(udp_hdr_t) + sizeof(dhcp_pkt_t);<BR>- p_desc->local_ds[1].lkey = p_port->ib_mgr.lkey;<BR>- p_desc->wr.num_ds = 2;<BR>+ p_desc->send_wr[0].local_ds[1].vaddr = cl_get_physaddr( p_desc->p_buf );<BR>+ p_desc->send_wr[0].local_ds[1].length = sizeof(ip_hdr_t) + sizeof(udp_hdr_t) + sizeof(dhcp_pkt_t);<BR>+ p_desc->send_wr[0].local_ds[1].lkey = p_port->ib_mgr.lkey;<BR>+ p_desc->send_wr[0].wr.num_ds = 2;<BR>+ p_desc->send_dir = SEND_UD_QP;<BR>  IPOIB_EXIT( IPOIB_DBG_SEND );<BR>  return NDIS_STATUS_SUCCESS;<BR> }<BR>@@ -3732,32 +4024,101 @@<BR>  p_ib_arp->hw_size = sizeof(ipoib_hw_addr_t);<BR>  p_ib_arp->prot_size = p_arp->prot_size;<BR>  p_ib_arp->op = p_arp->op;<BR>- p_ib_arp->src_hw.flags_qpn = p_port->ib_mgr.qpn;<BR>+ <BR>+ ipoib_addr_set_qpn( &p_ib_arp->src_hw, p_port->ib_mgr.qpn );<BR>+ <BR>+ if( p_port->p_adapter->params.cm_enabled )<BR>+ {<BR>+  ipoib_addr_set_flags( &p_ib_arp->src_hw, IPOIB_CM_FLAG_RC );<BR>+ }<BR>+<BR>  ib_gid_set_default( &p_ib_arp->src_hw.gid,<BR>   p_port->p_adapter->guids.port_guid.guid );<BR>  p_ib_arp->src_ip = p_arp->src_ip;<BR>  if( cl_memcmp( &p_arp->dst_hw, &null_hw, sizeof(mac_addr_t) ) )<BR>  {<BR>   /* Get the endpoint referenced by the dst_hw address. */<BR>+  net32_t qpn = 0;<BR>   status = __endpt_mgr_get_gid_qpn( p_port, p_arp->dst_hw,<BR>-   &p_ib_arp->dst_hw.gid, &p_ib_arp->dst_hw.flags_qpn );<BR>+   &p_ib_arp->dst_hw.gid, &qpn );<BR>   if( status != NDIS_STATUS_SUCCESS )<BR>   {<BR>    IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>     ("Failed lookup of destination HW address\n") );<BR>    return status;<BR>   }<BR>+  ipoib_addr_set_qpn( &p_ib_arp->dst_hw, qpn );<BR>+<BR>+  if( p_arp->op == ARP_OP_REP && <BR>+   p_port->p_adapter->params.cm_enabled && <BR>+   p_desc->p_endpt->cm_flag == IPOIB_CM_FLAG_RC )<BR>+  {<BR>+   cm_state_t cm_state;<BR>+   cm_state = <BR>+    ( cm_state_t )InterlockedCompareExchange( (volatile LONG *)&p_desc->p_endpt->conn.state,<BR>+        IPOIB_CM_CONNECT, IPOIB_CM_DISCONNECTED );<BR>+   switch( cm_state )<BR>+   {<BR>+   case IPOIB_CM_DISCONNECTED:<BR>+     IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,<BR>+      ("ARP REPLY pending Endpt[%p] QPN %#x MAC %02x:%02x:%02x:%02x:%02x:%02x\n",<BR>+      p_desc->p_endpt, <BR>+      cl_ntoh32( ipoib_addr_get_qpn( &p_ib_arp->dst_hw )),<BR>+      p_desc->p_endpt->mac.addr[0], p_desc->p_endpt->mac.addr[1],<BR>+      p_desc->p_endpt->mac.addr[2], p_desc->p_endpt->mac.addr[3],<BR>+      p_desc->p_endpt->mac.addr[4], p_desc->p_endpt->mac.addr[5] ) );<BR>+     ipoib_addr_set_sid( &p_desc->p_endpt->conn.service_id,<BR>+          ipoib_addr_get_qpn( &p_ib_arp->dst_hw ) );<BR>+<BR>+     ExFreeToNPagedLookasideList(<BR>+      &p_port->buf_mgr.send_buf_list, p_desc->p_buf );<BR>+     cl_qlist_insert_tail( &p_port->send_mgr.pending_list,<BR>+        IPOIB_LIST_ITEM_FROM_PACKET( p_desc->p_pkt ) );<BR>+     NdisInterlockedInsertTailList( &p_port->endpt_mgr.pending_conns, <BR>+            &p_desc->p_endpt->list_item, <BR>+            &p_port->endpt_mgr.conn_lock );<BR>+     cl_event_signal( &p_port->endpt_mgr.event );<BR>+     return NDIS_STATUS_PENDING;<BR>+   <BR>+   case IPOIB_CM_CONNECT:<BR>+    /* queue ARP REP packet until connected */<BR>+     ExFreeToNPagedLookasideList(<BR>+     &p_port->buf_mgr.send_buf_list, p_desc->p_buf );<BR>+     cl_qlist_insert_tail( &p_port->send_mgr.pending_list,<BR>+        IPOIB_LIST_ITEM_FROM_PACKET( p_desc->p_pkt ) );<BR>+     return NDIS_STATUS_PENDING;<BR>+   default:<BR>+    break;<BR>+   }<BR>+  }<BR>  }<BR>  else<BR>  {<BR>   cl_memclr( &p_ib_arp->dst_hw, sizeof(ipoib_hw_addr_t) );<BR>  }<BR>+<BR>+#if DBG<BR>+ if( p_port->p_adapter->params.cm_enabled )<BR>+ {<BR>+  IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,<BR>+  (" ARP SEND to ENDPT[%p] State: %d flag: %#x, QPN: %#x MAC %02x:%02x:%02x:%02x:%02x:%02x\n",<BR>+   p_desc->p_endpt, <BR>+   endpt_cm_get_state( p_desc->p_endpt ),<BR>+   p_desc->p_endpt->cm_flag, <BR>+   cl_ntoh32( ipoib_addr_get_qpn( &p_ib_arp->dst_hw )),<BR>+   p_desc->p_endpt->mac.addr[0], p_desc->p_endpt->mac.addr[1],<BR>+   p_desc->p_endpt->mac.addr[2], p_desc->p_endpt->mac.addr[3],<BR>+   p_desc->p_endpt->mac.addr[4], p_desc->p_endpt->mac.addr[5] ));<BR>+ }<BR>+#endif<BR>+<BR>  p_ib_arp->dst_ip = p_arp->dst_ip;<BR> <BR>- p_desc->local_ds[1].vaddr = cl_get_physaddr( p_ib_arp );<BR>- p_desc->local_ds[1].length = sizeof(ipoib_arp_pkt_t);<BR>- p_desc->local_ds[1].lkey = p_port->ib_mgr.lkey;<BR>- p_desc->wr.num_ds = 2;<BR>+ p_desc->send_wr[0].local_ds[1].vaddr = cl_get_physaddr( p_ib_arp );<BR>+ p_desc->send_wr[0].local_ds[1].length = sizeof(ipoib_arp_pkt_t);<BR>+ p_desc->send_wr[0].local_ds[1].lkey = p_port->ib_mgr.lkey;<BR>+ p_desc->send_wr[0].wr.num_ds = 2;<BR>+ p_desc->send_wr[0].wr.p_next = NULL;<BR> <BR>  IPOIB_EXIT( IPOIB_DBG_SEND );<BR>  return NDIS_STATUS_SUCCESS;<BR>@@ -3794,7 +4155,7 @@<BR>   return NDIS_STATUS_BUFFER_TOO_SHORT;<BR>  }<BR> <BR>- IPOIB_PRINT_EXIT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_SEND,<BR>+ IPOIB_PRINT_EXIT( TRACE_LEVEL_VERBOSE, IPOIB_DBG_SEND,<BR>   ("Ethernet header:\n"<BR>   "\tsrc MAC: %02X-%02X-%02X-%02X-%02X-%02X\n"<BR>   "\tdst MAC: %02X-%02X-%02X-%02X-%02X-%02X\n"<BR>@@ -3881,26 +4242,17 @@<BR>  PNDIS_PACKET_EXTENSION    PktExt;<BR>  PNDIS_TCP_IP_CHECKSUM_PACKET_INFO  pChecksumPktInfo; //NDIS 5.1<BR>  ULONG        mss;<BR>- LsoData        TheLsoData;<BR>- INT         IndexOfData = 0;<BR>- ULONG         PhysBufCount;<BR>- ULONG         PacketLength;<BR>- PNDIS_BUFFER       FirstBuffer;<BR>- uint16_t       lso_header_size;<BR> <BR>-<BR>  PERF_DECLARE( SendMgrFilter );<BR> <BR>  IPOIB_ENTER( IPOIB_DBG_SEND );<BR> <BR>  /* Format the send descriptor. */<BR>- cl_perf_start( SendMgrFilter );<BR> <BR>  PktExt = NDIS_PACKET_EXTENSION_FROM_PACKET(p_desc->p_pkt);<BR>- pChecksumPktInfo = (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&PktExt->NdisPacketInfo[TcpIpChecksumPacketInfo];<BR>+ pChecksumPktInfo = <BR>+  (PNDIS_TCP_IP_CHECKSUM_PACKET_INFO)&PktExt->NdisPacketInfo[TcpIpChecksumPacketInfo];<BR>  mss = PtrToUlong(PktExt->NdisPacketInfo[TcpLargeSendPacketInfo]);<BR>- //TODO: optimization: we already got total length from NdisGetFirstBufferFromPacketSafe before<BR>- NdisQueryPacket(p_desc->p_pkt, (PUINT)&PhysBufCount, NULL, &FirstBuffer,(PUINT)&PacketLength);<BR> <BR>  /* Format the send descriptor. */<BR>  hdr_idx = cl_atomic_inc( &p_port->hdr_idx );<BR>@@ -3909,49 +4261,27 @@<BR>  p_port->hdr[hdr_idx].type = p_eth_hdr->type;<BR>  p_port->hdr[hdr_idx].resv = 0;<BR> <BR>- if (mss)<BR>+ p_desc->send_wr[0].local_ds[0].vaddr = cl_get_physaddr( &p_port->hdr[hdr_idx] );<BR>+ p_desc->send_wr[0].local_ds[0].length = sizeof(ipoib_hdr_t);<BR>+ p_desc->send_wr[0].local_ds[0].lkey = p_port->ib_mgr.lkey;<BR>+ p_desc->send_wr[0].wr.send_opt = 0;<BR>+<BR>+ if( p_port->p_adapter->params.lso && mss )<BR>  {<BR>-  memset(&TheLsoData, 0, sizeof TheLsoData );<BR>-  status = GetLsoHeaderSize(<BR>-   p_port,<BR>-   FirstBuffer, <BR>-   &TheLsoData, <BR>-   &lso_header_size,<BR>-   &IndexOfData,<BR>-   &p_port->hdr[hdr_idx]<BR>-   <BR>-  );<BR>-  if ((status != NDIS_STATUS_SUCCESS ) || <BR>-   (TheLsoData.FullBuffers != TheLsoData.UsedBuffers)) {<BR>-   ASSERT(FALSE);<BR>-<BR>-   IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, ("<-- Throwing this packet\n"));<BR>-<BR>-   //NdisReleaseSpinLock(&Port->SendLock);<BR>-   //MP_ASSERT_NDIS_PACKET_TYPE(Packet);<BR>-   //SendComplete(Port, Packet, NDIS_STATUS_INVALID_PACKET);<BR>-   //NdisAcquireSpinLock(&Port->SendLock);<BR>-   //IPOIB_PRINT_EXIT<BR>+  status = __build_lso_desc( p_port, p_desc, mss, hdr_idx );<BR>+  if( status != NDIS_STATUS_SUCCESS )<BR>+  {<BR>+   IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+    ("__build_lso_desc returned 0x%08X.\n", status) );<BR>    return status;<BR>   }<BR>-  ASSERT(lso_header_size > 0);<BR>-  p_desc->wr.dgrm.ud.mss = mss;<BR>-  p_desc->wr.dgrm.ud.header = TheLsoData.LsoBuffers[0].pData;<BR>-  p_desc->wr.dgrm.ud.hlen = lso_header_size; <BR>-  // Tell NDIS how much we will send.<BR>-  PktExt->NdisPacketInfo[TcpLargeSendPacketInfo] = UlongToPtr(PacketLength);<BR>-  p_desc->wr.send_opt |= (IB_SEND_OPT_TX_IP_CSUM | IB_SEND_OPT_TX_TCP_UDP_CSUM) | IB_SEND_OPT_SIGNALED;<BR>-  __send_gen(p_port, p_desc, IndexOfData);<BR>-  p_desc->wr.wr_type = WR_LSO;<BR>- } else {<BR>-<BR>-  /* Setup the first local data segment (used for the IPoIB header). */<BR>-  p_desc->local_ds[0].vaddr = cl_get_physaddr( &p_port->hdr[hdr_idx] );<BR>-  p_desc->local_ds[0].length = sizeof(ipoib_hdr_t);<BR>-  p_desc->local_ds[0].lkey = p_port->ib_mgr.lkey;<BR>-<BR>+ }<BR>+ else<BR>+ {<BR>+  uint32_t i;<BR>+  cl_perf_start( SendMgrFilter );<BR>   status = __send_mgr_filter(<BR>-   p_port, p_eth_hdr, p_buf, buf_len, p_desc);<BR>+   p_port, p_eth_hdr, p_buf, buf_len, p_desc );<BR>   cl_perf_stop( &p_port->p_adapter->perf, SendMgrFilter );<BR>   if( status != NDIS_STATUS_SUCCESS )<BR>   {<BR>@@ -3959,49 +4289,140 @@<BR>     ("__send_mgr_filter returned 0x%08X.\n", status) );<BR>    return status;<BR>   }<BR>-  p_desc->wr.wr_type = WR_SEND;<BR>-  p_desc->wr.send_opt = IB_SEND_OPT_SIGNALED;<BR>- }<BR> <BR>+  if( p_desc->send_dir == SEND_UD_QP )<BR>+  {<BR>+   p_desc->send_qp = p_port->ib_mgr.h_qp; // UD QP<BR>+   for( i = 0; i < p_desc->num_wrs; i++ )<BR>+   {<BR>+    p_desc->send_wr[i].wr.dgrm.ud.remote_qp = p_desc->p_endpt->qpn;<BR>+    p_desc->send_wr[i].wr.dgrm.ud.remote_qkey = p_port->ib_mgr.bcast_rec.qkey;<BR>+    p_desc->send_wr[i].wr.dgrm.ud.h_av = p_desc->p_endpt->h_av;<BR>+    p_desc->send_wr[i].wr.dgrm.ud.pkey_index = p_port->pkey_index;<BR>+    p_desc->send_wr[i].wr.dgrm.ud.rsvd = NULL;<BR>+    p_desc->send_wr[i].wr.send_opt = 0;<BR> <BR>-<BR>- /* Setup the work request. */<BR>- p_desc->wr.p_next = NULL;<BR>- p_desc->wr.wr_id = (uintn_t)p_desc->p_pkt;<BR>-<BR>- if(p_port->p_adapter->params.send_chksum_offload && <BR>-  (pChecksumPktInfo->Transmit.NdisPacketChecksumV4 || pChecksumPktInfo->Transmit.NdisPacketChecksumV6))<BR>- {<BR>-  // Set transimition checksum offloading <BR>-  if (pChecksumPktInfo->Transmit.NdisPacketIpChecksum) <BR>+    if( p_port->p_adapter->params.send_chksum_offload && <BR>+     ( pChecksumPktInfo->Transmit.NdisPacketChecksumV4 || <BR>+     pChecksumPktInfo->Transmit.NdisPacketChecksumV6 ))<BR>+    {<BR>+     // Set transimition checksum offloading <BR>+     if( pChecksumPktInfo->Transmit.NdisPacketIpChecksum )<BR>+     {<BR>+      p_desc->send_wr[i].wr.send_opt |= IB_SEND_OPT_TX_IP_CSUM;<BR>+     }<BR>+     if( pChecksumPktInfo->Transmit.NdisPacketTcpChecksum )<BR>+     {<BR>+      p_desc->send_wr[i].wr.send_opt |= IB_SEND_OPT_TX_TCP_UDP_CSUM;<BR>+     }<BR>+    }<BR>+   }<BR>+  }<BR>+  else // RC QP<BR>   {<BR>-   p_desc->wr.send_opt |= IB_SEND_OPT_TX_IP_CSUM;<BR>+   CL_ASSERT( p_desc->send_dir == SEND_RC_QP );<BR>+   p_desc->send_qp = p_desc->p_endpt->conn.h_work_qp;<BR>   }<BR>-  if(pChecksumPktInfo->Transmit.NdisPacketTcpChecksum ||<BR>-     pChecksumPktInfo->Transmit.NdisPacketUdpChecksum ) <BR>-  {      <BR>-   p_desc->wr.send_opt |= IB_SEND_OPT_TX_TCP_UDP_CSUM;<BR>+  for( i = 0; i < p_desc->num_wrs; i++ )<BR>+  {<BR>+   p_desc->send_wr[i].wr.wr_type = WR_SEND;<BR>+   p_desc->send_wr[i].wr.wr_id = (uintn_t)p_desc->p_pkt;<BR>+   p_desc->send_wr[i].wr.ds_array = &p_desc->send_wr[i].local_ds[0];<BR>+   if( i )<BR>+   {<BR>+    p_desc->send_wr[i-1].wr.p_next = &p_desc->send_wr[i].wr;<BR>+   }<BR>   }<BR>+  p_desc->send_wr[p_desc->num_wrs - 1].wr.send_opt |= IB_SEND_OPT_SIGNALED;<BR>+  p_desc->send_wr[p_desc->num_wrs - 1].wr.p_next = NULL;<BR>  }<BR>- <BR>- p_desc->wr.ds_array = p_desc->local_ds;<BR> <BR>- p_desc->wr.dgrm.ud.remote_qp = p_desc->p_endpt1->qpn;<BR>- p_desc->wr.dgrm.ud.remote_qkey = p_port->ib_mgr.bcast_rec.qkey;<BR>- p_desc->wr.dgrm.ud.h_av = p_desc->p_endpt1->h_av;<BR>- p_desc->wr.dgrm.ud.pkey_index = p_port->pkey_index;<BR>- p_desc->wr.dgrm.ud.rsvd = NULL;<BR>-<BR>  /* Store context in our reserved area of the packet. */<BR>  IPOIB_PORT_FROM_PACKET( p_desc->p_pkt ) = p_port;<BR>- IPOIB_ENDPT_FROM_PACKET( p_desc->p_pkt ) = p_desc->p_endpt1;<BR>+ IPOIB_ENDPT_FROM_PACKET( p_desc->p_pkt ) = p_desc->p_endpt;<BR>  IPOIB_SEND_FROM_PACKET( p_desc->p_pkt ) = p_desc->p_buf;<BR> <BR>  IPOIB_EXIT( IPOIB_DBG_SEND );<BR>  return NDIS_STATUS_SUCCESS;<BR> }<BR> <BR>+static NDIS_STATUS<BR>+__build_lso_desc(<BR>+ IN    ipoib_port_t* const   p_port,<BR>+ IN OUT   ipoib_send_desc_t* const p_desc,<BR>+ IN    ULONG      mss,<BR>+ IN    int32_t      hdr_idx )<BR>+{<BR>+ NDIS_STATUS   status;<BR>+ PNDIS_PACKET_EXTENSION    PktExt;<BR>+ LsoData        TheLsoData;<BR>+ INT         IndexOfData = 0;<BR>+ ULONG         PhysBufCount;<BR>+ ULONG         PacketLength;<BR>+ PNDIS_BUFFER       FirstBuffer;<BR>+ uint16_t       lso_header_size;<BR> <BR>+ IPOIB_ENTER( IPOIB_DBG_SEND );<BR>+<BR>+ NdisQueryPacket(p_desc->p_pkt, (PUINT)&PhysBufCount, NULL, <BR>+       &FirstBuffer,(PUINT)&PacketLength);<BR>+ PktExt = NDIS_PACKET_EXTENSION_FROM_PACKET(p_desc->p_pkt);<BR>+<BR>+ memset(&TheLsoData, 0, sizeof TheLsoData );<BR>+ status = GetLsoHeaderSize(<BR>+  p_port,<BR>+  FirstBuffer, <BR>+  &TheLsoData, <BR>+  &lso_header_size,<BR>+  &IndexOfData,<BR>+  &p_port->hdr[hdr_idx] );<BR>+<BR>+ if ((status != NDIS_STATUS_SUCCESS ) || <BR>+  (TheLsoData.FullBuffers != TheLsoData.UsedBuffers)) <BR>+ {<BR>+  ASSERT(FALSE);<BR>+<BR>+  IPOIB_PRINT(TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR, ("<-- Throwing this packet\n"));<BR>+<BR>+  //NdisReleaseSpinLock(&Port->SendLock);<BR>+  //MP_ASSERT_NDIS_PACKET_TYPE(Packet);<BR>+  //SendComplete(Port, Packet, NDIS_STATUS_INVALID_PACKET);<BR>+  //NdisAcquireSpinLock(&Port->SendLock);<BR>+  //IPOIB_PRINT_EXIT<BR>+  if( status == NDIS_STATUS_SUCCESS )<BR>+  {<BR>+   status = NDIS_STATUS_INVALID_PACKET;<BR>+  }<BR>+  return status;<BR>+ }<BR>+ ASSERT(lso_header_size > 0);<BR>+ // Tell NDIS how much we will send.<BR>+ PktExt->NdisPacketInfo[TcpLargeSendPacketInfo] = UlongToPtr(PacketLength);<BR>+<BR>+ p_desc->send_wr[0].wr.dgrm.ud.mss = mss;<BR>+ p_desc->send_wr[0].wr.dgrm.ud.header = TheLsoData.LsoBuffers[0].pData;<BR>+ p_desc->send_wr[0].wr.dgrm.ud.hlen = lso_header_size; <BR>+ p_desc->send_wr[0].wr.dgrm.ud.remote_qp = p_desc->p_endpt->qpn;<BR>+ p_desc->send_wr[0].wr.dgrm.ud.remote_qkey = p_port->ib_mgr.bcast_rec.qkey;<BR>+ p_desc->send_wr[0].wr.dgrm.ud.h_av = p_desc->p_endpt->h_av;<BR>+ p_desc->send_wr[0].wr.dgrm.ud.pkey_index = p_port->pkey_index;<BR>+ p_desc->send_wr[0].wr.dgrm.ud.rsvd = NULL;<BR>+ <BR>+ p_desc->send_wr[0].wr.wr_id = (uintn_t)p_desc->p_pkt;<BR>+ p_desc->send_wr[0].wr.ds_array = p_desc->send_wr[0].local_ds;<BR>+ p_desc->send_wr[0].wr.wr_type = WR_LSO;<BR>+ p_desc->send_wr[0].wr.send_opt = <BR>+  (IB_SEND_OPT_TX_IP_CSUM | IB_SEND_OPT_TX_TCP_UDP_CSUM) | IB_SEND_OPT_SIGNALED;<BR>+ <BR>+ p_desc->send_wr[0].wr.p_next = NULL;<BR>+ p_desc->send_qp = p_port->ib_mgr.h_qp;<BR>+ p_desc->send_dir = SEND_UD_QP;<BR>+ status = __send_gen(p_port, p_desc, IndexOfData );<BR>+<BR>+ IPOIB_EXIT( IPOIB_DBG_SEND );<BR>+ return status;<BR>+}<BR>+<BR> static inline void<BR> __process_failed_send(<BR>  IN    ipoib_port_t* const   p_port,<BR>@@ -4015,8 +4436,8 @@<BR>   p_desc->p_pkt, status );<BR>  ipoib_inc_send_stat( p_port->p_adapter, IP_STAT_ERROR, 0 );<BR>  /* Deref the endpoint. */<BR>- if( p_desc->p_endpt1 )<BR>-  ipoib_endpt_deref( p_desc->p_endpt1 );<BR>+ if( p_desc->p_endpt )<BR>+  ipoib_endpt_deref( p_desc->p_endpt );<BR> <BR>  if( p_desc->p_buf )<BR>  {<BR>@@ -4041,6 +4462,7 @@<BR>  eth_hdr_t   *p_eth_hdr;<BR>  NDIS_BUFFER   *p_buf;<BR>  UINT    buf_len;<BR>+ ib_send_wr_t  *p_wr_failed;<BR> <BR>  PERF_DECLARE( GetEthHdr );<BR>  PERF_DECLARE( BuildSendDesc );<BR>@@ -4076,8 +4498,10 @@<BR>  for( i = 0; i < num_packets; i++ )<BR>  {<BR>   desc.p_pkt = p_packet_array[i];<BR>-  desc.p_endpt1 = NULL;<BR>+  desc.p_endpt = NULL;<BR>   desc.p_buf = NULL;<BR>+  desc.send_qp = NULL;<BR>+  desc.num_wrs = 1;<BR> <BR>   /* Get the ethernet header so we can find the endpoint. */<BR>   cl_perf_start( GetEthHdr );<BR>@@ -4101,7 +4525,7 @@<BR>    ip_hdr_t   *p_ip_hdr;<BR>    NDIS_BUFFER   *p_ip_hdr_buf;<BR>    UINT    ip_hdr_buf_len;<BR>-<BR>+   <BR>    // Extract the ip hdr <BR>    if(buf_len >= sizeof(ip_hdr_t)+ sizeof(eth_hdr_t))<BR>    {<BR>@@ -4139,7 +4563,7 @@<BR>    p_eth_hdr->dst.addr[3] = ((unsigned char*)&p_ip_hdr->dst_ip)[1];<BR>   }<BR> h_end:<BR>-  status = __send_mgr_queue( p_port, p_eth_hdr, &desc.p_endpt1 );<BR>+  status = __send_mgr_queue( p_port, p_eth_hdr, &desc.p_endpt );<BR>   cl_perf_stop( &p_port->p_adapter->perf, SendMgrQueue );<BR>   if( status == NDIS_STATUS_PENDING )<BR>   {<BR>@@ -4171,6 +4595,11 @@<BR>   cl_perf_stop( &p_port->p_adapter->perf, BuildSendDesc );<BR>   if( status != NDIS_STATUS_SUCCESS )<BR>   {<BR>+   if( status == NDIS_STATUS_PENDING )<BR>+   {<BR>+    ipoib_endpt_deref( desc.p_endpt );<BR>+    continue;<BR>+   }<BR>    cl_perf_start( ProcessFailedSends );<BR>    __process_failed_send( p_port, &desc, status );<BR>    cl_perf_stop( &p_port->p_adapter->perf, ProcessFailedSends );<BR>@@ -4179,7 +4608,7 @@<BR> <BR>   /* Post the WR. */<BR>   cl_perf_start( PostSend );<BR>-  ib_status = p_port->p_adapter->p_ifc->post_send( p_port->ib_mgr.h_qp, &desc.wr, NULL );<BR>+  ib_status = p_port->p_adapter->p_ifc->post_send( desc.send_qp, &desc.send_wr[0].wr, &p_wr_failed );<BR>   cl_perf_stop( &p_port->p_adapter->perf, PostSend );<BR>   if( ib_status != IB_SUCCESS )<BR>   {<BR>@@ -4213,6 +4642,7 @@<BR>  eth_hdr_t   *p_eth_hdr;<BR>  NDIS_BUFFER   *p_buf;<BR>  UINT    buf_len;<BR>+ ib_send_wr_t  *p_wr_failed;<BR> <BR>  PERF_DECLARE( GetEndpt );<BR>  PERF_DECLARE( BuildSendDesc );<BR>@@ -4248,8 +4678,10 @@<BR> <BR>   desc.p_pkt = IPOIB_PACKET_FROM_LIST_ITEM(<BR>    cl_qlist_remove_head( &p_port->send_mgr.pending_list ) );<BR>-  desc.p_endpt1 = NULL;<BR>+  desc.p_endpt = NULL;<BR>   desc.p_buf = NULL;<BR>+  desc.send_qp = NULL;<BR>+  desc.num_wrs = 1;<BR> <BR>   /* Get the ethernet header so we can find the endpoint. */<BR>   status = __send_mgr_get_eth_hdr(<BR>@@ -4263,11 +4695,11 @@<BR>   }<BR> <BR>   cl_perf_start( GetEndpt );<BR>-  status = __endpt_mgr_ref( p_port, p_eth_hdr->dst, &desc.p_endpt1 );<BR>+  status = __endpt_mgr_ref( p_port, p_eth_hdr->dst, &desc.p_endpt );<BR>   cl_perf_stop( &p_port->p_adapter->perf, GetEndpt );<BR>   if( status == NDIS_STATUS_PENDING )<BR>   {<BR>-   CL_ASSERT(desc.p_endpt1 == NULL);<BR>+   CL_ASSERT(desc.p_endpt == NULL);<BR>    cl_qlist_insert_head( &p_port->send_mgr.pending_list,<BR>     IPOIB_LIST_ITEM_FROM_PACKET( desc.p_pkt ) );<BR>    break;<BR>@@ -4275,7 +4707,7 @@<BR>   else if( status != NDIS_STATUS_SUCCESS )<BR>   {<BR>    ASSERT( status == NDIS_STATUS_NO_ROUTE_TO_DESTINATION );<BR>-   CL_ASSERT(desc.p_endpt1 == NULL);<BR>+   CL_ASSERT(desc.p_endpt == NULL);<BR> <BR>    if( ETH_IS_MULTICAST( p_eth_hdr->dst.addr ) )<BR>    {<BR>@@ -4305,6 +4737,12 @@<BR>   cl_perf_stop( &p_port->p_adapter->perf, BuildSendDesc );<BR>   if( status != NDIS_STATUS_SUCCESS )<BR>   {<BR>+   if( status == NDIS_STATUS_PENDING )<BR>+   {<BR>+    /* ARP REPLY packet queued */<BR>+    ipoib_endpt_deref( desc.p_endpt );<BR>+    continue;<BR>+   }<BR>    cl_perf_start( ProcessFailedSends );<BR>    __process_failed_send( p_port, &desc, status );<BR>    cl_perf_stop( &p_port->p_adapter->perf, ProcessFailedSends );<BR>@@ -4313,7 +4751,7 @@<BR> <BR>   /* Post the WR. */<BR>   cl_perf_start( PostSend );<BR>-  ib_status = p_port->p_adapter->p_ifc->post_send( p_port->ib_mgr.h_qp, &desc.wr, NULL );<BR>+  ib_status = p_port->p_adapter->p_ifc->post_send( desc.send_qp, &desc.send_wr[0].wr, &p_wr_failed );<BR>   cl_perf_stop( &p_port->p_adapter->perf, PostSend );<BR>   if( ib_status != IB_SUCCESS )<BR>   {<BR>@@ -4498,18 +4936,126 @@<BR>  IPOIB_EXIT( IPOIB_DBG_INIT );<BR> }<BR> <BR>+static void<BR>+__endpt_cm_mgr_thread(<BR>+IN  void*  p_context );<BR> <BR> static ib_api_status_t<BR> __endpt_mgr_init(<BR>  IN    ipoib_port_t* const   p_port )<BR> {<BR>  IPOIB_ENTER( IPOIB_DBG_INIT );<BR>- UNUSED_PARAM( p_port );<BR>+  <BR>+ if( p_port->p_adapter->params.cm_enabled )<BR>+ {<BR>+  cl_fmap_init( &p_port->endpt_mgr.conn_endpts, __gid_cmp );<BR>+  <BR>+  NdisInitializeListHead( &p_port->endpt_mgr.pending_conns );<BR>+  NdisAllocateSpinLock( &p_port->endpt_mgr.conn_lock );<BR>+  cl_event_init( &p_port->endpt_mgr.event, FALSE );<BR>+ <BR>+  NdisInitializeListHead( &p_port->endpt_mgr.remove_conns );<BR>+  NdisAllocateSpinLock( &p_port->endpt_mgr.remove_lock );<BR>+<BR>+  cl_thread_init( &p_port->endpt_mgr.h_thread, <BR>+      __endpt_cm_mgr_thread,<BR>+      ( const void *)p_port, <BR>+      "CmEndPtMgr" );<BR>+ }<BR>+<BR>  IPOIB_EXIT( IPOIB_DBG_INIT );<BR>  return IB_SUCCESS;<BR> }<BR> <BR>+static void<BR>+__endpt_cm_mgr_thread(<BR>+IN  void*  p_context )<BR>+{<BR>+ ib_api_status_t ib_status;<BR>+ LIST_ENTRY  *p_item;<BR>+ ipoib_endpt_t *p_endpt;<BR>+ ipoib_port_t *p_port =( ipoib_port_t *)p_context;<BR>+ <BR>+ IPOIB_PRINT_EXIT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT, <BR>+  ("Starting Port [%d] Endpt CM thread \n", p_port->port_num ) );<BR> <BR>+ while( !p_port->endpt_mgr.thread_is_done )<BR>+ {<BR>+  cl_event_wait_on( &p_port->endpt_mgr.event, EVENT_NO_TIMEOUT, FALSE );<BR>+ <BR>+  while( ( p_item = NdisInterlockedRemoveHeadList( <BR>+        &p_port->endpt_mgr.pending_conns,<BR>+        &p_port->endpt_mgr.conn_lock) ) != NULL )<BR>+  {<BR>+<BR>+   p_endpt = PARENT_STRUCT( p_item, ipoib_endpt_t, list_item );<BR>+   if( p_port->endpt_mgr.thread_is_done )<BR>+   {<BR>+    endpt_cm_set_state( p_endpt, IPOIB_CM_DISCONNECTED );<BR>+    continue;<BR>+   }<BR>+<BR>+   IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,<BR>+    ("Endpt[%p] CONNECT REQ to MAC %02x:%02x:%02x:%02x:%02x:%02x\n",<BR>+    p_endpt,<BR>+    p_endpt->mac.addr[0], p_endpt->mac.addr[1],<BR>+    p_endpt->mac.addr[2], p_endpt->mac.addr[3],<BR>+    p_endpt->mac.addr[4], p_endpt->mac.addr[5] ) );<BR>+   <BR>+   if( !p_endpt->conn.h_send_qp )<BR>+   {<BR>+    ib_status = endpt_cm_create_qp( p_endpt, &p_endpt->conn.h_send_qp );<BR>+    if( ib_status != IB_SUCCESS )<BR>+    {<BR>+     IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+      ("Endpt [%p ] CM create QP failed status %#x\n", p_endpt, ib_status ) );<BR>+    }<BR>+    else<BR>+    {<BR>+     ib_status = ipoib_endpt_connect( p_endpt );<BR>+     if( ib_status != IB_SUCCESS && ib_status != IB_PENDING )<BR>+     {<BR>+      IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+       ("Endpt [ %p ] conn REQ failed status %#x\n", p_endpt, ib_status ) );<BR>+     }<BR>+    }<BR>+    if( ib_status != IB_SUCCESS && ib_status != IB_PENDING )<BR>+    {<BR>+     endpt_cm_set_state( p_endpt, IPOIB_CM_DESTROY );<BR>+     endpt_cm_flush_recv( p_port, p_endpt );<BR>+     endpt_cm_set_state( p_endpt, IPOIB_CM_DISCONNECTED );<BR>+    }<BR>+   }<BR>+<BR>+  }//while( p_item != NULL )<BR>+<BR>+  while( ( p_item = NdisInterlockedRemoveHeadList(<BR>+        &p_port->endpt_mgr.remove_conns,<BR>+        &p_port->endpt_mgr.remove_lock ) ) != NULL )<BR>+  {<BR>+   p_endpt = PARENT_STRUCT( p_item, ipoib_endpt_t, list_item );<BR>+<BR>+   endpt_cm_set_state( p_endpt, IPOIB_CM_DESTROY );<BR>+<BR>+   IPOIB_PRINT( TRACE_LEVEL_WARNING, IPOIB_DBG_INIT,<BR>+    ("\nDESTROYING Endpt[%p]  MAC %02x:%02x:%02x:%02x:%02x:%02x\n",<BR>+    p_endpt,<BR>+    p_endpt->mac.addr[0], p_endpt->mac.addr[1],<BR>+    p_endpt->mac.addr[2], p_endpt->mac.addr[3],<BR>+    p_endpt->mac.addr[4], p_endpt->mac.addr[5] ) );<BR>+   endpt_cm_flush_recv( p_port, p_endpt );<BR>+   endpt_cm_set_state( p_endpt, IPOIB_CM_DISCONNECTED );<BR>+   cl_obj_destroy( &p_endpt->obj );<BR>+  }<BR>+ }<BR>+<BR>+ p_port->endpt_mgr.thread_is_done++;<BR>+ NdisFreeSpinLock( &p_port->endpt_mgr.conn_lock );<BR>+ <BR>+ IPOIB_PRINT_EXIT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT, <BR>+  (" Port [%d] Endpt thread is done\n", p_port->port_num ) );<BR>+}<BR>+<BR> static void<BR> __endpt_mgr_destroy(<BR>  IN    ipoib_port_t* const   p_port )<BR>@@ -4518,7 +5064,10 @@<BR>  CL_ASSERT( cl_is_qmap_empty( &p_port->endpt_mgr.mac_endpts ) );<BR>  CL_ASSERT( cl_is_qmap_empty( &p_port->endpt_mgr.lid_endpts ) );<BR>  CL_ASSERT( cl_is_fmap_empty( &p_port->endpt_mgr.gid_endpts ) );<BR>- UNUSED_PARAM( p_port );<BR>+ if( p_port->p_adapter->params.cm_enabled )<BR>+ {<BR>+  CL_ASSERT( cl_is_fmap_empty( &p_port->endpt_mgr.conn_endpts ) );<BR>+ }<BR>  IPOIB_EXIT( IPOIB_DBG_INIT );<BR> }<BR> <BR>@@ -4552,15 +5101,17 @@<BR>  IN    ipoib_port_t* const   p_port )<BR> {<BR>  cl_map_item_t *p_item;<BR>+ cl_fmap_item_t *p_fmap_item;<BR>  ipoib_endpt_t  *p_endpt;<BR>  cl_qlist_t   mc_list;<BR>+ cl_qlist_t   conn_list;<BR>  uint32_t   local_exist = 0;<BR> <BR> <BR>  IPOIB_ENTER( IPOIB_DBG_ENDPT );<BR> <BR>  cl_qlist_init( &mc_list );<BR>- <BR>+ cl_qlist_init( &conn_list );<BR>  cl_obj_lock( &p_port->obj );<BR>  /* Wait for all readers to complete. */<BR>  while( p_port->endpt_rdr )<BR>@@ -4583,8 +5134,8 @@<BR> <BR>  if( p_port->p_local_endpt )<BR>  {<BR>-  cl_fmap_remove_item( &p_port->endpt_mgr.gid_endpts,<BR>-   &p_port->p_local_endpt->gid_item );<BR>+  ipoib_port_cancel_listen( p_port, p_port->p_local_endpt );<BR>+<BR>   cl_qmap_remove_item( &p_port->endpt_mgr.mac_endpts,<BR>    &p_port->p_local_endpt->mac_item );<BR>   cl_qmap_remove_item( &p_port->endpt_mgr.lid_endpts,<BR>@@ -4616,8 +5167,26 @@<BR>    cl_qlist_insert_tail(<BR>     &mc_list, &p_endpt->mac_item.pool_item.list_item );<BR>   }<BR>-  else if( p_endpt->h_av )<BR>+  /* destroy connected endpoints if any */<BR>+  else if( p_port->p_adapter->params.cm_enabled &&<BR>+     endpt_cm_get_state( p_endpt ) != IPOIB_CM_DISCONNECTED )<BR>   {<BR>+   p_fmap_item = cl_fmap_get( &p_port->endpt_mgr.conn_endpts, &p_endpt->dgid );<BR>+   if( p_fmap_item != cl_fmap_end( &p_port->endpt_mgr.conn_endpts ) )<BR>+   {<BR>+    cl_fmap_remove_item( &p_port->endpt_mgr.conn_endpts, <BR>+     &p_endpt->conn_item );<BR>+   }<BR>+   cl_qmap_remove_item( &p_port->endpt_mgr.mac_endpts,<BR>+    &p_endpt->mac_item );<BR>+   cl_fmap_remove_item( &p_port->endpt_mgr.gid_endpts,<BR>+    &p_endpt->gid_item );<BR>+<BR>+   cl_qlist_insert_tail(<BR>+    &conn_list, &p_endpt->mac_item.pool_item.list_item );<BR>+  }<BR>+  if( p_endpt->h_av )<BR>+  {<BR>    /* Destroy the AV for all other endpoints. */<BR>    p_port->p_adapter->p_ifc->destroy_av( p_endpt->h_av );<BR>    p_endpt->h_av = NULL;<BR>@@ -4636,6 +5205,12 @@<BR> #endif<BR>  cl_obj_unlock( &p_port->obj );<BR> <BR>+ while( cl_qlist_count( &conn_list ) )<BR>+ {<BR>+  endpt_cm_destroy_conn( p_port,<BR>+   PARENT_STRUCT( cl_qlist_remove_head( &conn_list ),<BR>+   ipoib_endpt_t, mac_item.pool_item.list_item ) );<BR>+ }<BR> <BR>  if(cl_qlist_count( &mc_list ) - local_exist)<BR>  {<BR>@@ -4673,6 +5248,8 @@<BR>  IN    ipoib_port_t* const   p_port,<BR>  IN    ipoib_endpt_t* const  p_endpt )<BR> {<BR>+ cl_fmap_item_t* p_fmap_item;<BR>+<BR>  IPOIB_ENTER( IPOIB_DBG_ENDPT );<BR> <BR>  /* This function must be called from the recieve path */<BR>@@ -4690,7 +5267,16 @@<BR>   * in the LID map if the GID has the same subnet prefix as us.<BR>   */<BR>  cl_fmap_remove_item( &p_port->endpt_mgr.gid_endpts, &p_endpt->gid_item );<BR>-<BR>+ if( p_port->p_adapter->params.cm_enabled )<BR>+ {<BR>+  p_fmap_item = cl_fmap_get( &p_port->endpt_mgr.conn_endpts, &p_endpt->dgid );<BR>+  <BR>+  if( p_fmap_item != cl_fmap_end( &p_port->endpt_mgr.conn_endpts ) )<BR>+  {<BR>+   cl_fmap_remove_item( &p_port->endpt_mgr.conn_endpts, <BR>+    &p_endpt->conn_item );<BR>+  }<BR>+ }<BR>  if( p_endpt->dlid )<BR>  {<BR>   cl_qmap_remove_item( &p_port->endpt_mgr.lid_endpts,<BR>@@ -4699,7 +5285,7 @@<BR> <BR>  cl_obj_unlock( &p_port->obj );<BR> <BR>- cl_obj_destroy( &p_endpt->obj );<BR>+ endpt_cm_destroy_conn( p_port, p_endpt );<BR> <BR>  IPOIB_EXIT( IPOIB_DBG_ENDPT );<BR> }<BR>@@ -4848,7 +5434,7 @@<BR> <BR>  cl_obj_lock( &p_port->obj );<BR> <BR>- IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_ENDPT,<BR>+ IPOIB_PRINT( TRACE_LEVEL_VERBOSE, IPOIB_DBG_ENDPT,<BR>   ("Look for :\t  MAC: %02X-%02X-%02X-%02X-%02X-%02X\n",<BR>   mac.addr[0], mac.addr[1], mac.addr[2],<BR>   mac.addr[3], mac.addr[4], mac.addr[5]) );<BR>@@ -5102,6 +5688,7 @@<BR>  IN  const mac_addr_t     mac )<BR> {<BR>  cl_map_item_t *p_item;<BR>+ cl_fmap_item_t  *p_fmap_item;<BR>  ipoib_endpt_t *p_endpt;<BR>  uint64_t  key;<BR> <BR>@@ -5130,6 +5717,17 @@<BR>   cl_fmap_remove_item(<BR>    &p_port->endpt_mgr.gid_endpts, &p_endpt->gid_item );<BR> <BR>+  if( p_port->p_adapter->params.cm_enabled )<BR>+  {<BR>+   p_fmap_item = cl_fmap_get( &p_port->endpt_mgr.conn_endpts, &p_endpt->dgid );<BR>+  <BR>+   if( p_fmap_item != cl_fmap_end( &p_port->endpt_mgr.conn_endpts ) )<BR>+   {<BR>+    cl_fmap_remove_item( &p_port->endpt_mgr.conn_endpts, <BR>+     &p_endpt->conn_item );<BR>+   }<BR>+  }<BR>+<BR>   if( p_endpt->dlid )<BR>   {<BR>    cl_qmap_remove_item(<BR>@@ -5137,7 +5735,9 @@<BR>   }<BR> <BR>   cl_obj_unlock( &p_port->obj );<BR>-  cl_obj_destroy( &p_endpt->obj );<BR>+<BR>+  endpt_cm_destroy_conn( p_port, p_endpt );<BR>+<BR> #if DBG<BR>   cl_atomic_dec( &p_port->ref[ref_endpt_track] );<BR>   IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_ENDPT,<BR>@@ -5296,8 +5896,8 @@<BR>  cl_memclr( &av_attr, sizeof(ib_av_attr_t) );<BR>  av_attr.port_num = p_port->port_num;<BR>  av_attr.sl = 0;<BR>- IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ENDPT,<BR>-  ("<__endpt_mgr_add_local>:  av_attr.dlid = p_port_info->base_lid = %d\n",p_port_info->base_lid));<BR>+ IPOIB_PRINT_EXIT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_ENDPT,<BR>+  (" av_attr.dlid = p_port_info->base_lid = %d\n", cl_ntoh16( p_port_info->base_lid ) ));<BR>  av_attr.dlid = p_port_info->base_lid;<BR>  av_attr.static_rate = p_port->ib_mgr.rate;<BR>  av_attr.path_bits = 0;<BR>@@ -5760,7 +6360,7 @@<BR>   cl_obj_lock( &p_port->obj );<BR>  }<BR> <BR>- if(! p_port->p_local_endpt)<BR>+ if( !p_port->p_local_endpt )<BR>  {<BR>   ib_port_info_t port_info;<BR>   cl_memclr(&port_info, sizeof(port_info));<BR>@@ -5853,6 +6453,20 @@<BR>   return;<BR>  }<BR> <BR>+ if( p_port->p_adapter->params.cm_enabled &&<BR>+  !p_port->p_local_endpt->conn.h_cm_listen )<BR>+ {<BR>+  if( ipoib_port_listen( p_port ) != IB_SUCCESS )<BR>+  {<BR>+   IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+    ("Port CM Listen failed\n" ) );<BR>+   /*keep going with UD only */<BR>+   p_port->p_adapter->params.cm_enabled = FALSE;<BR>+<BR>+   NdisWriteErrorLogEntry( p_port->p_adapter->h_adapter,<BR>+    EVENT_IPOIB_CONNECTED_MODE_ERR, 1, 0xbadc0de3 );<BR>+  }<BR>+ }<BR>  /* garbage collector timer is needed when link is active */<BR>  gc_due_time.QuadPart = -(int64_t)(((uint64_t)p_port->p_adapter->params.mc_leave_rescan * 2000000) * 10);<BR>  KeSetTimerEx(&p_port->gc_timer,gc_due_time,<BR>@@ -6277,7 +6891,7 @@<BR>  }<BR>  IpHdr = (ip_hdr_t UNALIGNED*)pSrc;<BR>  IpHeaderLen = (uint16_t)IP_HEADER_LENGTH(IpHdr);<BR>- ASSERT(IpHdr->prot == PROTOCOL_TCP);<BR>+ ASSERT(IpHdr->prot == IP_PROT_TCP);<BR>  if (CurrLength < IpHeaderLen) {<BR>   IPOIB_PRINT(TRACE_LEVEL_VERBOSE, IPOIB_DBG_ERROR, ("Error processing packets\n"));<BR>   return status;<BR>@@ -6328,7 +6942,7 @@<BR>  TcpHdr = (tcp_hdr_t UNALIGNED *)pSrc;<BR>  TcpHeaderLen = TCP_HEADER_LENGTH(TcpHdr);<BR> <BR>- ASSERT(TcpHeaderLen == 20);<BR>+ //ASSERT(TcpHeaderLen == 20);<BR>  <BR>  if (CurrLength < TcpHeaderLen) {<BR>   //IPOIB_PRINT(TRACE_LEVEL_VERBOSE, ETH, ("Error porcessing packets\n"));<BR>@@ -6442,4 +7056,451 @@<BR>  __port_do_mcast_garbage(p_port);<BR> }<BR> <BR>+ipoib_endpt_t*<BR>+ipoib_endpt_get_by_gid(<BR>+ IN    ipoib_port_t* const   p_port,<BR>+ IN  const ib_gid_t* const    p_gid )<BR>+{<BR>+ return __endpt_mgr_get_by_gid( p_port, p_gid );<BR>+}<BR> <BR>+ipoib_endpt_t*<BR>+ipoib_endpt_get_by_lid(<BR>+ IN    ipoib_port_t* const   p_port,<BR>+ IN  const net16_t      lid )<BR>+{<BR>+ return __endpt_mgr_get_by_lid( p_port, lid );<BR>+}<BR>+<BR>+ib_api_status_t<BR>+ipoib_recv_dhcp(<BR>+ IN    ipoib_port_t* const   p_port,<BR>+ IN  const ipoib_pkt_t* const   p_ipoib,<BR>+  OUT   eth_pkt_t* const   p_eth,<BR>+ IN    ipoib_endpt_t* const  p_src,<BR>+ IN    ipoib_endpt_t* const  p_dst )<BR>+{<BR>+ return __recv_dhcp(<BR>+  p_port, p_ipoib, p_eth, p_src,p_dst );<BR>+}<BR>+<BR>+void<BR>+ipoib_port_cancel_xmit(<BR>+ IN    ipoib_port_t* const  p_port,<BR>+ IN    PVOID      cancel_id )<BR>+{<BR>+ cl_list_item_t  *p_item;<BR>+ NDIS_PACKET*  p_packet;<BR>+ PVOID   packet_id;<BR>+ cl_qlist_t  cancel_list;<BR>+<BR>+ IPOIB_ENTER( IPOIB_DBG_SEND );<BR>+<BR>+ cl_qlist_init( &cancel_list );<BR>+<BR>+ cl_spinlock_acquire( &p_port->send_lock );<BR>+<BR>+ for( p_item = cl_qlist_head( &p_port->send_mgr.pending_list );<BR>+  p_item != cl_qlist_end( &p_port->send_mgr.pending_list );<BR>+  p_item = cl_qlist_next( p_item ) )<BR>+ {<BR>+  p_packet = IPOIB_PACKET_FROM_LIST_ITEM( p_item );<BR>+  packet_id = NDIS_GET_PACKET_CANCEL_ID( p_packet );<BR>+  if( packet_id == cancel_id )<BR>+  {<BR>+   cl_qlist_remove_item( &p_port->send_mgr.pending_list, p_item );<BR>+   NDIS_SET_PACKET_STATUS( p_packet, NDIS_STATUS_REQUEST_ABORTED );<BR>+   cl_qlist_insert_tail( &cancel_list, IPOIB_LIST_ITEM_FROM_PACKET( p_packet ) );<BR>+  }<BR>+ }<BR>+ cl_spinlock_release( &p_port->send_lock );<BR>+<BR>+ if( cl_qlist_count( &cancel_list ) )<BR>+ {<BR>+  while( ( p_item = cl_qlist_remove_head( &cancel_list )) <BR>+        != cl_qlist_end( &cancel_list ))<BR>+  {<BR>+   p_packet = IPOIB_PACKET_FROM_LIST_ITEM( p_item );<BR>+   NdisMSendComplete( p_port->p_adapter->h_adapter, <BR>+      p_packet, NDIS_STATUS_REQUEST_ABORTED );<BR>+  }<BR>+ }<BR>+ IPOIB_EXIT( IPOIB_DBG_SEND );<BR>+}<BR>+<BR>+/* use code from ipoib_mac_to_path without lookup for endpt <BR>+*  Useful if endpt is already known.<BR>+*/<BR>+NTSTATUS<BR>+ipoib_endpt_get_path(<BR>+ IN   ipoib_port_t* const   p_port,<BR>+ IN   ipoib_endpt_t* const  p_endpt,<BR>+ OUT   ib_path_rec_t*    p_path )<BR>+{<BR>+ uint8_t   sl;<BR>+ net32_t   flow_lbl;<BR>+ uint8_t   hop_limit;<BR>+<BR>+ IPOIB_ENTER( IPOIB_DBG_ENDPT );<BR>+<BR>+ cl_obj_lock( &p_port->obj );<BR>+<BR>+ if( p_port->p_local_endpt == NULL || <BR>+  p_endpt == NULL )<BR>+ {<BR>+  cl_obj_unlock( &p_port->obj );<BR>+  IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+   ("No local endpoint.\n") );<BR>+  return STATUS_INVALID_PARAMETER;<BR>+ }<BR>+<BR>+ p_path->resv0 = 0;<BR>+ p_path->dgid = p_endpt->dgid;<BR>+ p_path->sgid = p_port->p_local_endpt->dgid;<BR>+ p_path->dlid = p_endpt->dlid;<BR>+ p_path->slid = p_port->p_local_endpt->dlid;<BR>+<BR>+ ib_member_get_sl_flow_hop(<BR>+  p_port->ib_mgr.bcast_rec.sl_flow_hop,<BR>+  &sl,<BR>+  &flow_lbl,<BR>+  &hop_limit<BR>+  );<BR>+ ib_path_rec_set_hop_flow_raw( p_path, hop_limit, flow_lbl, FALSE );<BR>+<BR>+ p_path->tclass = p_port->ib_mgr.bcast_rec.tclass;<BR>+ p_path->num_path = 1;<BR>+ p_path->pkey = p_port->ib_mgr.bcast_rec.pkey;<BR>+ p_path->mtu = p_port->ib_mgr.bcast_rec.mtu;<BR>+ p_path->rate = p_port->ib_mgr.bcast_rec.rate;<BR>+ if( p_path->slid == p_path->dlid )<BR>+  p_path->pkt_life = 0;<BR>+ else<BR>+  p_path->pkt_life = p_port->ib_mgr.bcast_rec.pkt_life;<BR>+ p_path->preference = 0;<BR>+ p_path->resv1 = 0;<BR>+ p_path->resv2 = 0;<BR>+<BR>+ cl_obj_unlock( &p_port->obj );<BR>+<BR>+ IPOIB_EXIT( IPOIB_DBG_ENDPT );<BR>+ return STATUS_SUCCESS;<BR>+}<BR>+<BR>+/* <BR>+*  Put all fragments into separate WR and chain together.<BR>+*  The last WR will be set to generate CQ Event.<BR>+*  lookaside buffer is used for ipoib and ip headers attached to each WR.<BR>+*  Buffer will be released on last WR send completion.<BR>+*/<BR>+static NDIS_STATUS<BR>+__send_fragments(<BR>+IN  ipoib_port_t* const   p_port,<BR>+IN  ipoib_send_desc_t* const p_desc,<BR>+IN  eth_hdr_t* const   p_eth_hdr,<BR>+IN  ip_hdr_t* const    p_ip_hdr,<BR>+IN  uint32_t     buf_len,<BR>+IN  NDIS_BUFFER*    p_ndis_buf )<BR>+{<BR>+ uint32_t ds_idx = 0;<BR>+ uint32_t wr_idx = 0;<BR>+ uint32_t sgl_idx = 2; //skip eth hdr, ip hdr<BR>+ uint32_t options_len = 0;<BR>+ uint8_t* p_options = NULL;<BR>+ uint8_t* p_buf;<BR>+ uint32_t frag_offset = 0;<BR>+ uint32_t next_sge;<BR>+ uint32_t wr_size = 0;<BR>+ uint32_t ip_hdr_len = IP_HEADER_LENGTH( p_ip_hdr );<BR>+ uint32_t total_ip_len = cl_ntoh16( p_ip_hdr->length );<BR>+<BR>+ SCATTER_GATHER_LIST  *p_sgl;<BR>+<BR>+ IPOIB_ENTER( IPOIB_DBG_SEND );<BR>+<BR>+ if( IP_DONT_FRAGMENT(p_ip_hdr) )<BR>+   return NDIS_STATUS_INVALID_PACKET;<BR>+ <BR>+ p_sgl = NDIS_PER_PACKET_INFO_FROM_PACKET( p_desc->p_pkt, ScatterGatherListPacketInfo );<BR>+ if( !p_sgl )<BR>+ {<BR>+  ASSERT( p_sgl );<BR>+  IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+   ("Failed to get SGL from packet.\n") );<BR>+  return NDIS_STATUS_FAILURE;<BR>+ }<BR>+ if( ( p_sgl->NumberOfElements > MAX_SEND_SGE ||<BR>+  p_sgl->Elements[0].Length < sizeof(eth_hdr_t)) )<BR>+ {<BR>+  IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+   ("Too many SG Elements in packet.\n") );<BR>+  return NDIS_STATUS_FAILURE;<BR>+ }<BR>+ p_buf = (uint8_t *)<BR>+  ExAllocateFromNPagedLookasideList( &p_port->buf_mgr.send_buf_list );<BR>+ if( !p_buf )<BR>+ {<BR>+  IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+   ("Failed to allocate lookaside buffer.\n") );<BR>+  return NDIS_STATUS_RESOURCES;<BR>+ }<BR>+ p_desc->p_buf = (send_buf_t*)p_buf;<BR>+<BR>+ /* build first fragment WR */<BR>+ ((ipoib_hdr_t*)p_buf)->type = p_eth_hdr->type;<BR>+ ((ipoib_hdr_t*)p_buf)->resv = 0;<BR>+ p_desc->send_wr[0].local_ds[0].vaddr = cl_get_physaddr( (void *)p_buf );<BR>+ p_desc->send_wr[0].local_ds[0].length = sizeof( ipoib_hdr_t );<BR>+ p_desc->send_wr[0].local_ds[0].lkey = p_port->ib_mgr.lkey;<BR>+ <BR>+ p_buf += sizeof( ipoib_hdr_t );<BR>+<BR>+ if( buf_len < ip_hdr_len )<BR>+ {  /* ip options in a separate buffer */<BR>+  CL_ASSERT( buf_len == sizeof( ip_hdr_t ) );<BR>+  NdisGetNextBuffer( p_ndis_buf, &p_ndis_buf );<BR>+  if( !p_ndis_buf )<BR>+  {<BR>+   IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+    ("Failed to get IP options buffer.\n") );<BR>+   return NDIS_STATUS_FAILURE;<BR>+  }<BR>+  NdisQueryBufferSafe( p_ndis_buf, &p_options, &options_len, NormalPagePriority );<BR>+  if( !p_options )<BR>+  {<BR>+   IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,<BR>+    ("Failed to query IP options buffer address.\n") );<BR>+   return NDIS_STATUS_FAILURE;<BR>+  }<BR>+  cl_memcpy( p_buf, p_ip_hdr, sizeof( ip_hdr_t ) );<BR>+  if( p_options && options_len )<BR>+  { <BR>+   cl_memcpy( &p_buf[sizeof(ip_hdr_t)], p_options, options_len );<BR>+  }<BR>+  wr_size = buf_len + options_len;<BR>+  sgl_idx++;<BR>+ }<BR>+ else<BR>+ {  /*options probably in the same buffer */<BR>+  cl_memcpy( p_buf, p_ip_hdr, buf_len );<BR>+  options_len = ip_hdr_len - sizeof( ip_hdr_t );<BR>+  if( options_len )<BR>+  {<BR>+   p_options = p_buf + sizeof( ip_hdr_t );<BR>+  }<BR>+  frag_offset += ( buf_len - ip_hdr_len );<BR>+  wr_size = buf_len;<BR>+ }<BR>+ ++ds_idx;<BR>+<BR>+ p_desc->send_wr[wr_idx].local_ds[ds_idx].vaddr = cl_get_physaddr( p_buf );<BR>+ p_desc->send_wr[wr_idx].local_ds[ds_idx].lkey = p_port->ib_mgr.lkey;<BR>+ p_desc->send_wr[wr_idx].local_ds[ds_idx].length = wr_size;<BR>+ <BR>+ /* count how much data can be put into the first WR beside IP header.<BR>+  * other protocols headers possibly supplied in subsequent buffers.<BR>+  */<BR>+ for( sgl_idx; sgl_idx < p_sgl->NumberOfElements; sgl_idx++ )<BR>+ {<BR>+  next_sge = p_sgl->Elements[sgl_idx].Length;<BR>+<BR>+  /* add sgl if it can fit into the same WR <BR>+  * Note: so far not going to split large SGE between WRs,<BR>+  * so first fragment could be a smaller size.<BR>+  */<BR>+  if( next_sge <= ( p_port->p_adapter->params.payload_mtu - wr_size ) )<BR>+  {<BR>+   ++ds_idx;<BR>+   wr_size += next_sge;<BR>+   frag_offset += next_sge;<BR>+   p_desc->send_wr[wr_idx].local_ds[ds_idx].vaddr = <BR>+         p_sgl->Elements[sgl_idx].Address.QuadPart;<BR>+   p_desc->send_wr[wr_idx].local_ds[ds_idx].length = next_sge;<BR>+   p_desc->send_wr[wr_idx].local_ds[ds_idx].lkey = p_port->ib_mgr.lkey;<BR>+  }<BR>+  else<BR>+  {<BR>+   /* fix ip hdr for the first fragment and move on */<BR>+   __update_fragment_ip_hdr( (ip_hdr_t* const)p_buf,<BR>+    (uint16_t)wr_size, IP_FRAGMENT_OFFSET(p_ip_hdr), TRUE );<BR>+<BR>+   p_desc->send_wr[wr_idx].wr.num_ds = ds_idx + 1;<BR>+   p_buf += ip_hdr_len;<BR>+   p_buf += (( buf_len > ip_hdr_len ) ? ( buf_len - ip_hdr_len ): 0);<BR>+   frag_offset += ( (IP_FRAGMENT_OFFSET(p_ip_hdr)) << 3 );<BR>+   ++wr_idx;<BR>+   ds_idx = 0;<BR>+   break;<BR>+  }<BR>+ }<BR>+ total_ip_len -= wr_size;<BR>+ wr_size = 0;<BR>+<BR>+ for( sgl_idx, wr_idx; sgl_idx < p_sgl->NumberOfElements; sgl_idx++ )<BR>+ {<BR>+  uint32_t seg_len;<BR>+  uint64_t next_sgl_addr;<BR>+  <BR>+  if( wr_idx >= ( MAX_WRS_PER_MSG - 1 ) )<BR>+   return NDIS_STATUS_RESOURCES;<BR>+  <BR>+  next_sge = p_sgl->Elements[sgl_idx].Length;<BR>+  next_sgl_addr = p_sgl->Elements[sgl_idx].Address.QuadPart;<BR>+<BR>+  while( next_sge )<BR>+  {<BR>+   if( ds_idx == 0 )<BR>+   { /* new ipoib + ip header */<BR>+    ((ipoib_hdr_t*)p_buf)->type = p_eth_hdr->type;<BR>+    ((ipoib_hdr_t*)p_buf)->resv = 0;<BR>+    p_desc->send_wr[wr_idx].local_ds[ds_idx].vaddr = cl_get_physaddr( p_buf );<BR>+    p_desc->send_wr[wr_idx].local_ds[ds_idx].lkey = p_port->ib_mgr.lkey;<BR>+    p_desc->send_wr[wr_idx].local_ds[ds_idx].length = sizeof( ipoib_hdr_t );<BR>+    p_buf += sizeof( ipoib_hdr_t );<BR>+    ++ds_idx;<BR>+<BR>+    cl_memcpy( p_buf, p_ip_hdr, sizeof( ip_hdr_t ) );<BR>+    if( p_options && options_len )<BR>+    {<BR>+     /* copy ip options if needed */<BR>+     __copy_ip_options( &p_buf[sizeof(ip_hdr_t)], <BR>+        p_options, options_len, FALSE );<BR>+    }<BR>+    wr_size = ip_hdr_len;<BR>+   }<BR>+   if( ds_idx == 1 )<BR>+   {<BR>+    p_desc->send_wr[wr_idx].local_ds[ds_idx].length = ip_hdr_len;<BR>+    p_desc->send_wr[wr_idx].local_ds[ds_idx].vaddr = cl_get_physaddr( p_buf );<BR>+    p_desc->send_wr[wr_idx].local_ds[ds_idx].lkey = p_port->ib_mgr.lkey;<BR>+    ++ds_idx;<BR>+   }<BR>+<BR>+   seg_len = ( next_sge > ( p_port->p_adapter->params.payload_mtu - wr_size ) )?<BR>+    ( p_port->p_adapter->params.payload_mtu - wr_size ) : next_sge;<BR>+<BR>+   p_desc->send_wr[wr_idx].local_ds[ds_idx].vaddr = next_sgl_addr;<BR>+   p_desc->send_wr[wr_idx].local_ds[ds_idx].length = seg_len;<BR>+   p_desc->send_wr[wr_idx].local_ds[ds_idx].lkey = p_port->ib_mgr.lkey;<BR>+   ++ds_idx;<BR>+   <BR>+   wr_size += seg_len;<BR>+   total_ip_len -= seg_len;<BR>+<BR>+   if( wr_size >= p_port->p_adapter->params.payload_mtu || total_ip_len == 0 )<BR>+   { /* fix ip hdr for that fragment */<BR>+    __update_fragment_ip_hdr( (ip_hdr_t* const)p_buf, (uint16_t)wr_size,<BR>+     ((uint16_t)(frag_offset >> 3 )), <BR>+     (BOOLEAN)(( total_ip_len > 0 ) || IP_MORE_FRAGMENTS( p_ip_hdr)) );<BR>+    p_desc->send_wr[wr_idx].wr.num_ds = ds_idx;<BR>+    if( total_ip_len > 0 )<BR>+    {<BR>+     ++wr_idx;<BR>+     frag_offset += (wr_size - ip_hdr_len);<BR>+     wr_size = 0;<BR>+     ds_idx = 0;<BR>+     p_buf += ip_hdr_len;<BR>+    }<BR>+   }<BR>+   next_sge -= seg_len;<BR>+   if( next_sge > 0 )<BR>+   {<BR>+    next_sgl_addr += seg_len;<BR>+   }<BR>+  }<BR>+ }<BR>+ p_desc->num_wrs += wr_idx;<BR>+ <BR>+ IPOIB_EXIT( IPOIB_DBG_SEND );<BR>+ return NDIS_STATUS_SUCCESS;<BR>+}<BR>+<BR>+static void<BR>+__update_fragment_ip_hdr(<BR>+IN  ip_hdr_t* const  p_ip_hdr,<BR>+IN  uint16_t   fragment_size, <BR>+IN  uint16_t   fragment_offset, <BR>+IN  BOOLEAN    more_fragments )<BR>+{<BR>+<BR>+ p_ip_hdr->length = cl_hton16( fragment_size ); // bytes<BR>+ p_ip_hdr->offset = cl_hton16( fragment_offset ); // 8-byte units<BR>+ if( more_fragments )<BR>+ {<BR>+  IP_SET_MORE_FRAGMENTS( p_ip_hdr );<BR>+ }<BR>+ else<BR>+ {<BR>+  IP_SET_LAST_FRAGMENT( p_ip_hdr );<BR>+ }<BR>+ p_ip_hdr->chksum = 0;<BR>+ p_ip_hdr->chksum = ipchksum( (uint16_t*)p_ip_hdr, IP_HEADER_LENGTH(p_ip_hdr) );<BR>+}<BR>+<BR>+static void<BR>+__copy_ip_options(<BR>+IN  uint8_t* p_buf,<BR>+IN  uint8_t* p_options,<BR>+IN  uint32_t options_len,<BR>+IN  BOOLEAN  copy_all )<BR>+{<BR>+ uint32_t option_length;<BR>+ uint32_t total_length = 0;<BR>+ uint32_t copied_length = 0;<BR>+ uint8_t* p_src = p_options;<BR>+ uint8_t* p_dst = p_buf;<BR>+<BR>+ if( p_options == NULL || options_len == 0 )<BR>+  return;<BR>+ if( copy_all )<BR>+ {<BR>+  cl_memcpy( p_dst, p_src, options_len );<BR>+  return;<BR>+ }<BR>+ do<BR>+ {<BR>+  if( ( *p_src ) == 0 ) // end of options list<BR>+  {<BR>+   total_length++;<BR>+   break;<BR>+  }<BR>+  if( ( *p_src ) == 0x1 ) // no op<BR>+  {<BR>+   p_src++;<BR>+   total_length++;<BR>+   continue;<BR>+  }<BR>+  /*from RFC791: <BR>+  * This option may be used between options, for example, to align<BR>+        * the beginning of a subsequent option on a 32 bit boundary.<BR>+  */<BR>+  if( copied_length && (copied_length % 4) )<BR>+  {<BR>+   uint32_t align = 4 - (copied_length % 4);<BR>+   cl_memset( p_dst, 0x1, (size_t)align );<BR>+   p_dst += align;<BR>+   copied_length += align;<BR>+  }<BR>+  option_length = *(p_src + 1);<BR>+<BR>+  if( *p_src & 0x80 )<BR>+  {<BR>+   cl_memcpy( p_dst, p_src, option_length );<BR>+   p_dst += option_length;<BR>+   copied_length += option_length;<BR>+  }<BR>+  total_length += option_length;<BR>+  p_src += option_length;<BR>+<BR>+ }while( total_length < options_len );<BR>+<BR>+ CL_ASSERT( total_length == options_len );<BR>+ CL_ASSERT( copied_length <= 40 );<BR>+<BR>+ /* padding the rest */<BR>+ if( options_len > copied_length )<BR>+ {<BR>+  cl_memclr( p_dst, ( options_len - copied_length ) );<BR>+ }<BR>+ return;<BR>+}<BR>Index: ulp/ipoib/kernel/ipoib_port.h<BR>===================================================================<BR>--- ulp/ipoib/kernel/ipoib_port.h (revision 1776)<BR>+++ ulp/ipoib/kernel/ipoib_port.h (working copy)<BR>@@ -42,8 +42,8 @@<BR> #include <complib/cl_qmap.h><BR> #include <complib/cl_fleximap.h><BR> #include <ip_packet.h><BR>+#include "ipoib_xfr_mgr.h"<BR> #include "ipoib_endpoint.h"<BR>-#include "ipoib_xfr_mgr.h"<BR> <BR> <BR> /*<BR>@@ -51,11 +51,6 @@<BR>  */<BR> #define IPOIB_INLINE_RECV 1<BR> <BR>-<BR>-/* Max send data segment list size. */<BR>-#define MAX_SEND_SGE 30 //TODO optimize this value<BR>-<BR>-<BR> /* <BR>  *  Invalid pkey index<BR>  */<BR>@@ -75,7 +70,7 @@<BR> #define IPOIB_ENDPT_FROM_PACKET( P ) \<BR>  (((ipoib_endpt_t**)P->MiniportReservedEx)[1])<BR> #define IPOIB_RECV_FROM_PACKET( P ) \<BR>- (((ipoib_recv_desc_t**)P->MiniportReservedEx)[1])<BR>+ (((void **)P->MiniportReservedEx)[1])<BR> #define IPOIB_SEND_FROM_PACKET( P )  \<BR>  (((send_buf_t**)P->MiniportReservedEx)[2])<BR> #define IPOIB_PACKET_FROM_LIST_ITEM( I ) \<BR>@@ -92,6 +87,7 @@<BR>  ib_cq_handle_t   h_send_cq;<BR>  ib_qp_handle_t   h_qp;<BR>  ib_query_handle_t  h_query;<BR>+ ib_srq_handle_t   h_srq;<BR>  net32_t     qpn;<BR> <BR>  ib_mr_handle_t   h_mr;<BR>@@ -188,7 +184,7 @@<BR>  ipoib_hdr_t  hdr;<BR>  union _payload<BR>  {<BR>-  uint8_t   data[MAX_PAYLOAD_MTU];<BR>+  uint8_t   data[MAX_UD_PAYLOAD_MTU];<BR>   ipoib_arp_pkt_t arp;<BR>   ip_pkt_t  ip;<BR> <BR>@@ -275,7 +271,7 @@<BR> */<BR> typedef union _send_buf<BR> {<BR>- uint8_t   data[MAX_PAYLOAD_MTU];<BR>+ uint8_t   data[MAX_UD_PAYLOAD_MTU];<BR>  ipoib_arp_pkt_t arp;<BR>  ip_pkt_t  ip;<BR> <BR>@@ -326,11 +322,29 @@<BR> {<BR>  PKT_TYPE_UCAST,<BR>  PKT_TYPE_BCAST,<BR>- PKT_TYPE_MCAST<BR>+ PKT_TYPE_MCAST,<BR>+ PKT_TYPE_CM_UCAST<BR> <BR> } ipoib_pkt_type_t;<BR> <BR>+typedef struct _ipoib_cm_desc<BR>+{<BR>+ cl_pool_item_t    item; /* Must be first. */<BR>+ uint32_t     len;<BR>+ ipoib_pkt_type_t   type;<BR>+ ib_recv_wr_t    wr;<BR>+ ib_local_ds_t    local_ds[2];<BR>+ cl_list_item_t    list_item;<BR>+ uint8_t*     p_alloc_buf;<BR>+ uint8_t*     p_buf;<BR>+ uint32_t     alloc_buf_size;<BR>+ uint32_t     buf_size;<BR>+ net32_t      lkey;<BR>+ ib_mr_handle_t    h_mr;<BR>+ NDIS_TCP_IP_CHECKSUM_PACKET_INFO ndis_csum;<BR> <BR>+} ipoib_cm_desc_t;<BR>+<BR> typedef struct _ipoib_recv_desc<BR> {<BR>  cl_pool_item_t  item; /* Must be first. */<BR>@@ -373,16 +387,27 @@<BR> * The pool item is always first to allow casting form a cl_pool_item_t or<BR> * cl_list_item_t to the descriptor.<BR> *********/<BR>+typedef struct __ipoib_send_wr<BR>+{<BR>+ ib_send_wr_t  wr;<BR>+ ib_local_ds_t  local_ds[MAX_SEND_SGE]; /* Must be last. */<BR>+} ipoib_send_wr_t;<BR> <BR>+typedef enum __send_dir<BR>+{<BR>+ SEND_UD_QP = 1,<BR>+ SEND_RC_QP = 2<BR>+} send_dir_t;<BR> <BR> typedef struct _ipoib_send_desc<BR> {<BR>  NDIS_PACKET   *p_pkt;<BR>- ipoib_endpt_t  *p_endpt1;<BR>+ ipoib_endpt_t  *p_endpt;<BR>  send_buf_t   *p_buf;<BR>- ib_send_wr_t  wr;<BR>- ipoib_hdr_t   pkt_hdr;<BR>- ib_local_ds_t  local_ds[MAX_SEND_SGE]; /* Must be last. */<BR>+ ib_qp_handle_t  send_qp;<BR>+ send_dir_t   send_dir;<BR>+ uint32_t   num_wrs;<BR>+ ipoib_send_wr_t  send_wr[MAX_WRS_PER_MSG];<BR> <BR> } ipoib_send_desc_t;<BR> /*<BR>@@ -461,7 +486,14 @@<BR>  cl_qmap_t    mac_endpts;<BR>  cl_fmap_t    gid_endpts;<BR>  cl_qmap_t    lid_endpts;<BR>-<BR>+ cl_fmap_t    conn_endpts;<BR>+ LIST_ENTRY     pending_conns;<BR>+ LIST_ENTRY    remove_conns;<BR>+ NDIS_SPIN_LOCK    conn_lock;<BR>+ NDIS_SPIN_LOCK   remove_lock;<BR>+ cl_thread_t    h_thread;<BR>+ cl_event_t    event;<BR>+ uint32_t    thread_is_done;<BR> } ipoib_endpt_mgr_t;<BR> /*<BR> * FIELDS<BR>@@ -474,6 +506,9 @@<BR> * lid_endpts<BR> *  Map of enpoints, keyed by LID.  Only enpoints on the same subnet<BR> *  are inserted in the LID map.<BR>+*<BR>+* conn_endpts<BR>+*  Map of connected endpts, keyed by remote gid.<BR> *********/<BR> <BR> <BR>@@ -506,8 +541,11 @@<BR> <BR>  ipoib_endpt_mgr_t  endpt_mgr;<BR> <BR>+ endpt_buf_mgr_t   cm_buf_mgr;<BR>+ endpt_recv_mgr_t  cm_recv_mgr;<BR>+<BR>  ipoib_endpt_t   *p_local_endpt;<BR>-<BR>+ ib_ca_attr_t   *p_ca_attrs;<BR> #if DBG<BR>  atomic32_t    ref[ref_array_size];<BR> #endif<BR>@@ -632,6 +670,12 @@<BR>  IN    ipoib_port_t *    p_port,<BR>  IN    int      type);<BR> <BR>+NTSTATUS<BR>+ipoib_endpt_get_path(<BR>+ IN   ipoib_port_t* const   p_port,<BR>+ IN   ipoib_endpt_t* const  p_endpt,<BR>+ OUT   ib_path_rec_t*    p_path );<BR>+<BR> #if DBG<BR> // This function is only used to monitor send failures<BR> static inline VOID NdisMSendCompleteX(<BR>@@ -649,4 +693,91 @@<BR> #define NdisMSendCompleteX NdisMSendComplete<BR> #endif<BR> <BR>+ipoib_endpt_t*<BR>+ipoib_endpt_get_by_gid(<BR>+ IN    ipoib_port_t* const   p_port,<BR>+ IN  const ib_gid_t* const    p_gid );<BR>+<BR>+ipoib_endpt_t*<BR>+ipoib_endpt_get_by_lid(<BR>+ IN    ipoib_port_t* const   p_port,<BR>+ IN  const net16_t      lid );<BR>+<BR>+ib_api_status_t<BR>+ipoib_port_srq_init(<BR>+ IN  ipoib_port_t* const  p_port );<BR>+<BR>+void<BR>+ipoib_port_srq_destroy( <BR>+ IN  ipoib_port_t* const  p_port );<BR>+<BR>+ib_api_status_t<BR>+ipoib_port_listen(<BR>+  IN  ipoib_port_t* const  p_port );<BR>+<BR>+ib_api_status_t<BR>+ipoib_port_cancel_listen(<BR>+ IN  ipoib_port_t* const p_port,<BR>+ IN  ipoib_endpt_t* const p_endpt );<BR>+<BR>+ib_api_status_t<BR>+endpt_cm_buf_mgr_init(<BR>+ IN  ipoib_port_t* const   p_port );<BR>+<BR>+void<BR>+endpt_cm_buf_mgr_destroy(<BR>+ IN  ipoib_port_t* const  p_port );<BR>+<BR>+void<BR>+endpt_cm_buf_mgr_reset(<BR>+ IN  ipoib_port_t* const  p_port );<BR>+<BR>+void<BR>+endpt_cm_buf_mgr_put_recv(<BR>+ IN  endpt_buf_mgr_t * const  p_buf_mgr,<BR>+ IN  ipoib_cm_desc_t* const  p_desc );<BR>+<BR>+void<BR>+endpt_cm_buf_mgr_put_recv_list(<BR>+ IN  endpt_buf_mgr_t * const  p_buf_mgr,<BR>+ IN  cl_qlist_t* const   p_list );<BR>+<BR>+uint32_t<BR>+endpt_cm_recv_mgr_build_pkt_array(<BR>+ IN  ipoib_port_t* const   p_port,<BR>+ IN  ipoib_endpt_t* const  p_endpt,<BR>+ IN  cl_qlist_t* const   p_done_list,<BR>+ IN OUT uint32_t*     p_bytes_recv );<BR>+<BR>+ib_api_status_t<BR>+endpt_cm_post_recv(<BR>+ IN  ipoib_port_t* const   p_port );<BR>+<BR>+void<BR>+endpt_cm_destroy_conn(<BR>+ IN  ipoib_port_t* const   p_port,<BR>+ IN  ipoib_endpt_t* const  p_endpt );<BR>+<BR>+void<BR>+endpt_cm_disconnect(<BR>+ IN  ipoib_port_t* const  p_port,<BR>+ IN  ipoib_endpt_t* const  p_endpt );<BR>+void<BR>+endpt_cm_flush_recv(<BR>+ IN    ipoib_port_t* const  p_port,<BR>+ IN    ipoib_endpt_t* const p_endpt );<BR>+<BR>+ib_api_status_t<BR>+ipoib_recv_dhcp(<BR>+ IN    ipoib_port_t* const   p_port,<BR>+ IN  const ipoib_pkt_t* const   p_ipoib,<BR>+  OUT   eth_pkt_t* const   p_eth,<BR>+ IN    ipoib_endpt_t* const  p_src,<BR>+ IN    ipoib_endpt_t* const  p_dst );<BR>+<BR>+void<BR>+ipoib_port_cancel_xmit(<BR>+ IN    ipoib_port_t* const  p_port,<BR>+ IN    PVOID      cancel_id );<BR>+<BR> #endif /* _IPOIB_PORT_H_ */<BR>Index: ulp/ipoib/kernel/ipoib_xfr_mgr.h<BR>===================================================================<BR>--- ulp/ipoib/kernel/ipoib_xfr_mgr.h (revision 1776)<BR>+++ ulp/ipoib/kernel/ipoib_xfr_mgr.h (working copy)<BR>@@ -97,7 +97,7 @@<BR> ipoib_addr_get_flags(<BR>  IN  const ipoib_hw_addr_t* const  p_addr )<BR> {<BR>- return (uint8_t)(cl_ntoh32( p_addr->flags_qpn ) >> 24);<BR>+ return (uint8_t)( p_addr->flags_qpn & 0x000000ff);<BR> }<BR> <BR> static inline void<BR>@@ -105,15 +105,15 @@<BR>  IN    ipoib_hw_addr_t* const  p_addr,<BR>  IN  const uint8_t      flags )<BR> {<BR>- p_addr->flags_qpn &= cl_ntoh32( 0xFFFFFF00 );<BR>- p_addr->flags_qpn |= cl_ntoh32( flags );<BR>+ p_addr->flags_qpn &= ( 0xFFFFFF00 );<BR>+ p_addr->flags_qpn |= ( flags );<BR> }<BR> <BR> static inline net32_t<BR> ipoib_addr_get_qpn(<BR>  IN  const ipoib_hw_addr_t* const  p_addr )<BR> {<BR>- return cl_ntoh32( cl_ntoh32( p_addr->flags_qpn ) >> 8 );<BR>+ return( ( p_addr->flags_qpn ) & 0xffffff00 );<BR> }<BR> <BR> static inline void<BR>@@ -121,10 +121,19 @@<BR>  IN    ipoib_hw_addr_t* const  p_addr,<BR>  IN  const net32_t      qpn )<BR> {<BR>- p_addr->flags_qpn = cl_ntoh32( (cl_ntoh32(<BR>-  p_addr->flags_qpn ) & 0x000000FF ) | (cl_ntoh32( qpn ) << 8) );<BR>+ p_addr->flags_qpn &= ( 0x000000FF );<BR>+ p_addr->flags_qpn |= qpn ;<BR> }<BR> <BR>+static inline void<BR>+ipoib_addr_set_sid(<BR>+ IN net64_t* const  p_sid,<BR>+ IN const net32_t  qpn )<BR>+{<BR>+ *p_sid = qpn;<BR>+ *p_sid <<= 32;<BR>+ *p_sid |= IPOIB_CM_FLAG_SVCID;<BR>+}<BR> <BR> /****f* IPOIB/ipoib_mac_from_sst_guid<BR> * NAME<BR>Index: ulp/ipoib/kernel/netipoib-xp32.inf<BR>===================================================================<BR>--- ulp/ipoib/kernel/netipoib-xp32.inf (revision 1776)<BR>+++ ulp/ipoib/kernel/netipoib-xp32.inf (working copy)<BR>@@ -138,7 +138,7 @@<BR> HKR, Ndi\Params\PayloadMtu,  Type,  0, "dword"<BR> HKR, Ndi\Params\PayloadMtu,  Default, 0, "2044"<BR> HKR, Ndi\Params\PayloadMtu,  Min,  0, "512"<BR>-HKR, Ndi\Params\PayloadMtu,  Max,  0, "4092"<BR>+HKR, Ndi\Params\PayloadMtu,  Max,  0, "65520"<BR> <BR> HKR, Ndi\Params\MCLeaveRescan,  ParamDesc, 0, %MC_RESCAN_STR%<BR> HKR, Ndi\Params\MCLeaveRescan,  Type,  0, "dword"<BR>@@ -161,6 +161,12 @@<BR> HKR, Ndi\Params\BCJoinRetry,  Min,  0, "0"<BR> HKR, Ndi\Params\BCJoinRetry,  Max,  0, "1000"<BR> <BR>+HKR, Ndi\Params\CmEnabled,  ParamDesc, 0, %CONNECTED_MODE_STR%<BR>+HKR, Ndi\Params\CmEnabled,  Type,  0, "enum"<BR>+HKR, Ndi\Params\CmEnabled,  Default, 0, "0"<BR>+HKR, Ndi\Params\CmEnabled,  Optional, 0, "0"<BR>+HKR, Ndi\Params\CmEnabled\enum, "0", 0, %DISABLED_STR%<BR>+HKR, Ndi\Params\CmEnabled\enum, "1", 0, %ENABLED_STR%<BR> <BR> [IpoibService]<BR> DisplayName     = %IpoibServiceDispName%<BR>@@ -261,4 +267,5 @@<BR> ENABLED_IF_STR  = "Enabled (if supported by HW)"<BR> ENABLED_STR  = "Enabled"<BR> DISABLED_STR  = "Disabled"<BR>-BYPASS_STR  = "Bypass"<BR>\ No newline at end of file<BR>+BYPASS_STR  = "Bypass"<BR>+CONNECTED_MODE_STR = "Connected mode"<BR>Index: ulp/ipoib/kernel/netipoib.inx<BR>===================================================================<BR>--- ulp/ipoib/kernel/netipoib.inx (revision 1776)<BR>+++ ulp/ipoib/kernel/netipoib.inx (working copy)<BR>@@ -141,7 +141,7 @@<BR> HKR, Ndi\Params\PayloadMtu,  Type,  0, "dword"<BR> HKR, Ndi\Params\PayloadMtu,  Default, 0, "2044"<BR> HKR, Ndi\Params\PayloadMtu,  Min,  0, "512"<BR>-HKR, Ndi\Params\PayloadMtu,  Max,  0, "4092"<BR>+HKR, Ndi\Params\PayloadMtu,  Max,  0, "65520"<BR> <BR> HKR, Ndi\Params\MCLeaveRescan,  ParamDesc, 0, %MC_RESCAN_STR%<BR> HKR, Ndi\Params\MCLeaveRescan,  Type,  0, "dword"<BR>@@ -164,6 +164,12 @@<BR> HKR, Ndi\Params\BCJoinRetry,  Min,  0, "0"<BR> HKR, Ndi\Params\BCJoinRetry,  Max,  0, "1000"<BR> <BR>+HKR, Ndi\Params\CmEnabled,  ParamDesc, 0, %CONNECTED_MODE_STR%<BR>+HKR, Ndi\Params\CmEnabled,  Type,  0, "enum"<BR>+HKR, Ndi\Params\CmEnabled,  Default, 0, "0"<BR>+HKR, Ndi\Params\CmEnabled,  Optional, 0, "0"<BR>+HKR, Ndi\Params\CmEnabled\enum, "0", 0, %DISABLED_STR%<BR>+HKR, Ndi\Params\CmEnabled\enum, "1", 0, %ENABLED_STR%<BR> <BR> [IpoibService]<BR> DisplayName     = %IpoibServiceDispName%<BR>@@ -268,4 +274,5 @@<BR> ENABLED_IF_STR  = "Enabled (if supported by HW)"<BR> ENABLED_STR  = "Enabled"<BR> DISABLED_STR  = "Disabled"<BR>-BYPASS_STR  = "Bypass"<BR>\ No newline at end of file<BR>+BYPASS_STR  = "Bypass"<BR>+CONNECTED_MODE_STR = "Connected mode"<BR>\ No newline at end of file<BR>Index: ulp/ipoib/kernel/SOURCES<BR>===================================================================<BR>--- ulp/ipoib/kernel/SOURCES (revision 1776)<BR>+++ ulp/ipoib/kernel/SOURCES (working copy)<BR>@@ -23,7 +23,8 @@<BR>   ipoib_adapter.c \<BR>   ipoib_endpoint.c \<BR>   ipoib_port.c \<BR>-  ipoib_ibat.c<BR>+  ipoib_ibat.c \<BR>+  ipoib_cm.c<BR> <BR> INCLUDES=..;..\..\..\inc;..\..\..\inc\kernel;<BR> <BR></P></BODY></HTML>