xref: /illumos-gate/usr/src/uts/common/sys/ib/ibtl/ibti_cm.h (revision 79033acb)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef	_SYS_IB_IBTL_IBTI_CM_H
28 #define	_SYS_IB_IBTL_IBTI_CM_H
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 /*
33  * ibti_cm.h
34  *
35  * This file contains the data structure definitions for the IBTI
36  * communication manager (CM). It is only included in ibti.h
37  */
38 
39 #ifdef	__cplusplus
40 extern "C" {
41 #endif
42 
43 /*
44  * Defines.
45  */
46 #define	IBT_MAX_PRIV_DATA_SZ		224
47 #define	IBT_DREP_PRIV_DATA_SZ		224
48 #define	IBT_RTU_PRIV_DATA_SZ		224
49 #define	IBT_MRA_PRIV_DATA_SZ		222
50 #define	IBT_DREQ_PRIV_DATA_SZ		220
51 #define	IBT_REP_PRIV_DATA_SZ		196
52 #define	IBT_LAP_PRIV_DATA_SZ		168
53 #define	IBT_APR_PRIV_DATA_SZ		148
54 #define	IBT_REJ_PRIV_DATA_SZ		148
55 #define	IBT_REQ_PRIV_DATA_SZ		92
56 #define	IBT_SIDR_REQ_PRIV_DATA_SZ	216
57 #define	IBT_SIDR_REP_PRIV_DATA_SZ	136
58 
59 #define	IBT_CM_ADDL_REJ_LEN	72	/* Additional Rej Info len */
60 					/* This is the max consumer addl */
61 					/* reject info len */
62 #define	IBT_CM_SIDR_CP_LEN	72	/* SIDR REP Class Port Info len */
63 #define	IBT_CM_APR_ADDL_LEN	72	/* Additional Info len in APR message */
64 
65 typedef	uint8_t	ibt_priv_data_len_t;
66 
67 /*
68  * CM channel handler reject reasons.
69  *
70  * Refer to InfiniBand Architecture Release Volume 1 Rev 1.0a:
71  * Section 12.6.7.2	Rejection Reason
72  */
73 typedef enum ibt_cm_reason_e {
74 	IBT_CM_SUCCESS		= 0,	/* Success */
75 	IBT_CM_NO_CHAN		= 1,	/* Remote unable to allocate a CHAN */
76 	IBT_CM_NO_EEC		= 2,	/* Remote unable to allocate an EEC */
77 	IBT_CM_NO_RESC		= 3,	/* Remote unable to allocate resource */
78 	IBT_CM_TIMEOUT		= 4,	/* CM protocol timed out waiting for */
79 					/* a msg */
80 	IBT_CM_NOT_SUPPORTED 	= 5,	/* Request not supported */
81 	IBT_CM_INVALID_CID 	= 6,	/* Local CID or Remote CID invalid */
82 	IBT_CM_INVALID_COMM_INS	= 7,	/* Local CID, Remote CID, Channel */
83 					/* does not refer to a valid */
84 					/* communication Instance. */
85 	IBT_CM_INVALID_SID 	= 8,	/* Service not supported or not */
86 					/* recognized */
87 	IBT_CM_INVALID_SRV_TYPE	= 9,	/* Invalid transport service type */
88 	IBT_CM_CONN_STALE 	= 10,	/* Stale connection */
89 	IBT_CM_INVALID_RDC 	= 11,	/* RDC does not exist */
90 	IBT_CM_PRIM_GID 	= 12,	/* Primary remote port gid rejected. */
91 	IBT_CM_PRIM_LID 	= 13,	/* Primary remote port lid rejected. */
92 	IBT_CM_INVALID_PRIM_SL 	= 14,	/* Primary Requested SL not supported */
93 	IBT_CM_INVALID_PRIM_TC 	= 15,	/* Primary Requested traffic class */
94 					/* not supported */
95 	IBT_CM_INVALID_PRIM_HOP	= 16,	/* Primary Requested hop limit not */
96 					/* accepted */
97 	IBT_CM_INVALID_PRIM_RATE = 17,	/* Primary Packet rate not accepted */
98 	IBT_CM_ALT_GID 		= 18,	/* Alternate remote port gid rejected */
99 	IBT_CM_ALT_LID 		= 19,	/* Alternate remote port lid rejected */
100 	IBT_CM_INVALID_ALT_SL 	= 20,	/* Alternate Requested SL not */
101 					/* supported */
102 	IBT_CM_INVALID_ALT_TC 	= 21,	/* Alternate Requested traffic class */
103 					/* not supported */
104 	IBT_CM_INVALID_ALT_HOP 	= 22,	/* Alternate Requested hop limit */
105 					/* accepted */
106 	IBT_CM_INVALID_ALT_RATE = 23,	/* Alternate Packet rate not accepted */
107 	IBT_CM_REDIRECT_CM 	= 24,	/* Port & CM redirected */
108 	IBT_CM_PORT_REDIRECT 	= 25,	/* Port redirected */
109 	IBT_CM_INVALID_MTU 	= 26,	/* Path MTU not supported */
110 	IBT_CM_INSUFF_RESOURCE	= 27,	/* Insufficient responder resources */
111 	IBT_CM_CONSUMER 	= 28,	/* Consumer rejected connection */
112 	IBT_CM_RNR_RETRY_CNT_REJ = 29,	/* RNR NAK retry count rejected */
113 	IBT_CM_DUP_COM_ID	= 30,	/* Local CID in REQ is duplicated */
114 	IBT_CM_CLASS_NO_SUPPORT	= 31,	/* Class version not supported */
115 	IBT_CM_INVALID_PRIM_FLOW = 32,	/* Invalid primary flow label */
116 	IBT_CM_INVALID_ALT_FLOW = 33,	/* Invalid alternate flow label */
117 	IBT_CM_DUP_CONN_REQ	= 1000, /* Duplicate connection request */
118 	IBT_CM_ABORT		= 1001,	/* Connection aborted */
119 	IBT_CM_CI_FAILURE	= 1002,	/* A call to CI failed, could be */
120 					/* query/modify channel */
121 	IBT_CM_CHAN_INVALID_STATE = 1003 /* Passive's QP is not in Init */
122 					/* state */
123 
124 } ibt_cm_reason_t;
125 
126 /*
127  * CM flags.
128  */
129 typedef uint8_t ibt_cm_flags_t;
130 
131 #define	IBT_CM_NO_FLAGS		0x0
132 #define	IBT_CM_FLOW_CONTROL	0x1
133 #define	IBT_CM_SRQ_EXISTS	0x2
134 
135 
136 /*
137  * The CM Handler function return values.
138  */
139 typedef enum ibt_cm_status_e {
140 	IBT_CM_ACCEPT		= 0,
141 	IBT_CM_REJECT		= 1,
142 	IBT_CM_REDIRECT_PORT	= 2,	/* Redirect port */
143 	IBT_CM_REDIRECT		= 3,	/* Redirect port and CM */
144 	IBT_CM_NO_CHANNEL	= 4,	/* Unable to allocate a channel */
145 	IBT_CM_NO_RESOURCE	= 5,	/* Unable to allocate a resource */
146 	IBT_CM_DEFAULT		= 6,	/* Do the default action */
147 	IBT_CM_DEFER		= 7	/* Can't complete processing now */
148 } ibt_cm_status_t;			/* will call ibt_cm_proceed() */
149 					/* later */
150 
151 /*
152  * SIDR_REP status type
153  */
154 typedef enum ibt_sidr_status_e {
155 	IBT_CM_SREP_CHAN_VALID	= 0,
156 	IBT_CM_SREP_SID_INVALID	= 1,	/* Service ID not supported */
157 	IBT_CM_SREP_REJ		= 2,	/* Service provider reject */
158 	IBT_CM_SREP_NO_CHAN	= 3,	/* No channel available */
159 	IBT_CM_SREP_REDIRECT	= 4,	/* Redirect request */
160 	IBT_CM_SREP_CL_INVALID	= 5,	/* Class Version is invalid */
161 	IBT_CM_SREP_TIMEOUT	= 1000	/* No SIDR_REP received */
162 } ibt_sidr_status_t;
163 
164 /*
165  * Alternate path status type
166  * The implementation defined status codes begin from 20. The status codes
167  * below 20 are based on apr_status in the APR mad.
168  */
169 typedef enum ibt_ap_status_e {
170 	IBT_CM_AP_LOADED	= 0,	/* AP loaded successfully */
171 	IBT_CM_AP_INVALID_COMMID = 1,	/* Invalid communication instance */
172 	IBT_CM_AP_NOT_SUPPORTED	= 2,	/* Alternate paths not supported */
173 	IBT_CM_AP_REJECT	= 3,	/* Failover port rejected */
174 	IBT_CM_AP_REDIRECT	= 4,	/* Reject - redirect */
175 	IBT_CM_AP_MATCH_PRIM	= 5,	/* AP matches primary path */
176 	IBT_CM_AP_QPNEECN_INVALID = 6,	/* AP QPN/EECN does not match */
177 	IBT_CM_AP_RLID_REJECTED	= 7,	/* AP remote port lid rejected */
178 	IBT_CM_AP_RGID_REJECTED	= 8,	/* AP remote port gid rejected */
179 	IBT_CM_AP_FLOW_REJECTED	= 9,	/* AP flow label rejected */
180 	IBT_CM_AP_TCLASS_REJECTED = 10,	/* AP traffic class rejected */
181 	IBT_CM_AP_HOP_REJECTED	= 11,	/* AP hop limit rejected */
182 	IBT_CM_AP_RATE_REJECTED	= 12,	/* AP static packet rate rejected */
183 	IBT_CM_AP_SL_REJECTED	= 13,	/* AP service level rejected */
184 	IBT_CM_AP_TIMEOUT	= 1000,	/* LAP timed out */
185 	IBT_CM_AP_ABORT		= 1001	/* ibt_set_alternate_path returned */
186 					/* earlier because of connection */
187 					/* getting closed */
188 } ibt_ap_status_t;
189 
190 /*
191  * Communication event types.
192  */
193 typedef enum ibt_cm_event_type_e {
194 	IBT_CM_EVENT_REQ_RCV	= 0x1,
195 	IBT_CM_EVENT_REP_RCV,
196 	IBT_CM_EVENT_MRA_RCV,
197 	IBT_CM_EVENT_LAP_RCV,
198 	IBT_CM_EVENT_APR_RCV,
199 	IBT_CM_EVENT_CONN_EST,		/* RTU has been sent/recvd and it is */
200 					/* OK to use the connection */
201 	IBT_CM_EVENT_CONN_CLOSED,	/* Connection has been closed and it */
202 					/* is OK to free resources associated */
203 					/* with the connection. */
204 	IBT_CM_EVENT_FAILURE		/* The CM Failure see cf_code in the */
205 					/* ibt_cm_conn_failed_t struct for */
206 					/* details of the failure */
207 } ibt_cm_event_type_t;
208 
209 /*
210  * CM and Port redirect information.
211  */
212 typedef struct ibt_redirect_info_s {
213 	ib_gid_t	rdi_gid;
214 	uint8_t		rdi_tclass;
215 	uint8_t		rdi_sl:4;
216 	uint_t		rdi_flow:20;
217 	ib_lid_t	rdi_dlid;
218 	ib_qpn_t	rdi_qpn;
219 	ib_qkey_t	rdi_qkey;
220 	ib_pkey_t	rdi_pkey;
221 } ibt_redirect_info_t;
222 
223 /*
224  * Values for rep_failover_status.
225  */
226 #define	IBT_CM_FAILOVER_ACCEPT		0x00 /* Failover port accepted */
227 #define	IBT_CM_FAILOVER_REJ_NOTSUPP	0x01 /* Failover not supported */
228 #define	IBT_CM_FAILOVER_REJ		0x02 /* Failover port rejected */
229 
230 /*
231  * CM REP_RCV event structure.
232  */
233 typedef struct ibt_cm_rep_rcv_s {
234 	uint8_t		rep_rdma_ra_in;		/* Arbitrated responder */
235 						/* resources (rdma_ra_in) */
236 	uint8_t		rep_rdma_ra_out;	/* Arbitrated initiator */
237 						/* depth (rdma_ra_out) */
238 	clock_t		rep_service_time;	/* time in clock ticks */
239 						/* Time to complete */
240 						/* processing of REP event */
241 	uint8_t		rep_failover_status;	/* Failover Port status */
242 	ibt_cm_flags_t	rep_flags;		/* EE flow control, SRQ etc */
243 } ibt_cm_rep_rcv_t;
244 
245 
246 /*
247  * Values for mra_msg_type.
248  */
249 #define	IBT_CM_MRA_TYPE_REQ	0x00	/* mra_msg values */
250 #define	IBT_CM_MRA_TYPE_REP	0x01
251 #define	IBT_CM_MRA_TYPE_LAP	0x02
252 
253 /*
254  * CM MRA_RCV event structure.
255  */
256 typedef struct ibt_cm_mra_rcv_s {
257 	uint8_t		mra_msg_type;	/* The message being MRA'd */
258 	clock_t		mra_service_time;	/* timeout in microseconds */
259 } ibt_cm_mra_rcv_t;
260 
261 /*
262  * CM LAP_RCV event structure.
263  */
264 typedef struct ibt_cm_lap_rcv_s {
265 	ibt_adds_vect_t	lap_alternate_path;
266 	clock_t		lap_timeout;		/* timeout in microseconds */
267 						/* This is the time that the */
268 						/* Service handler has to */
269 						/* return to the CM */
270 } ibt_cm_lap_rcv_t;
271 
272 /*
273  * Consumer defined Additional reject information.
274  */
275 typedef struct ibt_ari_con_s {
276 	uint8_t		rej_ari_len;			/* Length */
277 	uint8_t		rej_ari[IBT_CM_ADDL_REJ_LEN];	/* Buffer */
278 } ibt_ari_con_t;
279 
280 /*
281  * Additional reject information.
282  */
283 typedef union ibt_arej_info_u {
284 	ibt_ari_con_t		ari_consumer;	/* IBT_CM_CONSUMER */
285 	ib_gid_t		ari_gid;	/* IBT_CM_PRIM_GID, */
286 						/* IBT_CM_ALT_GID, */
287 						/* IBT_CM_PORT_REDIRECT */
288 	ib_lid_t		ari_lid;	/* IBT_CM_PRIM_LID, */
289 						/* IBT_CM_ALT_LID */
290 	uint8_t			ari_sl:4;	/* IBT_CM_INVALID_PRIM_SL, */
291 						/* IBT_CM_INVALID_ALT_SL */
292 	uint8_t			ari_tclass;	/* IBT_CM_INVALID_PRIM_TC, */
293 						/* IBT_CM_INVALID_ALT_TC */
294 	uint8_t			ari_hop;	/* IBT_CM_INVALID_PRIM_HOP, */
295 						/* IBT_CM_INVALID_ALT_HOP */
296 	uint_t			ari_flow:20;	/* IBT_CM_INVALID_PRIM_FLOW, */
297 						/* IBT_CM_INVALID_ALT_FLOW */
298 	ibt_srate_t		ari_rate;	/* IBT_CM_INVALID_PRIM_RATE, */
299 						/* IBT_CM_INVALID_ALT_RATE */
300 	ib_mtu_t		ari_mtu;	/* IBT_CM_INVALID_MTU */
301 	ibt_redirect_info_t	ari_redirect;	/* IBT_CM_REDIRECT_CM */
302 } ibt_arej_info_t;
303 
304 /*
305  * CM APR_RCV event structure.
306  */
307 typedef struct ibt_cm_apr_rcv_s {
308 	ibt_ap_status_t		apr_status;
309 	boolean_t		apr_arej_info_valid;
310 	ibt_arej_info_t		apr_arej_info;
311 } ibt_cm_apr_rcv_t;
312 
313 
314 /*
315  * Connection Failed Message type (values of cf_msg).
316  * Identifies the CM message that either timed out or is being rejected.
317  */
318 #define	IBT_CM_FAILURE_REQ	0x00
319 #define	IBT_CM_FAILURE_REP	0x01
320 #define	IBT_CM_FAILURE_UNKNOWN	0x02
321 #define	IBT_CM_FAILURE_LAP	0x03
322 
323 /*
324  * CM Failure code (values of cf_code).
325  * Identifies the reason for failure.
326  */
327 #define	IBT_CM_FAILURE_REJ_SENT	0x00
328 #define	IBT_CM_FAILURE_REJ_RCV	0x01
329 #define	IBT_CM_FAILURE_TIMEOUT	0x02
330 #define	IBT_CM_FAILURE_DUP	0x03
331 #define	IBT_CM_FAILURE_STALE	0x04
332 
333 /*
334  * IBT_CM_EVENT_FAILURE event struct.
335  */
336 typedef struct ibt_cm_conn_failed_s {
337 	uint8_t		cf_code;	/* Failure Code */
338 	uint8_t		cf_msg;		/* The message that timed out or is */
339 					/* being rejected */
340 	boolean_t	cf_arej_info_valid;	/* Is cf_additional valid? */
341 	ibt_cm_reason_t	cf_reason;	/* Reject reason */
342 	ibt_arej_info_t	cf_additional;	/* Additional Reject info */
343 } ibt_cm_conn_failed_t;
344 
345 
346 /*
347  * CM REQ_RCV event structure.
348  *
349  * The req_cm_opaque is an IBTF CM opaque (to the client) value, that should
350  * be returned to the IBTF CM if the client/server CM handler wishes to call
351  * ibt_cm_delay().
352  *
353  *	prim_addr->av_dgid		Is the GID of the requester.
354  *	prim_addr->av_sgid		Is the local GID to which the
355  *					requester is attempting to establish
356  *					a connection to.
357  *	hca_guid			Is the HCA GUID that contains the
358  *					prim_addr->av_sgid
359  *	prim_hca_port			Is the port on the hca_guid that
360  *					prim_addr->av_sgid is on.
361  */
362 typedef struct ibt_cm_req_rcv_s {
363 	ib_svc_id_t	req_service_id;
364 	ibt_tran_srv_t	req_transport;
365 	ib_guid_t	req_hca_guid;
366 	uint8_t		req_prim_hca_port;
367 	uint8_t		req_alt_hca_port;
368 	ibt_adds_vect_t	req_prim_addr;
369 	ibt_adds_vect_t	req_alt_addr;
370 	uint8_t		req_rdma_ra_in;   	/* Offered responder */
371 						/* resources. */
372 	uint8_t		req_rdma_ra_out; 	/* Offered initiator depth */
373 	clock_t		req_timeout;		/* timeout in microseconds */
374 						/* This is the time that the */
375 						/* Service handler has to */
376 						/* return to the CM */
377 	ib_qpn_t	req_remote_qpn;
378 	ib_qkey_t	req_remote_qkey;
379 	ib_pkey_t	req_pkey;
380 	ibt_cm_flags_t	req_flags;		/* EE flow control etc */
381 	uint8_t		req_retry_cnt:3;
382 	ibt_rnr_retry_cnt_t	req_rnr_retry_cnt;
383 	ib_eecn_t	req_opaque1;
384 	ib_eecn_t	req_opaque2;
385 } ibt_cm_req_rcv_t;
386 
387 /*
388  * The IBT_CM_EVENT_CONN_CLOSED event is generated by the CM when a connection
389  * has been closed. The reason the connection was closed is given in the
390  * "closed" member of the cm_event as one of:
391  *
392  * A client can only call ibt_free_channel() to free channel resources on
393  * receipt of the IBT_CM_EVENT_CONN_CLOSED event.
394  */
395 #define	IBT_CM_CLOSED_DREP_RCVD		0x01
396 #define	IBT_CM_CLOSED_DREQ_RCVD		0x02
397 #define	IBT_CM_CLOSED_REJ_RCVD		0x03
398 #define	IBT_CM_CLOSED_DREQ_TIMEOUT	0x04
399 #define	IBT_CM_CLOSED_DUP		0x05
400 #define	IBT_CM_CLOSED_ABORT		0x06
401 #define	IBT_CM_CLOSED_STALE		0x07
402 #define	IBT_CM_CLOSED_ALREADY		0x08
403 
404 /*
405  * Operation type in ibt_cm_event_type_t.
406  *
407  * Note:
408  * 	The IBT_CM_EVENT_CONN_EST event has no associated "cm_event"
409  *	field in the ibt_cm_event_t structure.
410  *
411  *	The cm_session_id is a CM opaque (to the client) value, that
412  *	should be returned to the CM if the client/server CM handler wishes
413  *	to call ibt_cm_delay() or ibt_cm_proceed().
414  *
415  */
416 typedef struct ibt_cm_event_s {
417 	ibt_cm_event_type_t	cm_type;	/* Describes the event */
418 	void			*cm_session_id;	/* Used by the CM */
419 	ibt_channel_hdl_t	cm_channel;	/* Event channel. Not valid */
420 						/* for ibt_cm_req_rcv_t */
421 	ibt_eec_hdl_t		cm_opaque;
422 	ibt_priv_data_len_t	cm_priv_data_len;	/* 0 if no private */
423 	void			*cm_priv_data;		/* data returned */
424 	union {
425 		ibt_cm_rep_rcv_t		rep;
426 		ibt_cm_req_rcv_t 		req;
427 		ibt_cm_lap_rcv_t		lap;
428 		ibt_cm_apr_rcv_t		apr;
429 		ibt_cm_mra_rcv_t		mra;
430 		ibt_cm_conn_failed_t		failed;
431 		uint8_t				closed;
432 	} cm_event;	/* operation specific */
433 } ibt_cm_event_t;
434 
435 /*
436  * CM Return structure for an incoming REQ
437  * Server handler that wishes to accept the connection, fills all the
438  * values before returning to CM
439  */
440 typedef struct ibt_cm_ret_rep_s {
441 	ibt_channel_hdl_t	cm_channel;	/* The channel overwhich the */
442 						/* connection will be */
443 						/* established */
444 						/* can be returned NULL */
445 						/* if no resources available */
446 	uint8_t			cm_rdma_ra_out; /* max RDMA-R/Atomic sent */
447 						/* Number of RDMA RD's & */
448 						/* Atomics outstanding */
449 	uint8_t			cm_rdma_ra_in;	/* Incoming RDMA-R/Atomic */
450 						/* Responder resources for */
451 						/* handling incoming */
452 						/* RDMA RD's & Atomics */
453 	ibt_rnr_retry_cnt_t	cm_rnr_retry_cnt;
454 } ibt_cm_ret_rep_t;
455 
456 /*
457  * Define an ibt_cm_proceed() argument union.
458  *
459  * rep is valid when an IBT client cm handler has decided to continue a
460  * REQ_RCV, accepting the connection.
461  *
462  * rej is valid when an IBT client cm handler has decided to continue a
463  * REQ_RCV or REP_RCV, rejecting the message.
464  *
465  * apr is valid when an IBT client cm handler has decided to continue a
466  * LAP_RCV, redirecting the lap request.
467  */
468 typedef union ibt_cm_proceed_reply_s {
469 	ibt_cm_ret_rep_t	rep;	/* Return for REP */
470 	ibt_arej_info_t		rej;	/* Return for REJ */
471 	ibt_redirect_info_t	apr;	/* Return for APR */
472 } ibt_cm_proceed_reply_t;
473 
474 
475 /*
476  * Define a CM handler return arguments structure.
477  *
478  * cm_ret.rep is returned to the CM when an IBT client cm handler has
479  * decided to accept a connection in response to a CM REQ_RCV event.
480  *
481  * cm_ret.rej is returned to the CM when an IBT client cm handler
482  * has decided to reject the connection in response to a CM REQ_RCV event.
483  *
484  * cm_ret.apr is returned to the CM when an IBT client cm handler
485  * has decided to redirect the lap request in response to a CM LAP RCV event.
486  *
487  * The client/server should update cm_ret_len with number of private data
488  * bytes filled in priv_data arg of the cm handler.
489  */
490 typedef struct ibt_cm_return_args_s {
491 	ibt_priv_data_len_t	cm_ret_len;
492 	union {
493 		ibt_cm_ret_rep_t	rep;	/* Return for REP */
494 		ibt_arej_info_t		rej;	/* Return for REJ */
495 		ibt_redirect_info_t	apr;	/* Return for APR */
496 	} cm_ret;	/* reply specific */
497 } ibt_cm_return_args_t;
498 
499 
500 /*
501  * Communication Manager UD event types.
502  */
503 typedef enum ibt_cm_ud_event_type_e {
504 	IBT_CM_UD_EVENT_SIDR_REQ	= 1,
505 	IBT_CM_UD_EVENT_SIDR_REP	= 2
506 } ibt_cm_ud_event_type_t;
507 
508 /*
509  * CM SIDR_REQ event structure.
510  */
511 typedef struct ibt_cm_sidr_req_s {
512 	ib_guid_t	sreq_hca_guid;
513 	uint8_t		sreq_hca_port;
514 	ib_pkey_t	sreq_pkey;
515 	ib_svc_id_t	sreq_service_id;
516 } ibt_cm_sidr_req_t;
517 
518 /*
519  * CM SIDR_REP event structure.
520  */
521 typedef struct ibt_cm_sidr_rep_s {
522 	ibt_sidr_status_t	srep_status;
523 	ib_svc_id_t		srep_service_id;
524 	ib_qkey_t		srep_remote_qkey;
525 	ib_qpn_t		srep_remote_qpn;
526 	ibt_redirect_info_t	srep_redirect;	/* Only valid if redirect */
527 } ibt_cm_sidr_rep_t;
528 
529 /*
530  * Operation type in ibt_cm_ud_event_type_t.
531  *
532  * The cm_session_id is a CM opaque (to the client) value, that
533  * should be returned to the CM if the client/server CM handler
534  * wishes to call ibt_cm_ud_proceed().
535  */
536 typedef struct ibt_cm_ud_event_s {
537 	ibt_cm_ud_event_type_t	cm_type;	/* Describes the event record */
538 	void			*cm_session_id;	/* Used by the CM */
539 	ibt_priv_data_len_t	cm_priv_data_len;
540 	void			*cm_priv_data;
541 	union {
542 		ibt_cm_sidr_rep_t	sidr_rep;
543 		ibt_cm_sidr_req_t	sidr_req;
544 	} cm_event;				/* operation specific */
545 } ibt_cm_ud_event_t;
546 
547 
548 /*
549  * Define a CM UD handler return arguments structure.
550  *
551  * The information here is returned to the CM when an IBT client CM UD
552  * handler has decided to communicate (via UD messages) with the requester
553  * of the SIDR_REQ_RCV event.
554  *
555  * The ud_channel encodes the QPN and Q_Key to be placed in the SIDR_REP.
556  *
557  * CM sets ud_ret_len to 0 before calling the UD CM handler.  If the CM UD
558  * handler wishes to send private data back, it needs to update ud_ret_len
559  * with the actual number of bytes to be sent back in the SIDR_REP MAD.  It
560  * copies said data to the buffer pointed to by the ret_priv_data argument.
561  *
562  * The ud_redirect structure should only be updated if the UD CM handler is
563  * Redirecting a CM request.
564  */
565 typedef struct ibt_cm_ud_return_args_s {
566 	ibt_priv_data_len_t	ud_ret_len;
567 	ibt_channel_hdl_t	ud_channel;
568 	ibt_redirect_info_t	ud_redirect;
569 } ibt_cm_ud_return_args_t;
570 
571 
572 /*
573  * IBT Client CM Callback function typedefs.
574  *
575  * ibt_cm_handler_t:
576  *
577  * The CM event handler function. An IBT client callback that handles
578  * CM events. If the handler will exceed the event service timeout
579  * then it should call ibt_cm_delay(), specifying the maximum time it
580  * will take to complete processing the CM event.
581  *
582  * Clients are advised not to issue blocking calls from a cm handler, as this
583  * would block the CM threads, and could delay or block other client
584  * connections.
585  *
586  * Clients are allowed to make resource clean up/free calls in the CM handler
587  * such as ibt_free_cq, ibt_free_rc/ud_channel, etc. on connection failure
588  * or tear down.
589  *
590  * Clients should not call ibt_close_rc_channel in the cm handler for connection
591  * failure or tear down events, as these events already perform the processing
592  * necessary to close the channel.
593  *
594  * Clients can call ibt_close_rc_channel only in the non-blocking mode from
595  * the cm handler for connection abort.
596  */
597 typedef ibt_cm_status_t (*ibt_cm_handler_t)(void *cm_private,
598     ibt_cm_event_t *event, ibt_cm_return_args_t *ret_args,
599     void *ret_priv_data, ibt_priv_data_len_t ret_len_max);
600 
601 /*
602  * ibt_cm_ud_handler_t	- Pointer to the CM UD event handler function.
603  *			  This function should handle the following CM
604  *			  events:
605  *				IBT_CM_UD_EVENT_SIDR_REQ
606  *				IBT_CM_UD_EVENT_SIDR_REP
607  */
608 typedef ibt_cm_status_t (*ibt_cm_ud_handler_t)(void *ud_cm_private,
609     ibt_cm_ud_event_t *event, ibt_cm_ud_return_args_t *ret_args,
610     void *ret_priv_data, ibt_priv_data_len_t ret_len_max);
611 
612 #ifdef __cplusplus
613 }
614 #endif
615 
616 #endif /* _SYS_IB_IBTL_IBTI_CM_H */
617