--- A/ulp/ipoib_NDIS6_CM/kernel/ipoib_port.h	Tue Jan 11 17:54:42 2011
+++ B/ulp/ipoib_NDIS6_CM/kernel/ipoib_port.h	Tue Jan 11 16:54:23 2011
@@ -72,6 +72,10 @@
 #define IPOIB_RECV_FROM_NBL( P )	\
 	(((ipoib_recv_desc_t**)NET_BUFFER_LIST_MINIPORT_RESERVED(P))[0])
 	
+//Used in CM RECV flow
+#define IPOIB_CM_RECV_FROM_NBL( P )	\
+	(((ipoib_cm_recv_desc_t**)NET_BUFFER_LIST_MINIPORT_RESERVED(P))[0])
+	
 //Used in CM SEND flow - to update
 #define IPOIB_LIST_ITEM_FROM_NBL( P ) \
 	((cl_list_item_t*)NET_BUFFER_LIST_MINIPORT_RESERVED(P))
@@ -102,6 +106,7 @@
 	ib_qp_handle_t			h_qp;
 	ib_query_handle_t		h_query;
 	ib_srq_handle_t			h_srq;
+	atomic32_t				srq_qp_cnt;
 	net32_t					qpn;
 
 	ib_mr_handle_t			h_mr;
@@ -126,11 +131,20 @@
 *		Send CQ handle.
 *
 *	h_qp
-*		QP handle for data transfers.
+*		QP handle for UD data transfers.
 *
 *	h_query
 *		Query handle for cancelling SA queries.
 *
+*	h_srq
+*		SRQ (Shared Receive Queue) handle
+*
+*	srq_qp_cnt
+*		number of QPs bound to the SRQ
+*
+*	qpn
+*		local QP number in net byte-order.
+*
 *	h_mr
 *		Registration handle for all of physical memory.  Used for
 *		send/receive buffers to simplify growing the receive pool.
@@ -138,6 +152,9 @@
 *	lkey
 *		LKey for the memory region.
 *
+*	rate
+*		port rate
+*
 *	bcast_rec
 *		Cached information about the broadcast group, used to specify
 *		parameters used to join other multicast groups.
@@ -337,8 +354,8 @@
 *
 *	send_buf_list
 *		Lookaside list for dynamically allocating send buffers for send
-*		that require copies (ARP, DHCP, and any with more physical pages
-*		than can fit in the local data segments).
+*		operations which require copies (ARP, DHCP, IP fragmentation and any with more
+*		physical pages than can fit in the local data segments).
 *********/
 
 typedef enum _ipoib_pkt_type
@@ -350,31 +367,101 @@
 
 }	ipoib_pkt_type_t;
 
-typedef struct _ipoib_cm_desc
+
+typedef enum __ib_recv_mode
 {
-	cl_pool_item_t				item;	/* Must be first. */
-	uint32_t					len;
-	ipoib_pkt_type_t			type;
-	ib_recv_wr_t				wr;
-	ib_local_ds_t				local_ds[2];
-	cl_list_item_t				list_item;
-	uint8_t*					p_alloc_buf;
-	uint8_t*					p_buf;
-	uint32_t					alloc_buf_size;
-	uint32_t					buf_size;
-	net32_t						lkey;
-	ib_mr_handle_t				h_mr;
-	NDIS_TCP_IP_CHECKSUM_PACKET_INFO	ndis_csum;
+	RECV_UD = 1,
+	RECV_RC = 2
+
+}	ib_recv_mode_t;
 
