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