1*9e39c5baSBill Taylor /*
2*9e39c5baSBill Taylor * CDDL HEADER START
3*9e39c5baSBill Taylor *
4*9e39c5baSBill Taylor * The contents of this file are subject to the terms of the
5*9e39c5baSBill Taylor * Common Development and Distribution License (the "License").
6*9e39c5baSBill Taylor * You may not use this file except in compliance with the License.
7*9e39c5baSBill Taylor *
8*9e39c5baSBill Taylor * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*9e39c5baSBill Taylor * or http://www.opensolaris.org/os/licensing.
10*9e39c5baSBill Taylor * See the License for the specific language governing permissions
11*9e39c5baSBill Taylor * and limitations under the License.
12*9e39c5baSBill Taylor *
13*9e39c5baSBill Taylor * When distributing Covered Code, include this CDDL HEADER in each
14*9e39c5baSBill Taylor * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*9e39c5baSBill Taylor * If applicable, add the following below this CDDL HEADER, with the
16*9e39c5baSBill Taylor * fields enclosed by brackets "[]" replaced with your own identifying
17*9e39c5baSBill Taylor * information: Portions Copyright [yyyy] [name of copyright owner]
18*9e39c5baSBill Taylor *
19*9e39c5baSBill Taylor * CDDL HEADER END
20*9e39c5baSBill Taylor */
21*9e39c5baSBill Taylor
22*9e39c5baSBill Taylor /*
23*9e39c5baSBill Taylor * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24*9e39c5baSBill Taylor * Use is subject to license terms.
25*9e39c5baSBill Taylor */
26*9e39c5baSBill Taylor
27*9e39c5baSBill Taylor #include <strings.h>
28*9e39c5baSBill Taylor
29*9e39c5baSBill Taylor #include <dapl.h>
30*9e39c5baSBill Taylor #include <dapl_adapter_util.h>
31*9e39c5baSBill Taylor #include <dapl_evd_util.h>
32*9e39c5baSBill Taylor #include <dapl_cr_util.h>
33*9e39c5baSBill Taylor #include <dapl_lmr_util.h>
34*9e39c5baSBill Taylor #include <dapl_rmr_util.h>
35*9e39c5baSBill Taylor #include <dapl_cookie.h>
36*9e39c5baSBill Taylor #include <dapl_name_service.h>
37*9e39c5baSBill Taylor #include <dapl_tavor_ibtf_impl.h>
38*9e39c5baSBill Taylor
39*9e39c5baSBill Taylor /* Function prototypes */
40*9e39c5baSBill Taylor extern DAT_RETURN dapls_tavor_wrid_init(ib_qp_handle_t);
41*9e39c5baSBill Taylor extern void dapls_tavor_wrid_cleanup(DAPL_EP *, ib_qp_handle_t);
42*9e39c5baSBill Taylor
43*9e39c5baSBill Taylor int g_dapl_loopback_connection = 0;
44*9e39c5baSBill Taylor
45*9e39c5baSBill Taylor /*
46*9e39c5baSBill Taylor * dapls_ib_connect
47*9e39c5baSBill Taylor *
48*9e39c5baSBill Taylor * Initiate a connection with the passive listener on another node
49*9e39c5baSBill Taylor *
50*9e39c5baSBill Taylor * Input:
51*9e39c5baSBill Taylor * ep_handle,
52*9e39c5baSBill Taylor * remote_ia_address,
53*9e39c5baSBill Taylor * remote_conn_qual,
54*9e39c5baSBill Taylor * prd_size size of private data and structure
55*9e39c5baSBill Taylor * prd_prt pointer to private data structure
56*9e39c5baSBill Taylor *
57*9e39c5baSBill Taylor * Output:
58*9e39c5baSBill Taylor * none
59*9e39c5baSBill Taylor *
60*9e39c5baSBill Taylor * Returns:
61*9e39c5baSBill Taylor * DAT_SUCCESS
62*9e39c5baSBill Taylor * DAT_INSUFFICIENT_RESOURCES
63*9e39c5baSBill Taylor * DAT_INVALID_PARAMETER
64*9e39c5baSBill Taylor *
65*9e39c5baSBill Taylor */
66*9e39c5baSBill Taylor
67*9e39c5baSBill Taylor DAT_RETURN
dapls_ib_connect(IN DAT_EP_HANDLE ep_handle,IN DAT_IA_ADDRESS_PTR remote_ia_address,IN DAT_CONN_QUAL remote_conn_qual,IN DAT_COUNT prd_size,IN DAPL_PRIVATE * prd_ptr,IN DAT_TIMEOUT timeout)68*9e39c5baSBill Taylor dapls_ib_connect(IN DAT_EP_HANDLE ep_handle,
69*9e39c5baSBill Taylor IN DAT_IA_ADDRESS_PTR remote_ia_address, IN DAT_CONN_QUAL remote_conn_qual,
70*9e39c5baSBill Taylor IN DAT_COUNT prd_size, IN DAPL_PRIVATE *prd_ptr, IN DAT_TIMEOUT timeout)
71*9e39c5baSBill Taylor {
72*9e39c5baSBill Taylor dapl_ep_connect_t args;
73*9e39c5baSBill Taylor DAPL_EP *ep_p = (DAPL_EP *)ep_handle;
74*9e39c5baSBill Taylor struct sockaddr *s;
75*9e39c5baSBill Taylor char addr_buf[64];
76*9e39c5baSBill Taylor ib_gid_t dgid;
77*9e39c5baSBill Taylor int retval;
78*9e39c5baSBill Taylor struct sockaddr_in6 *v6addr;
79*9e39c5baSBill Taylor struct sockaddr_in *v4addr;
80*9e39c5baSBill Taylor dapl_ia_addr_t *sap;
81*9e39c5baSBill Taylor
82*9e39c5baSBill Taylor s = (struct sockaddr *)remote_ia_address;
83*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_CM,
84*9e39c5baSBill Taylor "dapls_ib_connect: ep 0x%p\n"
85*9e39c5baSBill Taylor " addr %s, conn_qual %016llu, ep_hkey %016llx\n"
86*9e39c5baSBill Taylor " prd_size %d, timeout 0x%x\n",
87*9e39c5baSBill Taylor ep_p, dapls_inet_ntop(s, addr_buf, 64), remote_conn_qual,
88*9e39c5baSBill Taylor ep_p->qp_handle->ep_hkey, prd_size, timeout);
89*9e39c5baSBill Taylor if (ep_p->qp_handle == NULL) {
90*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
91*9e39c5baSBill Taylor "dapls_ib_connect: ep 0x%p, addr %s, conn_qual %016llu, "
92*9e39c5baSBill Taylor "qp_handle == NULL\n", ep_p, dapls_inet_ntop(s,
93*9e39c5baSBill Taylor addr_buf, 64), remote_conn_qual);
94*9e39c5baSBill Taylor return (DAT_INVALID_PARAMETER);
95*9e39c5baSBill Taylor }
96*9e39c5baSBill Taylor if (timeout == DAT_TIMEOUT_INFINITE) {
97*9e39c5baSBill Taylor args.epc_timeout = 0;
98*9e39c5baSBill Taylor } else {
99*9e39c5baSBill Taylor args.epc_timeout = timeout;
100*9e39c5baSBill Taylor }
101*9e39c5baSBill Taylor /* resolve remote address to dgid */
102*9e39c5baSBill Taylor retval = dapls_ns_lookup_address(ep_p->header.owner_ia,
103*9e39c5baSBill Taylor remote_ia_address, timeout, &dgid);
104*9e39c5baSBill Taylor if (retval == DAT_SUCCESS) {
105*9e39c5baSBill Taylor args.epc_dgid = dgid;
106*9e39c5baSBill Taylor } else if ((retval & DAT_SUBTYPE_MASK) ==
107*9e39c5baSBill Taylor DAT_INVALID_ADDRESS_UNREACHABLE) {
108*9e39c5baSBill Taylor /* let the kernel driver look up the dgid from ATS */
109*9e39c5baSBill Taylor args.epc_dgid.gid_guid = 0ULL;
110*9e39c5baSBill Taylor args.epc_dgid.gid_prefix = 0ULL;
111*9e39c5baSBill Taylor } else {
112*9e39c5baSBill Taylor return (retval);
113*9e39c5baSBill Taylor }
114*9e39c5baSBill Taylor args.epc_sid = remote_conn_qual;
115*9e39c5baSBill Taylor args.epc_hkey = ep_p->qp_handle->ep_hkey;
116*9e39c5baSBill Taylor sap = (dapl_ia_addr_t *)&args.epc_raddr_sadata;
117*9e39c5baSBill Taylor /*
118*9e39c5baSBill Taylor * filled in the remote_ia_address for consistent though
119*9e39c5baSBill Taylor * not necessary when dapls_ns_lookup_address has resolved the dgid
120*9e39c5baSBill Taylor */
121*9e39c5baSBill Taylor switch (s->sa_family) {
122*9e39c5baSBill Taylor case AF_INET:
123*9e39c5baSBill Taylor /* LINTED: E_BAD_PTR_CAST_ALIGN */
124*9e39c5baSBill Taylor v4addr = (struct sockaddr_in *)s;
125*9e39c5baSBill Taylor sap->iad_v4pad[0] = 0;
126*9e39c5baSBill Taylor sap->iad_v4pad[1] = 0;
127*9e39c5baSBill Taylor sap->iad_v4pad[2] = 0;
128*9e39c5baSBill Taylor sap->iad_v4 = v4addr->sin_addr;
129*9e39c5baSBill Taylor break;
130*9e39c5baSBill Taylor case AF_INET6:
131*9e39c5baSBill Taylor /* LINTED: E_BAD_PTR_CAST_ALIGN */
132*9e39c5baSBill Taylor v6addr = (struct sockaddr_in6 *)s;
133*9e39c5baSBill Taylor sap->iad_v6 = v6addr->sin6_addr;
134*9e39c5baSBill Taylor break;
135*9e39c5baSBill Taylor }
136*9e39c5baSBill Taylor
137*9e39c5baSBill Taylor /* establish the hello message */
138*9e39c5baSBill Taylor (void) dapl_os_memzero((void *)&prd_ptr->hello_msg,
139*9e39c5baSBill Taylor sizeof (DAPL_HELLO_MSG));
140*9e39c5baSBill Taylor /* on ATS leave the msg blank to avoid confusion to 3rd parties */
141*9e39c5baSBill Taylor if ((args.epc_dgid.gid_guid | args.epc_dgid.gid_prefix)) {
142*9e39c5baSBill Taylor prd_ptr->hello_msg.hi_checksum = DAPL_CHECKSUM;
143*9e39c5baSBill Taylor prd_ptr->hello_msg.hi_clen = prd_size;
144*9e39c5baSBill Taylor prd_ptr->hello_msg.hi_mid = 0;
145*9e39c5baSBill Taylor prd_ptr->hello_msg.hi_vers = DAPL_HELLO_MSG_VERS;
146*9e39c5baSBill Taylor
147*9e39c5baSBill Taylor /* fill in local address */
148*9e39c5baSBill Taylor s = (struct sockaddr *)
149*9e39c5baSBill Taylor &ep_p->header.owner_ia->hca_ptr->hca_address;
150*9e39c5baSBill Taylor prd_ptr->hello_msg.hi_ipv = (uint8_t)s->sa_family;
151*9e39c5baSBill Taylor switch (s->sa_family) {
152*9e39c5baSBill Taylor case AF_INET:
153*9e39c5baSBill Taylor /* LINTED: E_BAD_PTR_CAST_ALIGN */
154*9e39c5baSBill Taylor v4addr = (struct sockaddr_in *)s;
155*9e39c5baSBill Taylor prd_ptr->hello_msg.hi_port = v4addr->sin_port;
156*9e39c5baSBill Taylor prd_ptr->hello_msg.hi_v4ipaddr = v4addr->sin_addr;
157*9e39c5baSBill Taylor break;
158*9e39c5baSBill Taylor case AF_INET6:
159*9e39c5baSBill Taylor /* LINTED: E_BAD_PTR_CAST_ALIGN */
160*9e39c5baSBill Taylor v6addr = (struct sockaddr_in6 *)s;
161*9e39c5baSBill Taylor prd_ptr->hello_msg.hi_port = v6addr->sin6_port;
162*9e39c5baSBill Taylor prd_ptr->hello_msg.hi_v6ipaddr = v6addr->sin6_addr;
163*9e39c5baSBill Taylor break;
164*9e39c5baSBill Taylor default:
165*9e39c5baSBill Taylor break; /* fall through */
166*9e39c5baSBill Taylor }
167*9e39c5baSBill Taylor }
168*9e39c5baSBill Taylor if (prd_size > 0) {
169*9e39c5baSBill Taylor (void) dapl_os_memcpy((void *)&args.epc_priv[0],
170*9e39c5baSBill Taylor (void *)prd_ptr, sizeof (DAPL_PRIVATE));
171*9e39c5baSBill Taylor } else {
172*9e39c5baSBill Taylor (void) dapl_os_memcpy((void *)
173*9e39c5baSBill Taylor &args.epc_priv[DAPL_CONSUMER_MAX_PRIVATE_DATA_SIZE],
174*9e39c5baSBill Taylor (void *)&prd_ptr->hello_msg, sizeof (DAPL_HELLO_MSG));
175*9e39c5baSBill Taylor }
176*9e39c5baSBill Taylor args.epc_priv_sz = sizeof (DAPL_PRIVATE);
177*9e39c5baSBill Taylor
178*9e39c5baSBill Taylor retval = ioctl(ep_p->header.owner_ia->hca_ptr->ib_hca_handle->ia_fd,
179*9e39c5baSBill Taylor DAPL_EP_CONNECT, &args);
180*9e39c5baSBill Taylor if (retval != 0) {
181*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
182*9e39c5baSBill Taylor "dapls_ib_connect: connect failed %s, retval %d\n\n",
183*9e39c5baSBill Taylor strerror(errno), retval);
184*9e39c5baSBill Taylor return (dapls_convert_error(errno, retval));
185*9e39c5baSBill Taylor }
186*9e39c5baSBill Taylor
187*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_CM,
188*9e39c5baSBill Taylor "dapls_ib_connect: connected to %s\n\n",
189*9e39c5baSBill Taylor dapls_inet_ntop(s, addr_buf, 64));
190*9e39c5baSBill Taylor return (DAT_SUCCESS);
191*9e39c5baSBill Taylor }
192*9e39c5baSBill Taylor
193*9e39c5baSBill Taylor /*
194*9e39c5baSBill Taylor * dapls_ib_disconnect
195*9e39c5baSBill Taylor *
196*9e39c5baSBill Taylor * Disconnect an EP
197*9e39c5baSBill Taylor *
198*9e39c5baSBill Taylor * Input:
199*9e39c5baSBill Taylor * ep_handle,
200*9e39c5baSBill Taylor * disconnect_flags
201*9e39c5baSBill Taylor *
202*9e39c5baSBill Taylor * Output:
203*9e39c5baSBill Taylor * none
204*9e39c5baSBill Taylor *
205*9e39c5baSBill Taylor * Returns:
206*9e39c5baSBill Taylor * DAT_SUCCESS
207*9e39c5baSBill Taylor * DAT_INSUFFICIENT_RESOURCES
208*9e39c5baSBill Taylor * DAT_INVALID_PARAMETER
209*9e39c5baSBill Taylor *
210*9e39c5baSBill Taylor */
211*9e39c5baSBill Taylor /* ARGSUSED */
212*9e39c5baSBill Taylor DAT_RETURN
dapls_ib_disconnect(IN DAPL_EP * ep_ptr,IN DAT_CLOSE_FLAGS close_flags)213*9e39c5baSBill Taylor dapls_ib_disconnect(IN DAPL_EP *ep_ptr,
214*9e39c5baSBill Taylor IN DAT_CLOSE_FLAGS close_flags)
215*9e39c5baSBill Taylor {
216*9e39c5baSBill Taylor dapl_ep_disconnect_t args;
217*9e39c5baSBill Taylor struct sockaddr *s;
218*9e39c5baSBill Taylor char addr_buf[64];
219*9e39c5baSBill Taylor int retval;
220*9e39c5baSBill Taylor
221*9e39c5baSBill Taylor if (ep_ptr->qp_handle == NULL) {
222*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
223*9e39c5baSBill Taylor "dapls_ib_disconnect: qp_handle == NULL\n");
224*9e39c5baSBill Taylor return (DAT_INVALID_PARAMETER);
225*9e39c5baSBill Taylor }
226*9e39c5baSBill Taylor args.epd_hkey = ep_ptr->qp_handle->ep_hkey;
227*9e39c5baSBill Taylor
228*9e39c5baSBill Taylor retval = ioctl(ep_ptr->header.owner_ia->hca_ptr->ib_hca_handle->ia_fd,
229*9e39c5baSBill Taylor DAPL_EP_DISCONNECT, &args);
230*9e39c5baSBill Taylor /* no reason for disconnect to fail so transition the state */
231*9e39c5baSBill Taylor ep_ptr->qp_state = IBT_STATE_ERROR;
232*9e39c5baSBill Taylor
233*9e39c5baSBill Taylor if (retval != 0) {
234*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
235*9e39c5baSBill Taylor "dapls_ib_disconnect: disconnect failed %s\n",
236*9e39c5baSBill Taylor strerror(errno));
237*9e39c5baSBill Taylor return (dapls_convert_error(errno, retval));
238*9e39c5baSBill Taylor }
239*9e39c5baSBill Taylor s = (struct sockaddr *)ep_ptr->param.remote_ia_address_ptr;
240*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_CM,
241*9e39c5baSBill Taylor "dapls_ib_disconnect: disconnected from %s, conn_qual %016llu\n",
242*9e39c5baSBill Taylor dapls_inet_ntop(s, addr_buf, 64), ep_ptr->param.remote_port_qual);
243*9e39c5baSBill Taylor return (DAT_SUCCESS);
244*9e39c5baSBill Taylor }
245*9e39c5baSBill Taylor
246*9e39c5baSBill Taylor
247*9e39c5baSBill Taylor /*
248*9e39c5baSBill Taylor * dapls_ib_connected
249*9e39c5baSBill Taylor *
250*9e39c5baSBill Taylor * transition qp_state to IBT_STATE_RTS
251*9e39c5baSBill Taylor *
252*9e39c5baSBill Taylor */
253*9e39c5baSBill Taylor void
dapls_ib_connected(IN DAPL_EP * ep_ptr)254*9e39c5baSBill Taylor dapls_ib_connected(IN DAPL_EP *ep_ptr)
255*9e39c5baSBill Taylor {
256*9e39c5baSBill Taylor ep_ptr->qp_state = IBT_STATE_RTS;
257*9e39c5baSBill Taylor }
258*9e39c5baSBill Taylor
259*9e39c5baSBill Taylor
260*9e39c5baSBill Taylor /*
261*9e39c5baSBill Taylor * dapls_ib_disconnect_clean
262*9e39c5baSBill Taylor *
263*9e39c5baSBill Taylor * transition qp_state to IBT_STATE_ERROR.
264*9e39c5baSBill Taylor * abort connection if necessary.
265*9e39c5baSBill Taylor *
266*9e39c5baSBill Taylor * Input:
267*9e39c5baSBill Taylor * ep_ptr DAPL_EP
268*9e39c5baSBill Taylor *
269*9e39c5baSBill Taylor * Output:
270*9e39c5baSBill Taylor * none
271*9e39c5baSBill Taylor *
272*9e39c5baSBill Taylor * Returns:
273*9e39c5baSBill Taylor * void
274*9e39c5baSBill Taylor *
275*9e39c5baSBill Taylor */
276*9e39c5baSBill Taylor /* ARGSUSED */
277*9e39c5baSBill Taylor void
dapls_ib_disconnect_clean(IN DAPL_EP * ep_ptr,IN DAT_BOOLEAN active,IN const ib_cm_events_t ib_cm_event)278*9e39c5baSBill Taylor dapls_ib_disconnect_clean(IN DAPL_EP *ep_ptr, IN DAT_BOOLEAN active,
279*9e39c5baSBill Taylor IN const ib_cm_events_t ib_cm_event)
280*9e39c5baSBill Taylor {
281*9e39c5baSBill Taylor switch (ib_cm_event) {
282*9e39c5baSBill Taylor case IB_CME_CONNECTED:
283*9e39c5baSBill Taylor case IB_CME_CONNECTION_REQUEST_PENDING:
284*9e39c5baSBill Taylor case IB_CME_CONNECTION_REQUEST_PENDING_PRIVATE_DATA:
285*9e39c5baSBill Taylor (void) dapls_ib_disconnect(ep_ptr, DAT_CLOSE_ABRUPT_FLAG);
286*9e39c5baSBill Taylor /* FALLTHROUGH */
287*9e39c5baSBill Taylor case IB_CME_DESTINATION_REJECT:
288*9e39c5baSBill Taylor case IB_CME_DESTINATION_REJECT_PRIVATE_DATA:
289*9e39c5baSBill Taylor case IB_CME_DESTINATION_UNREACHABLE:
290*9e39c5baSBill Taylor case IB_CME_TOO_MANY_CONNECTION_REQUESTS:
291*9e39c5baSBill Taylor case IB_CME_LOCAL_FAILURE:
292*9e39c5baSBill Taylor case IB_CME_TIMED_OUT:
293*9e39c5baSBill Taylor case IB_CME_DISCONNECTED_ON_LINK_DOWN:
294*9e39c5baSBill Taylor ep_ptr->qp_state = IBT_STATE_ERROR;
295*9e39c5baSBill Taylor }
296*9e39c5baSBill Taylor }
297*9e39c5baSBill Taylor
298*9e39c5baSBill Taylor
299*9e39c5baSBill Taylor /*
300*9e39c5baSBill Taylor * dapls_ib_reinit_ep
301*9e39c5baSBill Taylor *
302*9e39c5baSBill Taylor * Move the QP to INIT state again.
303*9e39c5baSBill Taylor *
304*9e39c5baSBill Taylor * Input:
305*9e39c5baSBill Taylor * ep_ptr DAPL_EP
306*9e39c5baSBill Taylor *
307*9e39c5baSBill Taylor * Output:
308*9e39c5baSBill Taylor * none
309*9e39c5baSBill Taylor *
310*9e39c5baSBill Taylor * Returns:
311*9e39c5baSBill Taylor * void
312*9e39c5baSBill Taylor *
313*9e39c5baSBill Taylor */
314*9e39c5baSBill Taylor void
dapls_ib_reinit_ep(IN DAPL_EP * ep_ptr)315*9e39c5baSBill Taylor dapls_ib_reinit_ep(IN DAPL_EP *ep_ptr)
316*9e39c5baSBill Taylor {
317*9e39c5baSBill Taylor dapl_ep_reinit_t reinit_args;
318*9e39c5baSBill Taylor ib_hca_handle_t hca_hndl;
319*9e39c5baSBill Taylor ib_qp_handle_t qp_p;
320*9e39c5baSBill Taylor char addr_buf[64];
321*9e39c5baSBill Taylor int retval;
322*9e39c5baSBill Taylor
323*9e39c5baSBill Taylor hca_hndl = ep_ptr->header.owner_ia->hca_ptr->ib_hca_handle;
324*9e39c5baSBill Taylor qp_p = ep_ptr->qp_handle;
325*9e39c5baSBill Taylor
326*9e39c5baSBill Taylor if (qp_p == NULL) {
327*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
328*9e39c5baSBill Taylor "dapls_ib_reinit: qp_handle == NULL\n");
329*9e39c5baSBill Taylor return;
330*9e39c5baSBill Taylor }
331*9e39c5baSBill Taylor /*
332*9e39c5baSBill Taylor * Do all the work request cleanup processing right away
333*9e39c5baSBill Taylor * no one should really be doing any operation on this
334*9e39c5baSBill Taylor * qp (we are not threadsafe)...
335*9e39c5baSBill Taylor */
336*9e39c5baSBill Taylor dapls_tavor_wrid_cleanup(ep_ptr, qp_p);
337*9e39c5baSBill Taylor
338*9e39c5baSBill Taylor reinit_args.epri_hkey = qp_p->ep_hkey;
339*9e39c5baSBill Taylor if (ioctl(hca_hndl->ia_fd, DAPL_EP_REINIT, &reinit_args) != 0) {
340*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
341*9e39c5baSBill Taylor "dapls_ib_reinit: reinit failed %s\n",
342*9e39c5baSBill Taylor strerror(errno));
343*9e39c5baSBill Taylor return;
344*9e39c5baSBill Taylor }
345*9e39c5baSBill Taylor
346*9e39c5baSBill Taylor qp_p->qp_sq_lastwqeaddr = NULL;
347*9e39c5baSBill Taylor qp_p->qp_rq_lastwqeaddr = NULL;
348*9e39c5baSBill Taylor
349*9e39c5baSBill Taylor /*
350*9e39c5baSBill Taylor * Setup data structure for work request processing
351*9e39c5baSBill Taylor */
352*9e39c5baSBill Taylor retval = dapls_tavor_wrid_init(qp_p);
353*9e39c5baSBill Taylor if (retval != DAT_SUCCESS) {
354*9e39c5baSBill Taylor /*
355*9e39c5baSBill Taylor * we failed to create data structures for work request
356*9e39c5baSBill Taylor * processing. Lets unmap and leave, the qp will get
357*9e39c5baSBill Taylor * cleaned when ep gets destroyed - the ep is unusable
358*9e39c5baSBill Taylor * in this state.
359*9e39c5baSBill Taylor */
360*9e39c5baSBill Taylor if (munmap((void *)qp_p->qp_addr, qp_p->qp_map_len) < 0) {
361*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
362*9e39c5baSBill Taylor "qp_free: munmap failed(%d)\n", errno);
363*9e39c5baSBill Taylor }
364*9e39c5baSBill Taylor qp_p->qp_addr = NULL;
365*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_CM,
366*9e39c5baSBill Taylor "dapls_ib_reinit: wrid_init failed %d\n", retval);
367*9e39c5baSBill Taylor return;
368*9e39c5baSBill Taylor }
369*9e39c5baSBill Taylor
370*9e39c5baSBill Taylor /* we have a new ep and it is in the init state */
371*9e39c5baSBill Taylor ep_ptr->qp_state = IBT_STATE_INIT;
372*9e39c5baSBill Taylor
373*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_CM,
374*9e39c5baSBill Taylor "dapls_ib_reinit: successful, ia_address %s, conn_qual %016llu\n",
375*9e39c5baSBill Taylor dapls_inet_ntop((struct sockaddr *)ep_ptr->param.
376*9e39c5baSBill Taylor remote_ia_address_ptr, addr_buf, 64),
377*9e39c5baSBill Taylor ep_ptr->param.remote_port_qual);
378*9e39c5baSBill Taylor }
379*9e39c5baSBill Taylor
380*9e39c5baSBill Taylor
381*9e39c5baSBill Taylor /*
382*9e39c5baSBill Taylor * dapl_ib_setup_conn_listener
383*9e39c5baSBill Taylor *
384*9e39c5baSBill Taylor * Have the CM set up a connection listener.
385*9e39c5baSBill Taylor *
386*9e39c5baSBill Taylor * Input:
387*9e39c5baSBill Taylor * ibm_hca_handle HCA handle
388*9e39c5baSBill Taylor * qp_handle QP handle
389*9e39c5baSBill Taylor *
390*9e39c5baSBill Taylor * Output:
391*9e39c5baSBill Taylor * none
392*9e39c5baSBill Taylor *
393*9e39c5baSBill Taylor * Returns:
394*9e39c5baSBill Taylor * DAT_SUCCESS
395*9e39c5baSBill Taylor * DAT_INSUFFICIENT_RESOURCES
396*9e39c5baSBill Taylor * DAT_INVALID_PARAMETER
397*9e39c5baSBill Taylor *
398*9e39c5baSBill Taylor */
399*9e39c5baSBill Taylor DAT_RETURN
dapls_ib_setup_conn_listener(IN DAPL_IA * ia_ptr,IN DAT_UINT64 ServiceID,IN DAPL_SP * sp_ptr)400*9e39c5baSBill Taylor dapls_ib_setup_conn_listener(IN DAPL_IA *ia_ptr,
401*9e39c5baSBill Taylor IN DAT_UINT64 ServiceID, IN DAPL_SP *sp_ptr)
402*9e39c5baSBill Taylor {
403*9e39c5baSBill Taylor ib_hca_handle_t hca_hdl = ia_ptr->hca_ptr->ib_hca_handle;
404*9e39c5baSBill Taylor struct dapls_ib_cm_srvc_handle *srvc_hdl;
405*9e39c5baSBill Taylor dapl_service_register_t args;
406*9e39c5baSBill Taylor struct sockaddr *s;
407*9e39c5baSBill Taylor char addr_buf[64];
408*9e39c5baSBill Taylor DAPL_EVD *evd_p = (DAPL_EVD *)sp_ptr->evd_handle;
409*9e39c5baSBill Taylor int retval;
410*9e39c5baSBill Taylor
411*9e39c5baSBill Taylor if (hca_hdl == NULL) {
412*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
413*9e39c5baSBill Taylor "setup_conn_listener: hca_handle == NULL\n");
414*9e39c5baSBill Taylor return (DAT_INVALID_PARAMETER);
415*9e39c5baSBill Taylor }
416*9e39c5baSBill Taylor if (evd_p == NULL) {
417*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
418*9e39c5baSBill Taylor "setup_conn_listener: evd_p == NULL\n");
419*9e39c5baSBill Taylor return (DAT_INVALID_PARAMETER);
420*9e39c5baSBill Taylor }
421*9e39c5baSBill Taylor srvc_hdl = (struct dapls_ib_cm_srvc_handle *)
422*9e39c5baSBill Taylor dapl_os_alloc(sizeof (*srvc_hdl));
423*9e39c5baSBill Taylor if (srvc_hdl == NULL) {
424*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
425*9e39c5baSBill Taylor "setup_conn_listener: srvc_handle == NULL\n");
426*9e39c5baSBill Taylor return (DAT_INSUFFICIENT_RESOURCES);
427*9e39c5baSBill Taylor }
428*9e39c5baSBill Taylor
429*9e39c5baSBill Taylor args.sr_sid = ServiceID;
430*9e39c5baSBill Taylor args.sr_evd_hkey = evd_p->ib_cq_handle->evd_hkey;
431*9e39c5baSBill Taylor args.sr_sp_cookie = (uintptr_t)sp_ptr;
432*9e39c5baSBill Taylor
433*9e39c5baSBill Taylor retval = ioctl(hca_hdl->ia_fd, DAPL_SERVICE_REGISTER, &args);
434*9e39c5baSBill Taylor if (retval != 0) {
435*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
436*9e39c5baSBill Taylor "setup_conn_listener: register failed %s\n",
437*9e39c5baSBill Taylor strerror(errno));
438*9e39c5baSBill Taylor dapl_os_free(srvc_hdl, sizeof (*srvc_hdl));
439*9e39c5baSBill Taylor return (dapls_convert_error(errno, retval));
440*9e39c5baSBill Taylor }
441*9e39c5baSBill Taylor srvc_hdl->sv_sp_hkey = args.sr_sp_hkey;
442*9e39c5baSBill Taylor sp_ptr->cm_srvc_handle = srvc_hdl;
443*9e39c5baSBill Taylor sp_ptr->conn_qual = args.sr_retsid;
444*9e39c5baSBill Taylor
445*9e39c5baSBill Taylor s = (struct sockaddr *)&ia_ptr->hca_ptr->hca_address;
446*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_CM,
447*9e39c5baSBill Taylor "setup_conn_listener: listening on ia_address %s, "
448*9e39c5baSBill Taylor "conn_qual %016llu\n\n", dapls_inet_ntop(s, addr_buf, 64),
449*9e39c5baSBill Taylor sp_ptr->conn_qual);
450*9e39c5baSBill Taylor return (DAT_SUCCESS);
451*9e39c5baSBill Taylor }
452*9e39c5baSBill Taylor
453*9e39c5baSBill Taylor /*
454*9e39c5baSBill Taylor * dapl_ib_remove_conn_listener
455*9e39c5baSBill Taylor *
456*9e39c5baSBill Taylor * Have the CM remove a connection listener.
457*9e39c5baSBill Taylor *
458*9e39c5baSBill Taylor * Input:
459*9e39c5baSBill Taylor * ia_handle IA handle
460*9e39c5baSBill Taylor * ServiceID IB Channel Service ID
461*9e39c5baSBill Taylor *
462*9e39c5baSBill Taylor * Output:
463*9e39c5baSBill Taylor * none
464*9e39c5baSBill Taylor *
465*9e39c5baSBill Taylor * Returns:
466*9e39c5baSBill Taylor * DAT_SUCCESS
467*9e39c5baSBill Taylor * DAT_INVALID_PARAMETER
468*9e39c5baSBill Taylor *
469*9e39c5baSBill Taylor */
470*9e39c5baSBill Taylor DAT_RETURN
dapls_ib_remove_conn_listener(IN DAPL_IA * ia_ptr,IN DAPL_SP * sp_ptr)471*9e39c5baSBill Taylor dapls_ib_remove_conn_listener(IN DAPL_IA *ia_ptr, IN DAPL_SP *sp_ptr)
472*9e39c5baSBill Taylor {
473*9e39c5baSBill Taylor ib_hca_handle_t hca_hdl = ia_ptr->hca_ptr->ib_hca_handle;
474*9e39c5baSBill Taylor struct dapls_ib_cm_srvc_handle *srvc_hdl;
475*9e39c5baSBill Taylor dapl_service_deregister_t args;
476*9e39c5baSBill Taylor struct sockaddr *s;
477*9e39c5baSBill Taylor char addr_buf[64];
478*9e39c5baSBill Taylor int retval;
479*9e39c5baSBill Taylor
480*9e39c5baSBill Taylor if (hca_hdl == NULL) {
481*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
482*9e39c5baSBill Taylor "remove_conn_listener: hca_handle == NULL\n");
483*9e39c5baSBill Taylor return (DAT_INVALID_PARAMETER);
484*9e39c5baSBill Taylor }
485*9e39c5baSBill Taylor srvc_hdl = (struct dapls_ib_cm_srvc_handle *)sp_ptr->
486*9e39c5baSBill Taylor cm_srvc_handle;
487*9e39c5baSBill Taylor
488*9e39c5baSBill Taylor args.sdr_sp_hkey = srvc_hdl->sv_sp_hkey;
489*9e39c5baSBill Taylor retval = ioctl(hca_hdl->ia_fd, DAPL_SERVICE_DEREGISTER, &args);
490*9e39c5baSBill Taylor if (retval != 0) {
491*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
492*9e39c5baSBill Taylor "remove_conn_listener: deregister failed %s\n",
493*9e39c5baSBill Taylor strerror(errno));
494*9e39c5baSBill Taylor return (dapls_convert_error(errno, retval));
495*9e39c5baSBill Taylor }
496*9e39c5baSBill Taylor dapl_os_free(srvc_hdl, sizeof (*srvc_hdl));
497*9e39c5baSBill Taylor sp_ptr->cm_srvc_handle = NULL;
498*9e39c5baSBill Taylor
499*9e39c5baSBill Taylor s = (struct sockaddr *)&ia_ptr->hca_ptr->hca_address;
500*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_CM,
501*9e39c5baSBill Taylor "remove_conn_listener: successful, ia_address %s, "
502*9e39c5baSBill Taylor "conn_qual %016llu\n\n", dapls_inet_ntop(s, addr_buf, 64),
503*9e39c5baSBill Taylor sp_ptr->conn_qual);
504*9e39c5baSBill Taylor return (DAT_SUCCESS);
505*9e39c5baSBill Taylor }
506*9e39c5baSBill Taylor
507*9e39c5baSBill Taylor /*
508*9e39c5baSBill Taylor * dapls_ib_reject_connection
509*9e39c5baSBill Taylor *
510*9e39c5baSBill Taylor * Perform necessary steps to reject a connection
511*9e39c5baSBill Taylor *
512*9e39c5baSBill Taylor * Input:
513*9e39c5baSBill Taylor * cr_handle
514*9e39c5baSBill Taylor *
515*9e39c5baSBill Taylor * Output:
516*9e39c5baSBill Taylor * none
517*9e39c5baSBill Taylor *
518*9e39c5baSBill Taylor * Returns:
519*9e39c5baSBill Taylor * DAT_SUCCESS
520*9e39c5baSBill Taylor * DAT_INSUFFICIENT_RESOURCES
521*9e39c5baSBill Taylor * DAT_INVALID_PARAMETER
522*9e39c5baSBill Taylor *
523*9e39c5baSBill Taylor */
524*9e39c5baSBill Taylor DAT_RETURN
dapls_ib_reject_connection(IN ib_cm_handle_t cm_handle,IN int reject_reason,IN DAPL_SP * sp_ptr)525*9e39c5baSBill Taylor dapls_ib_reject_connection(IN ib_cm_handle_t cm_handle,
526*9e39c5baSBill Taylor IN int reject_reason, IN DAPL_SP *sp_ptr)
527*9e39c5baSBill Taylor {
528*9e39c5baSBill Taylor dapl_cr_reject_t args;
529*9e39c5baSBill Taylor int retval;
530*9e39c5baSBill Taylor
531*9e39c5baSBill Taylor args.crr_reason = reject_reason;
532*9e39c5baSBill Taylor args.crr_bkl_cookie = (uint64_t)cm_handle;
533*9e39c5baSBill Taylor args.crr_sp_hkey = sp_ptr->cm_srvc_handle->sv_sp_hkey;
534*9e39c5baSBill Taylor
535*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_CM,
536*9e39c5baSBill Taylor "dapls_ib_reject: fd %d, sp_hkey %016llx, bkl_index 0x%llx\n",
537*9e39c5baSBill Taylor sp_ptr->header.owner_ia->hca_ptr->ib_hca_handle->ia_fd,
538*9e39c5baSBill Taylor args.crr_sp_hkey, args.crr_bkl_cookie);
539*9e39c5baSBill Taylor
540*9e39c5baSBill Taylor retval = ioctl(sp_ptr->header.owner_ia->hca_ptr->ib_hca_handle->ia_fd,
541*9e39c5baSBill Taylor DAPL_CR_REJECT, &args);
542*9e39c5baSBill Taylor if (retval != 0) {
543*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
544*9e39c5baSBill Taylor "dapls_ib_reject: reject failed %s\n",
545*9e39c5baSBill Taylor strerror(errno));
546*9e39c5baSBill Taylor return (dapls_convert_error(errno, retval));
547*9e39c5baSBill Taylor }
548*9e39c5baSBill Taylor return (DAT_SUCCESS);
549*9e39c5baSBill Taylor }
550*9e39c5baSBill Taylor
551*9e39c5baSBill Taylor
552*9e39c5baSBill Taylor /*
553*9e39c5baSBill Taylor * dapls_ib_accept_connection
554*9e39c5baSBill Taylor *
555*9e39c5baSBill Taylor * Perform necessary steps to accept a connection
556*9e39c5baSBill Taylor *
557*9e39c5baSBill Taylor * Input:
558*9e39c5baSBill Taylor * cr_handle
559*9e39c5baSBill Taylor * ep_handle
560*9e39c5baSBill Taylor * private_data_size
561*9e39c5baSBill Taylor * private_data
562*9e39c5baSBill Taylor *
563*9e39c5baSBill Taylor * Output:
564*9e39c5baSBill Taylor * none
565*9e39c5baSBill Taylor *
566*9e39c5baSBill Taylor * Returns:
567*9e39c5baSBill Taylor * DAT_SUCCESS
568*9e39c5baSBill Taylor * DAT_INSUFFICIENT_RESOURCES
569*9e39c5baSBill Taylor * DAT_INVALID_PARAMETER
570*9e39c5baSBill Taylor *
571*9e39c5baSBill Taylor */
572*9e39c5baSBill Taylor DAT_RETURN
dapls_ib_accept_connection(IN DAT_CR_HANDLE cr_handle,IN DAT_EP_HANDLE ep_handle,IN DAPL_PRIVATE * prd_ptr)573*9e39c5baSBill Taylor dapls_ib_accept_connection(IN DAT_CR_HANDLE cr_handle,
574*9e39c5baSBill Taylor IN DAT_EP_HANDLE ep_handle, IN DAPL_PRIVATE *prd_ptr)
575*9e39c5baSBill Taylor {
576*9e39c5baSBill Taylor DAPL_EP *ep_p = (DAPL_EP *)ep_handle;
577*9e39c5baSBill Taylor DAPL_CR *cr_p = (DAPL_CR *)cr_handle;
578*9e39c5baSBill Taylor dapl_cr_accept_t args;
579*9e39c5baSBill Taylor int retval;
580*9e39c5baSBill Taylor
581*9e39c5baSBill Taylor /* check if ep is valid */
582*9e39c5baSBill Taylor if (ep_p->qp_handle == NULL) {
583*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
584*9e39c5baSBill Taylor "dapls_ib_accept: qp_handle == NULL\n");
585*9e39c5baSBill Taylor return (DAT_INVALID_PARAMETER);
586*9e39c5baSBill Taylor }
587*9e39c5baSBill Taylor
588*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_CM,
589*9e39c5baSBill Taylor "dapls_ib_accept: fd %d, sp_hkey %016llx, "
590*9e39c5baSBill Taylor "bkl_index 0x%llx, ep_hkey %016llx\n",
591*9e39c5baSBill Taylor cr_p->header.owner_ia->hca_ptr->ib_hca_handle->ia_fd,
592*9e39c5baSBill Taylor cr_p->sp_ptr->cm_srvc_handle->sv_sp_hkey,
593*9e39c5baSBill Taylor (uint64_t)cr_p->ib_cm_handle, ep_p->qp_handle->ep_hkey);
594*9e39c5baSBill Taylor
595*9e39c5baSBill Taylor args.cra_bkl_cookie = (uint64_t)cr_p->ib_cm_handle;
596*9e39c5baSBill Taylor args.cra_sp_hkey = cr_p->sp_ptr->cm_srvc_handle->sv_sp_hkey;
597*9e39c5baSBill Taylor args.cra_ep_hkey = ep_p->qp_handle->ep_hkey;
598*9e39c5baSBill Taylor
599*9e39c5baSBill Taylor args.cra_priv_sz = IB_MAX_REP_PDATA_SIZE;
600*9e39c5baSBill Taylor bcopy(prd_ptr, args.cra_priv, IB_MAX_REP_PDATA_SIZE);
601*9e39c5baSBill Taylor
602*9e39c5baSBill Taylor retval = ioctl(cr_p->header.owner_ia->hca_ptr->ib_hca_handle->ia_fd,
603*9e39c5baSBill Taylor DAPL_CR_ACCEPT, &args);
604*9e39c5baSBill Taylor if (retval != 0) {
605*9e39c5baSBill Taylor ep_p->qp_state = IBT_STATE_ERROR;
606*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
607*9e39c5baSBill Taylor "dapls_ib_accept: accept failed %s\n",
608*9e39c5baSBill Taylor strerror(errno));
609*9e39c5baSBill Taylor return (dapls_convert_error(errno, retval));
610*9e39c5baSBill Taylor }
611*9e39c5baSBill Taylor return (DAT_SUCCESS);
612*9e39c5baSBill Taylor }
613*9e39c5baSBill Taylor /*
614*9e39c5baSBill Taylor * dapls_ib_cm_remote_addr
615*9e39c5baSBill Taylor *
616*9e39c5baSBill Taylor * Obtain the remote IP address given a connection
617*9e39c5baSBill Taylor *
618*9e39c5baSBill Taylor * Input:
619*9e39c5baSBill Taylor * cr_handle
620*9e39c5baSBill Taylor * private data structure handle (only for IBHOSTS_NAMING)
621*9e39c5baSBill Taylor *
622*9e39c5baSBill Taylor * Output:
623*9e39c5baSBill Taylor * remote_ia_address: where to place the remote address
624*9e39c5baSBill Taylor *
625*9e39c5baSBill Taylor * Returns:
626*9e39c5baSBill Taylor * DAT_SUCCESS
627*9e39c5baSBill Taylor * DAT_INSUFFICIENT_RESOURCES
628*9e39c5baSBill Taylor * DAT_INVALID_PARAMETER
629*9e39c5baSBill Taylor *
630*9e39c5baSBill Taylor */
631*9e39c5baSBill Taylor /* ARGSUSED */
632*9e39c5baSBill Taylor DAT_RETURN
dapls_ib_cm_remote_addr(IN DAT_HANDLE dat_handle,IN DAPL_PRIVATE * prd_ptr,OUT DAT_SOCK_ADDR6 * remote_ia_address)633*9e39c5baSBill Taylor dapls_ib_cm_remote_addr(
634*9e39c5baSBill Taylor IN DAT_HANDLE dat_handle,
635*9e39c5baSBill Taylor IN DAPL_PRIVATE *prd_ptr,
636*9e39c5baSBill Taylor OUT DAT_SOCK_ADDR6 *remote_ia_address)
637*9e39c5baSBill Taylor {
638*9e39c5baSBill Taylor return (DAT_SUCCESS);
639*9e39c5baSBill Taylor }
640*9e39c5baSBill Taylor
641*9e39c5baSBill Taylor
642*9e39c5baSBill Taylor /*
643*9e39c5baSBill Taylor * dapls_ib_handoff_connection
644*9e39c5baSBill Taylor *
645*9e39c5baSBill Taylor * handoff connection to a different qualifier
646*9e39c5baSBill Taylor *
647*9e39c5baSBill Taylor * Input:
648*9e39c5baSBill Taylor * cr_ptr
649*9e39c5baSBill Taylor * cr_handoff
650*9e39c5baSBill Taylor *
651*9e39c5baSBill Taylor * Output:
652*9e39c5baSBill Taylor * none
653*9e39c5baSBill Taylor *
654*9e39c5baSBill Taylor * Returns:
655*9e39c5baSBill Taylor * DAT_SUCCESS
656*9e39c5baSBill Taylor * DAT_INSUFFICIENT_RESOURCES
657*9e39c5baSBill Taylor * DAT_INVALID_PARAMETER
658*9e39c5baSBill Taylor *
659*9e39c5baSBill Taylor */
660*9e39c5baSBill Taylor DAT_RETURN
dapls_ib_handoff_connection(IN DAPL_CR * cr_ptr,IN DAT_CONN_QUAL cr_handoff)661*9e39c5baSBill Taylor dapls_ib_handoff_connection(IN DAPL_CR *cr_ptr, IN DAT_CONN_QUAL cr_handoff)
662*9e39c5baSBill Taylor {
663*9e39c5baSBill Taylor dapl_cr_handoff_t args;
664*9e39c5baSBill Taylor int retval;
665*9e39c5baSBill Taylor
666*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_CM,
667*9e39c5baSBill Taylor "dapls_ib_handoff: fd %d, sp_hkey %016llx, "
668*9e39c5baSBill Taylor "bkl_index 0x%llx conn_qual %llu\n",
669*9e39c5baSBill Taylor cr_ptr->header.owner_ia->hca_ptr->ib_hca_handle->ia_fd,
670*9e39c5baSBill Taylor cr_ptr->sp_ptr->cm_srvc_handle->sv_sp_hkey,
671*9e39c5baSBill Taylor (uint64_t)cr_ptr->ib_cm_handle, cr_handoff);
672*9e39c5baSBill Taylor
673*9e39c5baSBill Taylor args.crh_bkl_cookie = (uint64_t)cr_ptr->ib_cm_handle;
674*9e39c5baSBill Taylor args.crh_sp_hkey = cr_ptr->sp_ptr->cm_srvc_handle->sv_sp_hkey;
675*9e39c5baSBill Taylor args.crh_conn_qual = cr_handoff;
676*9e39c5baSBill Taylor
677*9e39c5baSBill Taylor retval = ioctl(cr_ptr->header.owner_ia->hca_ptr->ib_hca_handle->ia_fd,
678*9e39c5baSBill Taylor DAPL_CR_HANDOFF, &args);
679*9e39c5baSBill Taylor if (retval != 0) {
680*9e39c5baSBill Taylor dapl_dbg_log(DAPL_DBG_TYPE_ERR,
681*9e39c5baSBill Taylor "dapls_ib_handoff: failed %s\n", strerror(errno));
682*9e39c5baSBill Taylor return (dapls_convert_error(errno, retval));
683*9e39c5baSBill Taylor }
684*9e39c5baSBill Taylor return (DAT_SUCCESS);
685*9e39c5baSBill Taylor }
686