-}	ipoib_cm_desc_t;
+
+
+typedef struct _ipoib_cm_recv_desc
+{
+	cl_pool_item_t			item;	/* Must be first. */
+	uint32_t				len;
+	ipoib_pkt_type_t		type;
+	ib_recv_mode_t			recv_mode;/* matches ipoib_recv_desc_t to this offset */
+	ib_recv_wr_t			wr;
+	ib_local_ds_t			local_ds[MAX_CM_RECV_SGE];	/* 1 ds_local / phys page */
+	cl_list_item_t			list_item;
+	ipoib_endpt_t*			p_endpt;
+	uint8_t*				p_alloc_buf;
+	uint8_t*				p_buf;
+	uint32_t				alloc_buf_size;
+	uint32_t				buf_size;
+	NET_BUFFER_LIST*		p_NBL;
+	MDL*					p_mdl;	
+	NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csum;
+
+}	ipoib_cm_recv_desc_t;
+/*
+* FIELDS
+*	item
+*		Pool item for storing descriptors in a pool.
+*
+*	len
+*		Length to indicate to NDIS.  This is different than the length of the
+*		received data as some data is IPoIB specific and filtered out.
+*
+*	type
+*		Type of packet, used in filtering received packets against the packet
+*		filter.  Also used to update stats.
+*
+*	recv_mode
+*		IB connection mode RC(reliable connection) or UD(datagram)
+*
+*	wr
+*		Receive work request.
+*
+*	local_ds
+*		Local data segments.  The second segment is only used if a buffer
+*		spans physical pages.
+*
+*	list_item
+*		used when this recv desc is on the recv list (valid data)
+*
+*	p_endpt
+*		remote endpoint struct
+*
+*	p_alloc_buf
+*		allocated receive buffer start address; also start of Ethernet header.
+*
+*	p_buf
+*		Buffer for the CM receive as p_aloc_buf+OFFSET == p_buf, due to adding Enet
+*		header in front of received ipoib CM data. ipoib_hdeader_t is overlayed
+*		by the synthesized ethernet header prior to passing buffer to NDIS receive
+*		routine.
+*
+*	p_alloc_buf_size
+*		actual byte size of allocated buffer.
+*
+*	buf_size
+*		byte size from p_buf to end of allocated buffer.
+*
+*	p_NBL
+*		allocated NBL (NetworkBufferList)
+*
+*	p_MDL
+*		allocated MDL (Memory Descriptor List) for p_buf - sizeof(eth_hdr)
+*
+*	csum
+*		hardware utilized checksum status block.
+*/
 
 typedef struct _ipoib_recv_desc
 {
 	cl_pool_item_t		item;	/* Must be first. */
 	uint32_t			len;
 	ipoib_pkt_type_t	type;
+	ib_recv_mode_t		recv_mode;	/* matches ipoib_cm_recv_desc_t to this offset */
 	ib_recv_wr_t		wr;
 	ib_local_ds_t		local_ds[2];
+#if UD_NBL_IN_DESC
+	NET_BUFFER_LIST		*p_NBL;
+	MDL					*p_mdl;	
+#endif
 	NDIS_TCP_IP_CHECKSUM_PACKET_INFO	ndis_csum;
 #if IPOIB_INLINE_RECV
 	recv_buf_t			buf;
@@ -396,6 +483,9 @@
 *		Type of packet, used in filtering received packets against the packet
 *		filter.  Also used to update stats.
 *
+*	recv_mode
+*		IB recv mode: RC(reliable connection) or UD(datagram)
+*
 *	wr
 *		Receive work request.
 *
@@ -403,6 +493,9 @@
 *		Local data segments.  The second segment is only used if a buffer
 *		spans physical pages.
 *
+*	ndis_csum
+*		hardware utilized checksum status block.
+*
 *	buf
 *		Buffer for the receive.
 *
@@ -418,42 +511,28 @@
 	ib_local_ds_t		local_ds[MAX_SEND_SGE];	/* Must be last. */
 } ipoib_send_wr_t;
 
