<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>