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