-typedef enum __send_dir
-{
-	SEND_UD_QP = 1,
-	SEND_RC_QP = 2
-} send_dir_t;
 
 typedef struct _ipoib_send_desc
 {
 	PNET_BUFFER_LIST    p_netbuf_list;
-	ipoib_endpt_t		*p_endpt;
 	ib_qp_handle_t		send_qp;
-	send_dir_t			send_dir;
 	uint32_t			num_wrs;
 	ipoib_send_wr_t		send_wr[MAX_WRS_PER_MSG];
 
 }	ipoib_send_desc_t;
 /*
 * FIELDS
-*	p_pkt
-*		Pointer to the NDIS_PACKET associated with the send operation.
-*
-*	p_endpt
-*		Endpoint for this send.
+*	p_netbuf_list
+*		Pointer to the NET_BUFFER_LIST associated with the send operation.
 *
-*	p_buf
-*		Buffer for the send, if allocated.
-*
-*	wr
-*		Send work request.
+*	send_qp
+*		QP on which to Send work request.
 *
-*	pkt_hdr
-*		IPoIB packet header, pointed to by the first local datasegment.
+*	num_wrs
+*		count of work-requests (in send_wr) linked together.
 *
-*	local_ds
-*		Local data segment array.  Placed last to allow allocating beyond the
-*		end of the descriptor for additional datasegments.
+*	send_wr
+*		Vector of IB work requests
 *
 * NOTES
 *	The pool item is always first to allow casting form a cl_pool_item_t or
@@ -478,7 +557,7 @@
 *
 *	done_list
 *		List of receive descriptors (ipoib_desc_t) polled from the RX CQ which
-*		are used to construct the recv_NBL_array, which is then used to indicated
+*		are used to construct the recv_NBL_array; array is then used to indicate
 *		received packets to NDIS 6.
 *********/
 
@@ -616,8 +695,7 @@
 	ipoib_send_desc_t *		p_desc;
 
 	ipoib_endpt_mgr_t		endpt_mgr;
-	endpt_buf_mgr_t			cm_buf_mgr;
-	endpt_recv_mgr_t		cm_recv_mgr;
+	cm_buf_mgr_t			cm_buf_mgr;
 
 	ipoib_endpt_t			*p_local_endpt;
 	ib_ca_attr_t			*p_ca_attrs;
@@ -635,6 +713,7 @@
 	ib_net16_t				base_lid;
 	LONG					n_no_progress;
 	PIO_WORKITEM			pPoWorkItem;
+	PIO_WORKITEM			pPoWorkItemCM;
 	ipoib_hdr_t				hdr[1];	/* Must be last! */
 
 }	ipoib_port_t;
@@ -653,10 +732,10 @@
 *		State of the port object.  Tracks QP state fairly closely.
 *
 *	recv_lock
-*		Spinlock to protect receive operations.
+*		Spinlock to protect UD receive operations.
 *
 *	send_lock
-*		Spinlock to protect send operations.
+*		Spinlock to protect UD/RC send operations from NDIS callback.
 *
 *	p_adapter
 *		Parent adapter.  Used to get AL handle.
@@ -667,17 +746,73 @@
 *	max_sq_sge_supported
 *		The actual number of SGEs that will be used for UD QP
 *
+*	sa_event
+*		Event signalled on SA query completion.
+*
+*	mcast_cnt
+*		count of mcast group members
+*
+*	leave_mcast_event
+*		event signalled upon leaving mcast group
+*
 *	ib_mgr
 *		IB resource manager.
 *
-*	recv_mgr
-*		Receive manager.
+*	ipoib_buf_mgr
+*		send/recv buffer pools
 *
 *	send_mgr
 *		Send manager.
 *
+*	recv_mgr
+*		Recv manager.
+*
+*	p_desc
+*		send descriptor used by all send operations (serialization point).
+*
 *	endpt_mgr
