xref: /illumos-gate/usr/src/uts/common/sys/ib/ibtl/impl/ibtl.h (revision 7830165bb404e703a4653a49ad9fe110003bde03)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef _SYS_IB_IBTL_IMPL_IBTL_H
27 #define	_SYS_IB_IBTL_IMPL_IBTL_H
28 
29 /*
30  * ibtl.h
31  *
32  * All data structures and function prototypes that are specific to the
33  * IBTL implementation.
34  */
35 #include <sys/note.h>
36 #include <sys/ib/ibtl/ibvti.h>
37 #include <sys/ib/ibtl/ibti.h>
38 #include <sys/ib/ibtl/ibci.h>
39 #include <sys/ib/ibtl/impl/ibtl_util.h>
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 
45 /*
46  * Define a per IBT Client state structure. Its address is returned
47  * to the IBT client as an opaque IBT Client Handle - ibt_clnt_hdl_t.
48  *
49  * ibt_attach() allocates one of these structures.
50  *
51  * For each IBT Client registered with the IBTL, we maintain a list
52  * of HCAs, clnt_hca_list, that this IBT Client is using.
53  *
54  * This list is updated by ibt_open_hca().
55  */
56 typedef struct ibtl_clnt_s {
57 	char			clnt_name[8];	/* (just a debugging aid) */
58 	ibt_clnt_modinfo_t	*clnt_modinfop;	/* Pointer to IBT client's */
59 						/* module information */
60 	void			*clnt_private;	/* IBT Client's private ptr */
61 	dev_info_t		*clnt_dip;	/* IBT Client's dip */
62 	struct	ibtl_clnt_s	*clnt_list_link;
63 	uint32_t		clnt_async_cnt;
64 	uint32_t		clnt_srv_cnt;	/* Service resource counter */
65 	struct	ibtl_hca_s	*clnt_hca_list;	/* HCAs this client is using. */
66 						/* link is ha_hca_link */
67 	ibt_sm_notice_handler_t	clnt_sm_trap_handler; /* may be NULL */
68 	void			*clnt_sm_trap_handler_arg;
69 } ibtl_clnt_t;
70 
71 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibtl_clnt_s::{clnt_name clnt_modinfop
72     clnt_private clnt_dip}))
73 
74 /* HCA Device State. */
75 typedef enum ibtl_hca_state_e {
76 	IBTL_HCA_DEV_ATTACHED	= 1,	/* new HCA attached */
77 	IBTL_HCA_DEV_DETACHED	= 2,	/* detached */
78 	IBTL_HCA_DEV_DETACHING	= 3	/* not detached yet */
79 } ibtl_hca_state_t;
80 
81 /*
82  * Define a type to record hca async PORT_UP and PORT_DOWN events for
83  * processing by async thread(s). At the time an async is made by an
84  * HCA driver (presumably at interrupt level), a call is made to IBTL.
85  * IBTL marks this field, and wakes up an async thread for delivery
86  * to IBT clients as appropriate.
87  */
88 
89 typedef enum ibtl_async_port_status_e {
90 	IBTL_HCA_PORT_UNKNOWN	= 0x0,	/* initial state */
91 	IBTL_HCA_PORT_UP	= 0x1,
92 	IBTL_HCA_PORT_DOWN	= 0x2,
93 	IBTL_HCA_PORT_CHANGED	= 0x4
94 } ibtl_async_port_status_t;
95 
96 /*
97  * Bit definition(s) for {qp,cq,eec,hd,ha,srq}_async_flags.
98  *
99  *	IBTL_ASYNC_PENDING	This structure is known by the async_threads.
100  *				It will be checked for additional async work
101  *				before this bit is cleared, so new async
102  *				events/errors do not require this structure
103  *				to be linked onto its async list.
104  *
105  *	IBTL_ASYNC_FREE_OBJECT  Client has called ibt_free_*, and the
106  *				the structure should be kmem_freed when
107  *				the outstanding asyncs complete.
108  */
109 typedef enum ibtl_async_flags_e {
110 	IBTL_ASYNC_PENDING	= 0x1,
111 	IBTL_ASYNC_FREE_OBJECT	= 0x2
112 } ibtl_async_flags_t;
113 
114 /*
115  * Keeps track of all data associated with HCA port kstats.
116  */
117 typedef struct ibtl_hca_port_kstat_s {
118 	struct ibtl_hca_devinfo_s *pks_hca_devp;
119 	uint_t			pks_port_num;
120 	struct kstat		*pks_stats_ksp;
121 	struct kstat		*pks_pkeys_ksp;
122 } ibtl_hca_port_kstat_t;
123 
124 /*
125  * Define a per CI HCA Device structure. Its address is returned
126  * to the CI as an opaque IBTL HCA Handle - ibc_hdl_t.
127  *
128  * ibc_ci_attach() allocates one of these and adds it to ibtl_hca_list.
129  *
130  * The hd_hca_dev_link is the link for the ibtl_hca_list. It is the
131  * list of HCA devices registered with the IBTL.
132  *
133  * The hd_clnt_list is a list of IBT Clients using this HCA.
134  * The hd_clnt_list->l_head points to the ha_clnt_link field of a client's
135  * ibtl_hca_s structure.
136  *
137  * This list is updated by ibt_open_hca().
138  */
139 typedef struct ibtl_hca_devinfo_s {
140 	struct ibtl_hca_devinfo_s *hd_hca_dev_link; /* Next HCA Device */
141 	ibtl_hca_state_t	hd_state;	/* HCA device state: */
142 						/* attached/detached */
143 	uint_t			hd_portinfo_len; /* #bytes of portinfo */
144 	ibt_hca_portinfo_t	*hd_portinfop;	/* ptr to portinfo cache */
145 	struct ibtl_hca_s	*hd_clnt_list;	/* IBT Client using this HCA. */
146 	ibc_hca_hdl_t		hd_ibc_hca_hdl;	/* CI HCA handle */
147 	ibc_operations_t	*hd_ibc_ops;	/* operations vector */
148 	ibt_hca_attr_t		*hd_hca_attr;	/* hca attributes */
149 	dev_info_t		*hd_hca_dip;	/* HCA devinfo pointer */
150 	struct ibtl_hca_devinfo_s *hd_async_link; /* async list link */
151 	kcondvar_t		hd_portinfo_cv;	/* waiting for ibc_query */
152 	int			hd_portinfo_waiters; /* any waiters */
153 	uint8_t			hd_portinfo_locked_port;
154 						/* port whose info is queried */
155 	kcondvar_t		hd_async_busy_cv; /* wakeup when #clients = 0 */
156 	int			hd_async_busy;	/* only 1 async at a time */
157 	ibt_async_code_t	hd_async_codes;	/* all codes for this HCA */
158 	ibt_async_code_t	hd_async_code;	/* current code being run */
159 	ibt_async_event_t	hd_async_event;	/* current event being run */
160 	ibtl_async_flags_t	hd_async_flags;	/* see *_async_flags above */
161 	uint64_t		hd_fma_ena;	/* FMA data for LOCAL CATASTR */
162 	uint32_t		hd_async_task_cnt; /* #clients doing asyncs */
163 	kcondvar_t		hd_async_task_cv; /* wakeup when #clients = 0 */
164 	uint_t			hd_multism;	/* 1 - MultiSM, 0 - Single SM */
165 	ibtl_hca_port_kstat_t	*hd_hca_port_ks_info;	/* port kstat ptr */
166 	uint_t			hd_hca_port_ks_info_len; /* port kstat size */
167 		/* The following must be at the end of this struct */
168 	ibtl_async_port_status_t hd_async_port[1]; /* per-port async data */
169 } ibtl_hca_devinfo_t;
170 
171 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibtl_hca_devinfo_s::hd_ibc_ops))
172 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibtl_hca_devinfo_s::hd_ibc_hca_hdl))
173 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibtl_hca_devinfo_s::hd_hca_attr))
174 _NOTE(SCHEME_PROTECTS_DATA("hd_async_busy and hd_async_busy_cv",
175     ibtl_hca_devinfo_s::{hd_async_code hd_async_event}))
176 
177 /*
178  * Define a HCA info structure.
179  *
180  * The IBTL function ibt_open_hca() allocates one of these.
181  *
182  * For each client instance registered with the IBTL, we maintain a list
183  * of HCAs that it is using.  The elements of that list include the
184  * address of the CI HCA device structure, a pointer to the client
185  * structure, and reference counts of HCA resources that this client
186  * device is using.
187  *
188  * Note: ha_qpn_cnt is protected by a global mutex to deal with a client
189  * trying to open the HCA while it is actively being closed.
190  *
191  * ha_hca_link is the link to the next HCA info struct that this client is
192  * using.
193  *
194  * ha_clnt_link is the link to the next IBT client (ibtl_clnt_t) that is using
195  * the same CI HCA (ibtl_hca_devinfo_t). The link points to that client's
196  * ibtl_hca_t because an IBT client can use more than one CI HCA.
197  */
198 typedef struct ibtl_hca_s {
199 	struct ibtl_hca_s	*ha_hca_link;	/* Next HCA used by client */
200 	struct ibtl_hca_s	*ha_clnt_link;	/* Next client using same HCA */
201 	ibtl_hca_devinfo_t	*ha_hca_devp;	/* CI HCA device structure. */
202 	ibtl_clnt_t		*ha_clnt_devp;	/* Client state struct */
203 	void			*ha_clnt_private;
204 	kmutex_t		ha_mutex;	/* Mutex to protect resource */
205 						/* counters. */
206 	int			ha_flags;	/* misc. flags */
207 	uint32_t		ha_qp_cnt;	/* QP resource counter */
208 	uint32_t		ha_eec_cnt;	/* EEC resource counter */
209 	uint32_t		ha_cq_cnt;	/* CQ resource counter */
210 	uint32_t		ha_pd_cnt;	/* PD resource counter */
211 	uint32_t		ha_ah_cnt;	/* AH resource counter */
212 	uint32_t		ha_mr_cnt;	/* Mem Region resource count */
213 	uint32_t		ha_mw_cnt;	/* Mem Window resource count */
214 	uint32_t		ha_qpn_cnt;	/* QPN resource counter */
215 	uint32_t		ha_srq_cnt;	/* SRQ resource counter */
216 	ibtl_async_flags_t	ha_async_flags;	/* see *_async_flags above */
217 	uint32_t		ha_async_cnt;	/* #asyncs in progress */
218 	uint32_t		ha_fmr_pool_cnt; /* FMR Pool resource count */
219 	uint32_t		ha_ma_cnt;	/* Mem Area resource count */
220 } ibtl_hca_t;
221 
222 /* ha_flags values */
223 #define	IBTL_HA_CLOSING	1	/* In process of closing, so don't allow open */
224 
225 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibtl_hca_s::ha_clnt_devp))
226 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibtl_hca_s::ha_hca_devp))
227 
228 /*
229  * Bit definition(s) for cq_impl_flags.
230  *
231  *	IBTL_CQ_PENDING		This CQ is known by the ibtl_cq_threads,
232  *				and it will be checked for additional work
233  *				before this bit is cleared, so new work
234  *				will be seen without this cq being added
235  *				to the cq list.
236  *
237  *	IBTL_CQ_CALL_CLIENT	Mark that the HCA driver has called
238  *				ibc_cq_handler with new work on this CQ,
239  *				so IBTL should call the client handler
240  *				again before it is considered done.
241  *
242  *	IBTL_CQ_FREE		Mark that ibt_free_cq is sleeping until
243  *				ibtl_cq_threads is done with this CQ.
244  */
245 typedef enum ibtl_cq_impl_flags_e {
246 	IBTL_CQ_PENDING		= 0x1,
247 	IBTL_CQ_CALL_CLIENT	= 0x2,
248 	IBTL_CQ_FREE		= 0x4
249 } ibtl_cq_impl_flags_t;
250 
251 
252 /*
253  * Define a per CQ state structure.
254  *
255  * The ibt_alloc_cq() allocates one of these. A CQ is associated with a
256  * particular HCA, whose handle is recorded in the cq_hca field.
257  * The cq_ibc_cq_hdl field is initialized with the CI CQ handle returned
258  * from the ibc_alloc_cq() call to the HCA driver.
259  *
260  * In order to set/get the client's private data, cq_clnt_private, clients
261  * need to use ibt_set_cq_private() and ibt_get_cq_private() calls.
262  *
263  * An IBT client registers a CQ completion handler callback and private
264  * callback argument (probably the client instance soft state structure) using
265  * the ibt_set_cq_handler() IBT routine. The comp_handler, arg fields of the
266  * structure are initialized with the values passed in by the IBTL client.
267  * These two fields are the only fields protected by the cq_mutex.
268  *
269  * When a completion event is posted to an IBT client, the
270  * client completion handler is called with the following arguments:
271  *
272  *	- The Client Handle, that is passed into the IBTL on ibt_attach call.
273  *	- The CQ Handle upon which the completion occurred.
274  *	- The private client argument, set during handler registration via
275  *	  ibt_set_cq_handler() call.
276  *
277  * The address of the ibtl_cq_s structure is passed in as the ibt_cq_hdl_t
278  * (callback arg) in the CI ibc_alloc_cq() function. Thus when a CI calls
279  * the IBTL completion handler (ibc_ci_cq_handler()) we can de-mux
280  * directly to the targeted IBT client.
281  *
282  */
283 typedef struct ibtl_cq_s {
284 	ibc_cq_hdl_t		cq_ibc_cq_hdl;	/* CI CQ handle */
285 	ibtl_hca_t		*cq_hca;	/* IBTL HCA hdl */
286 	ibt_cq_handler_t	cq_comp_handler; /* Completion handler */
287 	void			*cq_arg;	/* CQ handler's argument */
288 	kmutex_t		cq_mutex;	/* Mutex. */
289 	void			*cq_clnt_private; /* Client's Private. */
290 	struct ibtl_cq_s	*cq_link;	/* link for queuing cq to */
291 						/* to be handled in a thread */
292 	struct ibtl_cq_s	*cq_async_link;	/* list link for asyncs */
293 	ibtl_cq_impl_flags_t	cq_impl_flags;	/* dynamic bits if cq */
294 						/* handler runs in a thread */
295 	int			cq_in_thread;	/* mark if cq handler is to */
296 						/* be called in a thread */
297 	ibt_async_code_t	cq_async_codes;
298 	ibtl_async_flags_t	cq_async_flags;	/* see *_async_flags above */
299 	uint64_t		cq_fma_ena;	/* FMA data */
300 } ibtl_cq_t;
301 
302 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibtl_cq_s::{cq_in_thread cq_hca
303     cq_ibc_cq_hdl}))
304 
305 /*
306  * Define a per SRQ state structure.
307  *
308  * ibt_alloc_srq() allocates one of these. A SRQ is associated with a
309  * particular HCA, whose handle is recorded in the srq_hca field.
310  * The srq_ibc_srq_hdl field is initialized with the CI SRQ handle returned
311  * from the ibc_alloc_srq() call to the HCA driver.
312  *
313  * In order to set/get the client's private data, srq_clnt_private, clients
314  * need to use ibt_set_srq_private() and ibt_get_srq_private() calls.
315  *
316  * The address of the ibtl_srq_s structure is passed in as the ibt_srq_hdl_t
317  * (callback arg) in the CI ibc_alloc_srq() function.
318  */
319 typedef struct ibtl_srq_s {
320 	ibc_srq_hdl_t		srq_ibc_srq_hdl;	/* CI SRQ handle */
321 	ibtl_hca_t		*srq_hca;		/* IBTL HCA hdl */
322 	void			*srq_clnt_private;	/* Client's Private. */
323 	struct ibtl_srq_s	*srq_async_link;	/* Async Link list */
324 	ibt_async_code_t	srq_async_codes;
325 	ibtl_async_flags_t	srq_async_flags;	/* Async_flags */
326 	uint64_t		srq_fma_ena;		/* FMA data */
327 } ibtl_srq_t;
328 
329 /*
330  * Define a per QP state structure.
331  *
332  * The qp_hca field is initialized with the ibtl_hca_hdl_t of the HCA in
333  * which the QP was allocated. The qp_ibc_qp_hdl field is initialized with
334  * the CI QP handle.
335  *
336  * The ibtl_qp_t structure also maintains a channel connection state
337  * structure that is only valid for RC and RD QP's. The information about
338  * the respective Send and Receive CQ, the RDD and PD Handles are also stored.
339  *
340  * The IBTA spec does not include the signal type or PD on a QP query
341  * operation. In order to implement the "CLONE" feature of the alloc rc|ud
342  * channel functions we need to cache these values.
343  */
344 typedef struct ibtl_qp_s {
345 	ibt_tran_srv_t		qp_type;	/* QP type */
346 	ibt_attr_flags_t	qp_flags;
347 	ibc_qp_hdl_t		qp_ibc_qp_hdl;	/* CI QP handle */
348 	ibc_pd_hdl_t		qp_pd_hdl;	/* CI PD Hdl */
349 	ibtl_hca_t		*qp_hca;	/* IBTL HCA handle */
350 	ibtl_cq_t		*qp_send_cq;	/* IBTL CQ handle */
351 	ibtl_cq_t		*qp_recv_cq;	/* IBTL CQ handle */
352 	struct ibtl_qp_s	*qp_async_link;	/* async list link */
353 	ibt_async_code_t	qp_async_codes;
354 	ibtl_async_flags_t	qp_async_flags;	/* see *_async_flags above */
355 	uint64_t		qp_cat_fma_ena;	/* FMA data */
356 	uint64_t		qp_pth_fma_ena;	/* FMA data */
357 	uint64_t		qp_inv_fma_ena;	/* FMA data */
358 	uint64_t		qp_acc_fma_ena;	/* FMA data */
359 } ibtl_qp_t;
360 
361 
362 /*
363  * Define a per EEC state structure.
364  *
365  * The ibt_alloc_eec() allocates an ibt_eec_s structure and initializes
366  * the eec_hca field with the ibtl_hca_hdl_t of the HCA in which the EEC
367  * was allocated. The eec_ibc_eec_hdl field is initialized with the
368  * CI EEC handle.
369  *
370  * The information about CI's RDD Handle and channel connection state structure
371  * is also maintained.
372  */
373 typedef struct ibtl_eec_s {
374 	ibc_eec_hdl_t		eec_ibc_eec_hdl;	/* CI EEC Handle. */
375 	ibtl_hca_t		*eec_hca;		/* IBTL HCA Hdl */
376 	ibc_rdd_hdl_t		eec_ibc_rdd_hdl;	/* CI RDD Handle. */
377 	struct ibtl_channel_s	*eec_channel;
378 	struct ibtl_eec_s	*eec_async_link;	/* async list link */
379 	ibt_async_code_t	eec_async_codes;
380 	ibtl_async_flags_t	eec_async_flags;
381 	uint64_t		eec_cat_fma_ena;	/* FMA data */
382 	uint64_t		eec_pth_fma_ena;	/* FMA data */
383 } ibtl_eec_t;
384 
385 /*
386  * Define an ibt RD communication channel struct. This holds information
387  * specific to an RD QP.
388  */
389 typedef struct ibtl_rd_chan_s {
390 	ibtl_eec_t		*rd_eec;	/* point to the EEC */
391 } ibtl_rd_chan_t;
392 
393 /*
394  * Define an ibt UD communication channel struct. This holds information
395  * specific to a UD QP.
396  */
397 typedef struct ibtl_ud_chan_s {
398 	uint8_t			ud_port_num;	/* track the port number for */
399 						/* ibt_modify_reply_ud_dest() */
400 	ib_qkey_t		ud_qkey;	/* track the qkey */
401 } ibtl_ud_chan_t;
402 
403 /*
404  * Define an ibt RC communication channel struct. This holds information
405  * specific to an RC QP.
406  */
407 typedef struct ibtl_rc_chan_s {
408 	int			rc_free_flags;	/* Track connection state as */
409 						/* we will need to delay for */
410 						/* TIMEWAIT before freeing. */
411 	ibc_qpn_hdl_t		rc_qpn_hdl;	/* Store qpn_hdl while in */
412 						/* TIMEWAIT delay. */
413 } ibtl_rc_chan_t;
414 
415 /* bit definitions for rc_free_flags */
416 #define	IBTL_RC_QP_CONNECTED	0x1
417 #define	IBTL_RC_QP_CLOSING	0x2
418 #define	IBTL_RC_QP_CLOSED	0x4
419 #define	IBTL_RC_QP_FREED	0x8
420 
421 /*
422  * Define a per Channel state structure.
423  *
424  * A ibtl_channel_s is allocated each time a TI client calls a
425  * channel allocation routine ibt_alloc_rc_channel() or ibt_alloc_ud_channel()
426  * or VTI client calls ibt_alloc_qp() or ibt_alloc_special_qp().
427  *
428  * In order to set/get the client's private data, ch_clnt_private,
429  * TI client's need to use ibt_set_chan_private() and ibt_get_chan_private()
430  * or VTI clients need to use ibt_set_qp_private() and ibt_get_qp_private().
431  */
432 typedef struct ibtl_channel_s {
433 	/* The ibtl_qp_t must be at the first of this struct */
434 	ibtl_qp_t		ch_qp;		/* IBTL QP handle */
435 	union {					/* transport specific */
436 		ibtl_rc_chan_t	rc;		/* RC Channel specific */
437 		ibtl_rd_chan_t	rd;		/* RD Channel specific */
438 		ibtl_ud_chan_t	ud;		/* UD Channel specific */
439 	} ch_transport;
440 	ibt_cep_state_t		ch_current_state; /* track the current state */
441 	void			*ch_clnt_private; /* Client's Private data */
442 	kmutex_t		ch_cm_mutex;	/* for ch_cm_private, etc. */
443 	kcondvar_t		ch_cm_cv;	/* for recycle_rc */
444 	void			*ch_cm_private;	/* Ptr to CM state */
445 } ibtl_channel_t;
446 
447 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibtl_channel_s))
448 
449 /*
450  * MACROS
451  */
452 #define	IBTL_CHAN2QP(ibt_chan)		(&(ibt_chan)->ch_qp)
453 #define	IBTL_CHAN2HCA(ibt_chan)		(ibt_chan)->ch_qp.qp_hca
454 
455 #define	IBTL_CHAN2CIQP(ibt_chan)	(ibt_chan->ch_qp.qp_ibc_qp_hdl)
456 
457 #define	IBTL_QP2CHAN(ibtl_qp)		(ibtl_channel_t *)(ibtl_qp)
458 #define	IBTL_EEC2CHAN(ibtl_eec)		(ibtl_eec)->eec_channel
459 
460 /*
461  * Get IBC HCA Handle from IBT Handles.
462  */
463 #define	IBTL_HDIP2CIHCA(hca_devp)	(hca_devp)->hd_ibc_hca_hdl
464 #define	IBTL_HCA2CIHCA(ibtl_hca)	IBTL_HDIP2CIHCA(ibtl_hca->ha_hca_devp)
465 #define	IBTL_ECC2CIHCA(ibtl_eec)	IBTL_HCA2CIHCA((ibtl_eec)->eec_hca)
466 #define	IBTL_CQ2CIHCA(ibtl_cq)		IBTL_HCA2CIHCA((ibtl_cq)->cq_hca)
467 #define	IBTL_CHAN2CIHCA(ibt_chan)	IBTL_HCA2CIHCA((ibt_chan)->ch_qp.qp_hca)
468 #define	IBTL_SRQ2CIHCA(ibtl_srq)	IBTL_HCA2CIHCA((ibtl_srq)->srq_hca)
469 
470 /*
471  * Get a pointer to the HCA ops structure from IBT handles.
472  */
473 #define	IBTL_HDIP2CIHCAOPS_P(hca_devp)	(hca_devp)->hd_ibc_ops
474 #define	IBTL_HCA2CIHCAOPS_P(ibtl_hca)	\
475 	IBTL_HDIP2CIHCAOPS_P(ibtl_hca->ha_hca_devp)
476 #define	IBTL_CQ2CIHCAOPS_P(ibtl_cq)	IBTL_HCA2CIHCAOPS_P((ibtl_cq)->cq_hca)
477 #define	IBTL_CHAN2CIHCAOPS_P(ibt_chan)	\
478 	IBTL_HCA2CIHCAOPS_P((ibt_chan)->ch_qp.qp_hca)
479 #define	IBTL_SRQ2CIHCAOPS_P(ibtl_srq)	\
480 	IBTL_HCA2CIHCAOPS_P((ibtl_srq)->srq_hca)
481 
482 /*
483  * Get Client Handle from IBT Handles.
484  */
485 #define	IBTL_HCA2CLNT(ibtl_hca)		(ibtl_hca)->ha_clnt_devp
486 #define	IBTL_ECC2CLNT(ibtl_eec)		IBTL_HCA2CLNT((ibtl_eec)->eec_hca)
487 #define	IBTL_CQ2CLNT(ibtl_cq)		IBTL_HCA2CLNT((ibtl_cq)->cq_hca)
488 #define	IBTL_CHAN2CLNT(ibt_chan)	IBTL_HCA2CLNT((ibt_chan)->ch_qp.qp_hca)
489 
490 /*
491  * Get a Pointer to the client modinfo from IBT Handles.
492  */
493 #define	IBTL_HCA2MODI_P(ibtl_hca)	\
494 	((IBTL_HCA2CLNT(ibtl_hca))->clnt_modinfop)
495 
496 #define	IBTL_EEC2MODI_P(ibtl_eec)	\
497 	((IBTL_EEC2CLNT(ibtl_eec))->clnt_modinfop)
498 
499 #define	IBTL_CQ2MODI_P(ibtl_cq)		((IBTL_CQ2CLNT(ibtl_cq))->clnt_modinfop)
500 
501 #define	IBTL_CHAN2MODI_P(chan)		((IBTL_CHAN2CLNT(chan))->clnt_modinfop)
502 
503 /*
504  * Using HCA Device Info Pointer, access HCA Attributes values for
505  *	Max SGID Table Size, Max PKEY Table Size.
506  */
507 #define	IBTL_HDIP2SGIDTBLSZ(hca)	\
508 		(hca)->hd_hca_attr->hca_max_port_sgid_tbl_sz
509 #define	IBTL_HDIP2PKEYTBLSZ(hca)	\
510 		(hca)->hd_hca_attr->hca_max_port_pkey_tbl_sz
511 
512 /*
513  * Using IBTL HCA Handle, access HCA Attributes values.
514  *			viz.	HCA Node GUID,
515  *				Number of Ports on this HCA Device,
516  *				Max SGID Table Size
517  *				Max PKEY Table Size
518  */
519 #define	IBTL_HCA2HCAGUID(hca_hdl) \
520 	(hca_hdl)->ha_hca_devp->hd_hca_attr->hca_node_guid
521 #define	IBTL_HCA2NPORTS(hca_hdl) \
522 	(hca_hdl)->ha_hca_devp->hd_hca_attr->hca_nports
523 #define	IBTL_HCA2SGIDTBLSZ(hca_hdl) \
524 	(hca_hdl)->ha_hca_devp->hd_hca_attr->hca_max_port_sgid_tbl_sz
525 #define	IBTL_HCA2PKEYTBLSZ(hca_hdl) \
526 	(hca_hdl)->ha_hca_devp->hd_hca_attr->hca_max_port_pkey_tbl_sz
527 
528 /* possible strlen of a IB driver's name */
529 #define	IBTL_DRVNAME_LEN	40
530 
531 /* strings passed to ib_dprintfN() are this long */
532 #define	IBTL_PRINT_BUF_LEN	4096
533 
534 /* Check if client isn't CM/DM/IBMA */
535 #define	IBTL_GENERIC_CLIENT(clntp) \
536 	(((clntp)->clnt_modinfop->mi_clnt_class != IBT_CM) && \
537 	    ((clntp)->clnt_modinfop->mi_clnt_class != IBT_DM) && \
538 	    ((clntp)->clnt_modinfop->mi_clnt_class != IBT_IBMA))
539 
540 /*
541  * Function Prototypes that are specific to the IBTL implementation.
542  */
543 ibtl_hca_devinfo_t *ibtl_get_hcadevinfo(ib_guid_t hca_guid);
544 ibt_status_t ibtl_init_hca_portinfo(ibtl_hca_devinfo_t *hca_devp);
545 void	ibtl_reinit_hca_portinfo(ibtl_hca_devinfo_t *hca_devp, uint8_t port);
546 
547 void	ibtl_init_cep_states(void);
548 void	ibtl_ib2usec_init(void);
549 void	ibtl_logging_initialization(void);
550 void	ibtl_logging_destroy(void);
551 void	ibtl_thread_init(void);
552 void	ibtl_thread_init2(void);
553 void	ibtl_thread_fini(void);
554 void	ibtl_announce_new_hca(ibtl_hca_devinfo_t *hca_devp);
555 void	ibtl_another_cq_handler_in_thread(void);
556 int	ibtl_detach_all_clients(ibtl_hca_devinfo_t *hcap);
557 void	ibtl_qp_flow_control_enter(void);
558 void	ibtl_qp_flow_control_exit(void);
559 
560 /* synchronization of asyncs when freeing an object */
561 void	ibtl_free_qp_async_check(ibtl_qp_t *ibtl_qp);
562 void	ibtl_free_cq_async_check(ibtl_cq_t *ibtl_cq);
563 void	ibtl_free_srq_async_check(ibtl_srq_t *ibtl_srq);
564 void	ibtl_free_eec_async_check(ibtl_eec_t *ibtl_eec);
565 void	ibtl_free_hca_async_check(ibt_hca_hdl_t ibt_hca);
566 void	ibtl_free_clnt_async_check(ibtl_clnt_t *clntp);
567 
568 /* synchronization of cq_handler callbacks and free_cq */
569 void	ibtl_free_cq_check(ibtl_cq_t *ibtl_cq);
570 
571 /* release_qpn and close_hca synchronization */
572 void	ibtl_close_hca_check(ibt_hca_hdl_t ibt_hca);
573 
574 /* Global List of HCA devices, and associated lock. */
575 extern struct ibtl_hca_devinfo_s *ibtl_hca_list; /* link is hd_hca_dev_link */
576 
577 /* Global List of IBT Client Instances, and associated lock. */
578 extern struct ibtl_clnt_s *ibtl_clnt_list; /* link is clnt_list_link */
579 extern kmutex_t ibtl_clnt_list_mutex;
580 
581 /* Lock for the race between the client and CM to free QPs. */
582 extern kmutex_t ibtl_free_qp_mutex;
583 
584 /* Lock for the race between the client closing the HCA and QPN being freed. */
585 extern kcondvar_t ibtl_close_hca_cv;
586 
587 /* Limit the flow of QP verb calls */
588 extern kmutex_t ibtl_qp_mutex;
589 extern kcondvar_t ibtl_qp_cv;
590 
591 /* Async handlers and client private for well known clients of IBTL */
592 extern ibt_async_handler_t ibtl_cm_async_handler;
593 extern ibt_async_handler_t ibtl_dm_async_handler;
594 extern ibt_async_handler_t ibtl_ibma_async_handler;
595 extern void *ibtl_cm_clnt_private;
596 extern void *ibtl_dm_clnt_private;
597 extern void *ibtl_ibma_clnt_private;
598 
599 /* cache for fast GID => portinfo lookup */
600 extern boolean_t ibtl_fast_gid_cache_valid;
601 
602 
603 /* The following structs are used to pass info in and out of the APIs */
604 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_rc_chan_alloc_args_s))
605 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_rc_chan_query_attr_s))
606 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_rc_chan_modify_attr_s))
607 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_ud_dest_query_attr_s))
608 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_ud_chan_alloc_args_s))
609 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_ud_chan_query_attr_s))
610 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_ud_chan_modify_attr_s))
611 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_ud_dest_s))
612 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_qp_alloc_attr_s))
613 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_qp_info_s))
614 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_hca_portinfo_s))
615 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_adds_vect_s))
616 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_cep_path_s))
617 _NOTE(SCHEME_PROTECTS_DATA("client managed", ibt_mr_desc_s))
618 _NOTE(SCHEME_PROTECTS_DATA("GIDs are transient", ib_gid_s))
619 
620 #ifdef __cplusplus
621 }
622 #endif
623 
624 #endif /* _SYS_IB_IBTL_IMPL_IBTL_H */
625