xref: /illumos-gate/usr/src/uts/common/sys/ib/ibtl/ibti_common.h (revision 6a634c9dca3093f3922e4b7ab826d7bdf17bf78e)
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 (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
23  */
24 
25 #ifndef	_SYS_IB_IBTL_IBTI_COMMON_H
26 #define	_SYS_IB_IBTL_IBTI_COMMON_H
27 
28 /*
29  * ibti_common.h
30  *
31  * This file contains the shared/common transport data types and function
32  * prototypes.
33  */
34 #include <sys/types.h>
35 #include <sys/ib/ib_types.h>
36 #include <sys/ib/ibtl/ibtl_status.h>
37 #include <sys/ib/ibtl/ibtl_types.h>
38 #include <sys/ib/ibtl/ibti_cm.h>
39 #include <sys/isa_defs.h>
40 #include <sys/byteorder.h>
41 
42 #ifdef __cplusplus
43 extern "C" {
44 #endif
45 
46 /*
47  * Max number of paths that can be requested in an ibt_get_paths() call,
48  * if IBT_PATH_PERF or IBT_PATH_AVAIL flag (ibt_path_flags_t) is set.
49  */
50 #define	IBT_MAX_SPECIAL_PATHS	2
51 
52 /*
53  * The name of DDI Event, generated when the properties of IOC device
54  * node properties were modified.
55  */
56 #define	IB_PROP_UPDATE_EVENT	"SUNW,IB:IB_PROP_UPDATE"
57 
58 
59 /* Transport Interface version */
60 typedef int ibt_version_t;
61 #define	IBTI_V1		1
62 #define	IBTI_V2		2
63 #define	IBTI_V3		3
64 #define	IBTI_V4		4
65 #define	IBTI_V_CURR	IBTI_V4
66 
67 /*
68  * Driver class type. Identifies a type of client driver so that
69  * "IBTF Policy" decisions can be made on a driver class basis.
70  * The last class should always be IBT_CLNT_NUM, and any new classes added
71  * must be defined before IBT_CLNT_NUM. The class values must be above 0.
72  * Any class values below or equal to 0 shall be invalid
73  */
74 typedef enum ibt_clnt_class_e {
75 	IBT_STORAGE_DEV = 0x1,	/* SCSI, FC, etc.. */
76 	IBT_NETWORK_DEV,	/* Network driver with associated client H/W */
77 	IBT_GENERIC_DEV,	/* Generic client H/W device driver */
78 	IBT_NETWORK,		/* Network driver with no associated */
79 				/* client H/W, e.g., IPoIB */
80 	IBT_GENERIC,		/* A generic IB driver not */
81 				/* associated with client H/W */
82 	IBT_USER,		/* A user application IBT interface driver */
83 	IBT_IBMA,		/* The IBMA Module */
84 	IBT_CM,			/* The CM Module */
85 	IBT_DM,			/* The DM Module */
86 	IBT_DM_AGENT,		/* DM Agent Module */
87 	IBT_GENERIC_MISC,	/* Generic Misc Module */
88 	IBT_CLASS_NUM		/* Place holder for class count */
89 } ibt_clnt_class_t;
90 
91 #define	IBT_TEST_DEV	999	/* Place holder for modules that test IBTL */
92 
93 #define	IBT_CLNT_DEVICE_CLASS(class)	((class) == IBT_STORAGE_DEV || \
94 					(class) == IBT_NETWORK_DEV || \
95 					(class) == IBT_GENERIC_DEV)
96 
97 #define	IBT_CLNT_GENERAL_CLASS(class)	((class) == IBT_NETWORK || \
98 					(class) == IBT_GENERIC || \
99 					(class) == IBT_DM_AGENT || \
100 					(class) == IBT_TEST_DEV || \
101 					(class) == IBT_GENERIC_MISC ||	\
102 					(class) == IBT_USER)
103 
104 #define	IBT_CLNT_MGMT_CLASS(class)	((class) == IBT_IBMA || \
105 					(class) == IBT_CM || \
106 					(class) == IBT_DM)
107 
108 /*
109  * These are some special client classes which don't have a 'dip' hence have
110  * to be handled specially in ibt_attach, where we bypass the check for a valid
111  * dip if the client belongs to the class below.
112  */
113 #define	IBT_MISCMOD_CLIENTS(class)	((class) == IBT_IBMA || \
114 					(class) == IBT_CM || \
115 					(class) == IBT_DM || \
116 					(class) == IBT_DM_AGENT || \
117 					(class) == IBT_GENERIC_MISC ||	\
118 					(class) == IBT_TEST_DEV)
119 
120 /*
121  * Event record & status returns for asynchronous events and errors.
122  */
123 typedef struct ibt_async_event_s {
124 	uint64_t		ev_fma_ena;		/* FMA Error data */
125 	ibt_channel_hdl_t	ev_chan_hdl;		/* Channel handle */
126 	ibt_cq_hdl_t		ev_cq_hdl;		/* CQ handle */
127 	ib_guid_t		ev_hca_guid;		/* HCA node GUID */
128 	ibt_srq_hdl_t		ev_srq_hdl;		/* SRQ handle */
129 	ibt_port_change_t	ev_port_flags;		/* Port Change flags */
130 	uint8_t			ev_port;		/* HCA port */
131 	ibt_fc_syndrome_t	ev_fc;			/* FEXCH syndrome */
132 } ibt_async_event_t;
133 
134 /*
135  * IBT Client Callback function typedefs.
136  *
137  * ibt_async_handler_t
138  *	Pointer to an async event/error handler function.  This function is
139  *	called when an async event/error is detected on a HCA that is being
140  *	used by the IBT client driver that registered the function.
141  */
142 typedef void (*ibt_async_handler_t)(void *clnt_private,
143     ibt_hca_hdl_t hca_hdl, ibt_async_code_t code, ibt_async_event_t *event);
144 
145 /*
146  * IBT Client Memory Error Callback function typedefs.
147  *
148  * ibt_memory_handler_t
149  *	Pointer to an memory event/error handler function.
150  */
151 typedef void (*ibt_memory_handler_t)(void *clnt_private,
152     ibt_hca_hdl_t hca_hdl, ibt_mem_code_t code, ibt_mem_data_t *data);
153 
154 /*
155  * Define a client module information structure. All clients MUST
156  * define a global of type ibt_clnt_modinfo_t. A pointer to this global
157  * is passed into the IBTF by a client when calling ibt_attach().
158  * This struct must persist during the life of the client.
159  *
160  * The client's mi_async_handler is called when an async event/error is
161  * detected on a HCA that is being used by this client.
162  */
163 typedef struct ibt_clnt_modinfo_s {
164 	ibt_version_t		mi_ibt_version;		/* TI version */
165 	ibt_clnt_class_t	mi_clnt_class;		/* Type of client */
166 	ibt_async_handler_t	mi_async_handler;	/* Async Handler */
167 	ibt_memory_handler_t	mi_reserved;		/* Memory handler */
168 	char			*mi_clnt_name;		/* Client Name. */
169 } ibt_clnt_modinfo_t;
170 
171 
172 /*
173  * Definitions for use with ibt_register_subnet_notices()
174  */
175 typedef enum ibt_subnet_event_code_e {
176 	IBT_SM_EVENT_MCG_CREATED = 1,
177 	IBT_SM_EVENT_MCG_DELETED = 2,
178 	IBT_SM_EVENT_AVAILABLE	 = 3,
179 	IBT_SM_EVENT_UNAVAILABLE = 4,
180 	IBT_SM_EVENT_GID_AVAIL	 = 5,
181 	IBT_SM_EVENT_GID_UNAVAIL = 6
182 } ibt_subnet_event_code_t;
183 
184 typedef struct ibt_subnet_event_s {
185 	ib_gid_t sm_notice_gid;
186 } ibt_subnet_event_t;
187 
188 typedef void (*ibt_sm_notice_handler_t)(void *private, ib_gid_t gid,
189     ibt_subnet_event_code_t code, ibt_subnet_event_t *event);
190 
191 
192 /*
193  * MTU Request type.
194  */
195 typedef struct ibt_mtu_req_s {
196 	ib_mtu_t	r_mtu;		/* Requested MTU */
197 	ibt_selector_t	r_selector;	/* Qualifier for r_mtu */
198 } ibt_mtu_req_t;
199 
200 
201 /*
202  * Qflags, used by ibt_resize_queues().
203  */
204 typedef enum ibt_qflags_e {
205 	IBT_SEND_Q	= 1 << 0,	/* Op applies to the Send Q */
206 	IBT_RECV_Q	= 1 << 1	/* Op applies to the Recv Q */
207 } ibt_qflags_t;
208 
209 
210 /*
211  * ibt_cq_handler_t
212  *	Pointer to a work request completion handler function.  This function
213  *	is called when a WR completes on a CQ that is being used by the IBTF
214  *	client driver that registered the function.
215  */
216 typedef void (*ibt_cq_handler_t)(ibt_cq_hdl_t ibt_cq, void *arg);
217 
218 /* default CQ handler ID */
219 #define	IBT_CQ_HID_DEFAULT	(1)
220 
221 /*
222  * Service Data and flags.
223  *	(IBTA Spec Release 1.1, Vol-1 Ref: 15.2.5.14.4)
224  *
225  * The ServiceData8.1 (sb_data8[0]) through ServiceData64.2 (sb_data64[1])
226  * components together constitutes a 64-byte area in which any data may be
227  * placed. It is intended to be a convenient way for a service to provide its
228  * clients with some initial data.
229  *
230  * In addition, this 64-byte area is formally divided into a total of 30
231  * components, 16 8-bit (uint8_t) components, then 8 16-bit (uint16_t)
232  * components, then 6 32-bit (uint32_t) components, then 2 64-bit (uint64_t)
233  * components,  thereby assigning ComponentMask bits (ibt_srv_data_flags_t) to
234  * variously-sized segments of the data. All data are in host endian format.
235  * This allows query operations (ibt_get_paths()) to be used which match
236  * parts of the Service Data, making it possible, for example, for
237  * service-specific parts of the ServiceData to serve as a binary-coded
238  * extension to the ServiceName for purposes of lookup.
239  */
240 typedef enum ibt_srv_data_flags_e {
241 	IBT_NO_SDATA	= 0,
242 
243 	IBT_SDATA8_0	= (1 << 0),
244 	IBT_SDATA8_1	= (1 << 1),
245 	IBT_SDATA8_2	= (1 << 2),
246 	IBT_SDATA8_3	= (1 << 3),
247 	IBT_SDATA8_4	= (1 << 4),
248 	IBT_SDATA8_5	= (1 << 5),
249 	IBT_SDATA8_6	= (1 << 6),
250 	IBT_SDATA8_7	= (1 << 7),
251 	IBT_SDATA8_8	= (1 << 8),
252 	IBT_SDATA8_9	= (1 << 9),
253 	IBT_SDATA8_10	= (1 << 10),
254 	IBT_SDATA8_11	= (1 << 11),
255 	IBT_SDATA8_12	= (1 << 12),
256 	IBT_SDATA8_13	= (1 << 13),
257 	IBT_SDATA8_14	= (1 << 14),
258 	IBT_SDATA8_15	= (1 << 15),
259 
260 	IBT_SDATA16_0	= (1 << 16),
261 	IBT_SDATA16_1	= (1 << 17),
262 	IBT_SDATA16_2	= (1 << 18),
263 	IBT_SDATA16_3	= (1 << 19),
264 	IBT_SDATA16_4	= (1 << 20),
265 	IBT_SDATA16_5	= (1 << 21),
266 	IBT_SDATA16_6	= (1 << 22),
267 	IBT_SDATA16_7	= (1 << 23),
268 
269 	IBT_SDATA32_0	= (1 << 24),
270 	IBT_SDATA32_1	= (1 << 25),
271 	IBT_SDATA32_2	= (1 << 26),
272 	IBT_SDATA32_3	= (1 << 27),
273 
274 	IBT_SDATA64_0	= (1 << 28),
275 	IBT_SDATA64_1	= (1 << 29),
276 
277 	IBT_SDATA_ALL	= 0x3FFFFFFF
278 } ibt_srv_data_flags_t;
279 
280 typedef struct ibt_srv_data_s {
281 	uint8_t		s_data8[16];	/* 8-bit service data fields. */
282 	uint16_t	s_data16[8];	/* 16-bit service data fields. */
283 	uint32_t	s_data32[4];	/* 32-bit service data fields. */
284 	uint64_t	s_data64[2];	/* 64-bit service data fields. */
285 } ibt_srv_data_t;
286 
287 /*
288  * Path flags, used in ibt_get_paths()
289  */
290 typedef enum ibt_path_flags_e {
291 	IBT_PATH_NO_FLAGS	= 0,
292 	IBT_PATH_APM		= 1 << 0,	/* APM is desired. */
293 	IBT_PATH_AVAIL		= 1 << 2,
294 	IBT_PATH_PERF		= 1 << 3,
295 	IBT_PATH_MULTI_SVC_DEST	= 1 << 4,	/* Multiple ServiceRecords */
296 	IBT_PATH_HOP		= 1 << 5,	/* pa_hop is specified. */
297 	IBT_PATH_PKEY		= 1 << 6	/* pa_pkey is specified. */
298 } ibt_path_flags_t;
299 
300 /*
301  * Path attributes.
302  *
303  * The ibt_path_attr_t structure is used to specify required attributes in a
304  * path from the requesting (source) node to a specified destination node.
305  * Attributes that are don't care should be set to NULL or '0'.
306  * A destination must be specified, where a destination can be defined as
307  * one of the following:
308  *
309  *	o Service Name
310  *	o Service ID (SID)
311  *	o Array of DGIDs.
312  *	o Service Name and Array of DGIDs.
313  */
314 typedef struct ibt_path_attr_s {
315 	ib_gid_t		*pa_dgids;	/* Array of DGIDs */
316 	ib_gid_t		pa_sgid;
317 	ib_guid_t		pa_hca_guid;
318 	char			*pa_sname;	/* ASCII Service name  */
319 						/* NULL Terminated */
320 	ib_svc_id_t		pa_sid;		/* Service ID */
321 	ibt_srv_data_flags_t	pa_sd_flags;	/* Service Data flags. */
322 	ibt_srv_data_t		pa_sdata;	/* Service Data */
323 	uint8_t			pa_hca_port_num;
324 	uint8_t			pa_num_dgids;	/* size of pa_dgids array */
325 	uint8_t			pa_sl:4;
326 	ibt_mtu_req_t		pa_mtu;
327 	ibt_srate_req_t		pa_srate;
328 	ibt_pkt_lt_req_t	pa_pkt_lt;	/* Packet Life Time Request */
329 	uint_t			pa_flow:20;
330 	uint8_t			pa_hop;		/* IBT_PATH_HOP */
331 	uint8_t			pa_tclass;
332 	ib_pkey_t		pa_pkey;	/* IBT_PATH_PKEY */
333 } ibt_path_attr_t;
334 
335 /*
336  * Path Information.
337  *
338  * The ibt_get_paths() performs SA Path record lookups to select a path(s) to
339  * a given destination(s), details of selected path(s) are returned in this
340  * structure.
341  *
342  * The ibt_path_info_t contains all the attributes of the best path(s), as
343  * as determined by IBTL, to the specified destination(s), including the
344  * local HCA and HCA port to use to access the fabric.
345  *
346  * The Service ID (pi_sid) and Service Data (pi_sdata) are returned only for
347  * lookups based on Service ID or/and Service Name.
348  */
349 typedef struct ibt_path_info_s {
350 	ib_guid_t	pi_hca_guid;		/* Local HCA GUID; 0 implies */
351 						/* this record is invalid */
352 	ib_svc_id_t	pi_sid;			/* Service ID */
353 	ibt_srv_data_t	pi_sdata;		/* Service Data */
354 
355 	ibt_cep_path_t	pi_prim_cep_path;	/* Contains CEP adds info */
356 	ibt_cep_path_t	pi_alt_cep_path;	/* RC & UC Only, valid if */
357 						/* cep_hca_port_num is not */
358 						/* '0' */
359 	ib_mtu_t	pi_path_mtu;		/* Common path MTU */
360 	ib_time_t	pi_prim_pkt_lt;
361 	ib_time_t	pi_alt_pkt_lt;
362 } ibt_path_info_t;
363 
364 /*
365  * Optional Alternate Path attributes.
366  *
367  * The ibt_alt_path_attr_t structure is used to specify additional optional
368  * attributes when requesting an alternate path for an existing channel.
369  *
370  * Attributes that are don't care should be set to NULL or '0'.
371  */
372 typedef struct ibt_alt_path_attr_s {
373 	ib_gid_t		apa_sgid;
374 	ib_gid_t		apa_dgid;
375 	ibt_srate_req_t		apa_srate;
376 	ibt_pkt_lt_req_t	apa_pkt_lt;	/* Packet Life Time Request */
377 	uint_t			apa_flow:20;
378 	uint8_t			apa_sl:4;
379 	uint8_t			apa_hop;
380 	uint8_t			apa_tclass;
381 } ibt_alt_path_attr_t;
382 
383 /*
384  * Path Information for Alternate Path - input to ibt_set_alt_path().
385  */
386 typedef struct ibt_alt_path_info_s {
387 	ibt_cep_path_t	ap_alt_cep_path;	/* RC & UC Only, valid if */
388 						/* cep_hca_port_num is not */
389 						/* '0' */
390 	ib_time_t	ap_alt_pkt_lt;
391 } ibt_alt_path_info_t;
392 
393 /*
394  * Open Channel flags, Used in ibt_open_rc_channel call
395  */
396 typedef enum ibt_chan_open_flags_e {
397 	IBT_OCHAN_NO_FLAGS		= 0,
398 	IBT_OCHAN_REDIRECTED		= 1 << 0,
399 	IBT_OCHAN_PORT_REDIRECTED	= 1 << 1,
400 	IBT_OCHAN_DUP			= 1 << 2,
401 	IBT_OCHAN_PORT_FIXED		= 1 << 3,
402 	IBT_OCHAN_OPAQUE1		= 1 << 4,
403 	IBT_OCHAN_OPAQUE2		= 1 << 5,
404 	IBT_OCHAN_OPAQUE3		= 1 << 6,
405 	IBT_OCHAN_OPAQUE4		= 1 << 7,
406 	IBT_OCHAN_OPAQUE5		= 1 << 8,
407 	IBT_OCHAN_OPAQUE6		= 1 << 9
408 } ibt_chan_open_flags_t;
409 
410 /*
411  * Arguments for ibt_open_rc_channel().
412  *
413  * oc_priv_data should be NULL or point to a buffer allocated by the caller,
414  * the size of which should be in oc_priv_data_len, where oc_priv_data_len <=
415  * IBT_REQ_PRIV_DATA_SZ.
416  *
417  * When ibt_open_rc_channel returns with ibt_cm_reason_t of
418  * IBT_CM_REDIRECT_PORT, the client can re-issue ibt_open_rc_channel setting
419  * new fields as follows:
420  *
421  * Set (ibt_chan_args_t)->oc_cm_cep_path  =
422  *    original (ibt_chan_open_args_t)->oc_path->pi_prim_cep_path.
423  * Set (ibt_chan_args_t)->oc_cm_pkt_lt  =
424  *    original (ibt_chan_open_args_t)->oc_prim_pkt_lt.
425  * Update (ibt_chan_args_t)->oc_path based on path information returned
426  * from ibt_get_paths using the gid in the return data below:
427  * 	(ibt_rc_returns_t)->rc_arej_info.ari_redirect_info.ari_gid.
428  * Set flags to IBT_OCHAN_PORT_REDIRECTED.
429  *
430  * Note : oc_cm_path is not used for any other scenario, and must be set for
431  * IBT_OCHAN_PORT_REDIRECTED.
432  *
433  * When ibt_open_rc_channel returns with ibt_cm_reason_t of
434  * IBT_CM_REDIRECT_CM, the client can re-issue ibt_open_rc_channel setting
435  * new fields as follows:
436  *
437  * Update (ibt_chan_args_t)->oc_path based on path information returned
438  * from ibt_get_paths using the return data in
439  * (ibt_rc_returns_t)->rc_arej_info.ari_redirect_info.
440  *
441  * Set (ibt_chan_args_t)->oc_cm_redirect_info =
442  *    Returned (ibt_rc_returns_t)->rc_arej_info.ari_redirect_info.
443  * Set flags to IBT_OCHAN_REDIRECTED.
444  *
445  * Note:
446  *
447  * IBT_OCHAN_PORT_REDIRECTED flag cannot be used to specify a remote CM MAD
448  * address, that is on a different subnet than the RC connection itself.
449  *
450  * Not specified attributes should be set to "NULL" or "0".
451  */
452 typedef struct ibt_chan_open_args_s {
453 	ibt_path_info_t 	*oc_path;	/* Primary & Alternate */
454 	ibt_cm_handler_t 	oc_cm_handler;	/* cm_handler - required */
455 	void			*oc_cm_clnt_private;	/* First argument to */
456 							/* cm_handler */
457 	ibt_rnr_retry_cnt_t	oc_path_rnr_retry_cnt;
458 	uint8_t			oc_path_retry_cnt:3;
459 	uint8_t			oc_rdma_ra_out;
460 	uint8_t			oc_rdma_ra_in;
461 	ibt_priv_data_len_t	oc_priv_data_len;	/* Number of bytes of */
462 							/* REQ Private data */
463 	void			*oc_priv_data;		/* REQ private data */
464 	ibt_channel_hdl_t	oc_dup_channel; 	/* IBT_OCHAN_DUP */
465 	ibt_redirect_info_t	*oc_cm_redirect_info;	/* Redirect params */
466 							/* for port and CM */
467 							/* redirection */
468 	ibt_cep_path_t		*oc_cm_cep_path;	/* Optional Path for */
469 							/* CM MADs on */
470 							/* port redirection */
471 	ib_time_t		oc_cm_pkt_lt;		/* Pkt life time for */
472 							/* CM MADs */
473 	uint32_t		oc_opaque1:4;
474 	uint32_t		oc_opaque2:24;
475 	uint32_t		oc_opaque3;
476 	uint32_t		oc_opaque4;
477 } ibt_chan_open_args_t;
478 
479 
480 /*
481  * Define an optional RC return arguments structure. This contains return
482  * parameters from ibt_open_rc_channel() when called in BLOCKING mode.
483  *
484  * rc_priv_data should be NULL or point to a buffer allocated by the caller,
485  * the size of which should be in rc_priv_data_len, where rc_priv_data_len <=
486  * IBT_REP_PRIV_DATA_SZ.
487  */
488 typedef struct ibt_rc_returns_s {
489 	uint8_t			rc_rdma_ra_in;	/* Arbitrated resp resources */
490 	uint8_t			rc_rdma_ra_out;	/* Arbitrated initiator depth */
491 	ibt_arej_info_t		rc_arej_info;
492 	ibt_cm_reason_t		rc_status;
493 	uint8_t			rc_failover_status;	/* Failover status */
494 	ibt_priv_data_len_t	rc_priv_data_len;
495 	void			*rc_priv_data;
496 } ibt_rc_returns_t;
497 
498 /*
499  * Define a callback function that can be used in Non-Blocking calls to
500  * ibt_recycle_rc().
501  */
502 
503 typedef	void	(*ibt_recycle_handler_t)(ibt_status_t ibt_status, void *arg);
504 
505 /*
506  * Define an optional return arguments structure from ibt_set_alt_path()
507  * This contains return parameters, when called in BLOCKING mode.
508  *
509  * ap_priv_data should be NULL or point to a buffer allocated by the caller,
510  * the size of which should be in ap_priv_data_len, where ap_priv_data_len <=
511  * IBT_APR_PRIV_DATA_SZ.
512  * The private data from APR is returned in ap_priv_data.
513  * The caller specifies amount of APR private data to be returned in
514  * ap_priv_data_len.
515  */
516 typedef struct ibt_ap_returns_s {
517 	ibt_ap_status_t		ap_status;
518 	boolean_t		ap_arej_info_valid;
519 	ibt_arej_info_t		ap_arej_info;	/* Only valid if redirect */
520 	ibt_priv_data_len_t	ap_priv_data_len;
521 	void			*ap_priv_data;
522 } ibt_ap_returns_t;
523 
524 /*
525  * UD remote destination attributes.
526  *
527  * ud_sid, ud_addr, ud_pkt_lt and ud_pkey_ix must be specified.
528  * These values can be as returned in an ibt_path_info_t struct from an
529  * ibt_get_paths() call.
530  *
531  * ud_priv_data should be NULL or point to a buffer allocated by the caller,
532  * the size of which is in ud_priv_data_len, where ud_priv_data_len <=
533  * IBT_SIDR_REQ_PRIV_DATA_SZ.
534  */
535 typedef struct ibt_ud_dest_attr_s {
536 	ib_svc_id_t		ud_sid;		/* Service ID */
537 	ibt_adds_vect_t		*ud_addr;	/* Address Info */
538 	uint16_t		ud_pkey_ix;	/* Pkey Index */
539 	ib_time_t		ud_pkt_lt;
540 	ibt_cm_ud_handler_t	ud_cm_handler;	/* An optional CM UD event */
541 						/* which must be NULL */
542 						/* if not specified. */
543 	void			*ud_cm_private; /* First arg to ud_cm_handler */
544 	ibt_priv_data_len_t	ud_priv_data_len;
545 	void			*ud_priv_data;	/* SIDR REQ private data */
546 } ibt_ud_dest_attr_t;
547 
548 /*
549  * Define an optional UD return arguments structure.
550  *
551  * ud_priv_data should be NULL or point to a buffer allocated by the caller,
552  * the size of which should be in ud_priv_data_len, where ud_priv_data_len <=
553  * IBT_SIDR_REP_PRIV_DATA_SZ.
554  */
555 typedef struct ibt_ud_returns_s {
556 	ibt_sidr_status_t	ud_status;
557 	ibt_redirect_info_t	ud_redirect;
558 	ib_qpn_t		ud_dqpn;	/* Returned destination QPN */
559 	ib_qkey_t		ud_qkey;	/* Q_Key for destination QPN */
560 	ibt_priv_data_len_t	ud_priv_data_len;
561 	void			*ud_priv_data;
562 } ibt_ud_returns_t;
563 
564 /*
565  * Multicast group attributes
566  * Not specified attributes should be set to "NULL" or "0".
567  * Used by ibt_join_mcg()/ibt_query_mcg().
568  *
569  * mc_qkey, mc_pkey, mc_flow, mc_tclass, mc_sl, mc_join_state are required for
570  * create - ibt_join_mcg().
571  */
572 typedef struct ibt_mcg_attr_s {
573 	ib_gid_t		mc_mgid;	/* MGID */
574 	ib_gid_t		mc_pgid;	/* SGID of the end port being */
575 						/* added to the MCG. */
576 	ib_qkey_t		mc_qkey;	/* Q_Key */
577 	ib_pkey_t		mc_pkey;	/* Partition key for this MCG */
578 	ibt_mtu_req_t		mc_mtu_req;	/* MTU */
579 	ibt_srate_req_t		mc_rate_req;	/* Static rate */
580 	ibt_pkt_lt_req_t	mc_pkt_lt_req;	/* Packet Life Time Request */
581 	uint_t			mc_flow:20;	/* FlowLabel. */
582 	uint8_t			mc_hop;		/* HopLimit */
583 	uint8_t			mc_tclass;	/* Traffic Class. */
584 	uint8_t			mc_sl:4;	/* Service Level */
585 	uint8_t			mc_scope:4,	/* Multicast Address Scope */
586 				mc_join_state:4; /* FULL For create */
587 	ib_lid_t		mc_opaque1;
588 } ibt_mcg_attr_t;
589 
590 /*
591  * Multicast group attributes.
592  * returned by ibt_join_mcg()/ibt_query_mcg().
593  */
594 typedef struct ibt_mcg_info_s {
595 	ibt_adds_vect_t		mc_adds_vect;   /* Address information */
596 	ib_mtu_t		mc_mtu;		/* MTU */
597 	ib_qkey_t		mc_qkey;	/* Q_Key */
598 	uint16_t		mc_pkey_ix;	/* Pkey Index */
599 	uint8_t			mc_scope:4;	/* Multicast Address Scope */
600 	clock_t			mc_opaque2;
601 } ibt_mcg_info_t;
602 
603 /*
604  * Define a callback function that can be used in Non-Blocking calls to
605  * ibt_join_mcg().
606  */
607 typedef void (*ibt_mcg_handler_t)(void *arg, ibt_status_t retval,
608     ibt_mcg_info_t *mcg_info_p);
609 
610 
611 /*
612  * Service Flags - sd_flags
613  *
614  *    IBT_SRV_PEER_TYPE_SID	Peer-to-peer Service IDs.
615  */
616 
617 typedef enum ibt_service_flags_e {
618 	IBT_SRV_NO_FLAGS	= 0x0,
619 	IBT_SRV_PEER_TYPE_SID	= 0x1
620 } ibt_service_flags_t;
621 
622 /*
623  * Define a Service ID Registration structure.
624  */
625 typedef struct ibt_srv_desc_s {
626 	ibt_cm_ud_handler_t	sd_ud_handler;	/* UD Service Handler */
627 	ibt_cm_handler_t	sd_handler;	/* Non-UD Service Handler */
628 	ibt_service_flags_t	sd_flags;	/* Flags */
629 } ibt_srv_desc_t;
630 
631 /*
632  * Flag to indicate ibt_bind_service() to or NOT-to clean-up Stale matching
633  * Local Service Records with SA prior to binding the new request.
634  */
635 #define	IBT_SBIND_NO_FLAGS	0
636 #define	IBT_SBIND_NO_CLEANUP	1
637 
638 /*
639  * Define a Service ID Binding structure (data for service records).
640  */
641 typedef struct ibt_srv_bind_s {
642 	uint64_t	sb_key[2];	/* Service Key */
643 	char		*sb_name;	/* Service Name (up to 63 chars) */
644 	uint32_t	sb_lease;	/* Service Lease period (in seconds) */
645 	ib_pkey_t	sb_pkey;	/* Service P_Key */
646 	ibt_srv_data_t	sb_data;	/* Service Data */
647 	uint_t		sb_flag;	/* indicates to/not-to clean-up stale */
648 					/* matching local service records. */
649 } ibt_srv_bind_t;
650 
651 /*
652  * ibt_cm_delay() flags.
653  *
654  * Refer to InfiniBand Architecture Release Volume 1 Rev 1.0a:
655  * Section 12.6.6 MRA
656  */
657 typedef enum ibt_cmdelay_flags_e {
658 	IBT_CM_DELAY_REQ	= 0,
659 	IBT_CM_DELAY_REP	= 1,
660 	IBT_CM_DELAY_LAP	= 2
661 } ibt_cmdelay_flags_t;
662 
663 /*
664  * The payload for DDI events passed on IB_PROP_UPDATE_EVENT.
665  * This is passed as the bus nexus data to event_handler(9e).
666  */
667 typedef struct ibt_prop_update_payload_s {
668 	union {
669 		struct {
670 			uint32_t	srv_updated:1;
671 			uint32_t	gid_updated:1;
672 		} _ib_prop_update_struct;
673 		uint32_t	prop_updated;
674 	} _ib_prop_update_union;
675 	ibt_status_t		ib_reprobe_status;
676 
677 #define	ib_srv_prop_updated	\
678     _ib_prop_update_union._ib_prop_update_struct.srv_updated
679 #define	ib_gid_prop_updated	\
680     _ib_prop_update_union._ib_prop_update_struct.gid_updated
681 #define	ib_prop_updated		\
682     _ib_prop_update_union.prop_updated
683 } ibt_prop_update_payload_t;
684 
685 
686 /*
687  * FUNCTION PROTOTYPES.
688  */
689 
690 /*
691  * ibt_attach() and ibt_detach():
692  *	These are the calls into IBTF used during client driver attach() and
693  *	detach().
694  *
695  *	The IBTF returns an ibt_clnt_hdl_t to the client. This handle is used
696  *	to identify this client device in all subsequent calls into the IBTF.
697  *
698  *	The ibt_detach() routine is called from a client driver's detach()
699  *	routine to deregister itself from the IBTF.
700  */
701 ibt_status_t ibt_attach(ibt_clnt_modinfo_t *mod_infop, dev_info_t *arg,
702     void *clnt_private, ibt_clnt_hdl_t *ibt_hdl_p);
703 
704 ibt_status_t ibt_detach(ibt_clnt_hdl_t ibt_hdl);
705 
706 /*
707  * HCA FUNCTIONS
708  */
709 
710 /*
711  * ibt_get_hca_list()
712  *	Returns the number of HCAs in a system and their node GUIDS.
713  *
714  *	If hca_list_p is not NULL then the memory for the array of GUIDs is
715  *	allocated by the IBTF and should be freed by the caller using
716  *	ibt_free_hca_list(). If hca_list_p is NULL then no memory is allocated
717  *	by ibt_get_hca_list and only the number of HCAs in a system is returned.
718  *
719  *	It is assumed that the caller can block in kmem_alloc.
720  *
721  * ibt_free_hca_list()
722  *	Free the memory allocated by ibt_get_hca_list().
723  */
724 uint_t ibt_get_hca_list(ib_guid_t **hca_list_p);
725 
726 void ibt_free_hca_list(ib_guid_t *hca_list, uint_t entries);
727 
728 /*
729  * ibt_open_hca()	- Open/Close a HCA. HCA can only be opened/closed
730  * ibt_close_hca()	  once. ibt_open_hca() takes a client's ibt handle
731  *			  and a GUID and returns a unique IBT client HCA
732  *			  handle.
733  *
734  * These routines can not be called from interrupt context.
735  */
736 ibt_status_t ibt_open_hca(ibt_clnt_hdl_t ibt_hdl, ib_guid_t hca_guid,
737     ibt_hca_hdl_t *hca_hdl);
738 
739 ibt_status_t ibt_close_hca(ibt_hca_hdl_t hca_hdl);
740 
741 
742 /*
743  * ibt_query_hca()
744  * ibt_query_hca_byguid()
745  * 	Returns the static attributes of the specified HCA
746  */
747 ibt_status_t ibt_query_hca(ibt_hca_hdl_t hca_hdl, ibt_hca_attr_t *hca_attrs);
748 
749 ibt_status_t ibt_query_hca_byguid(ib_guid_t hca_guid,
750     ibt_hca_attr_t *hca_attrs);
751 
752 
753 /*
754  * ibt_query_hca_ports()
755  * ibt_query_hca_ports_byguid()
756  *	Returns HCA port/ports attributes for the specified HCA port/ports.
757  *	ibt_query_hca_ports() allocates the memory required for the
758  *	ibt_hca_portinfo_t struct as well as the memory required for the SGID
759  *	and P_Key tables contained within that struct.
760  *
761  * ibt_free_portinfo()
762  *	Frees the memory allocated for a specified ibt_hca_portinfo_t struct.
763  */
764 ibt_status_t ibt_query_hca_ports(ibt_hca_hdl_t hca_hdl, uint8_t port,
765     ibt_hca_portinfo_t **port_info_p, uint_t *ports_p, uint_t *size_p);
766 
767 ibt_status_t ibt_query_hca_ports_byguid(ib_guid_t hca_guid, uint8_t port,
768     ibt_hca_portinfo_t **port_info_p, uint_t *ports_p, uint_t *size_p);
769 
770 void ibt_free_portinfo(ibt_hca_portinfo_t *port_info, uint_t size);
771 
772 /*
773  * ibt_set_hca_private()	- Set/get the client private data.
774  * ibt_get_hca_private()
775  */
776 void ibt_set_hca_private(ibt_hca_hdl_t hca_hdl, void *clnt_private);
777 void *ibt_get_hca_private(ibt_hca_hdl_t hca_hdl);
778 
779 /*
780  * ibt_hca_handle_to_guid()
781  *	A helper function to retrieve HCA GUID for the specified handle.
782  *	Returns HCA GUID on which the specified Channel is allocated. Valid
783  *	if it is non-NULL on return.
784  */
785 ib_guid_t ibt_hca_handle_to_guid(ibt_hca_hdl_t hca);
786 
787 /*
788  * ibt_hca_guid_to_handle()
789  *	A helper function to retrieve a hca handle from a HCA GUID.
790  */
791 ibt_status_t ibt_hca_guid_to_handle(ibt_clnt_hdl_t ibt_hdl, ib_guid_t hca_guid,
792     ibt_hca_hdl_t *hca_hdl);
793 
794 /*
795  * CONNECTION ESTABLISHMENT/TEAR DOWN FUNCTIONS.
796  */
797 
798 /*
799  * ibt_get_paths
800  *	Finds the best path to a specified destination (as determined by the
801  *	IBTL) that satisfies the requirements specified in an ibt_path_attr_t
802  *	struct.
803  */
804 ibt_status_t ibt_get_paths(ibt_clnt_hdl_t ibt_hdl, ibt_path_flags_t flags,
805     ibt_path_attr_t *attr, uint8_t max_paths, ibt_path_info_t *paths,
806     uint8_t *num_paths_p);
807 
808 
809 /*
810  * Callback function that can be used in ibt_aget_paths(), a Non-Blocking
811  * version of ibt_get_paths().
812  */
813 typedef void (*ibt_path_handler_t)(void *arg, ibt_status_t retval,
814     ibt_path_info_t *paths, uint8_t num_paths);
815 
816 /*
817  * Find path(s) to a given destination or service asynchronously.
818  * ibt_aget_paths() is a Non-Blocking version of ibt_get_paths().
819  */
820 ibt_status_t ibt_aget_paths(ibt_clnt_hdl_t ibt_hdl, ibt_path_flags_t flags,
821     ibt_path_attr_t *attr, uint8_t max_paths, ibt_path_handler_t func,
822     void  *arg);
823 
824 /*
825  * ibt_get_alt_path
826  *	Finds the best alternate path to a specified channel (as determined by
827  *	the IBTL) that satisfies the requirements specified in an
828  *	ibt_alt_path_attr_t struct.  The specified channel must have been
829  *	previously opened successfully using ibt_open_rc_channel.
830  */
831 ibt_status_t ibt_get_alt_path(ibt_channel_hdl_t chan, ibt_path_flags_t flags,
832     ibt_alt_path_attr_t *attr, ibt_alt_path_info_t *alt_path);
833 
834 /*
835  * ibt_open_rc_channel
836  * 	ibt_open_rc_channel() opens a previously allocated RC communication
837  *	channel. The IBTL initiates the channel establishment protocol.
838  */
839 ibt_status_t ibt_open_rc_channel(ibt_channel_hdl_t rc_chan,
840     ibt_chan_open_flags_t flags, ibt_execution_mode_t mode,
841     ibt_chan_open_args_t *args, ibt_rc_returns_t *returns);
842 
843 /*
844  * ibt_close_rc_channel
845  *	Close the specified channel. Outstanding work requests are flushed
846  *	so that the client can do the associated clean up. After that, the
847  *	client will usually deregister the previously registered memory,
848  *	then free the channel by calling ibt_free_rc_channel().
849  *
850  *	This function will reuse CM event Handler provided in
851  *	ibt_open_rc_channel().
852  */
853 ibt_status_t ibt_close_rc_channel(ibt_channel_hdl_t rc_chan,
854     ibt_execution_mode_t mode, void *priv_data,
855     ibt_priv_data_len_t priv_data_len, uint8_t *ret_status,
856     void *ret_priv_data, ibt_priv_data_len_t *ret_priv_data_len_p);
857 
858 /*
859  * ibt_prime_close_rc_channel
860  *
861  *	Allocates resources required for a close rc channel operation.
862  *	Calling ibt_prime_close_rc_channel() allows a channel to be
863  *	subsequently closed in interrupt context.
864  *
865  *	A call is first made to ibt_prime_close_rc_channel in non-interrupt
866  *	context, followed by ibt_close_rc_channel in non-blocking mode from
867  *	interrupt context
868  *
869  *	ibt_prime_close_rc_channel() can only be called on a previously opened
870  *	channel.
871  */
872 ibt_status_t ibt_prime_close_rc_channel(ibt_channel_hdl_t rc_chan);
873 
874 /*
875  * ibt_recycle_rc
876  *
877  *      Recycle a RC channel which has transitioned to Error state. The
878  *      ibt_recycle_rc() function transitions the channel from Error
879  *      state (IBT_STATE_ERROR) to the state ready for use by
880  *      ibt_open_rc_channel. Basically, this function is very similar to
881  *      ibt_alloc_rc_channel, but reuses an existing RC channel.
882  *
883  * Clients are allowed to make resource clean up/free calls in the CM handler
884  *
885  * Client(s) must not invoke blocking version (ie., func specified as NULL) of
886  * ibt_recycle_rc from cm callback for IBT_CM_EVENT_CONN_CLOSED
887  *
888  * Clients are strongly advised not to issue blocking calls from  func, as this
889  * would block the CM threads, and could delay or block other client connections
890  * and ibtl related API invocations.
891  */
892 ibt_status_t ibt_recycle_rc(ibt_channel_hdl_t rc_chan, ibt_cep_flags_t control,
893     uint8_t hca_port_num, ibt_recycle_handler_t func, void *arg);
894 
895 /*
896  * ibt_recycle_ud
897  *
898  *      Recycle a UD channel which has transitioned to Error state. The
899  *      ibt_recycle_ud() function transitions the channel from Error
900  *      state (IBT_STATE_ERROR) to a usable state (IBT_STATE_RTS).
901  *      Basically, this function is very similar to ibt_alloc_ud_channel,
902  *	but reuses an existing UD channel.
903  */
904 ibt_status_t ibt_recycle_ud(ibt_channel_hdl_t ud_chan, uint8_t hca_port_num,
905     uint16_t pkey_ix, ib_qkey_t qkey);
906 
907 /*
908  * MODIFY CHANNEL ATTRIBUTE FUNCTIONs.
909  */
910 
911 /*
912  * ibt_pause_sendq
913  * ibt_unpause_sendq
914  *	Place the send queue of the specified channel into the send queue
915  *	drained state.
916  *	Applicable for both RC and UD channels.
917  */
918 ibt_status_t ibt_pause_sendq(ibt_channel_hdl_t chan,
919     ibt_cep_modify_flags_t modify_flags);
920 
921 ibt_status_t ibt_unpause_sendq(ibt_channel_hdl_t chan);
922 
923 /*
924  * ibt_resize_queues()
925  *	Resize the SendQ/RecvQ sizes of a channel.
926  *
927  *	Applicable for both RC and UD channels.
928  */
929 ibt_status_t ibt_resize_queues(ibt_channel_hdl_t chan, ibt_qflags_t flags,
930     ibt_queue_sizes_t *request_sz, ibt_queue_sizes_t *actual_sz);
931 
932 /*
933  * ibt_query_queues()
934  *
935  *	Query the SendQ/RecvQ sizes of a channel.
936  *	Applicable for both RC and UD channels.
937  */
938 ibt_status_t ibt_query_queues(ibt_channel_hdl_t chan,
939     ibt_queue_sizes_t *actual_sz);
940 
941 /*
942  * ibt_modify_rdma
943  *	Enable/disable RDMA operations.
944  *
945  *	Applicable for RC channels only.
946  */
947 ibt_status_t ibt_modify_rdma(ibt_channel_hdl_t rc_chan,
948     ibt_cep_modify_flags_t modify_flags, ibt_cep_flags_t flags);
949 
950 
951 /*
952  * ibt_set_rdma_resource
953  *	Change the number of resources to be used for incoming and outgoing
954  *	RDMA reads & Atomics.
955  */
956 ibt_status_t ibt_set_rdma_resource(ibt_channel_hdl_t rc_chan,
957     ibt_cep_modify_flags_t modify_flags, uint8_t rdma_ra_out,
958     uint8_t rdma_ra_in);
959 
960 /*
961  * ibt_change_port
962  *	Change the primary physical port of an RC channel. (This is done only
963  *	if HCA supports this capability).  Can only be called on a paused
964  *	channel.
965  *	Applicable for RC channels only.
966  */
967 ibt_status_t ibt_change_port(ibt_channel_hdl_t rc_chan, uint8_t port_num);
968 
969 
970 /*
971  * SERVICE REGISTRATION FUNCTIONS
972  */
973 
974 /*
975  * ibt_register_service()
976  * ibt_deregister_service()
977  *	Register/deregister a Service (range of Service IDs) with the IBTF.
978  *
979  * ibt_bind_service()
980  * ibt_unbind_service()
981  * ibt_unbind_all_services()
982  *	Bind a Service to a given port (GID), and optionally create
983  *	service record(s) with the SA for ibt_get_paths() to find.
984  */
985 ibt_status_t ibt_register_service(ibt_clnt_hdl_t ibt_hdl,
986     ibt_srv_desc_t *service, ib_svc_id_t sid, int num_sids,
987     ibt_srv_hdl_t *srv_hdl_p, ib_svc_id_t *ret_sid_p);
988 
989 ibt_status_t ibt_deregister_service(ibt_clnt_hdl_t ibt_hdl,
990     ibt_srv_hdl_t srv_hdl);
991 
992 ibt_status_t ibt_bind_service(ibt_srv_hdl_t srv_hdl, ib_gid_t gid,
993     ibt_srv_bind_t *srv_bind, void *cm_private, ibt_sbind_hdl_t *sb_hdl_p);
994 
995 ibt_status_t ibt_unbind_service(ibt_srv_hdl_t srv_hdl, ibt_sbind_hdl_t sb_hdl);
996 ibt_status_t ibt_unbind_all_services(ibt_srv_hdl_t srv_hdl);
997 
998 /*
999  * ibt_cm_delay
1000  *	A client CM handler/srv_handler function can call this function to
1001  *	extend its response time to a CM event.
1002  *	Applicable for RC channels only.
1003  */
1004 ibt_status_t ibt_cm_delay(ibt_cmdelay_flags_t flags, void *cm_session_id,
1005     clock_t service_time, void *priv_data, ibt_priv_data_len_t priv_data_len);
1006 
1007 /*
1008  * ibt_cm_proceed
1009  *
1010  * An IBT client calls ibt_cm_proceed() to proceed with a connection that
1011  * previously deferred by the client returning IBT_CM_DEFER on a CM handler
1012  * callback. CM events that can be deferred and continued with ibt_cm_proceed()
1013  * are REQ_RCV, REP_RCV, LAP_RCV, and DREQ_RCV.
1014  *
1015  * NOTE :
1016  *
1017  * Typically CM completes processing of a client's CM handler return, with
1018  * IBT_CM_DEFER status, before  processing of the corresponding ibt_cm_proceed()
1019  * is started. However a race exists where by CM may not have completed the
1020  * client's handler return processing when ibt_cm_proceed() is called by a
1021  * client. In this case ibt_cm_proceed() will block until processing of the
1022  * client's CM handler return is complete.
1023  *
1024  * A client that returns IBT_CM_DEFER from the cm handler must
1025  * subsequently make a call to ibt_cm_proceed(). It is illegal to call
1026  * ibt_cm_proceed() on a channel that has not had the connection
1027  * establishment deferred.
1028  *
1029  * Client cannot call ibt_cm_proceed from the cm handler.
1030  */
1031 ibt_status_t ibt_cm_proceed(ibt_cm_event_type_t event, void *session_id,
1032     ibt_cm_status_t status, ibt_cm_proceed_reply_t *cm_event_data,
1033     void *priv_data, ibt_priv_data_len_t priv_data_len);
1034 
1035 /*
1036  * ibt_cm_ud_proceed
1037  *
1038  * An IBT client calls ibt_cm_ud_proceed() to proceed with an
1039  * IBT_CM_UD_EVENT_SIDR_REQ  UD event that was previously deferred by the
1040  * client returning IBT_CM_DEFER on a CM UD handler callback.
1041  * NOTE :
1042  *
1043  * Typically CM completes processing of a client's CM handler return, with
1044  * IBT_CM_DEFER status, before  processing of the corresponding
1045  * ibt_cm_ud_proceed() is started. However a race exists where by CM may not
1046  * have completed the client's handler return processing when
1047  * ibt_cm_ud_proceed() is called by a client. In this case ibt_cm_ud_proceed()
1048  * will block until processing of the client's CM handler return is complete.
1049  *
1050  * A client that returns IBT_CM_DEFER from the cm handler must
1051  * subsequently make a call to ibt_cm_ud_proceed(). It is illegal to call
1052  * ibt_cm_ud_proceed() on a channel that has not had the connection
1053  * establishment deferred.
1054  *
1055  * Client cannot call ibt_cm_ud_proceed from the cm handler.
1056  */
1057 ibt_status_t ibt_cm_ud_proceed(void *session_id, ibt_channel_hdl_t ud_channel,
1058     ibt_cm_status_t status, ibt_redirect_info_t *redirect_infop,
1059     void *priv_data, ibt_priv_data_len_t priv_data_len);
1060 
1061 
1062 /*
1063  * COMPLETION QUEUES.
1064  *
1065  * ibt_alloc_cq_sched()
1066  *	Reserve CQ scheduling class resources
1067  *
1068  * ibt_free_cq_sched()
1069  *	Free CQ scheduling class resources
1070  */
1071 ibt_status_t ibt_alloc_cq_sched(ibt_hca_hdl_t hca_hdl,
1072     ibt_cq_sched_attr_t *attr, ibt_sched_hdl_t *sched_hdl_p);
1073 
1074 ibt_status_t ibt_free_cq_sched(ibt_hca_hdl_t hca_hdl,
1075     ibt_sched_hdl_t sched_hdl);
1076 
1077 /*
1078  * ibt_alloc_cq()
1079  *	Allocate a completion queue.
1080  */
1081 ibt_status_t ibt_alloc_cq(ibt_hca_hdl_t hca_hdl, ibt_cq_attr_t *cq_attr,
1082     ibt_cq_hdl_t *ibt_cq_p, uint_t *real_size);
1083 
1084 /*
1085  * ibt_free_cq()
1086  *	Free allocated CQ resources.
1087  */
1088 ibt_status_t ibt_free_cq(ibt_cq_hdl_t ibt_cq);
1089 
1090 
1091 /*
1092  * ibt_enable_cq_notify()
1093  *	Enable notification requests on the specified CQ.
1094  *	Applicable for both RC and UD channels.
1095  *
1096  *	Completion notifications are disabled by setting the completion
1097  *	handler to NULL by calling ibt_set_cq_handler().
1098  */
1099 ibt_status_t ibt_enable_cq_notify(ibt_cq_hdl_t ibt_cq,
1100     ibt_cq_notify_flags_t notify_type);
1101 
1102 /*
1103  * ibt_set_cq_handler()
1104  *	Register a work request completion handler with the IBTF.
1105  *	Applicable for both RC and UD channels.
1106  *
1107  *	Completion notifications are disabled by setting the completion
1108  *	handler to NULL. When setting the handler to NULL, no additional
1109  *	calls to the CQ handler will be initiated.
1110  *
1111  *	This function does not otherwise change the state of previous
1112  *	calls to ibt_enable_cq_notify().
1113  */
1114 void ibt_set_cq_handler(ibt_cq_hdl_t ibt_cq,
1115     ibt_cq_handler_t completion_handler, void *arg);
1116 
1117 /*
1118  * ibt_poll_cq()
1119  *	Poll the specified CQ for the completion of work requests (WRs).
1120  *	If the CQ contains completed WRs, up to num_wc of them are returned.
1121  *	Applicable for both RC and UD channels.
1122  */
1123 ibt_status_t ibt_poll_cq(ibt_cq_hdl_t ibt_cq, ibt_wc_t *work_completions,
1124     uint_t num_wc, uint_t *num_polled);
1125 
1126 /*
1127  * ibt_query_cq()
1128  *	Return the total number of entries in the CQ.
1129  */
1130 ibt_status_t ibt_query_cq(ibt_cq_hdl_t ibt_cq, uint_t *entries,
1131     uint_t *count_p, uint_t *usec_p, ibt_cq_handler_id_t *hid_p);
1132 
1133 /*
1134  * ibt_query_cq_handler_id()
1135  *	Return interrupt characteristics of the CQ handler
1136  */
1137 ibt_status_t ibt_query_cq_handler_id(ibt_hca_hdl_t hca_hdl,
1138     ibt_cq_handler_id_t hid, ibt_cq_handler_attr_t *attrs);
1139 
1140 /*
1141  * ibt_resize_cq()
1142  *	Change the size of a CQ.
1143  */
1144 ibt_status_t ibt_resize_cq(ibt_cq_hdl_t ibt_cq, uint_t new_sz, uint_t *real_sz);
1145 
1146 /*
1147  * ibt_modify_cq()
1148  *	Change the interrupt moderation values of a CQ.
1149  *	"count" is number of completions before interrupting.
1150  *	"usec" is the number of microseconds before interrupting.
1151  */
1152 ibt_status_t ibt_modify_cq(ibt_cq_hdl_t ibt_cq, uint_t count, uint_t usec,
1153     ibt_cq_handler_id_t hid);
1154 
1155 /*
1156  * ibt_set_cq_private()
1157  * ibt_get_cq_private()
1158  *	Set/get the client private data.
1159  */
1160 void ibt_set_cq_private(ibt_cq_hdl_t ibt_cq, void *clnt_private);
1161 void *ibt_get_cq_private(ibt_cq_hdl_t ibt_cq);
1162 
1163 
1164 /*
1165  * Memory Management Functions.
1166  *	Applicable for both RC and UD channels.
1167  *
1168  * ibt_register_mr()
1169  * 	Prepares a virtually addressed memory region for use by a HCA. A
1170  *	description of the registered memory suitable for use in Work Requests
1171  *	(WRs) is returned in the ibt_mr_desc_t parameter.
1172  *
1173  * ibt_register_buf()
1174  * 	Prepares a memory region described by a buf(9S) struct for use by a
1175  *	HCA. A description of the registered memory suitable for use in
1176  *	Work Requests (WRs) is returned in the ibt_mr_desc_t parameter.
1177  *
1178  * ibt_query_mr()
1179  *	Retrieves information about a specified memory region.
1180  *
1181  * ibt_deregister_mr()
1182  *	Remove a memory region from a HCA translation table, and free all
1183  *	resources associated with the memory region.
1184  *
1185  * ibt_reregister_mr()
1186  * ibt_reregister_buf()
1187  *	Modify the attributes of an existing memory region.
1188  *
1189  * ibt_register_shared_mr()
1190  *	Given an existing memory region, a new memory region associated with
1191  *	the same physical locations is created.
1192  *
1193  * ibt_sync_mr()
1194  *	Sync a memory region for either RDMA reads or RDMA writes
1195  *
1196  * ibt_alloc_mw()
1197  *	Allocate a memory window.
1198  *
1199  * ibt_query_mw()
1200  *	Retrieves information about a specified memory window.
1201  *
1202  * ibt_free_mw()
1203  *	De-allocate the Memory Window.
1204  */
1205 ibt_status_t ibt_register_mr(ibt_hca_hdl_t hca_hdl, ibt_pd_hdl_t pd,
1206     ibt_mr_attr_t *mem_attr, ibt_mr_hdl_t *mr_hdl_p, ibt_mr_desc_t *mem_desc);
1207 
1208 ibt_status_t ibt_register_buf(ibt_hca_hdl_t hca_hdl, ibt_pd_hdl_t pd,
1209     ibt_smr_attr_t *mem_bpattr, struct buf *bp, ibt_mr_hdl_t *mr_hdl_p,
1210     ibt_mr_desc_t *mem_desc);
1211 
1212 ibt_status_t ibt_query_mr(ibt_hca_hdl_t hca_hdl, ibt_mr_hdl_t mr_hdl,
1213     ibt_mr_query_attr_t *attr);
1214 
1215 ibt_status_t ibt_deregister_mr(ibt_hca_hdl_t hca_hdl, ibt_mr_hdl_t mr_hdl);
1216 
1217 ibt_status_t ibt_reregister_mr(ibt_hca_hdl_t hca_hdl, ibt_mr_hdl_t mr_hdl,
1218     ibt_pd_hdl_t pd, ibt_mr_attr_t *mem_attr, ibt_mr_hdl_t *mr_hdl_p,
1219     ibt_mr_desc_t *mem_desc);
1220 
1221 ibt_status_t ibt_reregister_buf(ibt_hca_hdl_t hca_hdl, ibt_mr_hdl_t mr_hdl,
1222     ibt_pd_hdl_t pd, ibt_smr_attr_t *mem_bpattr, struct buf *bp,
1223     ibt_mr_hdl_t *mr_hdl_p, ibt_mr_desc_t *mem_desc);
1224 
1225 ibt_status_t ibt_register_shared_mr(ibt_hca_hdl_t hca_hdl, ibt_mr_hdl_t mr_hdl,
1226     ibt_pd_hdl_t pd, ibt_smr_attr_t *mem_sattr, ibt_mr_hdl_t *mr_hdl_p,
1227     ibt_mr_desc_t *mem_desc);
1228 
1229 ibt_status_t ibt_sync_mr(ibt_hca_hdl_t hca_hdl, ibt_mr_sync_t *mr_segments,
1230     size_t num_segments);
1231 
1232 ibt_status_t ibt_alloc_mw(ibt_hca_hdl_t hca_hdl, ibt_pd_hdl_t pd,
1233     ibt_mw_flags_t flags, ibt_mw_hdl_t *mw_hdl_p, ibt_rkey_t *rkey);
1234 
1235 ibt_status_t ibt_query_mw(ibt_hca_hdl_t hca_hdl, ibt_mw_hdl_t mw_hdl,
1236     ibt_mw_query_attr_t *mw_attr_p);
1237 
1238 ibt_status_t ibt_free_mw(ibt_hca_hdl_t hca_hdl, ibt_mw_hdl_t mw_hdl);
1239 
1240 /*
1241  * ibt_alloc_lkey()
1242  * 	Allocates physical buffer list resources for use in memory
1243  *	registrations.
1244  *
1245  *	Applicable for both RC and UD channels.
1246  */
1247 ibt_status_t ibt_alloc_lkey(ibt_hca_hdl_t hca_hdl, ibt_pd_hdl_t pd,
1248     ibt_lkey_flags_t flags, uint_t phys_buf_list_sz, ibt_mr_hdl_t *mr_p,
1249     ibt_pmr_desc_t *mem_desc_p);
1250 
1251 
1252 /*
1253  * Physical Memory Management Functions.
1254  *	Applicable for both RC and UD channels.
1255  *
1256  * ibt_register_phys_mr()
1257  *	Prepares a physically addressed memory region for use by a HCA.
1258  *
1259  * ibt_reregister_phys_mr()
1260  *	Modify the attributes of an existing memory region.
1261  */
1262 ibt_status_t ibt_register_phys_mr(ibt_hca_hdl_t hca_hdl, ibt_pd_hdl_t pd,
1263     ibt_pmr_attr_t *mem_pattr, ibt_mr_hdl_t *mr_hdl_p,
1264     ibt_pmr_desc_t *mem_desc_p);
1265 
1266 ibt_status_t ibt_reregister_phys_mr(ibt_hca_hdl_t hca_hdl, ibt_mr_hdl_t mr_hdl,
1267     ibt_pd_hdl_t pd, ibt_pmr_attr_t *mem_pattr, ibt_mr_hdl_t *mr_hdl_p,
1268     ibt_pmr_desc_t *mem_desc_p);
1269 
1270 
1271 /*
1272  * Register DMA Memory Region
1273  */
1274 ibt_status_t ibt_register_dma_mr(ibt_hca_hdl_t hca_hdl, ibt_pd_hdl_t pd,
1275     ibt_dmr_attr_t *mem_attr, ibt_mr_hdl_t *mr_hdl_p, ibt_mr_desc_t *mem_desc);
1276 
1277 
1278 /*
1279  * Address Translation.
1280  */
1281 
1282 /*
1283  * ibt_map_mem_area()
1284  *	Translate a kernel virtual address range into HCA physical addresses.
1285  *	A set of physical addresses, that can be used with "Reserved L_Key",
1286  *	register physical,  and "Fast Registration Work Request" operations
1287  *	is returned.
1288  */
1289 ibt_status_t ibt_map_mem_area(ibt_hca_hdl_t hca_hdl, ibt_va_attr_t *va_attrs,
1290     uint_t paddr_list_len, ibt_reg_req_t *reg_req, ibt_ma_hdl_t *ma_hdl_p);
1291 
1292 /*
1293  * ibt_unmap_mem_area()
1294  *	Un pin physical pages pinned during an ibt_map_mem_area() call.
1295  */
1296 ibt_status_t ibt_unmap_mem_area(ibt_hca_hdl_t hca_hdl, ibt_ma_hdl_t ma_hdl);
1297 
1298 /* ibt_map_mem_iov() */
1299 ibt_status_t ibt_map_mem_iov(ibt_hca_hdl_t hca_hdl,
1300     ibt_iov_attr_t *iov_attr, ibt_all_wr_t *wr, ibt_mi_hdl_t *mi_hdl);
1301 
1302 /* ibt_unmap_mem_iov() */
1303 ibt_status_t ibt_unmap_mem_iov(ibt_hca_hdl_t hca_hdl, ibt_mi_hdl_t mi_hdl);
1304 
1305 /*
1306  * Work Request Functions
1307  *	Applicable for RC and UD channels.
1308  *
1309  * ibt_post_send()
1310  *	Post send work requests to the specified channel.
1311  *
1312  * ibt_post_recv()
1313  * ibt_post_srq()
1314  *	Post receive work requests to the specified channel.
1315  */
1316 ibt_status_t ibt_post_send(ibt_channel_hdl_t chan, ibt_send_wr_t *wr_list,
1317     uint_t num_wr, uint_t *posted);
1318 
1319 ibt_status_t ibt_post_recv(ibt_channel_hdl_t chan, ibt_recv_wr_t *wr_list,
1320     uint_t num_wr, uint_t *posted);
1321 
1322 ibt_status_t ibt_post_srq(ibt_srq_hdl_t srq, ibt_recv_wr_t *wr_list,
1323     uint_t num_wr, uint_t *posted);
1324 
1325 
1326 /*
1327  * Alternate Path Migration Functions.
1328  *	Applicable for RC channels only.
1329  *
1330  *
1331  * ibt_get_alt_path()
1332  *	Finds the best alternate path to a specified channel (as determined by
1333  *	the IBTL) that satisfies the requirements specified in an
1334  *	ibt_alt_path_attr_t struct.  The specified channel must have been
1335  *	previously opened successfully using ibt_open_rc_channel.
1336  *	This function also ensures that the service being accessed by the
1337  *	channel is available at the selected alternate port.
1338  *
1339  *	Note: The apa_dgid must be on the same destination channel adapter,
1340  *	if specified.
1341  *
1342  *
1343  * ibt_set_alt_path()
1344  *	Load the specified alternate path. Causes the CM to send an LAP message
1345  *	to the remote node. If successful, the local channel is updated with
1346  *	the new alternate path and the channel migration state is set to REARM.
1347  *	Can only be called on a previously opened RC channel. The channel must
1348  *	be either in RTS or paused state.
1349  *
1350  *
1351  * ibt_migrate_path()
1352  *	Force the CI to use the alternate path. The alternate path becomes
1353  *	the primary path. A new alternate path should be loaded and enabled.
1354  */
1355 ibt_status_t ibt_get_alt_path(ibt_channel_hdl_t rc_chan, ibt_path_flags_t flags,
1356     ibt_alt_path_attr_t *attr, ibt_alt_path_info_t *alt_pathp);
1357 
1358 ibt_status_t ibt_set_alt_path(ibt_channel_hdl_t rc_chan,
1359     ibt_execution_mode_t mode, ibt_alt_path_info_t *alt_pinfo, void *priv_data,
1360     ibt_priv_data_len_t priv_data_len, ibt_ap_returns_t *ret_args);
1361 
1362 ibt_status_t ibt_migrate_path(ibt_channel_hdl_t rc_chan);
1363 
1364 
1365 /*
1366  * Multicast group Functions.
1367  *	Applicable for UD channels only.
1368  */
1369 
1370 /*
1371  * ibt_attach_mcg()
1372  *	Attaches a UD channel to the specified multicast group. On successful
1373  *	completion, this channel will be provided with a copy of every
1374  *	multicast message addressed to the group specified by the MGID
1375  *	(mcg_info->mc_adds_vect.av_dgid) and received on the HCA port with
1376  *	which the channel is associated.
1377  */
1378 ibt_status_t ibt_attach_mcg(ibt_channel_hdl_t ud_chan,
1379     ibt_mcg_info_t *mcg_info);
1380 
1381 /*
1382  * ibt_detach_mcg()
1383  *	Detach the specified UD channel from the specified multicast group.
1384  */
1385 ibt_status_t ibt_detach_mcg(ibt_channel_hdl_t ud_chan,
1386     ibt_mcg_info_t *mcg_info);
1387 
1388 /*
1389  * ibt_join_mcg()
1390  *	Join a multicast group.  The first full member "join" causes the MCG
1391  *	to be created.
1392  */
1393 ibt_status_t ibt_join_mcg(ib_gid_t rgid, ibt_mcg_attr_t *mcg_attr,
1394     ibt_mcg_info_t *mcg_info_p,  ibt_mcg_handler_t func, void  *arg);
1395 
1396 /*
1397  * ibt_leave_mcg()
1398  *	The port associated with the port GID shall be removed from the
1399  *	multicast group specified by MGID (mc_gid) or from all the multicast
1400  *	groups of which it is a member if the MGID (mc_gid) is not specified
1401  *	(i.e. mc_gid.mgid_prefix must have 8-bits of 11111111 at the start of
1402  *	the GID to identify this as being a multicast GID).
1403  *
1404  *	The last full member to leave causes the destruction of the Multicast
1405  *	Group.
1406  */
1407 ibt_status_t ibt_leave_mcg(ib_gid_t rgid, ib_gid_t mc_gid, ib_gid_t port_gid,
1408     uint8_t mc_join_state);
1409 
1410 /*
1411  * ibt_query_mcg()
1412  *	Request information on multicast groups that match the parameters
1413  *	specified in mcg_attr. Information on each multicast group is returned
1414  *	to the caller in the form of an array of ibt_mcg_info_t.
1415  *	ibt_query_mcg() allocates the memory for this array and returns a
1416  *	pointer to the array (mcgs_p) and the number of entries in the array
1417  *	(entries_p). This memory should be freed by the client using
1418  *	ibt_free_mcg_info().
1419  */
1420 ibt_status_t ibt_query_mcg(ib_gid_t rgid, ibt_mcg_attr_t *mcg_attr,
1421     uint_t mcgs_max_num, ibt_mcg_info_t **mcgs_info_p, uint_t *entries_p);
1422 
1423 /*
1424  * ibt_free_mcg_info()
1425  *	Free the memory allocated by successful ibt_query_mcg()
1426  */
1427 void ibt_free_mcg_info(ibt_mcg_info_t *mcgs_info, uint_t entries);
1428 
1429 
1430 /*
1431  * ibt_register_subnet_notices()
1432  *	Register a handler to be called for subnet notifications.
1433  */
1434 void ibt_register_subnet_notices(ibt_clnt_hdl_t ibt_hdl,
1435     ibt_sm_notice_handler_t sm_notice_handler, void *private);
1436 
1437 
1438 /*
1439  * Protection Domain Functions.
1440  *
1441  * ibt_alloc_pd()
1442  * ibt_free_pd()
1443  * 	Allocate/Release a protection domain
1444  */
1445 ibt_status_t ibt_alloc_pd(ibt_hca_hdl_t hca_hdl, ibt_pd_flags_t flags,
1446     ibt_pd_hdl_t *pd);
1447 ibt_status_t ibt_free_pd(ibt_hca_hdl_t hca_hdl, ibt_pd_hdl_t pd);
1448 
1449 /*
1450  * P_Key to P_Key Index conversion Functions.
1451  *
1452  * ibt_pkey2index_byguid
1453  * ibt_pkey2index	Convert a P_Key into a P_Key index.
1454  *
1455  * ibt_index2pkey_byguid
1456  * ibt_index2pkey	Convert a P_Key Index into a P_Key.
1457  */
1458 ibt_status_t ibt_pkey2index(ibt_hca_hdl_t hca_hdl, uint8_t port_num,
1459     ib_pkey_t pkey, uint16_t *pkey_ix);
1460 
1461 ibt_status_t ibt_index2pkey(ibt_hca_hdl_t hca_hdl, uint8_t port_num,
1462     uint16_t pkey_ix, ib_pkey_t *pkey);
1463 
1464 ibt_status_t ibt_pkey2index_byguid(ib_guid_t hca_guid, uint8_t port_num,
1465     ib_pkey_t pkey, uint16_t *pkey_ix);
1466 
1467 ibt_status_t ibt_index2pkey_byguid(ib_guid_t hca_guid, uint8_t port_num,
1468     uint16_t pkey_ix, ib_pkey_t *pkey);
1469 
1470 /*
1471  *  ibt_ci_data_in()
1472  *
1473  *  Pass CI specific userland data for CI objects to the CI.
1474  */
1475 ibt_status_t ibt_ci_data_in(ibt_hca_hdl_t hca, ibt_ci_data_flags_t flags,
1476     ibt_object_type_t object, void *ibt_object_handle, void *data_p,
1477     size_t data_sz);
1478 
1479 /*
1480  *  ibt_ci_data_out()
1481  *
1482  *  Obtain CI specific userland data for CI objects.
1483  */
1484 ibt_status_t ibt_ci_data_out(ibt_hca_hdl_t hca, ibt_ci_data_flags_t flags,
1485     ibt_object_type_t object, void *ibt_object_handle, void *data_p,
1486     size_t data_sz);
1487 
1488 
1489 /*
1490  * Node Information.
1491  */
1492 
1493 /* Node type : n_node_type */
1494 #define	IBT_NODE_TYPE_CHANNEL_ADAPTER	1	/* HCA or TCA */
1495 #define	IBT_NODE_TYPE_SWITCH		2
1496 #define	IBT_NODE_TYPE_ROUTER		3
1497 
1498 typedef struct ibt_node_info_s {
1499 	ib_guid_t	n_sys_img_guid;	/* System Image GUID */
1500 	ib_guid_t	n_node_guid;	/* Node GUID */
1501 	ib_guid_t	n_port_guid;	/* Port GUID */
1502 	uint16_t	n_dev_id;	/* Device ID */
1503 	uint32_t	n_revision;	/* Device Revision */
1504 	uint32_t	n_vendor_id:24;	/* Device Vendor ID */
1505 	uint8_t		n_num_ports;	/* Number of ports on this node. */
1506 	uint8_t		n_port_num;	/* Port number. */
1507 	uint8_t		n_node_type;	/* Node type */
1508 	char		n_description[64]; /* NULL terminated ASCII string */
1509 } ibt_node_info_t;
1510 
1511 
1512 /*
1513  * ibt_gid_to_node_info()
1514  *	Retrieve node information for the specified GID.
1515  */
1516 ibt_status_t ibt_gid_to_node_info(ib_gid_t gid, ibt_node_info_t *node_info_p);
1517 
1518 /*
1519  * ibt_reprobe_dev
1520  *	Reprobe properties for IOC device node.
1521  */
1522 ibt_status_t	ibt_reprobe_dev(dev_info_t *dip);
1523 
1524 /*
1525  * ibt_get_companion_port_gids()
1526  *
1527  *	Get list of GID's available on a companion port(s) of the specified
1528  *	GID or list of GIDs available on a specified Node GUID/System Image
1529  *	GUID.
1530  */
1531 ibt_status_t ibt_get_companion_port_gids(ib_gid_t gid, ib_guid_t hca_guid,
1532     ib_guid_t sysimg_guid, ib_gid_t **gids_p, uint_t *num_gids_p);
1533 
1534 /*
1535  * SHARED RECEIVE QUEUE
1536  */
1537 
1538 
1539 /*
1540  * ibt_alloc_srq()
1541  *	Allocate a shared receive queue.
1542  */
1543 ibt_status_t ibt_alloc_srq(ibt_hca_hdl_t hca_hdl, ibt_srq_flags_t flags,
1544     ibt_pd_hdl_t pd, ibt_srq_sizes_t *sizes, ibt_srq_hdl_t *ibt_srq_p,
1545     ibt_srq_sizes_t *real_size_p);
1546 
1547 /*
1548  * ibt_free_srq()
1549  *	Free allocated SRQ resources.
1550  */
1551 ibt_status_t ibt_free_srq(ibt_srq_hdl_t ibt_srq);
1552 
1553 /*
1554  * ibt_query_srq()
1555  *	Query a shared receive queue.
1556  */
1557 ibt_status_t ibt_query_srq(ibt_srq_hdl_t ibt_srq, ibt_pd_hdl_t *pd_p,
1558     ibt_srq_sizes_t *sizes_p, uint_t *limit_p);
1559 
1560 /*
1561  * ibt_modify_srq()
1562  *	Modify a shared receive queue.
1563  */
1564 ibt_status_t ibt_modify_srq(ibt_srq_hdl_t ibt_srq, ibt_srq_modify_flags_t flags,
1565     uint_t size, uint_t limit, uint_t *real_size_p);
1566 
1567 /*
1568  * ibt_set_srq_private()
1569  * ibt_get_srq_private()
1570  *	Set/get the SRQ client private data.
1571  */
1572 void ibt_set_srq_private(ibt_srq_hdl_t ibt_srq, void *clnt_private);
1573 void *ibt_get_srq_private(ibt_srq_hdl_t ibt_srq);
1574 
1575 /*
1576  * ibt_check_failure()
1577  * 	Function to test for special case failures
1578  */
1579 ibt_failure_type_t ibt_check_failure(ibt_status_t status, uint64_t *reserved_p);
1580 
1581 
1582 /*
1583  * ibt_hw_is_present() returns 0 when there is no IB hardware actively
1584  * running.  This is primarily useful for modules like rpcmod which needs a
1585  * quick check to decide whether or not it should try to use InfiniBand.
1586  */
1587 int ibt_hw_is_present();
1588 
1589 /*
1590  * Fast Memory Registration (FMR).
1591  *
1592  * ibt_create_fmr_pool
1593  *	Not fast-path.
1594  *	ibt_create_fmr_pool() verifies that the HCA supports FMR and allocates
1595  *	and initializes an "FMR pool".  This pool contains state specific to
1596  *	this registration, including the watermark setting to determine when
1597  *	to sync, and the total number of FMR regions available within this pool.
1598  *
1599  * ibt_destroy_fmr_pool
1600  *	ibt_destroy_fmr_pool() deallocates all of the FMR regions in a specific
1601  *	pool.  All state and information regarding the pool are destroyed and
1602  *	returned as free space once again.  No more use of FMR regions in this
1603  *	pool are possible without a subsequent call to ibt_create_fmr_pool().
1604  *
1605  * ibt_flush_fmr_pool
1606  *	ibt_flush_fmr_pool forces a flush to occur.  At the client's request,
1607  *	any unmapped FMR regions (See 'ibt_deregister_mr())') are returned to
1608  *	a free state.  This function allows for an asynchronous cleanup of
1609  *	formerly used FMR regions.  Sync operation is also performed internally
1610  *	by HCA driver, when 'watermark' settings for the number of free FMR
1611  *	regions left in the "pool" is reached.
1612  *
1613  * ibt_register_physical_fmr
1614  *	ibt_register_physical_fmr() assigns a "free" entry from the FMR Pool.
1615  *	It first consults the "FMR cache" to see if this is a duplicate memory
1616  *	registration to something already in use.  If not, then a free entry
1617  *	in the "pool" is marked used.
1618  *
1619  * ibt_deregister_fmr
1620  *	The ibt_deregister_fmr un-maps the resources reserved from the FMR
1621  *	pool by ibt_register_physical_fmr().   The ibt_deregister_fmr() will
1622  *	mark the region as free in the FMR Pool.
1623  */
1624 ibt_status_t ibt_create_fmr_pool(ibt_hca_hdl_t hca_hdl, ibt_pd_hdl_t pd,
1625     ibt_fmr_pool_attr_t *fmr_params, ibt_fmr_pool_hdl_t *fmr_pool_p);
1626 
1627 ibt_status_t ibt_destroy_fmr_pool(ibt_hca_hdl_t hca_hdl,
1628     ibt_fmr_pool_hdl_t fmr_pool);
1629 
1630 ibt_status_t ibt_flush_fmr_pool(ibt_hca_hdl_t hca_hdl,
1631     ibt_fmr_pool_hdl_t fmr_pool);
1632 
1633 ibt_status_t ibt_register_physical_fmr(ibt_hca_hdl_t hca_hdl,
1634     ibt_fmr_pool_hdl_t fmr_pool, ibt_pmr_attr_t *mem_pattr,
1635     ibt_mr_hdl_t *mr_hdl_p, ibt_pmr_desc_t *mem_desc_p);
1636 
1637 ibt_status_t ibt_deregister_fmr(ibt_hca_hdl_t hca, ibt_mr_hdl_t mr_hdl);
1638 
1639 /*
1640  * IP SUPPORT
1641  */
1642 
1643 /*
1644  * IP get_paths
1645  * Returns an array (or single) of paths and source IP addresses. In the
1646  * simplest form just the destination IP address is specified, and one path
1647  * is requested, then one ibt_path_info_t struct and one source IP.
1648  *
1649  * More than one path can be requested to a single destination, in which case
1650  * the requested number of ibt_path_info_t's are returned, and the same
1651  * number of SRC IP address, with the first SRC IP address corrosponding
1652  * to the first ibt_path_info_t, etc.
1653  *
1654  * Restrictions on the source end point can be specified, in the form of a
1655  * source IP address (this implicitly defines the HCA, HCA port and Pkey)
1656  * HCA, HCA port, and sgid (implicitly defines HCA and HCA port).
1657  * Combinations are allowed but they  must be consistent.
1658  *
1659  * Path attributes can also be specified, these can also affect local HCA
1660  * selection.
1661  *
1662  * ibt_get_ip_paths()  internally does (among other things):
1663  *
1664  *   o ibt_get_list_of_ibd_ipaddr_and_macaddr( OUT list_ipaddr_macaddr)
1665  *
1666  *   o extract_pkey_and_sgid(IN list_ipaddr_macaddr, OUT list_pkey_and_sgid)
1667  *
1668  *   o map_dst_ip_addr(IN dst_ip_addr, OUT dst_pkey, OUT dgid) - See Note
1669  *
1670  *   o filter_by_pkey(IN list_pkey_and_sgid, IN dst_pkey, OUT list_of_sgid)
1671  *
1672  *   o do_multipath_query(IN list_of_sgid, IN dst_pkey, IN dgid, OUT path_list)
1673  *
1674  *   o pick_a_good_path(IN path_list, OUT the_path)
1675  *
1676  *   o find_matching_src_ip(IN the_path, IN list_ipaddr_macaddr, OUT src_ip)
1677  *
1678  * The ibd instance which got the ARP response is only on one P_Key
1679  * knowing the ibd instance (or which IPonIB MCG) got the ARP response
1680  * determins the P_Key associated with a dgid. If the proposedi "ip2mac()"
1681  * API is used to get an IP to GID translations, then returned 'sockaddr_dl'
1682  * contains the interface name and index.
1683  *
1684  *
1685  * Example:
1686  *   ip_path_attr.ipa_dst_ip = dst_ip_addr;
1687  *   ip_path_attr.ipa_ndst = 1;
1688  *   ip_path_attr.ipa_max_paths = 1;
1689  *
1690  *   status = ibt_get_ip_paths(clnt_hdl, flags, &ip_path_attr, &paths,
1691  *      &num_paths_p, &src_ip);
1692  *
1693  *   sid = ibt_get_ip_sid(protocol_num, dst_port);
1694  *   path_info->sid = sid;
1695  *
1696  *   ip_cm_info.src_addr = src_ip;
1697  *   ip_cm_info.dst_addr = dst_ip_addr;
1698  *   ip_cm_info.src_port = src_port
1699  *
1700  *   ibt_format_ip_private_data(ip_cm_info, priv_data_len, &priv_data);
1701  *   ibt_open_rc_channel(chan, private_data);
1702  */
1703 typedef struct ibt_ip_path_attr_s {
1704 	ibt_ip_addr_t		*ipa_dst_ip;		/* Required */
1705 	ibt_ip_addr_t		ipa_src_ip;		/* Optional */
1706 	ib_guid_t		ipa_hca_guid;		/* Optional */
1707 	uint8_t			ipa_hca_port_num;	/* Optional */
1708 	uint8_t			ipa_max_paths;		/* Required */
1709 	uint8_t			ipa_ndst;		/* Required */
1710 	uint8_t			ipa_sl:4;		/* Optional */
1711 	ibt_mtu_req_t		ipa_mtu;		/* Optional */
1712 	ibt_srate_req_t		ipa_srate;		/* Optional */
1713 	ibt_pkt_lt_req_t	ipa_pkt_lt;		/* Optional */
1714 	uint_t			ipa_flow:20;		/* Optional */
1715 	uint8_t			ipa_hop;		/* Optional */
1716 	uint8_t			ipa_tclass;		/* Optional */
1717 	zoneid_t		ipa_zoneid;	/* Default 0 = Global Zone */
1718 } ibt_ip_path_attr_t;
1719 
1720 /*
1721  * Path SRC IP addresses
1722  */
1723 typedef struct ibt_path_ip_src_s {
1724 	ibt_ip_addr_t	ip_primary;
1725 	ibt_ip_addr_t	ip_alternate;
1726 } ibt_path_ip_src_t;
1727 
1728 
1729 ibt_status_t ibt_get_ip_paths(ibt_clnt_hdl_t ibt_hdl, ibt_path_flags_t flags,
1730     ibt_ip_path_attr_t *attr, ibt_path_info_t *paths_p, uint8_t *num_paths_p,
1731     ibt_path_ip_src_t *src_ip_p);
1732 
1733 /*
1734  * ibt_get_src_ip()
1735  *	Get List of IP-Address that matches the parameters specified in
1736  *	srcip_attr.  As a given MAC address can have both IPv4 and IPv6
1737  *	addressed configured, caller can optional request to return only
1738  *	the desired family by specifying the "sip_family" field.  If
1739  *	"sip_family" is AF_UNSPEC, then all assigned IP address (IPv4
1740  *	and/or IPv6) will be returned. In case of IPv6 address, scope_id
1741  *	for that specific address will also be returned.
1742  *	"sip_zoneid" will specify the zones the user is interested in.
1743  *
1744  *	Information on each ip-address is returned to the caller in the
1745  *	form of an array of ibt_srcip_info_t.  ibt_get_src_ip() allocates the
1746  *	memory for this array and returns a pointer to the array (src_info_p)
1747  *	and the number of entries in the array (entries_p). This memory
1748  *	should be freed by the client using ibt_free_srcip_info().
1749  *
1750  * ibt_free_srcip_info()
1751  *	Free the memory allocated by successful ibt_get_src_ip()
1752  */
1753 typedef struct ibt_srcip_attr_s {
1754 	ib_gid_t	sip_gid;	/* REQUIRED: Local Port GID */
1755 	zoneid_t	sip_zoneid;	/* Zero means Global Zone */
1756 	ib_pkey_t	sip_pkey;	/* Optional */
1757 	sa_family_t	sip_family;	/* Optional : IPv4 or IPv6 */
1758 } ibt_srcip_attr_t;
1759 
1760 /*
1761  * ip_flag : Flag to indicate whether the returned list of ip-address
1762  * has any duplicate records.
1763  */
1764 #define	IBT_IPADDR_NO_FLAGS	0
1765 #define	IBT_IPADDR_DUPLICATE	1
1766 
1767 typedef struct ibt_srcip_info_s {
1768 	ibt_ip_addr_t	ip_addr;
1769 	zoneid_t	ip_zoneid;	/* ZoneId of this ip-addr */
1770 	uint_t		ip_flag;	/* Flag to indicate any gotchas */
1771 } ibt_srcip_info_t;
1772 
1773 ibt_status_t ibt_get_src_ip(ibt_srcip_attr_t *srcip_attr,
1774     ibt_srcip_info_t **src_info_p, uint_t *entries_p);
1775 
1776 void ibt_free_srcip_info(ibt_srcip_info_t *src_info, uint_t entries);
1777 
1778 
1779 /*
1780  * Callback function that can be used in ibt_aget_ip_paths(), a Non-Blocking
1781  * version of ibt_get_ip_paths().
1782  */
1783 typedef void (*ibt_ip_path_handler_t)(void *arg, ibt_status_t retval,
1784     ibt_path_info_t *paths_p, uint8_t num_paths, ibt_path_ip_src_t *src_ip_p);
1785 
1786 /*
1787  * Find path(s) to a given destination or service asynchronously.
1788  * ibt_aget_ip_paths() is a Non-Blocking version of ibt_get_ip_paths().
1789  */
1790 ibt_status_t ibt_aget_ip_paths(ibt_clnt_hdl_t ibt_hdl, ibt_path_flags_t flags,
1791     ibt_ip_path_attr_t *attr, ibt_ip_path_handler_t func, void  *arg);
1792 
1793 /*
1794  * IP RDMA protocol functions
1795  */
1796 
1797 /*
1798  * IBTF manages the port number space for non well known ports. If a ULP
1799  * is not using TCP/UDP and a well known port, then ibt_get_ip_sid() returns
1800  * an sid based on the IP protocol number '0' (reserved) and an IBTF assigned
1801  * port number.  ibt_release_ip_sid() should be used to release the hold
1802  * of SID created by ibt_get_ip_sid().
1803  */
1804 ib_svc_id_t ibt_get_ip_sid(uint8_t protocol_num, in_port_t dst_port);
1805 ibt_status_t ibt_release_ip_sid(ib_svc_id_t sid);
1806 
1807 uint8_t ibt_get_ip_protocol_num(ib_svc_id_t sid);
1808 in_port_t ibt_get_ip_dst_port(ib_svc_id_t sid);
1809 
1810 /*
1811  * Functions to format/extract the RDMA IP CM private data
1812  */
1813 typedef struct ibt_ip_cm_info_s {
1814 	ibt_ip_addr_t	src_addr;
1815 	ibt_ip_addr_t	dst_addr;
1816 	in_port_t	src_port;
1817 } ibt_ip_cm_info_t;
1818 
1819 /*
1820  * If a ULP is using IP addressing as defined by the RDMA IP CM Service IBTA
1821  * Annex 11, then it must always allocate a private data buffer for use in
1822  * the ibt_open_rc_channel(9F) call. The minimum size of the buffer is
1823  * IBT_IP_HDR_PRIV_DATA_SZ, if the ULP has no ULP specific private data.
1824  * This allows ibt_format_ip_private_data() to place the RDMA IP CM service
1825  * hello message in the private data of the REQ. If the ULP has some ULP
1826  * specific private data then it should allocate a buffer big enough to
1827  * contain that data plus an additional IBT_IP_HDR_PRIV_DATA_SZ bytes.
1828  * The ULP should place its  ULP specific private data at offset
1829  * IBT_IP_HDR_PRIV_DATA_SZ in the allocated buffer before calling
1830  * ibt_format_ip_private_data().
1831  */
1832 ibt_status_t ibt_format_ip_private_data(ibt_ip_cm_info_t *ip_cm_info,
1833     ibt_priv_data_len_t priv_data_len, void *priv_data_p);
1834 ibt_status_t ibt_get_ip_data(ibt_priv_data_len_t priv_data_len,
1835     void *priv_data, ibt_ip_cm_info_t *ip_info_p);
1836 
1837 /*
1838  * The ibt_alt_ip_path_attr_t structure is used to specify additional optional
1839  * attributes when requesting an alternate path for an existing channel.
1840  *
1841  * Attributes that are don't care should be set to NULL or '0'.
1842  */
1843 typedef struct ibt_alt_ip_path_attr_s {
1844 	ibt_ip_addr_t		apa_dst_ip;
1845 	ibt_ip_addr_t		apa_src_ip;
1846 	ibt_srate_req_t		apa_srate;
1847 	ibt_pkt_lt_req_t	apa_pkt_lt;	/* Packet Life Time Request */
1848 	uint_t			apa_flow:20;
1849 	uint8_t			apa_sl:4;
1850 	uint8_t			apa_hop;
1851 	uint8_t			apa_tclass;
1852 	zoneid_t		apa_zoneid;	/* Default 0 = Global Zone */
1853 } ibt_alt_ip_path_attr_t;
1854 
1855 ibt_status_t ibt_get_ip_alt_path(ibt_channel_hdl_t rc_chan,
1856     ibt_path_flags_t flags, ibt_alt_ip_path_attr_t *attr,
1857     ibt_alt_path_info_t *alt_path);
1858 
1859 /*
1860  * CONTRACT PRIVATE ONLY INTERFACES
1861  *
1862  * DO NOT USE THE FOLLOWING FUNCTIONS WITHOUT SIGNING THE CONTRACT
1863  * WITH IBTF GROUP.
1864  */
1865 
1866 /* Define an Address Record structure (data for ATS service records). */
1867 typedef struct ibt_ar_s {
1868 	ib_gid_t	ar_gid;		/* GID of local HCA port */
1869 	ib_pkey_t	ar_pkey;	/* P_Key valid on port of ar_gid */
1870 	uint8_t		ar_data[16];	/* Data affiliated with GID/P_Key */
1871 } ibt_ar_t;
1872 
1873 /*
1874  * ibt_register_ar()
1875  * ibt_deregister_ar()
1876  *	Register/deregister an Address Record with the SA.
1877  * ibt_query_ar()
1878  *	Query the SA for Address Records matching either GID/P_Key or Data.
1879  */
1880 ibt_status_t ibt_register_ar(ibt_clnt_hdl_t ibt_hdl, ibt_ar_t *arp);
1881 
1882 ibt_status_t ibt_deregister_ar(ibt_clnt_hdl_t ibt_hdl, ibt_ar_t *arp);
1883 
1884 ibt_status_t ibt_query_ar(ib_gid_t *sgid, ibt_ar_t *queryp, ibt_ar_t *resultp);
1885 
1886 
1887 /*
1888  * ibt_modify_system_image()
1889  * ibt_modify_system_image_byguid()
1890  *	Modify specified HCA's system image GUID.
1891  */
1892 ibt_status_t ibt_modify_system_image(ibt_hca_hdl_t hca_hdl, ib_guid_t sys_guid);
1893 
1894 ibt_status_t ibt_modify_system_image_byguid(ib_guid_t hca_guid,
1895     ib_guid_t sys_guid);
1896 
1897 
1898 /*
1899  * ibt_modify_port()
1900  * ibt_modify_port_byguid()
1901  *	Modify the specified port, or all ports attribute(s).
1902  */
1903 ibt_status_t ibt_modify_port(ibt_hca_hdl_t hca_hdl, uint8_t port,
1904     ibt_port_modify_flags_t flags, uint8_t init_type);
1905 
1906 ibt_status_t ibt_modify_port_byguid(ib_guid_t hca_guid, uint8_t port,
1907     ibt_port_modify_flags_t flags, uint8_t init_type);
1908 
1909 
1910 /*
1911  * ibt_get_port_state()
1912  * ibt_get_port_state_byguid()
1913  *	Return the most commonly requested attributes of an HCA port.
1914  *	If the link state is not IBT_PORT_ACTIVE, the other returned values
1915  *	are undefined.
1916  */
1917 ibt_status_t ibt_get_port_state(ibt_hca_hdl_t hca_hdl, uint8_t port,
1918     ib_gid_t *sgid_p, ib_lid_t *base_lid_p);
1919 
1920 ibt_status_t ibt_get_port_state_byguid(ib_guid_t hca_guid, uint8_t port,
1921     ib_gid_t *sgid_p, ib_lid_t *base_lid_p);
1922 
1923 /*
1924  * ibt_alloc_io_mem()
1925  * ibt_free_io_mem()
1926  *	Allocate and deallocate dma-able memory.
1927  */
1928 ibt_status_t ibt_alloc_io_mem(ibt_hca_hdl_t, size_t, ibt_mr_flags_t,
1929     caddr_t *, ibt_mem_alloc_hdl_t *);
1930 
1931 ibt_status_t ibt_free_io_mem(ibt_hca_hdl_t, ibt_mem_alloc_hdl_t);
1932 
1933 /*
1934  * Interfaces to get IB partition information.
1935  */
1936 
1937 typedef struct ibt_part_attr_s {
1938 	datalink_id_t	pa_dlinkid;
1939 	datalink_id_t	pa_plinkid;
1940 	uint8_t		pa_port;
1941 	ib_guid_t	pa_hca_guid;
1942 	ib_guid_t	pa_port_guid;
1943 	ib_pkey_t	pa_pkey;
1944 } ibt_part_attr_t;
1945 
1946 void ibt_register_part_attr_cb(
1947     ibt_status_t (*)(datalink_id_t, ibt_part_attr_t *),
1948     ibt_status_t (*)(ibt_part_attr_t **, int *));
1949 void ibt_unregister_part_attr_cb(void);
1950 
1951 ibt_status_t ibt_get_part_attr(datalink_id_t, ibt_part_attr_t *);
1952 ibt_status_t ibt_get_all_part_attr(ibt_part_attr_t **, int *);
1953 ibt_status_t ibt_free_part_attr(ibt_part_attr_t *, int);
1954 
1955 
1956 /*
1957  * ibt_lid_to_node_info()
1958  *	Retrieve node record information for the specified LID.
1959  */
1960 ibt_status_t ibt_lid_to_node_info(ib_lid_t lid, ibt_node_info_t *node_info_p);
1961 
1962 
1963 #ifdef __cplusplus
1964 }
1965 #endif
1966 
1967 #endif /* _SYS_IB_IBTL_IBTI_COMMON_H */
1968