-*		Endpoint manager.
+*		Endpoint manager
+*
+*	cm_buf_mgr
+*		Connected Mode SRQ recv buffer mgr.
+*
+*	p_local_endpoint
+*		our local endpoint description
+*	p_ca_attrs
+*		HCA attributes for this port
+*
+*	ref
+*		object reference count tracking
+*	endpt_rdr
+*		endpoint reader semaphore
+*
+*	hdr_idx
+*		ipoib header array hdr[] index.
+*
+*	pkey_index
+*
+*	gc_dpc
+*		garbage collector DPC thread.
+*
+*	gc_timer
+*		timer which starts periodic running of gc thread.
+*
+*	bc_join_retry
+*		broadcast join_retry_cnt
+*
+*	base_lid
+*		port's base LID
+*
+*	n_no_progress
+*
+*	pPoWorkItem
+*		DPC recv offload to worker thread
+*
+*	pPoWorkItemCM
+*		DPC recv offload to worker thread for Connected Mode
+*		
+*	hdr
+*		ipoib header array - 1 entry per outstanding send: UD or RC; see hdr_idx.
 *********/
 typedef struct _sgl_context
 {
@@ -702,11 +837,44 @@
 	PNET_BUFFER_LIST		p_nbl;
 	PNET_BUFFER				p_curr_nb;
 	ipoib_endpt_t			*p_endpt;
+	ipoib_send_desc_t 		*p_send_desc;
 	send_buf_t				*p_send_buf;
 	PSCATTER_GATHER_LIST	p_sgl;
 	UINT					tcp_payload;
 	PVOID					p_sg_buf;
 } ipoib_send_NB_SG;
+/*
+* FIELDS
+*
+*	pool_item
+*		for storing descriptors in the send_mgr.send_pool.
+*
+*	p_port
+*		HCA port which send is going out on.
+*
+*	p_nbl
+*		Net buffer list - data passed down from NDIS to xmit
+*
+*	p_cur_nb
+*		current list item in p_nbl list.
+*
+*	p_endpt
+*		sending (aka local) endpoint & link to sending HCA port.
+*
+*	*p_desc
+*		points to port->p_desc 
+*		p_desc->p_endpt == destination EP.
+*		
+*	p_sgl
+*		pointer to a scatter-gather list
+*
+*	tcp_payload
+*		used in LSO processing
+*		
+*	p_sg_buf
+*		scatter-gather buffer, used by p_sgl.
+*
+*********/
 
 ib_api_status_t
 ipoib_create_port(
@@ -730,14 +898,12 @@
 ib_api_status_t
 ipoib_port_join_mcast(
 	IN				ipoib_port_t* const			p_port,
-	IN		const	mac_addr_t				mac,
-	IN		const	uint8_t					state );
-
+	IN		const	mac_addr_t					mac,
+	IN		const	uint8_t						state );
 
 void
 ipoib_leave_mcast_cb(
-	IN				void				*context );
-
+	IN				void						*context );
 
 void
 ipoib_port_remove_endpt(
@@ -823,19 +989,23 @@
 ipoib_port_srq_destroy( 
 	IN		ipoib_port_t* const		p_port );
 
-#if 0 //CM
+#if IPOIB_CM
+
 ib_api_status_t
 ipoib_port_listen(
 	 IN		ipoib_port_t* const		p_port );
 
 ib_api_status_t
 ipoib_port_cancel_listen(
-	IN		ipoib_port_t*	const	p_port,
-	IN		ipoib_endpt_t* const	p_endpt ) {
-	UNUSED_PARAM(p_port);
-	UNUSED_PARAM(p_endpt);
-	return IB_SUCCESS;
-}
+	IN		ipoib_endpt_t* const	p_endpt );
+
+void 
+ipoib_send_complete_net_buffer(
+	IN		ipoib_send_NB_SG		*s_buf, 
+	IN		NDIS_STATUS 			status,
+	IN		ULONG					compl_flags,
+	IN		boolean_t				bLock );
+
 #endif 
 
 ib_api_status_t
@@ -846,20 +1016,6 @@
 endpt_cm_buf_mgr_destroy(
 	IN		ipoib_port_t* const		p_port );
 
