xref: /onnv-gate/usr/src/uts/common/sys/ib/mgt/ibmf/ibmf_impl.h (revision 8580:85b678a652f5)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*8580SBill.Taylor@Sun.COM  * Common Development and Distribution License (the "License").
6*8580SBill.Taylor@Sun.COM  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*8580SBill.Taylor@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #ifndef _SYS_IB_MGT_IBMF_IBMF_IMPL_H
270Sstevel@tonic-gate #define	_SYS_IB_MGT_IBMF_IBMF_IMPL_H
280Sstevel@tonic-gate 
290Sstevel@tonic-gate 
300Sstevel@tonic-gate /*
310Sstevel@tonic-gate  * This file contains the IBMF implementation dependent structures and defines.
320Sstevel@tonic-gate  */
330Sstevel@tonic-gate 
340Sstevel@tonic-gate #ifdef __cplusplus
350Sstevel@tonic-gate extern "C" {
360Sstevel@tonic-gate #endif
370Sstevel@tonic-gate 
380Sstevel@tonic-gate #include <sys/types.h>
390Sstevel@tonic-gate #include <sys/conf.h>
400Sstevel@tonic-gate #include <sys/modctl.h>
410Sstevel@tonic-gate #include <sys/kmem.h>
420Sstevel@tonic-gate #include <sys/ksynch.h>
430Sstevel@tonic-gate #include <sys/taskq.h>
440Sstevel@tonic-gate #include <sys/sunddi.h>
450Sstevel@tonic-gate #include <sys/disp.h>
460Sstevel@tonic-gate #include <sys/ib/ibtl/ibvti.h>
470Sstevel@tonic-gate #include <sys/ib/mgt/ibmf/ibmf.h>
480Sstevel@tonic-gate #include <sys/ib/mgt/ibmf/ibmf_rmpp.h>
490Sstevel@tonic-gate #include <sys/ib/mgt/ibmf/ibmf_kstat.h>
500Sstevel@tonic-gate #include <sys/ib/mgt/ibmf/ibmf_trace.h>
510Sstevel@tonic-gate 
520Sstevel@tonic-gate #define	IBMF_MEM_PER_WQE		(IBMF_MAD_SIZE + sizeof (ib_grh_t))
530Sstevel@tonic-gate #define	IBMF_MAX_SQ_WRE			64
540Sstevel@tonic-gate #define	IBMF_MAX_RQ_WRE			64
550Sstevel@tonic-gate #define	IBMF_MAX_POSTED_RQ_PER_QP	512
560Sstevel@tonic-gate #define	IBMF_MAX_POSTED_SQ_PER_QP	512
570Sstevel@tonic-gate #define	IBMF_MAX_SQ_WR_SGL_ELEMENTS	1
580Sstevel@tonic-gate #define	IBMF_MAX_RQ_WR_SGL_ELEMENTS	1
590Sstevel@tonic-gate #define	IBMF_MGMT_Q_KEY			0x80010000
600Sstevel@tonic-gate #define	IBMF_P_KEY_DEF_FULL		0xFFFF
610Sstevel@tonic-gate #define	IBMF_P_KEY_DEF_LIMITED		0x7FFF
620Sstevel@tonic-gate #define	IBMF_P_KEY_BASE_MASK		0x7FFF
630Sstevel@tonic-gate #define	IBMF_PKEY_MEMBERSHIP_MASK	0x8000
640Sstevel@tonic-gate 
650Sstevel@tonic-gate #define	IBMF_TASKQ_1THREAD		1
660Sstevel@tonic-gate #define	IBMF_TASKQ_NTHREADS		128
670Sstevel@tonic-gate 
680Sstevel@tonic-gate /*
690Sstevel@tonic-gate  * Work request ID format used for receive requests.
700Sstevel@tonic-gate  *
710Sstevel@tonic-gate  *  bit 0 set to 1
720Sstevel@tonic-gate  */
730Sstevel@tonic-gate #define	IBMF_RCV_CQE			0x1
740Sstevel@tonic-gate 
750Sstevel@tonic-gate /*
760Sstevel@tonic-gate  * Convenience macro used in the RMPP protocol to obtain R_Method field
770Sstevel@tonic-gate  * of MAD header with Response bit flipped.
780Sstevel@tonic-gate  */
790Sstevel@tonic-gate #define	IBMF_FLIP_RESP_BIT(r_method)					\
800Sstevel@tonic-gate 	(((r_method & 0x80) ^ 0x80) | (r_method & 0x7F))
810Sstevel@tonic-gate 
820Sstevel@tonic-gate /* Work Request ID macros */
830Sstevel@tonic-gate #define	IBMF_IS_RECV_WR_ID(id)				\
840Sstevel@tonic-gate 	(((uint64_t)(id) & IBMF_RCV_CQE) ? B_TRUE : B_FALSE)
850Sstevel@tonic-gate #define	IBMF_IS_SEND_WR_ID(id)				\
860Sstevel@tonic-gate 	(!(IBMF_IS_RECV_WR_ID((id))))
870Sstevel@tonic-gate 
880Sstevel@tonic-gate /* Decrement IBMF message reference count */
890Sstevel@tonic-gate #define	IBMF_MSG_DECR_REFCNT(msg)			{	\
900Sstevel@tonic-gate 	ASSERT(MUTEX_HELD(&(msg)->im_mutex));			\
910Sstevel@tonic-gate 	(msg)->im_ref_count--;					\
920Sstevel@tonic-gate }
930Sstevel@tonic-gate 
940Sstevel@tonic-gate /* Increment IBMF message reference count */
950Sstevel@tonic-gate #define	IBMF_MSG_INCR_REFCNT(msg)				\
960Sstevel@tonic-gate 	(msg)->im_ref_count++;
970Sstevel@tonic-gate 
980Sstevel@tonic-gate /* Callback setup/cleanup macros */
990Sstevel@tonic-gate #define	IBMF_RECV_CB_SETUP(clp)				{	\
1000Sstevel@tonic-gate 	ASSERT(MUTEX_HELD(&(clp)->ic_mutex));			\
1010Sstevel@tonic-gate 	(clp)->ic_flags |= IBMF_CLIENT_RECV_CB_ACTIVE;		\
1020Sstevel@tonic-gate 	(clp)->ic_recvs_active++;				\
1030Sstevel@tonic-gate 	mutex_enter(&(clp)->ic_kstat_mutex);			\
1040Sstevel@tonic-gate 	IBMF_ADD32_KSTATS((clp), recvs_active, 1);		\
1050Sstevel@tonic-gate 	mutex_exit(&(clp)->ic_kstat_mutex);			\
1060Sstevel@tonic-gate }
1070Sstevel@tonic-gate 
1080Sstevel@tonic-gate #define	IBMF_RECV_CB_CLEANUP(clp)			{		\
1090Sstevel@tonic-gate 	ASSERT(MUTEX_HELD(&(clp)->ic_mutex));				\
1100Sstevel@tonic-gate 	(clp)->ic_recvs_active--;					\
1110Sstevel@tonic-gate 	mutex_enter(&(clp)->ic_kstat_mutex);				\
1120Sstevel@tonic-gate 	IBMF_SUB32_KSTATS((clp), recvs_active, 1);			\
1130Sstevel@tonic-gate 	mutex_exit(&(clp)->ic_kstat_mutex);				\
1140Sstevel@tonic-gate 	if ((clp)->ic_recvs_active == 0)				\
1150Sstevel@tonic-gate 		(clp)->ic_flags &= ~IBMF_CLIENT_RECV_CB_ACTIVE;		\
1160Sstevel@tonic-gate 	if ((((clp)->ic_flags & IBMF_CLIENT_RECV_CB_ACTIVE) == 0) &&	\
1170Sstevel@tonic-gate 	    (((clp)->ic_flags & IBMF_CLIENT_TEAR_DOWN_CB) != 0))	\
1180Sstevel@tonic-gate 		cv_signal(&(clp)->ic_recv_cb_teardown_cv);		\
1190Sstevel@tonic-gate }
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate #define	IBMF_ALT_RECV_CB_SETUP(altqp)			{		\
1220Sstevel@tonic-gate 	ASSERT(MUTEX_HELD(&(altqp)->isq_mutex));			\
1230Sstevel@tonic-gate 	(altqp)->isq_flags |= IBMF_CLIENT_RECV_CB_ACTIVE;		\
1240Sstevel@tonic-gate 	(altqp)->isq_recvs_active++;					\
1250Sstevel@tonic-gate 	mutex_enter(&(altqp)->isq_client_hdl->ic_kstat_mutex);		\
1260Sstevel@tonic-gate 	IBMF_ADD32_KSTATS((altqp)->isq_client_hdl, recvs_active, 1);	\
1270Sstevel@tonic-gate 	mutex_exit(&(altqp)->isq_client_hdl->ic_kstat_mutex);		\
1280Sstevel@tonic-gate }
1290Sstevel@tonic-gate 
1300Sstevel@tonic-gate #define	IBMF_ALT_RECV_CB_CLEANUP(altqp)			{		\
1310Sstevel@tonic-gate 	ASSERT(MUTEX_HELD(&(altqp)->isq_mutex));			\
1320Sstevel@tonic-gate 	(altqp)->isq_recvs_active--;					\
1330Sstevel@tonic-gate 	mutex_enter(&(altqp)->isq_client_hdl->ic_kstat_mutex);		\
1340Sstevel@tonic-gate 	IBMF_SUB32_KSTATS((altqp)->isq_client_hdl, recvs_active, 1);	\
1350Sstevel@tonic-gate 	mutex_exit(&(altqp)->isq_client_hdl->ic_kstat_mutex);		\
1360Sstevel@tonic-gate 	if ((altqp)->isq_recvs_active == 0)				\
1370Sstevel@tonic-gate 		(altqp)->isq_flags &= ~IBMF_CLIENT_RECV_CB_ACTIVE;	\
1380Sstevel@tonic-gate 	if ((((altqp)->isq_flags & IBMF_CLIENT_RECV_CB_ACTIVE) == 0) &&	\
1390Sstevel@tonic-gate 	    (((altqp)->isq_flags & IBMF_CLIENT_TEAR_DOWN_CB) != 0))	\
1400Sstevel@tonic-gate 		cv_signal(&(altqp)->isq_recv_cb_teardown_cv);		\
1410Sstevel@tonic-gate }
1420Sstevel@tonic-gate 
1430Sstevel@tonic-gate /* warlock annotations for ibmf.h and ibmf_msg.h structures */
1440Sstevel@tonic-gate _NOTE(READ_ONLY_DATA(_ibmf_msg::im_msgbufs_send.im_bufs_cl_data
1450Sstevel@tonic-gate 	_ibmf_msg::im_msgbufs_send.im_bufs_cl_data_len
1460Sstevel@tonic-gate 	_ibmf_msg::im_msgbufs_send.im_bufs_cl_hdr
1470Sstevel@tonic-gate 	_ibmf_msg::im_msgbufs_send.im_bufs_cl_hdr_len
1480Sstevel@tonic-gate 	_ibmf_msg::im_msgbufs_send.im_bufs_mad_hdr
1490Sstevel@tonic-gate 	_ib_mad_hdr_t))
1500Sstevel@tonic-gate 
1510Sstevel@tonic-gate /*
1520Sstevel@tonic-gate  * WQE pool management contexts
1530Sstevel@tonic-gate  */
1540Sstevel@tonic-gate typedef struct _ibmf_wqe_mgt {
1550Sstevel@tonic-gate 	struct _ibmf_wqe_mgt	*wqe_mgt_next; /* next wqe management entry */
1560Sstevel@tonic-gate 	void			*wqes_kmem;	/* kmem allocated for WQEs */
1570Sstevel@tonic-gate 	uint64_t		wqes_kmem_sz; /* sizeof WQE kmem allocated */
1580Sstevel@tonic-gate 	ib_vaddr_t		wqes_ib_mem;	/* Registered memory */
1590Sstevel@tonic-gate 	ibt_lkey_t		wqes_ib_lkey;	/* Lkey that goes with it */
1600Sstevel@tonic-gate 	ibt_mr_hdl_t		wqes_ib_mem_hdl; /* IB mem handle */
1610Sstevel@tonic-gate 	kmutex_t		wqes_mutex;	/* WQE mgt context mutex */
1620Sstevel@tonic-gate } ibmf_wqe_mgt_t;
1630Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(ibmf_wqe_mgt_t::wqes_mutex,
1640Sstevel@tonic-gate     ibmf_wqe_mgt_t::wqes_kmem
1650Sstevel@tonic-gate     ibmf_wqe_mgt_t::wqes_kmem_sz
1660Sstevel@tonic-gate     ibmf_wqe_mgt_t::wqes_ib_mem
1670Sstevel@tonic-gate     ibmf_wqe_mgt_t::wqes_ib_lkey
1680Sstevel@tonic-gate     ibmf_wqe_mgt_t::wqes_ib_mem_hdl))
1690Sstevel@tonic-gate 
1700Sstevel@tonic-gate /*
1710Sstevel@tonic-gate  * structure used to keep track of qp handles
1720Sstevel@tonic-gate  */
1730Sstevel@tonic-gate typedef struct _ibmf_qp_t {
1740Sstevel@tonic-gate 	struct _ibmf_qp_t	*iq_next;	/* next in the list */
1750Sstevel@tonic-gate 	ibt_qp_hdl_t		iq_qp_handle;	/* qp handle from IB xport */
1760Sstevel@tonic-gate 	int			iq_port_num;	/* port num for this qp */
1770Sstevel@tonic-gate 	int			iq_qp_num;	/* qp num */
1780Sstevel@tonic-gate 	int			iq_qp_ref;	/* no. of clients using this */
1790Sstevel@tonic-gate 	uint_t			iq_flags;	/* for implementing state m/c */
1800Sstevel@tonic-gate 	uint_t			iq_rwqes_posted; /* posted receive wqes */
1810Sstevel@tonic-gate 	kmutex_t		iq_mutex;	/* mutex for some fields */
1820Sstevel@tonic-gate } ibmf_qp_t;
1830Sstevel@tonic-gate _NOTE(READ_ONLY_DATA(ibmf_qp_t::iq_port_num ibmf_qp_t::iq_qp_handle))
1840Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(ibmf_qp_t::iq_mutex,
1850Sstevel@tonic-gate     ibmf_qp_t::iq_rwqes_posted))
1860Sstevel@tonic-gate 
1870Sstevel@tonic-gate /* defines for iq_flags */
1880Sstevel@tonic-gate #define	IBMF_QP_FLAGS_INVALID				0x0001
1890Sstevel@tonic-gate #define	IBMF_QP_FLAGS_INITING				0x0002
1900Sstevel@tonic-gate #define	IBMF_QP_FLAGS_INITED				0x0004
1910Sstevel@tonic-gate #define	IBMF_QP_FLAGS_UNINITING				0x0008
1920Sstevel@tonic-gate 
1930Sstevel@tonic-gate /*
1940Sstevel@tonic-gate  * structure used to keep track of qp handles for qps other than
1950Sstevel@tonic-gate  * the special qps
1960Sstevel@tonic-gate  */
1970Sstevel@tonic-gate typedef struct _ibmf_alt_qp_t {
1980Sstevel@tonic-gate 	struct _ibmf_alt_qp_t	*isq_next;	/* next qp ctx on list */
1990Sstevel@tonic-gate 	ibt_qp_hdl_t		isq_qp_handle;	/* qp handle from IB xport */
2000Sstevel@tonic-gate 	ibt_chan_sizes_t	isq_qp_sizes;	/* qp sizes returned by alloc */
2010Sstevel@tonic-gate 	struct _ibmf_client	*isq_client_hdl; /* associated client handle */
2020Sstevel@tonic-gate 	ibmf_msg_cb_t		isq_recv_cb;	/* recv callback for this qp */
2030Sstevel@tonic-gate 	void			*isq_recv_cb_arg; /* arg for recv cb */
2040Sstevel@tonic-gate 	kcondvar_t		isq_recv_cb_teardown_cv; /* wait on teardown */
2050Sstevel@tonic-gate 	kmutex_t		isq_mutex;		/* qp context mutex */
2060Sstevel@tonic-gate 	int			isq_flags;	/* to keep track of state */
2070Sstevel@tonic-gate 	int			isq_sends_active; /* outstanding sends */
2080Sstevel@tonic-gate 	int			isq_recvs_active; /* outstanding recvs */
2090Sstevel@tonic-gate 	ib_qpn_t		isq_qpn;	/* qp number */
2100Sstevel@tonic-gate 	ib_pkey_t		isq_pkey;	/* qp's partition key */
2110Sstevel@tonic-gate 	ib_qkey_t		isq_qkey;	/* qp's queue keye */
2120Sstevel@tonic-gate 	int			isq_port_num;	/* port num for this qp */
2130Sstevel@tonic-gate 	boolean_t		isq_supports_rmpp; /* qp supports rmpp */
2140Sstevel@tonic-gate 	kcondvar_t		isq_sqd_cv; 	/* wait on SQD event */
2150Sstevel@tonic-gate 	int			isq_wqes_alloced; /* wqes allocated for QP */
2160Sstevel@tonic-gate 	kcondvar_t		isq_wqes_cv; 	/* wait on wqes destruction */
2170Sstevel@tonic-gate 	uint_t			isq_rwqes_posted; /* posted receive wqes */
2180Sstevel@tonic-gate 
2190Sstevel@tonic-gate 	/* Manage Send/Receive WQEs for Special QPs */
2200Sstevel@tonic-gate 	struct kmem_cache	*isq_send_wqes_cache; /* Send WQE cache */
2210Sstevel@tonic-gate 	struct kmem_cache	*isq_recv_wqes_cache; /* Receive WQE cache */
2220Sstevel@tonic-gate 	vmem_t			*isq_wqe_ib_vmem; /* IB virtual address arena */
2230Sstevel@tonic-gate 	kmutex_t		isq_wqe_mutex;	/* WQE management list mutex */
2240Sstevel@tonic-gate 	ibmf_wqe_mgt_t		*isq_wqe_mgt_list; /* WQE management list */
2250Sstevel@tonic-gate } ibmf_alt_qp_t;
2260Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(ibmf_alt_qp_t::isq_mutex,
2270Sstevel@tonic-gate     ibmf_alt_qp_t::isq_sends_active
2280Sstevel@tonic-gate     ibmf_alt_qp_t::isq_recvs_active
2290Sstevel@tonic-gate     ibmf_alt_qp_t::isq_pkey
2300Sstevel@tonic-gate     ibmf_alt_qp_t::isq_qkey
2310Sstevel@tonic-gate     ibmf_alt_qp_t::isq_recv_cb
2320Sstevel@tonic-gate     ibmf_alt_qp_t::isq_recv_cb_arg
2330Sstevel@tonic-gate     ibmf_alt_qp_t::isq_flags
2340Sstevel@tonic-gate     ibmf_alt_qp_t::isq_rwqes_posted))
2350Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(ibmf_alt_qp_t::isq_wqe_mutex,
2360Sstevel@tonic-gate     ibmf_alt_qp_t::isq_wqe_mgt_list))
2370Sstevel@tonic-gate _NOTE(READ_ONLY_DATA(ibmf_alt_qp_t::isq_port_num))
2380Sstevel@tonic-gate 
2390Sstevel@tonic-gate #define	IBMF_MSG_FLAGS_QUEUED		0x00001000	/* in the ib xport */
2400Sstevel@tonic-gate #define	IBMF_MSG_FLAGS_DONE		0x00002000	/* xport done */
2410Sstevel@tonic-gate #define	IBMF_MSG_FLAGS_BLOCKING		0x00004000	/* sync command */
2420Sstevel@tonic-gate 
2430Sstevel@tonic-gate /*
2440Sstevel@tonic-gate  * This structure is used to keep track of IBT returned ibt_ud_dest_t
2450Sstevel@tonic-gate  * structures.
2460Sstevel@tonic-gate  */
2470Sstevel@tonic-gate typedef struct ibmf_ud_dest_s {
2480Sstevel@tonic-gate 	ibt_ud_dest_t		ud_dest;
2490Sstevel@tonic-gate 	struct ibmf_ud_dest_s	*ud_next;
2500Sstevel@tonic-gate } ibmf_ud_dest_t;
2510Sstevel@tonic-gate 
2520Sstevel@tonic-gate /*
2530Sstevel@tonic-gate  * ibmf_msg_impl definition
2540Sstevel@tonic-gate  *	The IBMF client initializes various members of the msg while sending
2550Sstevel@tonic-gate  *	the message. IBMF fills in the various members of the msg when a message
2560Sstevel@tonic-gate  *	is received.
2570Sstevel@tonic-gate  */
2580Sstevel@tonic-gate typedef struct _ibmf_msg_impl {
2590Sstevel@tonic-gate 	ibmf_addr_info_t	im_local_addr;	/* local addressing info */
2600Sstevel@tonic-gate 	ibmf_global_addr_info_t	im_global_addr;	/* global addressing info */
2610Sstevel@tonic-gate 	int32_t			im_msg_status;	/* completion status */
2620Sstevel@tonic-gate 	uint32_t		im_msg_flags;	/* flags */
2630Sstevel@tonic-gate 	size_t			im_msg_sz_limit; /* max. message size */
2640Sstevel@tonic-gate 	ibmf_msg_bufs_t		im_msgbufs_send; /* input data to ibmf */
2650Sstevel@tonic-gate 	ibmf_msg_bufs_t		im_msgbufs_recv; /* output data from ibmf */
2660Sstevel@tonic-gate 	struct _ibmf_msg_impl	*im_msg_next;	/* next message on the list */
2670Sstevel@tonic-gate 	struct _ibmf_msg_impl	*im_msg_prev;	/* prev message on the list */
2680Sstevel@tonic-gate 	void			*im_client;	/* client that allocd the pkt */
2690Sstevel@tonic-gate 	ibmf_qp_handle_t	im_qp_hdl;	/* qp handle */
2700Sstevel@tonic-gate 	ibt_ud_dest_t		*im_ud_dest;	/* ptr to the pkt's ud_dest */
2710Sstevel@tonic-gate 	ibmf_ud_dest_t		*im_ibmf_ud_dest; /* ptr to the pkt's ud_dest */
2720Sstevel@tonic-gate 	ibmf_msg_cb_t		im_trans_cb;	/* transaction completion cb */
2730Sstevel@tonic-gate 	void			*im_trans_cb_arg; /* arg for completion cb */
2740Sstevel@tonic-gate 	uint64_t		im_tid;		/* transaction ID */
2750Sstevel@tonic-gate 	uint8_t			im_mgt_class; 	/* management class */
2760Sstevel@tonic-gate 	kmutex_t		im_mutex;	/* protects trans context */
2770Sstevel@tonic-gate 	uint32_t		im_state;	/* message state */
2780Sstevel@tonic-gate 	uint32_t		im_transp_op_flags; /* transaction operation */
2790Sstevel@tonic-gate 	uint32_t		im_flags;	/* message flags */
2800Sstevel@tonic-gate 	uint32_t		im_trans_state_flags;	/* state flags */
2810Sstevel@tonic-gate 	kcondvar_t		im_trans_cv;	/* wait for op completion */
2820Sstevel@tonic-gate 	ibmf_rmpp_ctx_t		im_rmpp_ctx; 	/* RMPP context */
2830Sstevel@tonic-gate 	ibmf_retrans_t		im_retrans;	/* retransmission info */
2840Sstevel@tonic-gate 	timeout_id_t		im_rp_timeout_id; /* response timeout ID */
2850Sstevel@tonic-gate 	timeout_id_t		im_tr_timeout_id; /* transaction timeout ID */
2860Sstevel@tonic-gate 	timeout_id_t		im_rp_unset_timeout_id; /* id for untimeout() */
2870Sstevel@tonic-gate 	timeout_id_t		im_tr_unset_timeout_id; /* id for untimeout() */
2880Sstevel@tonic-gate 	int			im_ref_count;	/* reference count */
2890Sstevel@tonic-gate 	boolean_t		im_unsolicited; /* msg was unsolicited recv */
2900Sstevel@tonic-gate 	int			im_pending_send_compls; /* send completions */
2910Sstevel@tonic-gate } ibmf_msg_impl_t;
2920Sstevel@tonic-gate _NOTE(READ_ONLY_DATA(ibmf_msg_impl_t::im_trans_cb
2930Sstevel@tonic-gate     ibmf_msg_impl_t::im_trans_cb_arg
2940Sstevel@tonic-gate     ibmf_msg_impl_t::im_transp_op_flags
2950Sstevel@tonic-gate     ibmf_msg_impl_t::im_local_addr
2960Sstevel@tonic-gate     ibmf_msg_impl_t::im_unsolicited
2970Sstevel@tonic-gate     ibmf_msg_impl_t::im_client))
2980Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(ibmf_msg_impl_t::im_mutex,
2990Sstevel@tonic-gate     ibmf_msg_impl_t::im_flags
3000Sstevel@tonic-gate     ibmf_msg_impl_t::im_trans_state_flags
3010Sstevel@tonic-gate     ibmf_msg_impl_t::im_msgbufs_recv
3020Sstevel@tonic-gate     ibmf_msg_impl_t::im_msg_status
3030Sstevel@tonic-gate     ibmf_msg_impl_t::im_rmpp_ctx))
3040Sstevel@tonic-gate 
3050Sstevel@tonic-gate /* im_flags */
3060Sstevel@tonic-gate #define	IBMF_MSG_FLAGS_SEQUENCED	0x1
3070Sstevel@tonic-gate #define	IBMF_MSG_FLAGS_SEND_RMPP	0x2
3080Sstevel@tonic-gate #define	IBMF_MSG_FLAGS_RECV_RMPP	0x4
3090Sstevel@tonic-gate #define	IBMF_MSG_FLAGS_NOT_RMPP		0x8
3100Sstevel@tonic-gate #define	IBMF_MSG_FLAGS_BUSY		0x10
3110Sstevel@tonic-gate #define	IBMF_MSG_FLAGS_FREE		0x20
3120Sstevel@tonic-gate #define	IBMF_MSG_FLAGS_ON_LIST		0x40
3130Sstevel@tonic-gate #define	IBMF_MSG_FLAGS_SET_TERMINATION	0x80
3140Sstevel@tonic-gate #define	IBMF_MSG_FLAGS_TERMINATION	0x100
3150Sstevel@tonic-gate 
3160Sstevel@tonic-gate /* retransmission parameter defaults for im_retrans field */
3170Sstevel@tonic-gate #define	IBMF_RETRANS_DEF_RTV		4000000		/* 4 seconds */
3180Sstevel@tonic-gate #define	IBMF_RETRANS_DEF_RTTV		100000		/* 100 milliseconds */
3190Sstevel@tonic-gate #define	IBMF_RETRANS_DEF_TRANS_TO	40000000	/* 40 seconds */
3200Sstevel@tonic-gate #define	IBMF_RETRANS_DEF_RETRIES	0
3210Sstevel@tonic-gate 
3220Sstevel@tonic-gate /*
3230Sstevel@tonic-gate  * Transaction state flags (im_trans_state_flags) definitions
3240Sstevel@tonic-gate  * Don't use 0x0 as a flag value since clients OR and AND the flags
3250Sstevel@tonic-gate  */
3260Sstevel@tonic-gate #define	IBMF_TRANS_STATE_FLAG_UNINIT		0x1
3270Sstevel@tonic-gate #define	IBMF_TRANS_STATE_FLAG_INIT		0x2
3280Sstevel@tonic-gate #define	IBMF_TRANS_STATE_FLAG_WAIT		0x4
3290Sstevel@tonic-gate #define	IBMF_TRANS_STATE_FLAG_DONE		0x8
3300Sstevel@tonic-gate #define	IBMF_TRANS_STATE_FLAG_SIGNALED		0x10
3310Sstevel@tonic-gate #define	IBMF_TRANS_STATE_FLAG_TIMEOUT		0x20
3320Sstevel@tonic-gate #define	IBMF_TRANS_STATE_FLAG_RECV_ACTIVE	0x40
3330Sstevel@tonic-gate #define	IBMF_TRANS_STATE_FLAG_RECV_DONE		0x80
3340Sstevel@tonic-gate #define	IBMF_TRANS_STATE_FLAG_SEND_DONE		0x100
3350Sstevel@tonic-gate 
3360Sstevel@tonic-gate /* Timer types */
3370Sstevel@tonic-gate typedef	enum _ibmf_timer_t {
3380Sstevel@tonic-gate 	IBMF_RESP_TIMER			= 1,
3390Sstevel@tonic-gate 	IBMF_TRANS_TIMER		= 2
3400Sstevel@tonic-gate } ibmf_timer_t;
3410Sstevel@tonic-gate 
3420Sstevel@tonic-gate /*
3430Sstevel@tonic-gate  * structure to hold specific client info taken from ibmf_register_info_t
3440Sstevel@tonic-gate  * since we can register for more than one client at a time, but each specific
3450Sstevel@tonic-gate  * ibmf_client_t only holds one client itself.
3460Sstevel@tonic-gate  */
3470Sstevel@tonic-gate typedef struct _ibmf_client_info {
3480Sstevel@tonic-gate 	ib_guid_t		ci_guid;
3490Sstevel@tonic-gate 	uint_t			port_num;
3500Sstevel@tonic-gate 	ibmf_client_type_t	client_class;
3510Sstevel@tonic-gate } ibmf_client_info_t;
3520Sstevel@tonic-gate 
3530Sstevel@tonic-gate /*
3540Sstevel@tonic-gate  * Defines for the client type (agent/manager/agent+manager)
3550Sstevel@tonic-gate  * Bits 16-19 of the client_class specify the client type.
3560Sstevel@tonic-gate  */
3570Sstevel@tonic-gate #define	IBMF_AGENT_ID			0x00010000
3580Sstevel@tonic-gate #define	IBMF_MANAGER_ID			0x00020000
3590Sstevel@tonic-gate #define	IBMF_AGENT_MANAGER_ID		0x00030000
3600Sstevel@tonic-gate 
3610Sstevel@tonic-gate /*
3620Sstevel@tonic-gate  * structure used to keep track of clients
3630Sstevel@tonic-gate  */
3640Sstevel@tonic-gate typedef struct _ibmf_client {
3650Sstevel@tonic-gate 	void			*ic_client_sig;	/* set for valid handles */
3660Sstevel@tonic-gate 	struct _ibmf_ci		*ic_myci;	/* pointer to CI */
3670Sstevel@tonic-gate 	struct _ibmf_client	*ic_next;	/* next client on list */
3680Sstevel@tonic-gate 	struct _ibmf_client	*ic_prev;	/* previous client on list */
3690Sstevel@tonic-gate 
3700Sstevel@tonic-gate 	taskq_t			*ic_send_taskq;	/* taskq for send cb */
3710Sstevel@tonic-gate 	taskq_t			*ic_recv_taskq;	/* taskq for receive cb */
3720Sstevel@tonic-gate 	uint_t			ic_init_state_class; /* taskq initialization */
3730Sstevel@tonic-gate 
3740Sstevel@tonic-gate 	ibmf_msg_impl_t		*ic_msg_list; /* protected by ic_mutex */
3750Sstevel@tonic-gate 	ibmf_msg_impl_t		*ic_msg_last; /* last message on list */
3760Sstevel@tonic-gate 	ibmf_msg_impl_t		*ic_term_msg_list; /* termination loop mesgs */
3770Sstevel@tonic-gate 	ibmf_msg_impl_t		*ic_term_msg_last; /* last message on list */
3780Sstevel@tonic-gate 	kmutex_t		ic_msg_mutex; /* protect the message list */
3790Sstevel@tonic-gate 
3800Sstevel@tonic-gate 	/* IBTL asynchronous event callback (eg. HCA offline) */
3810Sstevel@tonic-gate 	ibmf_async_event_cb_t	ic_async_cb; /* async/unsolicited handling */
3820Sstevel@tonic-gate 	void			*ic_async_cb_arg; /* args for async cb */
3830Sstevel@tonic-gate 
3840Sstevel@tonic-gate 	/* Asynchronous/Unsolicited message handler */
3850Sstevel@tonic-gate 	ibmf_msg_cb_t		ic_recv_cb;
3860Sstevel@tonic-gate 	void			*ic_recv_cb_arg;
3870Sstevel@tonic-gate 	kcondvar_t		ic_recv_cb_teardown_cv; /* wait on teardown */
3880Sstevel@tonic-gate 
3890Sstevel@tonic-gate 	ibmf_client_info_t	ic_client_info; /* client registration info */
3900Sstevel@tonic-gate 	ibmf_qp_t		*ic_qp;		/* special qp context */
3910Sstevel@tonic-gate 	ibt_hca_hdl_t		ic_ci_handle;	/* == ic_myci->ic_ci_handle */
3920Sstevel@tonic-gate 	kmutex_t		ic_mutex;	/* prot the client struct */
3930Sstevel@tonic-gate 	int			ic_flags;	/* to keep track of state */
3940Sstevel@tonic-gate 	int			ic_reg_flags;	/* flags specified during */
3950Sstevel@tonic-gate 						/* registration */
3960Sstevel@tonic-gate 
3970Sstevel@tonic-gate 	/* Statistics */
3980Sstevel@tonic-gate 	int			ic_msgs_alloced; /* no. msgs alloced by/for */
3990Sstevel@tonic-gate 	int			ic_msgs_active; /* no. msgs active */
4000Sstevel@tonic-gate 	int			ic_trans_active; /* outstanding transacts  */
4010Sstevel@tonic-gate 	int			ic_sends_active; /* outstanding sends */
4020Sstevel@tonic-gate 	int			ic_recvs_active; /* outstanding recvs */
4030Sstevel@tonic-gate 
4040Sstevel@tonic-gate 	ib_lid_t		ic_base_lid;	/* used to calculate pathbits */
4050Sstevel@tonic-gate 	kmutex_t		ic_kstat_mutex;	/* protect the kstat */
4060Sstevel@tonic-gate 	struct kstat		*ic_kstatp;	/* kstats for client */
4070Sstevel@tonic-gate } ibmf_client_t;
4080Sstevel@tonic-gate _NOTE(READ_ONLY_DATA(ibmf_client_t::ic_ci_handle
4090Sstevel@tonic-gate     ibmf_client_t::ic_client_info
4100Sstevel@tonic-gate     ibmf_client_t::ic_client_sig))
4110Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(ibmf_client_t::ic_msg_mutex,
4120Sstevel@tonic-gate     ibmf_client_t::ic_msg_list
4130Sstevel@tonic-gate     ibmf_client_t::ic_msg_last
4140Sstevel@tonic-gate     ibmf_client_t::ic_term_msg_list
4150Sstevel@tonic-gate     ibmf_client_t::ic_term_msg_last))
4160Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(ibmf_client_t::ic_mutex,
4170Sstevel@tonic-gate     ibmf_client_t::ic_msgs_alloced
4180Sstevel@tonic-gate     ibmf_client_t::ic_flags
4190Sstevel@tonic-gate     ibmf_client_t::ic_recv_cb
4200Sstevel@tonic-gate     ibmf_client_t::ic_recv_cb_arg))
4210Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(ibmf_client_t::ic_kstat_mutex,
4220Sstevel@tonic-gate     ibmf_client_t::ic_kstatp))
4230Sstevel@tonic-gate 
4240Sstevel@tonic-gate #define	IBMF_CLIENT_RECV_CB_ACTIVE		0x00000001 /* rcv CB active */
4250Sstevel@tonic-gate #define	IBMF_CLIENT_SEND_CB_ACTIVE		0x00000010 /* send CB active */
4260Sstevel@tonic-gate #define	IBMF_CLIENT_TEAR_DOWN_CB		0x00000100 /* client wants to */
4270Sstevel@tonic-gate 							    /* remove recv_cb */
4280Sstevel@tonic-gate 
4290Sstevel@tonic-gate /* IBMF_MAD_ONLY is used by the alternate QP context only (isq_flags) */
4300Sstevel@tonic-gate #define	IBMF_MAD_ONLY				0x00002000
4310Sstevel@tonic-gate #define	IBMF_RAW_ONLY				0x00004000
4320Sstevel@tonic-gate 
4330Sstevel@tonic-gate #define	IBMF_REG_MSG_LIST	0
4340Sstevel@tonic-gate #define	IBMF_TERM_MSG_LIST	1
4350Sstevel@tonic-gate 
4360Sstevel@tonic-gate /*
4370Sstevel@tonic-gate  * Send WQE context
4380Sstevel@tonic-gate  */
4390Sstevel@tonic-gate typedef struct _ibmf_send_wqe {
4400Sstevel@tonic-gate 	struct _ibmf_send_wqe	*send_wqe_next;
4410Sstevel@tonic-gate 	ibt_send_wr_t		send_wr;	/* IBT send work request */
4420Sstevel@tonic-gate 	ibmf_client_t		*send_client;	/* client that sent this */
4430Sstevel@tonic-gate 	void			*send_mem;	/* memory used in send */
4440Sstevel@tonic-gate 	ib_vaddr_t		send_sg_mem;	/* registered memory */
4450Sstevel@tonic-gate 	ibt_lkey_t		send_sg_lkey;	/* Lkey that goes with it */
4460Sstevel@tonic-gate 	ibt_mr_hdl_t		send_mem_hdl;	/* == ci_send_mr_handle in ci */
4470Sstevel@tonic-gate 	uint_t			send_wqe_flags;
4480Sstevel@tonic-gate 	uchar_t			send_port_num;	/* port this is posted to */
4490Sstevel@tonic-gate 	ibt_qp_hdl_t		send_qp_handle;	/* qp handle for this wqe */
4500Sstevel@tonic-gate 	ibmf_qp_handle_t	send_ibmf_qp_handle; /* ibmf qp handle */
4510Sstevel@tonic-gate 	ibmf_msg_impl_t		*send_msg;	/* message context */
4520Sstevel@tonic-gate 	uint32_t		send_status;	/* completion status */
4530Sstevel@tonic-gate 	uint32_t		send_rmpp_segment; /* rmpp segment */
4540Sstevel@tonic-gate } ibmf_send_wqe_t;
4550Sstevel@tonic-gate 
4560Sstevel@tonic-gate /*
4570Sstevel@tonic-gate  * Receive WQE context
4580Sstevel@tonic-gate  */
4590Sstevel@tonic-gate typedef struct _ibmf_recv_wqe {
4600Sstevel@tonic-gate 	struct _ibmf_recv_wqe	*recv_wqe_next;
4610Sstevel@tonic-gate 	ibt_recv_wr_t		recv_wr;
4620Sstevel@tonic-gate 	ibmf_client_t		*recv_client;	/* client that received this */
4630Sstevel@tonic-gate 	void			*recv_mem;	/* memory used in WQEs */
4640Sstevel@tonic-gate 	ibmf_qp_t		*recv_qpp;	/* qp this is posted */
4650Sstevel@tonic-gate 	ibt_wc_t		recv_wc;	/* corresponding  cqe */
4660Sstevel@tonic-gate 	ib_vaddr_t		recv_sg_mem;	/* registered mem */
4670Sstevel@tonic-gate 	ibt_lkey_t		recv_sg_lkey;	/* Lkey that goes with it */
4680Sstevel@tonic-gate 	ibt_mr_hdl_t		recv_mem_hdl;	/* == ci_recv_mr_handle in ci */
4690Sstevel@tonic-gate 	uint_t			recv_wqe_flags;
4700Sstevel@tonic-gate 	uchar_t			recv_port_num;	/* port this is posted to */
4710Sstevel@tonic-gate 	ibt_qp_hdl_t		recv_qp_handle;	/* ibt qp handle for this wqe */
4720Sstevel@tonic-gate 	ibmf_qp_handle_t	recv_ibmf_qp_handle; /* ibmf qp handle */
4730Sstevel@tonic-gate 	ibmf_msg_impl_t		*recv_msg;	/* message context */
4740Sstevel@tonic-gate } ibmf_recv_wqe_t;
4750Sstevel@tonic-gate 
4760Sstevel@tonic-gate #define	IBMF_RECV_WQE_FREE		0x00000001	/* WQE is free */
4770Sstevel@tonic-gate 
4780Sstevel@tonic-gate /*
4790Sstevel@tonic-gate  * Struct that keeps track of the underlying IB channel interface. There
4800Sstevel@tonic-gate  * is one per CI. Each clients on a given ci gets a reference to the CI.
4810Sstevel@tonic-gate  * References are tracked used ci_ref field; when ci_ref drops to 0, the
4820Sstevel@tonic-gate  * structure can be freed.
4830Sstevel@tonic-gate  */
4840Sstevel@tonic-gate typedef struct _ibmf_ci {
4850Sstevel@tonic-gate 	struct _ibmf_ci		*ci_next;
4860Sstevel@tonic-gate 	kmutex_t		ci_mutex;	/* protects the CI struct */
4870Sstevel@tonic-gate 	ibmf_client_t		*ci_clients;	/* list of clients;head */
4880Sstevel@tonic-gate 	ibmf_client_t		*ci_clients_last; /* tail */
4890Sstevel@tonic-gate 	kmutex_t		ci_clients_mutex; /* protect the client list */
4900Sstevel@tonic-gate 	ib_guid_t		ci_node_guid;	/* node GUID */
4910Sstevel@tonic-gate 	ibt_hca_hdl_t		ci_ci_handle;	/* HCA handle */
4920Sstevel@tonic-gate 	ibt_pd_hdl_t		ci_pd;		/* protection domain */
4930Sstevel@tonic-gate 	ibmf_qp_t		*ci_qp_list;	/* sp. QP list for all ports */
4940Sstevel@tonic-gate 	ibmf_qp_t		*ci_qp_list_tail;
4950Sstevel@tonic-gate 	kcondvar_t		ci_qp_cv;	/* wait for QP valid state */
4960Sstevel@tonic-gate 	ibt_cq_hdl_t		ci_cq_handle;	/* CQ handle for sp. QPs */
4970Sstevel@tonic-gate 	ibt_cq_hdl_t		ci_alt_cq_handle; /* CQ handle for alt. QPs */
4980Sstevel@tonic-gate 	ibmf_alt_qp_t		*ci_alt_qp_list; /* alternate QP list */
4990Sstevel@tonic-gate 
5000Sstevel@tonic-gate 	/* UD destination resources */
5010Sstevel@tonic-gate 	uint32_t		ci_ud_dest_list_count; /* resources in pool */
5020Sstevel@tonic-gate 	kmutex_t		ci_ud_dest_list_mutex; /* UD dest list mutex */
5030Sstevel@tonic-gate 	ibmf_ud_dest_t		*ci_ud_dest_list_head; /* start of list */
5040Sstevel@tonic-gate 
5050Sstevel@tonic-gate 	/* Send/Receive WQEs for Special QPs */
5060Sstevel@tonic-gate 	struct kmem_cache	*ci_send_wqes_cache; /* Send WQE cache */
5070Sstevel@tonic-gate 	struct kmem_cache	*ci_recv_wqes_cache; /* Receive WQE cache */
5080Sstevel@tonic-gate 	vmem_t			*ci_wqe_ib_vmem; /* IB virtual address arena */
5090Sstevel@tonic-gate 	kmutex_t		ci_wqe_mutex;	/* WQE management list mutex */
5100Sstevel@tonic-gate 	ibmf_wqe_mgt_t		*ci_wqe_mgt_list; /* WQE management list */
5110Sstevel@tonic-gate 
5120Sstevel@tonic-gate 	uint_t			ci_nports;	/* num ports on the CI */
5130Sstevel@tonic-gate 	uint32_t		ci_vendor_id:24; /* HCA vendor ID */
5140Sstevel@tonic-gate 	uint16_t		ci_device_id;	/* HCA device ID */
5150Sstevel@tonic-gate 	uint_t			ci_ref;		/* reference count */
5160Sstevel@tonic-gate 	uint16_t		ci_state;	/* CI context state */
5170Sstevel@tonic-gate 	uint16_t		ci_state_flags;	/* CI context state flags */
5180Sstevel@tonic-gate 	kcondvar_t		ci_state_cv;	/* wait on a state change */
5190Sstevel@tonic-gate 	uint_t			ci_init_state;	/* used in cleanup */
5200Sstevel@tonic-gate 
5210Sstevel@tonic-gate 	/* free QP synchronization with WQE completion processing */
5220Sstevel@tonic-gate 	int			ci_wqes_alloced; /* wqes alloced for sp QPs */
5230Sstevel@tonic-gate 	kcondvar_t		ci_wqes_cv; 	/* wait on wqes destruction */
5240Sstevel@tonic-gate 
5250Sstevel@tonic-gate 	/* port kstats */
5260Sstevel@tonic-gate 	struct kstat		*ci_port_kstatp;	/* kstats for client */
5270Sstevel@tonic-gate } ibmf_ci_t;
5280Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(ibmf_ci_t::ci_ud_dest_list_mutex,
5290Sstevel@tonic-gate     ibmf_ci_t::ci_ud_dest_list_count
5300Sstevel@tonic-gate     ibmf_ci_t::ci_ud_dest_list_head))
5310Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(ibmf_ci_t::ci_mutex,
5320Sstevel@tonic-gate     ibmf_ci_t::ci_state
5330Sstevel@tonic-gate     ibmf_ci_t::ci_port_kstatp))
5340Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(ibmf_ci_t::ci_clients_mutex,
5350Sstevel@tonic-gate     ibmf_ci_t::ci_clients
5360Sstevel@tonic-gate     ibmf_ci_t::ci_clients_last))
5370Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(ibmf_ci_t::ci_mutex,
5380Sstevel@tonic-gate     ibmf_qp_t::iq_next
5390Sstevel@tonic-gate     ibmf_qp_t::iq_flags))
5400Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(ibmf_ci_t::ci_wqe_mutex,
5410Sstevel@tonic-gate     ibmf_ci_t::ci_wqe_mgt_list))
5420Sstevel@tonic-gate _NOTE(READ_ONLY_DATA(ibmf_ci_t::ci_cq_handle))
5430Sstevel@tonic-gate 
5440Sstevel@tonic-gate #define	IBMF_CI_BLOCKED_ON_SEND_WQE		0x00000001 /* blockers on wqe */
5450Sstevel@tonic-gate 
5460Sstevel@tonic-gate /* defines for ci_init_state */
5470Sstevel@tonic-gate #define	IBMF_CI_INIT_HCA_INITED				0x0001
5480Sstevel@tonic-gate #define	IBMF_CI_INIT_MUTEX_CV_INITED			0x0002
5490Sstevel@tonic-gate #define	IBMF_CI_INIT_SEND_TASKQ_DONE			0x0004
5500Sstevel@tonic-gate #define	IBMF_CI_INIT_RECV_TASKQ_DONE			0x0008
5510Sstevel@tonic-gate #define	IBMF_CI_INIT_CQ_INITED				0x0010
5520Sstevel@tonic-gate #define	IBMF_CI_INIT_WQES_ALLOCED			0x0020
5530Sstevel@tonic-gate #define	IBMF_CI_INIT_HCA_LINKED				0x0040
5540Sstevel@tonic-gate #define	IBMF_CI_INIT_QP_LIST_INITED			0x0080
5550Sstevel@tonic-gate 
5560Sstevel@tonic-gate /* defines for ci_state */
5570Sstevel@tonic-gate #define	IBMF_CI_STATE_PRESENT				0x0001
5580Sstevel@tonic-gate #define	IBMF_CI_STATE_INITED				0x0002
5590Sstevel@tonic-gate #define	IBMF_CI_STATE_GONE				0x0003
5600Sstevel@tonic-gate 
5610Sstevel@tonic-gate /* defines for ci_state_flags */
5620Sstevel@tonic-gate #define	IBMF_CI_STATE_INIT_WAIT				0x0001
5630Sstevel@tonic-gate #define	IBMF_CI_STATE_UNINIT_WAIT			0x0002
5640Sstevel@tonic-gate #define	IBMF_CI_STATE_VALIDATE_WAIT			0x0004
5650Sstevel@tonic-gate 
5660Sstevel@tonic-gate #define	IBMF_CI_STATE_INVALIDATING			0x0100
5670Sstevel@tonic-gate #define	IBMF_CI_STATE_VALIDATING			0x0200
5680Sstevel@tonic-gate #define	IBMF_CI_STATE_UNINITING				0x0400
5690Sstevel@tonic-gate #define	IBMF_CI_STATE_INITING				0x0800
5700Sstevel@tonic-gate 
5710Sstevel@tonic-gate /*
5720Sstevel@tonic-gate  * for keeping track of ibmf state
5730Sstevel@tonic-gate  */
5740Sstevel@tonic-gate typedef struct _ibmf_state {
5750Sstevel@tonic-gate 	struct _ibmf_ci		*ibmf_ci_list;
5760Sstevel@tonic-gate 	struct _ibmf_ci		*ibmf_ci_list_tail;
5770Sstevel@tonic-gate 	ibt_clnt_hdl_t		ibmf_ibt_handle;
5780Sstevel@tonic-gate 	ibt_cq_handler_t	ibmf_cq_handler;
5790Sstevel@tonic-gate 	kmutex_t		ibmf_mutex;
5800Sstevel@tonic-gate 	ibt_clnt_modinfo_t	ibmf_ibt_modinfo;
5810Sstevel@tonic-gate 	taskq_t			*ibmf_taskq;	/* taskq for MAD processing */
5820Sstevel@tonic-gate 						/* for classes not registered */
5830Sstevel@tonic-gate } ibmf_state_t;
5840Sstevel@tonic-gate _NOTE(MUTEX_PROTECTS_DATA(ibmf_state_t::ibmf_mutex,
5850Sstevel@tonic-gate     ibmf_ci_t::ci_next))
5860Sstevel@tonic-gate 
5870Sstevel@tonic-gate /* UD Destination resource cache definitions */
5880Sstevel@tonic-gate /*
5890Sstevel@tonic-gate  * It is preferred that the difference between the hi and lo water
5900Sstevel@tonic-gate  * marks be only a few ud_dest resources. The intent is that a
5910Sstevel@tonic-gate  * thread that needs to run ibmf_i_populate_ud_dest_list() does not
5920Sstevel@tonic-gate  * spend too much time in this ud_dest resource population process
5930Sstevel@tonic-gate  * before it returns to its caller. A benefit of a higher lo water
5940Sstevel@tonic-gate  * mark is that the larger available pool of resources supports high
5950Sstevel@tonic-gate  * stress scenarios better.
5960Sstevel@tonic-gate  */
5970Sstevel@tonic-gate #define	IBMF_UD_DEST_HI_WATER_MARK	512
5980Sstevel@tonic-gate #define	IBMF_UD_DEST_LO_WATER_MARK	500
5990Sstevel@tonic-gate 
6000Sstevel@tonic-gate /*
6010Sstevel@tonic-gate  * Prototypes
6020Sstevel@tonic-gate  */
6030Sstevel@tonic-gate /* ci related functions */
6040Sstevel@tonic-gate int ibmf_i_validate_ci_guid_and_port(ib_guid_t hca_guid, uint8_t port_num);
6050Sstevel@tonic-gate int ibmf_i_get_ci(ibmf_register_info_t *client_infop, ibmf_ci_t **cipp);
6060Sstevel@tonic-gate void ibmf_i_release_ci(ibmf_ci_t *cip);
6070Sstevel@tonic-gate 
6080Sstevel@tonic-gate /* client related functions */
6090Sstevel@tonic-gate int ibmf_i_validate_classes_and_port(ibmf_ci_t *ibmf_cip,
6100Sstevel@tonic-gate     ibmf_register_info_t *client_infop);
6110Sstevel@tonic-gate int ibmf_i_validate_class_mask(ibmf_register_info_t *client_infop);
6120Sstevel@tonic-gate int ibmf_i_alloc_client(ibmf_register_info_t *client_infop, uint_t flags,
6130Sstevel@tonic-gate     ibmf_client_t **clientpp);
6140Sstevel@tonic-gate void ibmf_i_add_client(ibmf_ci_t *ibmf_ci, ibmf_client_t *ibmf_clientp);
6150Sstevel@tonic-gate 
6160Sstevel@tonic-gate void ibmf_i_free_client(ibmf_client_t *clientp);
6170Sstevel@tonic-gate void ibmf_i_delete_client(ibmf_ci_t *ibmf_ci, ibmf_client_t *ibmf_clientp);
6180Sstevel@tonic-gate int ibmf_i_lookup_client_by_mgmt_class(ibmf_ci_t *ibmf_cip, int port_num,
6190Sstevel@tonic-gate     ibmf_client_type_t class, ibmf_client_t **clientpp);
6200Sstevel@tonic-gate 
6210Sstevel@tonic-gate /* qp related functions */
6220Sstevel@tonic-gate int ibmf_i_get_qp(ibmf_ci_t *ibmf_cip, uint_t port_num,
6230Sstevel@tonic-gate     ibmf_client_type_t class, ibmf_qp_t **qppp);
6240Sstevel@tonic-gate void ibmf_i_release_qp(ibmf_ci_t *ibmf_cip, ibmf_qp_t **qpp);
6250Sstevel@tonic-gate int ibmf_i_alloc_qp(ibmf_client_t *clientp, ib_pkey_t p_key,
6260Sstevel@tonic-gate     ib_qkey_t q_key, uint_t flags, ibmf_qp_handle_t *ibmf_qp_handlep);
6270Sstevel@tonic-gate int ibmf_i_free_qp(ibmf_qp_handle_t ibmf_qp_handle, uint_t flags);
6280Sstevel@tonic-gate int ibmf_i_query_qp(ibmf_qp_handle_t ibmf_qp_handle, uint_t flags,
6290Sstevel@tonic-gate     uint_t *qp_nump, ib_pkey_t *p_keyp, ib_qkey_t *q_keyp, uint8_t *portnump);
6300Sstevel@tonic-gate int ibmf_i_modify_qp(ibmf_qp_handle_t ibmf_qp_handle, ib_pkey_t p_key,
6310Sstevel@tonic-gate     ib_qkey_t q_key, uint_t flags);
6320Sstevel@tonic-gate int ibmf_i_get_pkeyix(ibt_hca_hdl_t hca_handle, ib_pkey_t pkey,
6330Sstevel@tonic-gate     uint8_t port, ib_pkey_t *pkeyixp);
6340Sstevel@tonic-gate int ibmf_i_pkey_ix_to_key(ibmf_ci_t *cip, uint_t port_num, uint_t pkey_ix,
6350Sstevel@tonic-gate     ib_pkey_t *pkeyp);
6360Sstevel@tonic-gate 
6370Sstevel@tonic-gate /* pkt related functions */
6380Sstevel@tonic-gate int ibmf_i_issue_pkt(ibmf_client_t *clientp, ibmf_msg_impl_t *msgp,
6390Sstevel@tonic-gate     ibmf_qp_handle_t ibmf_qp_handle, ibmf_send_wqe_t *send_wqep);
6400Sstevel@tonic-gate int ibmf_i_alloc_ud_dest(ibmf_client_t *clientp,
6410Sstevel@tonic-gate     ibmf_msg_impl_t *msgimplp, ibt_ud_dest_hdl_t *ud_dest_p, boolean_t block);
6420Sstevel@tonic-gate void ibmf_i_free_ud_dest(ibmf_client_t *clientp,
6430Sstevel@tonic-gate     ibmf_msg_impl_t *msgimplp);
6440Sstevel@tonic-gate void ibmf_i_init_ud_dest(ibmf_ci_t *cip);
6450Sstevel@tonic-gate void ibmf_i_fini_ud_dest(ibmf_ci_t *cip);
6460Sstevel@tonic-gate ibmf_ud_dest_t *ibmf_i_get_ud_dest(ibmf_ci_t *cip);
6470Sstevel@tonic-gate void ibmf_i_put_ud_dest(ibmf_ci_t *cip, ibmf_ud_dest_t *ud_dest);
6480Sstevel@tonic-gate void ibmf_i_pop_ud_dest_thread(void *argp);
6490Sstevel@tonic-gate void ibmf_i_clean_ud_dest_list(ibmf_ci_t *cip, boolean_t all);
6500Sstevel@tonic-gate int ibmf_i_alloc_send_resources(ibmf_ci_t *cip, ibmf_msg_impl_t *msgp,
6510Sstevel@tonic-gate     boolean_t block, ibmf_send_wqe_t **swqepp);
6520Sstevel@tonic-gate void ibmf_i_free_send_resources(ibmf_ci_t *cip, ibmf_msg_impl_t *msgimplp,
6530Sstevel@tonic-gate     ibmf_send_wqe_t *swqep);
6540Sstevel@tonic-gate int ibmf_i_post_recv_buffer(ibmf_ci_t *cip, ibmf_qp_t *qpp, boolean_t block,
6550Sstevel@tonic-gate     ibmf_qp_handle_t ibmf_qp_handle);
6560Sstevel@tonic-gate int ibmf_i_is_ibmf_handle_valid(ibmf_handle_t ibmf_handle);
6570Sstevel@tonic-gate int ibmf_i_is_qp_handle_valid(ibmf_handle_t ibmf_handle,
6580Sstevel@tonic-gate     ibmf_qp_handle_t ibmf_qp_handle);
6590Sstevel@tonic-gate int ibmf_i_check_for_loopback(ibmf_msg_impl_t *msgimplp, ibmf_msg_cb_t msgp,
6600Sstevel@tonic-gate     void *msg_cb_args, ibmf_retrans_t *retrans, boolean_t *loopback);
6610Sstevel@tonic-gate int ibmf_i_ibt_to_ibmf_status(ibt_status_t ibt_status);
6620Sstevel@tonic-gate int ibmf_i_ibt_wc_to_ibmf_status(ibt_wc_status_t ibt_wc_status);
6630Sstevel@tonic-gate int ibmf_i_send_pkt(ibmf_client_t *clientp, ibmf_qp_handle_t ibmf_qp_handle,
6640Sstevel@tonic-gate     ibmf_msg_impl_t *msgimplp, int block);
6650Sstevel@tonic-gate int ibmf_i_send_single_pkt(ibmf_client_t *clientp,
6660Sstevel@tonic-gate     ibmf_qp_handle_t ibmf_qp_handle, ibmf_msg_impl_t *msgimplp, int block);
6670Sstevel@tonic-gate 
6680Sstevel@tonic-gate /* WQE related functions */
6690Sstevel@tonic-gate int ibmf_i_init_wqes(ibmf_ci_t *cip);
6700Sstevel@tonic-gate void ibmf_i_fini_wqes(ibmf_ci_t *cip);
6710Sstevel@tonic-gate void ibmf_i_init_send_wqe(ibmf_client_t *clientp,
6720Sstevel@tonic-gate     ibmf_msg_impl_t *msgimplp, ibt_wr_ds_t *sglp, ibmf_send_wqe_t *wqep,
6730Sstevel@tonic-gate     ibt_ud_dest_hdl_t ud_dest, ibt_qp_hdl_t ibt_qp_handle,
6740Sstevel@tonic-gate     ibmf_qp_handle_t ibmf_qp_handle);
6750Sstevel@tonic-gate void ibmf_i_init_recv_wqe(ibmf_qp_t *qpp, ibt_wr_ds_t *sglp,
6760Sstevel@tonic-gate     ibmf_recv_wqe_t *wqep, ibt_qp_hdl_t ibt_qp_handle,
6770Sstevel@tonic-gate     ibmf_qp_handle_t ibmf_qp_handle);
6780Sstevel@tonic-gate void ibmf_i_mad_completions(ibt_cq_hdl_t cq_handle, void *arg);
6790Sstevel@tonic-gate #ifdef DEBUG
6800Sstevel@tonic-gate void ibmf_i_dump_wcp(ibmf_ci_t *cip, ibt_wc_t *wcp, ibmf_recv_wqe_t *recv_wqep);
6810Sstevel@tonic-gate #endif
6820Sstevel@tonic-gate 
6830Sstevel@tonic-gate void ibmf_ibt_async_handler(void *clnt_private, ibt_hca_hdl_t hca_hdl,
6840Sstevel@tonic-gate     ibt_async_code_t code, ibt_async_event_t *event);
6850Sstevel@tonic-gate 
6860Sstevel@tonic-gate /* msg related functions */
6870Sstevel@tonic-gate void ibmf_i_init_msg(ibmf_msg_impl_t *msgimplp, ibmf_msg_cb_t trans_cb,
6880Sstevel@tonic-gate     void *trans_cb_arg, ibmf_retrans_t *retrans, boolean_t block);
6890Sstevel@tonic-gate void ibmf_i_client_add_msg(ibmf_client_t *clientp, ibmf_msg_impl_t *msgimplp);
6900Sstevel@tonic-gate void ibmf_i_client_rem_msg(ibmf_client_t *clientp, ibmf_msg_impl_t *msgimplp,
6910Sstevel@tonic-gate     uint_t *refcnt);
6920Sstevel@tonic-gate int ibmf_i_alloc_msg(ibmf_client_t *clientp, ibmf_msg_impl_t **msgp,
6930Sstevel@tonic-gate     int km_flags);
6940Sstevel@tonic-gate void ibmf_i_free_msg(ibmf_msg_impl_t *msgimplp);
6950Sstevel@tonic-gate int ibmf_i_msg_transport(ibmf_client_t *clientp,
6960Sstevel@tonic-gate     ibmf_qp_handle_t ibmf_qp_handle, ibmf_msg_impl_t *msgimplp, int blocking);
6970Sstevel@tonic-gate void ibmf_i_decrement_ref_count(ibmf_msg_impl_t *msgimplp);
6980Sstevel@tonic-gate void ibmf_i_handle_send_completion(ibmf_ci_t *cip, ibt_wc_t *wcp);
6990Sstevel@tonic-gate void ibmf_i_handle_recv_completion(ibmf_ci_t *cip, ibt_wc_t *wcp);
7000Sstevel@tonic-gate int ibmf_setup_recvbuf_on_error(ibmf_msg_impl_t *msgimplp, uchar_t *mad);
7010Sstevel@tonic-gate 
7020Sstevel@tonic-gate /* transaction related functions */
7030Sstevel@tonic-gate void ibmf_i_terminate_transaction(ibmf_client_t *clientp,
7040Sstevel@tonic-gate     ibmf_msg_impl_t *msgimplp, uint32_t status);
7050Sstevel@tonic-gate void ibmf_i_notify_client(ibmf_msg_impl_t *msgimplp);
7060Sstevel@tonic-gate void ibmf_i_notify_sequence(ibmf_client_t *clientp, ibmf_msg_impl_t *msgimplp,
7070Sstevel@tonic-gate     int msg_flags);
7080Sstevel@tonic-gate 
7090Sstevel@tonic-gate /* timer related functions */
7100Sstevel@tonic-gate void ibmf_i_set_timer(void (*func)(void *), ibmf_msg_impl_t *msgimplp,
7110Sstevel@tonic-gate     ibmf_timer_t type);
7120Sstevel@tonic-gate void ibmf_i_unset_timer(ibmf_msg_impl_t *msgimplp, ibmf_timer_t type);
7130Sstevel@tonic-gate void ibmf_i_recv_timeout(void *argp);
7140Sstevel@tonic-gate void ibmf_i_send_timeout(void *argp);
7150Sstevel@tonic-gate void ibmf_i_err_terminate_timeout(void *msgp);
7160Sstevel@tonic-gate 
7170Sstevel@tonic-gate /* rmpp related functions */
7180Sstevel@tonic-gate boolean_t ibmf_i_find_msg_client(ibmf_client_t *cl, ibmf_msg_impl_t *msgimplp,
7190Sstevel@tonic-gate     boolean_t inc_refcnt);
7200Sstevel@tonic-gate boolean_t ibmf_i_is_rmpp(ibmf_client_t *clientp,
7210Sstevel@tonic-gate     ibmf_qp_handle_t ibmf_qp_handle);
7220Sstevel@tonic-gate void ibmf_i_mgt_class_to_hdr_sz_off(uint32_t mgt_class, uint32_t *szp,
7230Sstevel@tonic-gate     uint32_t *offp);
7240Sstevel@tonic-gate ibmf_msg_impl_t *ibmf_i_find_msg(ibmf_client_t *clientp, uint64_t tid,
7250Sstevel@tonic-gate     uint8_t mgt_class, uint8_t r_method, ib_lid_t lid, ib_gid_t *gid,
7260Sstevel@tonic-gate     boolean_t gid_pr, ibmf_rmpp_hdr_t *rmpp_hdr, boolean_t msg_list);
7270Sstevel@tonic-gate #ifdef NOTDEF
7280Sstevel@tonic-gate ibmf_msg_impl_t *ibmf_i_find_term_msg(ibmf_client_t *clientp, uint64_t tid,
7290Sstevel@tonic-gate     uint8_t mgt_class, ib_lid_t lid, ib_gid_t *gid, boolean_t gid_pr,
7300Sstevel@tonic-gate     ibmf_rmpp_hdr_t *rmpp_hd);
7310Sstevel@tonic-gate #endif
7320Sstevel@tonic-gate void ibmf_i_handle_rmpp(ibmf_client_t *clientp, ibmf_qp_handle_t qp_hdl,
7330Sstevel@tonic-gate     ibmf_msg_impl_t *msgimpl, uchar_t *madp);
7340Sstevel@tonic-gate int ibmf_i_send_rmpp(ibmf_msg_impl_t *msgimplp, uint8_t rmpp_type,
7350Sstevel@tonic-gate     uint8_t rmpp_status, uint32_t segno, uint32_t nwl, int block);
7360Sstevel@tonic-gate int ibmf_i_send_rmpp_pkts(ibmf_client_t *clientp,
7370Sstevel@tonic-gate     ibmf_qp_handle_t ibmf_qp_handle, ibmf_msg_impl_t *msgimplp, boolean_t isDS,
7380Sstevel@tonic-gate     int block);
7390Sstevel@tonic-gate void ibmf_i_send_rmpp_window(ibmf_msg_impl_t *msgimplp, int block);
7400Sstevel@tonic-gate int ibmf_setup_term_ctx(ibmf_client_t *clientp, ibmf_msg_impl_t *regmsgimplp);
7410Sstevel@tonic-gate 
7420Sstevel@tonic-gate /* Alternate QP WQE cache functions */
7430Sstevel@tonic-gate int ibmf_altqp_send_wqe_cache_constructor(void *buf, void *cdrarg,
7440Sstevel@tonic-gate     int kmflags);
7450Sstevel@tonic-gate void ibmf_altqp_send_wqe_cache_destructor(void *buf, void *cdrarg);
7460Sstevel@tonic-gate int ibmf_altqp_recv_wqe_cache_constructor(void *buf, void *cdrarg,
7470Sstevel@tonic-gate     int kmflags);
7480Sstevel@tonic-gate void ibmf_altqp_recv_wqe_cache_destructor(void *buf, void *cdrarg);
7490Sstevel@tonic-gate int ibmf_i_init_altqp_wqes(ibmf_alt_qp_t *qp_ctx);
7500Sstevel@tonic-gate void ibmf_i_fini_altqp_wqes(ibmf_alt_qp_t *qp_ctx);
7510Sstevel@tonic-gate int ibmf_i_extend_wqe_cache(ibmf_ci_t *cip, ibmf_qp_handle_t ibmf_qp_handle,
7520Sstevel@tonic-gate     boolean_t block);
7530Sstevel@tonic-gate 
7540Sstevel@tonic-gate /* Receive callback functions */
7550Sstevel@tonic-gate void ibmf_i_recv_cb_setup(ibmf_client_t *clientp);
7560Sstevel@tonic-gate void ibmf_i_recv_cb_cleanup(ibmf_client_t *clientp);
7570Sstevel@tonic-gate void ibmf_i_alt_recv_cb_setup(ibmf_alt_qp_t *qpp);
7580Sstevel@tonic-gate void ibmf_i_alt_recv_cb_cleanup(ibmf_alt_qp_t *qpp);
7590Sstevel@tonic-gate 
7600Sstevel@tonic-gate /* UD Dest population thread */
7610Sstevel@tonic-gate int ibmf_ud_dest_tq_disp(ibmf_ci_t *cip);
7620Sstevel@tonic-gate 
7630Sstevel@tonic-gate #ifdef __cplusplus
7640Sstevel@tonic-gate }
7650Sstevel@tonic-gate #endif
7660Sstevel@tonic-gate 
7670Sstevel@tonic-gate #endif /* _SYS_IB_MGT_IBMF_IBMF_IMPL_H */
768