-void
-endpt_cm_buf_mgr_reset(
-	IN		ipoib_port_t* const		p_port );
-
-void
-endpt_cm_buf_mgr_put_recv(
-	IN		endpt_buf_mgr_t * const		p_buf_mgr,
-	IN		ipoib_cm_desc_t* const		p_desc );
-
-void
-endpt_cm_buf_mgr_put_recv_list(
-	IN		endpt_buf_mgr_t * const		p_buf_mgr,
-	IN		cl_qlist_t* const			p_list );
-
 uint32_t
 endpt_cm_recv_mgr_build_pkt_array(
 	IN		ipoib_port_t* const			p_port,
@@ -867,24 +1023,39 @@
 	IN		cl_qlist_t* const			p_done_list,
 	IN OUT	uint32_t*					p_bytes_recv );
 
-ib_api_status_t
-endpt_cm_post_recv(
-	IN		ipoib_port_t* const			p_port );
 
-/*void
-endpt_cm_destroy_conn(
+#if IPOIB_CM
+
+void
+ipoib_cm_buf_mgr_put_recv(
+	IN		ipoib_port_t* const			p_port,
+	IN		ipoib_cm_recv_desc_t* const	p_desc,
+	IN		NET_BUFFER_LIST* const		p_NBL OPTIONAL );
+
+ULONG ipoib_free_received_NBL(
+	IN		ipoib_port_t			*p_port,
+	IN		NET_BUFFER_LIST 		*p_net_buffer_lists );
+
+BOOLEAN
+cm_destroy_conn(
 	IN		ipoib_port_t* const			p_port,
 	IN		ipoib_endpt_t* const		p_endpt );
-*/
+
 void
 endpt_cm_disconnect(
-	IN		ipoib_port_t*	const		p_port,
 	IN		ipoib_endpt_t*	const		p_endpt );
+
 void
-endpt_cm_flush_recv(
+endpt_cm_release_resources(
 	IN				ipoib_port_t* const		p_port,
 	IN				ipoib_endpt_t* const	p_endpt );
 
+char *
+get_ipoib_pkt_type_str(
+	IN				ipoib_pkt_type_t t );
+
+#endif // IPOIB_CM
+
 ib_api_status_t
 ipoib_recv_dhcp(
 	IN				ipoib_port_t* const			p_port,
@@ -918,23 +1089,19 @@
 }
 
 
-
-
-
 // This function is only used to monitor send failures
 extern ULONG g_NBL_complete;
 extern ULONG g_NBL;
 
 static inline VOID NdisMSendNetBufferListsCompleteX(
-	IN ipoib_adapter_t* p_adapter,
-	IN PNET_BUFFER_LIST  NetBufferLists,
-	IN ULONG  SendCompleteFlags
-	) 
+	IN ipoib_adapter_t*		p_adapter,
+	IN PNET_BUFFER_LIST		NetBufferLists,
+	IN ULONG				SendCompleteFlags ) 
 {
 	++g_NBL_complete;
 	ipoib_cnt_inc( &p_adapter->n_send_NBL_done );
 
-#ifdef DBG	
+#if DBG	
 	ASSERT(NET_BUFFER_LIST_NEXT_NBL(NetBufferLists) == NULL);
 
 	if (NET_BUFFER_LIST_STATUS(NetBufferLists) != NDIS_STATUS_SUCCESS) {
@@ -943,10 +1110,17 @@
 				NET_BUFFER_LIST_STATUS(NetBufferLists)));
 	}
 	IPOIB_PRINT( TRACE_LEVEL_VERBOSE, IPOIB_DBG_SEND,
-				("Completing NBL=%x, g_NBL=%d, g_NBL_completed=%d \n", NetBufferLists, g_NBL, g_NBL_complete) );
+		("Completing NBL=%x, g_NBL=%d, g_NBL_completed=%d \n",
+			NetBufferLists, g_NBL, g_NBL_complete) );
 #endif
 
-	NdisMSendNetBufferListsComplete(p_adapter->h_adapter,NetBufferLists,SendCompleteFlags);
+	NdisMSendNetBufferListsComplete( p_adapter->h_adapter,
+									 NetBufferLists,
+									 SendCompleteFlags );
 }
+
+#if DBG
+char *get_ib_recv_mode_str(ib_recv_mode_t m);
+#endif
 
 #endif	/* _IPOIB_PORT_H_ */
