1219820Sjeff/* 2219820Sjeff * Copyright (c) 2005 Topspin Communications. All rights reserved. 3219820Sjeff * Copyright (c) 2005 PathScale, Inc. All rights reserved. 4219820Sjeff * Copyright (c) 2006 Cisco Systems, Inc. All rights reserved. 5219820Sjeff * 6219820Sjeff * This software is available to you under a choice of one of two 7219820Sjeff * licenses. You may choose to be licensed under the terms of the GNU 8219820Sjeff * General Public License (GPL) Version 2, available from the file 9219820Sjeff * COPYING in the main directory of this source tree, or the 10219820Sjeff * OpenIB.org BSD license below: 11219820Sjeff * 12219820Sjeff * Redistribution and use in source and binary forms, with or 13219820Sjeff * without modification, are permitted provided that the following 14219820Sjeff * conditions are met: 15219820Sjeff * 16219820Sjeff * - Redistributions of source code must retain the above 17219820Sjeff * copyright notice, this list of conditions and the following 18219820Sjeff * disclaimer. 19219820Sjeff * 20219820Sjeff * - Redistributions in binary form must reproduce the above 21219820Sjeff * copyright notice, this list of conditions and the following 22219820Sjeff * disclaimer in the documentation and/or other materials 23219820Sjeff * provided with the distribution. 24219820Sjeff * 25219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32219820Sjeff * SOFTWARE. 33219820Sjeff */ 34219820Sjeff 35219820Sjeff#if HAVE_CONFIG_H 36219820Sjeff# include <config.h> 37219820Sjeff#endif /* HAVE_CONFIG_H */ 38219820Sjeff 39219820Sjeff#include <stdio.h> 40219820Sjeff#include <unistd.h> 41219820Sjeff#include <stdlib.h> 42219820Sjeff#include <errno.h> 43219820Sjeff#include <alloca.h> 44219820Sjeff#include <string.h> 45219820Sjeff 46219820Sjeff#include "ibverbs.h" 47219820Sjeff 48219820Sjeffstatic int ibv_cmd_get_context_v2(struct ibv_context *context, 49219820Sjeff struct ibv_get_context *new_cmd, 50219820Sjeff size_t new_cmd_size, 51219820Sjeff struct ibv_get_context_resp *resp, 52219820Sjeff size_t resp_size) 53219820Sjeff{ 54219820Sjeff struct ibv_abi_compat_v2 *t; 55219820Sjeff struct ibv_get_context_v2 *cmd; 56219820Sjeff size_t cmd_size; 57219820Sjeff uint32_t cq_fd; 58219820Sjeff 59219820Sjeff t = malloc(sizeof *t); 60219820Sjeff if (!t) 61219820Sjeff return ENOMEM; 62219820Sjeff pthread_mutex_init(&t->in_use, NULL); 63219820Sjeff 64219820Sjeff cmd_size = sizeof *cmd + new_cmd_size - sizeof *new_cmd; 65219820Sjeff cmd = alloca(cmd_size); 66219820Sjeff memcpy(cmd->driver_data, new_cmd->driver_data, new_cmd_size - sizeof *new_cmd); 67219820Sjeff 68219820Sjeff IBV_INIT_CMD_RESP(cmd, cmd_size, GET_CONTEXT, resp, resp_size); 69219820Sjeff cmd->cq_fd_tab = (uintptr_t) &cq_fd; 70219820Sjeff 71219820Sjeff if (write(context->cmd_fd, cmd, cmd_size) != cmd_size) 72219820Sjeff return errno; 73219820Sjeff 74219820Sjeff VALGRIND_MAKE_MEM_DEFINED(resp, resp_size); 75219820Sjeff 76219820Sjeff context->async_fd = resp->async_fd; 77219820Sjeff context->num_comp_vectors = 1; 78219820Sjeff t->channel.context = context; 79219820Sjeff t->channel.fd = cq_fd; 80219820Sjeff t->channel.refcnt = 0; 81219820Sjeff context->abi_compat = t; 82219820Sjeff 83219820Sjeff return 0; 84219820Sjeff} 85219820Sjeff 86219820Sjeffint ibv_cmd_get_context(struct ibv_context *context, struct ibv_get_context *cmd, 87219820Sjeff size_t cmd_size, struct ibv_get_context_resp *resp, 88219820Sjeff size_t resp_size) 89219820Sjeff{ 90219820Sjeff if (abi_ver <= 2) 91219820Sjeff return ibv_cmd_get_context_v2(context, cmd, cmd_size, resp, resp_size); 92219820Sjeff 93219820Sjeff IBV_INIT_CMD_RESP(cmd, cmd_size, GET_CONTEXT, resp, resp_size); 94219820Sjeff 95219820Sjeff if (write(context->cmd_fd, cmd, cmd_size) != cmd_size) 96219820Sjeff return errno; 97219820Sjeff 98219820Sjeff VALGRIND_MAKE_MEM_DEFINED(resp, resp_size); 99219820Sjeff 100219820Sjeff context->async_fd = resp->async_fd; 101219820Sjeff context->num_comp_vectors = resp->num_comp_vectors; 102219820Sjeff 103219820Sjeff return 0; 104219820Sjeff} 105219820Sjeff 106219820Sjeffint ibv_cmd_query_device(struct ibv_context *context, 107219820Sjeff struct ibv_device_attr *device_attr, 108219820Sjeff uint64_t *raw_fw_ver, 109219820Sjeff struct ibv_query_device *cmd, size_t cmd_size) 110219820Sjeff{ 111219820Sjeff struct ibv_query_device_resp resp; 112219820Sjeff 113219820Sjeff IBV_INIT_CMD_RESP(cmd, cmd_size, QUERY_DEVICE, &resp, sizeof resp); 114219820Sjeff 115219820Sjeff if (write(context->cmd_fd, cmd, cmd_size) != cmd_size) 116219820Sjeff return errno; 117219820Sjeff 118219820Sjeff VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp); 119219820Sjeff 120219820Sjeff memset(device_attr->fw_ver, 0, sizeof device_attr->fw_ver); 121219820Sjeff *raw_fw_ver = resp.fw_ver; 122219820Sjeff device_attr->node_guid = resp.node_guid; 123219820Sjeff device_attr->sys_image_guid = resp.sys_image_guid; 124219820Sjeff device_attr->max_mr_size = resp.max_mr_size; 125219820Sjeff device_attr->page_size_cap = resp.page_size_cap; 126219820Sjeff device_attr->vendor_id = resp.vendor_id; 127219820Sjeff device_attr->vendor_part_id = resp.vendor_part_id; 128219820Sjeff device_attr->hw_ver = resp.hw_ver; 129219820Sjeff device_attr->max_qp = resp.max_qp; 130219820Sjeff device_attr->max_qp_wr = resp.max_qp_wr; 131219820Sjeff device_attr->device_cap_flags = resp.device_cap_flags; 132219820Sjeff device_attr->max_sge = resp.max_sge; 133219820Sjeff device_attr->max_sge_rd = resp.max_sge_rd; 134219820Sjeff device_attr->max_cq = resp.max_cq; 135219820Sjeff device_attr->max_cqe = resp.max_cqe; 136219820Sjeff device_attr->max_mr = resp.max_mr; 137219820Sjeff device_attr->max_pd = resp.max_pd; 138219820Sjeff device_attr->max_qp_rd_atom = resp.max_qp_rd_atom; 139219820Sjeff device_attr->max_ee_rd_atom = resp.max_ee_rd_atom; 140219820Sjeff device_attr->max_res_rd_atom = resp.max_res_rd_atom; 141219820Sjeff device_attr->max_qp_init_rd_atom = resp.max_qp_init_rd_atom; 142219820Sjeff device_attr->max_ee_init_rd_atom = resp.max_ee_init_rd_atom; 143219820Sjeff device_attr->atomic_cap = resp.atomic_cap; 144219820Sjeff device_attr->max_ee = resp.max_ee; 145219820Sjeff device_attr->max_rdd = resp.max_rdd; 146219820Sjeff device_attr->max_mw = resp.max_mw; 147219820Sjeff device_attr->max_raw_ipv6_qp = resp.max_raw_ipv6_qp; 148219820Sjeff device_attr->max_raw_ethy_qp = resp.max_raw_ethy_qp; 149219820Sjeff device_attr->max_mcast_grp = resp.max_mcast_grp; 150219820Sjeff device_attr->max_mcast_qp_attach = resp.max_mcast_qp_attach; 151219820Sjeff device_attr->max_total_mcast_qp_attach = resp.max_total_mcast_qp_attach; 152219820Sjeff device_attr->max_ah = resp.max_ah; 153219820Sjeff device_attr->max_fmr = resp.max_fmr; 154219820Sjeff device_attr->max_map_per_fmr = resp.max_map_per_fmr; 155219820Sjeff device_attr->max_srq = resp.max_srq; 156219820Sjeff device_attr->max_srq_wr = resp.max_srq_wr; 157219820Sjeff device_attr->max_srq_sge = resp.max_srq_sge; 158219820Sjeff device_attr->max_pkeys = resp.max_pkeys; 159219820Sjeff device_attr->local_ca_ack_delay = resp.local_ca_ack_delay; 160219820Sjeff device_attr->phys_port_cnt = resp.phys_port_cnt; 161219820Sjeff 162219820Sjeff return 0; 163219820Sjeff} 164219820Sjeff 165219820Sjeffint ibv_cmd_query_port(struct ibv_context *context, uint8_t port_num, 166219820Sjeff struct ibv_port_attr *port_attr, 167219820Sjeff struct ibv_query_port *cmd, size_t cmd_size) 168219820Sjeff{ 169219820Sjeff struct ibv_query_port_resp resp; 170219820Sjeff 171219820Sjeff IBV_INIT_CMD_RESP(cmd, cmd_size, QUERY_PORT, &resp, sizeof resp); 172219820Sjeff cmd->port_num = port_num; 173219820Sjeff memset(cmd->reserved, 0, sizeof cmd->reserved); 174219820Sjeff 175219820Sjeff if (write(context->cmd_fd, cmd, cmd_size) != cmd_size) 176219820Sjeff return errno; 177219820Sjeff 178219820Sjeff VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp); 179219820Sjeff 180219820Sjeff port_attr->state = resp.state; 181219820Sjeff port_attr->max_mtu = resp.max_mtu; 182219820Sjeff port_attr->active_mtu = resp.active_mtu; 183219820Sjeff port_attr->gid_tbl_len = resp.gid_tbl_len; 184219820Sjeff port_attr->port_cap_flags = resp.port_cap_flags; 185219820Sjeff port_attr->max_msg_sz = resp.max_msg_sz; 186219820Sjeff port_attr->bad_pkey_cntr = resp.bad_pkey_cntr; 187219820Sjeff port_attr->qkey_viol_cntr = resp.qkey_viol_cntr; 188219820Sjeff port_attr->pkey_tbl_len = resp.pkey_tbl_len; 189219820Sjeff port_attr->lid = resp.lid; 190219820Sjeff port_attr->sm_lid = resp.sm_lid; 191219820Sjeff port_attr->lmc = resp.lmc; 192219820Sjeff port_attr->max_vl_num = resp.max_vl_num; 193219820Sjeff port_attr->sm_sl = resp.sm_sl; 194219820Sjeff port_attr->subnet_timeout = resp.subnet_timeout; 195219820Sjeff port_attr->init_type_reply = resp.init_type_reply; 196219820Sjeff port_attr->active_width = resp.active_width; 197219820Sjeff port_attr->active_speed = resp.active_speed; 198219820Sjeff port_attr->phys_state = resp.phys_state; 199219820Sjeff port_attr->link_layer = resp.link_layer; 200219820Sjeff 201219820Sjeff return 0; 202219820Sjeff} 203219820Sjeff 204219820Sjeffint ibv_cmd_alloc_pd(struct ibv_context *context, struct ibv_pd *pd, 205219820Sjeff struct ibv_alloc_pd *cmd, size_t cmd_size, 206219820Sjeff struct ibv_alloc_pd_resp *resp, size_t resp_size) 207219820Sjeff{ 208219820Sjeff IBV_INIT_CMD_RESP(cmd, cmd_size, ALLOC_PD, resp, resp_size); 209219820Sjeff 210219820Sjeff if (write(context->cmd_fd, cmd, cmd_size) != cmd_size) 211219820Sjeff return errno; 212219820Sjeff 213219820Sjeff VALGRIND_MAKE_MEM_DEFINED(resp, resp_size); 214219820Sjeff 215219820Sjeff pd->handle = resp->pd_handle; 216219820Sjeff pd->context = context; 217219820Sjeff 218219820Sjeff return 0; 219219820Sjeff} 220219820Sjeff 221219820Sjeffint ibv_cmd_dealloc_pd(struct ibv_pd *pd) 222219820Sjeff{ 223219820Sjeff struct ibv_dealloc_pd cmd; 224219820Sjeff 225219820Sjeff IBV_INIT_CMD(&cmd, sizeof cmd, DEALLOC_PD); 226219820Sjeff cmd.pd_handle = pd->handle; 227219820Sjeff 228219820Sjeff if (write(pd->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) 229219820Sjeff return errno; 230219820Sjeff 231219820Sjeff return 0; 232219820Sjeff} 233219820Sjeff 234219820Sjeffint ibv_cmd_reg_mr(struct ibv_pd *pd, void *addr, size_t length, 235219820Sjeff uint64_t hca_va, int access, 236219820Sjeff struct ibv_mr *mr, struct ibv_reg_mr *cmd, 237219820Sjeff size_t cmd_size, 238219820Sjeff struct ibv_reg_mr_resp *resp, size_t resp_size) 239219820Sjeff{ 240219820Sjeff 241219820Sjeff IBV_INIT_CMD_RESP(cmd, cmd_size, REG_MR, resp, resp_size); 242219820Sjeff 243219820Sjeff cmd->start = (uintptr_t) addr; 244219820Sjeff cmd->length = length; 245219820Sjeff cmd->hca_va = hca_va; 246219820Sjeff cmd->pd_handle = pd->handle; 247219820Sjeff cmd->access_flags = access; 248219820Sjeff 249219820Sjeff if (write(pd->context->cmd_fd, cmd, cmd_size) != cmd_size) 250219820Sjeff return errno; 251219820Sjeff 252219820Sjeff VALGRIND_MAKE_MEM_DEFINED(resp, resp_size); 253219820Sjeff 254219820Sjeff mr->handle = resp->mr_handle; 255219820Sjeff mr->lkey = resp->lkey; 256219820Sjeff mr->rkey = resp->rkey; 257219820Sjeff mr->context = pd->context; 258219820Sjeff 259219820Sjeff return 0; 260219820Sjeff} 261219820Sjeff 262219820Sjeffint ibv_cmd_dereg_mr(struct ibv_mr *mr) 263219820Sjeff{ 264219820Sjeff struct ibv_dereg_mr cmd; 265219820Sjeff 266219820Sjeff IBV_INIT_CMD(&cmd, sizeof cmd, DEREG_MR); 267219820Sjeff cmd.mr_handle = mr->handle; 268219820Sjeff 269219820Sjeff if (write(mr->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) 270219820Sjeff return errno; 271219820Sjeff 272219820Sjeff return 0; 273219820Sjeff} 274219820Sjeff 275219820Sjeffstatic int ibv_cmd_create_cq_v2(struct ibv_context *context, int cqe, 276219820Sjeff struct ibv_cq *cq, 277219820Sjeff struct ibv_create_cq *new_cmd, size_t new_cmd_size, 278219820Sjeff struct ibv_create_cq_resp *resp, size_t resp_size) 279219820Sjeff{ 280219820Sjeff struct ibv_create_cq_v2 *cmd; 281219820Sjeff size_t cmd_size; 282219820Sjeff 283219820Sjeff cmd_size = sizeof *cmd + new_cmd_size - sizeof *new_cmd; 284219820Sjeff cmd = alloca(cmd_size); 285219820Sjeff memcpy(cmd->driver_data, new_cmd->driver_data, new_cmd_size - sizeof *new_cmd); 286219820Sjeff 287219820Sjeff IBV_INIT_CMD_RESP(cmd, cmd_size, CREATE_CQ, resp, resp_size); 288219820Sjeff cmd->user_handle = (uintptr_t) cq; 289219820Sjeff cmd->cqe = cqe; 290219820Sjeff cmd->event_handler = 0; 291219820Sjeff 292219820Sjeff if (write(context->cmd_fd, cmd, cmd_size) != cmd_size) 293219820Sjeff return errno; 294219820Sjeff 295219820Sjeff VALGRIND_MAKE_MEM_DEFINED(resp, resp_size); 296219820Sjeff 297219820Sjeff cq->handle = resp->cq_handle; 298219820Sjeff cq->cqe = resp->cqe; 299219820Sjeff cq->context = context; 300219820Sjeff 301219820Sjeff return 0; 302219820Sjeff} 303219820Sjeff 304219820Sjeffint ibv_cmd_create_cq(struct ibv_context *context, int cqe, 305219820Sjeff struct ibv_comp_channel *channel, 306219820Sjeff int comp_vector, struct ibv_cq *cq, 307219820Sjeff struct ibv_create_cq *cmd, size_t cmd_size, 308219820Sjeff struct ibv_create_cq_resp *resp, size_t resp_size) 309219820Sjeff{ 310219820Sjeff if (abi_ver <= 2) 311219820Sjeff return ibv_cmd_create_cq_v2(context, cqe, cq, 312219820Sjeff cmd, cmd_size, resp, resp_size); 313219820Sjeff 314219820Sjeff IBV_INIT_CMD_RESP(cmd, cmd_size, CREATE_CQ, resp, resp_size); 315219820Sjeff cmd->user_handle = (uintptr_t) cq; 316219820Sjeff cmd->cqe = cqe; 317219820Sjeff cmd->comp_vector = comp_vector; 318219820Sjeff cmd->comp_channel = channel ? channel->fd : -1; 319219820Sjeff cmd->reserved = 0; 320219820Sjeff 321219820Sjeff if (write(context->cmd_fd, cmd, cmd_size) != cmd_size) 322219820Sjeff return errno; 323219820Sjeff 324219820Sjeff VALGRIND_MAKE_MEM_DEFINED(resp, resp_size); 325219820Sjeff 326219820Sjeff cq->handle = resp->cq_handle; 327219820Sjeff cq->cqe = resp->cqe; 328219820Sjeff cq->context = context; 329219820Sjeff 330219820Sjeff return 0; 331219820Sjeff} 332219820Sjeff 333219820Sjeffint ibv_cmd_poll_cq(struct ibv_cq *ibcq, int ne, struct ibv_wc *wc) 334219820Sjeff{ 335219820Sjeff struct ibv_poll_cq cmd; 336219820Sjeff struct ibv_poll_cq_resp *resp; 337219820Sjeff int i; 338219820Sjeff int rsize; 339219820Sjeff int ret; 340219820Sjeff 341219820Sjeff rsize = sizeof *resp + ne * sizeof(struct ibv_kern_wc); 342219820Sjeff resp = malloc(rsize); 343219820Sjeff if (!resp) 344219820Sjeff return -1; 345219820Sjeff 346219820Sjeff IBV_INIT_CMD_RESP(&cmd, sizeof cmd, POLL_CQ, resp, rsize); 347219820Sjeff cmd.cq_handle = ibcq->handle; 348219820Sjeff cmd.ne = ne; 349219820Sjeff 350219820Sjeff if (write(ibcq->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) { 351219820Sjeff ret = -1; 352219820Sjeff goto out; 353219820Sjeff } 354219820Sjeff 355219820Sjeff VALGRIND_MAKE_MEM_DEFINED(resp, rsize); 356219820Sjeff 357219820Sjeff for (i = 0; i < resp->count; i++) { 358219820Sjeff wc[i].wr_id = resp->wc[i].wr_id; 359219820Sjeff wc[i].status = resp->wc[i].status; 360219820Sjeff wc[i].opcode = resp->wc[i].opcode; 361219820Sjeff wc[i].vendor_err = resp->wc[i].vendor_err; 362219820Sjeff wc[i].byte_len = resp->wc[i].byte_len; 363219820Sjeff wc[i].imm_data = resp->wc[i].imm_data; 364219820Sjeff wc[i].qp_num = resp->wc[i].qp_num; 365219820Sjeff wc[i].src_qp = resp->wc[i].src_qp; 366219820Sjeff wc[i].wc_flags = resp->wc[i].wc_flags; 367219820Sjeff wc[i].pkey_index = resp->wc[i].pkey_index; 368219820Sjeff wc[i].slid = resp->wc[i].slid; 369219820Sjeff wc[i].sl = resp->wc[i].sl; 370219820Sjeff wc[i].dlid_path_bits = resp->wc[i].dlid_path_bits; 371219820Sjeff } 372219820Sjeff 373219820Sjeff ret = resp->count; 374219820Sjeff 375219820Sjeffout: 376219820Sjeff free(resp); 377219820Sjeff return ret; 378219820Sjeff} 379219820Sjeff 380219820Sjeffint ibv_cmd_req_notify_cq(struct ibv_cq *ibcq, int solicited_only) 381219820Sjeff{ 382219820Sjeff struct ibv_req_notify_cq cmd; 383219820Sjeff 384219820Sjeff IBV_INIT_CMD(&cmd, sizeof cmd, REQ_NOTIFY_CQ); 385219820Sjeff cmd.cq_handle = ibcq->handle; 386219820Sjeff cmd.solicited = !!solicited_only; 387219820Sjeff 388219820Sjeff if (write(ibcq->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) 389219820Sjeff return errno; 390219820Sjeff 391219820Sjeff return 0; 392219820Sjeff} 393219820Sjeff 394219820Sjeffint ibv_cmd_resize_cq(struct ibv_cq *cq, int cqe, 395219820Sjeff struct ibv_resize_cq *cmd, size_t cmd_size, 396219820Sjeff struct ibv_resize_cq_resp *resp, size_t resp_size) 397219820Sjeff{ 398219820Sjeff 399219820Sjeff IBV_INIT_CMD_RESP(cmd, cmd_size, RESIZE_CQ, resp, resp_size); 400219820Sjeff cmd->cq_handle = cq->handle; 401219820Sjeff cmd->cqe = cqe; 402219820Sjeff 403219820Sjeff if (write(cq->context->cmd_fd, cmd, cmd_size) != cmd_size) 404219820Sjeff return errno; 405219820Sjeff 406219820Sjeff VALGRIND_MAKE_MEM_DEFINED(resp, resp_size); 407219820Sjeff 408219820Sjeff cq->cqe = resp->cqe; 409219820Sjeff 410219820Sjeff return 0; 411219820Sjeff} 412219820Sjeff 413219820Sjeffstatic int ibv_cmd_destroy_cq_v1(struct ibv_cq *cq) 414219820Sjeff{ 415219820Sjeff struct ibv_destroy_cq_v1 cmd; 416219820Sjeff 417219820Sjeff IBV_INIT_CMD(&cmd, sizeof cmd, DESTROY_CQ); 418219820Sjeff cmd.cq_handle = cq->handle; 419219820Sjeff 420219820Sjeff if (write(cq->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) 421219820Sjeff return errno; 422219820Sjeff 423219820Sjeff return 0; 424219820Sjeff} 425219820Sjeff 426219820Sjeffint ibv_cmd_destroy_cq(struct ibv_cq *cq) 427219820Sjeff{ 428219820Sjeff struct ibv_destroy_cq cmd; 429219820Sjeff struct ibv_destroy_cq_resp resp; 430219820Sjeff 431219820Sjeff if (abi_ver == 1) 432219820Sjeff return ibv_cmd_destroy_cq_v1(cq); 433219820Sjeff 434219820Sjeff IBV_INIT_CMD_RESP(&cmd, sizeof cmd, DESTROY_CQ, &resp, sizeof resp); 435219820Sjeff cmd.cq_handle = cq->handle; 436219820Sjeff cmd.reserved = 0; 437219820Sjeff 438219820Sjeff if (write(cq->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) 439219820Sjeff return errno; 440219820Sjeff 441219820Sjeff VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp); 442219820Sjeff 443219820Sjeff pthread_mutex_lock(&cq->mutex); 444219820Sjeff while (cq->comp_events_completed != resp.comp_events_reported || 445219820Sjeff cq->async_events_completed != resp.async_events_reported) 446219820Sjeff pthread_cond_wait(&cq->cond, &cq->mutex); 447219820Sjeff pthread_mutex_unlock(&cq->mutex); 448219820Sjeff 449219820Sjeff return 0; 450219820Sjeff} 451219820Sjeff 452219820Sjeffint ibv_cmd_create_srq(struct ibv_pd *pd, 453219820Sjeff struct ibv_srq *srq, struct ibv_srq_init_attr *attr, 454219820Sjeff struct ibv_create_srq *cmd, size_t cmd_size, 455219820Sjeff struct ibv_create_srq_resp *resp, size_t resp_size) 456219820Sjeff{ 457219820Sjeff IBV_INIT_CMD_RESP(cmd, cmd_size, CREATE_SRQ, resp, resp_size); 458219820Sjeff cmd->user_handle = (uintptr_t) srq; 459219820Sjeff cmd->pd_handle = pd->handle; 460219820Sjeff cmd->max_wr = attr->attr.max_wr; 461219820Sjeff cmd->max_sge = attr->attr.max_sge; 462219820Sjeff cmd->srq_limit = attr->attr.srq_limit; 463219820Sjeff 464219820Sjeff if (write(pd->context->cmd_fd, cmd, cmd_size) != cmd_size) 465219820Sjeff return errno; 466219820Sjeff 467219820Sjeff VALGRIND_MAKE_MEM_DEFINED(resp, resp_size); 468219820Sjeff 469219820Sjeff srq->handle = resp->srq_handle; 470219820Sjeff srq->context = pd->context; 471219820Sjeff 472219820Sjeff if (abi_ver > 5) { 473219820Sjeff attr->attr.max_wr = resp->max_wr; 474219820Sjeff attr->attr.max_sge = resp->max_sge; 475219820Sjeff } else { 476219820Sjeff struct ibv_create_srq_resp_v5 *resp_v5 = 477219820Sjeff (struct ibv_create_srq_resp_v5 *) resp; 478219820Sjeff 479219820Sjeff memmove((void *) resp + sizeof *resp, 480219820Sjeff (void *) resp_v5 + sizeof *resp_v5, 481219820Sjeff resp_size - sizeof *resp); 482219820Sjeff } 483219820Sjeff 484219820Sjeff return 0; 485219820Sjeff} 486219820Sjeff 487219820Sjeffint ibv_cmd_create_xrc_srq(struct ibv_pd *pd, 488219820Sjeff struct ibv_srq *srq, struct ibv_srq_init_attr *attr, 489219820Sjeff uint32_t xrcd_handle, uint32_t xrc_cq, 490219820Sjeff struct ibv_create_xrc_srq *cmd, size_t cmd_size, 491219820Sjeff struct ibv_create_srq_resp *resp, size_t resp_size) 492219820Sjeff{ 493219820Sjeff IBV_INIT_CMD_RESP(cmd, cmd_size, CREATE_XRC_SRQ, resp, resp_size); 494219820Sjeff cmd->user_handle = (uintptr_t) srq; 495219820Sjeff cmd->pd_handle = pd->handle; 496219820Sjeff cmd->max_wr = attr->attr.max_wr; 497219820Sjeff cmd->max_sge = attr->attr.max_sge; 498219820Sjeff cmd->srq_limit = attr->attr.srq_limit; 499219820Sjeff cmd->xrcd_handle = xrcd_handle; 500219820Sjeff cmd->xrc_cq = xrc_cq; 501219820Sjeff 502219820Sjeff if (write(pd->context->cmd_fd, cmd, cmd_size) != cmd_size) 503219820Sjeff return errno; 504219820Sjeff 505219820Sjeff VALGRIND_MAKE_MEM_DEFINED(resp, resp_size); 506219820Sjeff 507219820Sjeff srq->handle = resp->srq_handle; 508219820Sjeff srq->context = pd->context; 509219820Sjeff attr->attr.max_wr = resp->max_wr; 510219820Sjeff attr->attr.max_sge = resp->max_sge; 511219820Sjeff 512219820Sjeff return 0; 513219820Sjeff} 514219820Sjeff 515219820Sjeffstatic int ibv_cmd_modify_srq_v3(struct ibv_srq *srq, 516219820Sjeff struct ibv_srq_attr *srq_attr, 517219820Sjeff int srq_attr_mask, 518219820Sjeff struct ibv_modify_srq *new_cmd, 519219820Sjeff size_t new_cmd_size) 520219820Sjeff{ 521219820Sjeff struct ibv_modify_srq_v3 *cmd; 522219820Sjeff size_t cmd_size; 523219820Sjeff 524219820Sjeff cmd_size = sizeof *cmd + new_cmd_size - sizeof *new_cmd; 525219820Sjeff cmd = alloca(cmd_size); 526219820Sjeff memcpy(cmd->driver_data, new_cmd->driver_data, new_cmd_size - sizeof *new_cmd); 527219820Sjeff 528219820Sjeff IBV_INIT_CMD(cmd, cmd_size, MODIFY_SRQ); 529219820Sjeff 530219820Sjeff cmd->srq_handle = srq->handle; 531219820Sjeff cmd->attr_mask = srq_attr_mask; 532219820Sjeff cmd->max_wr = srq_attr->max_wr; 533219820Sjeff cmd->srq_limit = srq_attr->srq_limit; 534219820Sjeff cmd->max_sge = 0; 535219820Sjeff cmd->reserved = 0; 536219820Sjeff 537219820Sjeff if (write(srq->context->cmd_fd, cmd, cmd_size) != cmd_size) 538219820Sjeff return errno; 539219820Sjeff 540219820Sjeff return 0; 541219820Sjeff} 542219820Sjeff 543219820Sjeffint ibv_cmd_modify_srq(struct ibv_srq *srq, 544219820Sjeff struct ibv_srq_attr *srq_attr, 545219820Sjeff int srq_attr_mask, 546219820Sjeff struct ibv_modify_srq *cmd, size_t cmd_size) 547219820Sjeff{ 548219820Sjeff if (abi_ver == 3) 549219820Sjeff return ibv_cmd_modify_srq_v3(srq, srq_attr, srq_attr_mask, 550219820Sjeff cmd, cmd_size); 551219820Sjeff 552219820Sjeff IBV_INIT_CMD(cmd, cmd_size, MODIFY_SRQ); 553219820Sjeff 554219820Sjeff cmd->srq_handle = srq->handle; 555219820Sjeff cmd->attr_mask = srq_attr_mask; 556219820Sjeff cmd->max_wr = srq_attr->max_wr; 557219820Sjeff cmd->srq_limit = srq_attr->srq_limit; 558219820Sjeff 559219820Sjeff if (write(srq->context->cmd_fd, cmd, cmd_size) != cmd_size) 560219820Sjeff return errno; 561219820Sjeff 562219820Sjeff return 0; 563219820Sjeff} 564219820Sjeff 565219820Sjeffint ibv_cmd_query_srq(struct ibv_srq *srq, struct ibv_srq_attr *srq_attr, 566219820Sjeff struct ibv_query_srq *cmd, size_t cmd_size) 567219820Sjeff{ 568219820Sjeff struct ibv_query_srq_resp resp; 569219820Sjeff 570219820Sjeff IBV_INIT_CMD_RESP(cmd, cmd_size, QUERY_SRQ, &resp, sizeof resp); 571219820Sjeff cmd->srq_handle = srq->handle; 572219820Sjeff cmd->reserved = 0; 573219820Sjeff 574219820Sjeff if (write(srq->context->cmd_fd, cmd, cmd_size) != cmd_size) 575219820Sjeff return errno; 576219820Sjeff 577219820Sjeff VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp); 578219820Sjeff 579219820Sjeff srq_attr->max_wr = resp.max_wr; 580219820Sjeff srq_attr->max_sge = resp.max_sge; 581219820Sjeff srq_attr->srq_limit = resp.srq_limit; 582219820Sjeff 583219820Sjeff return 0; 584219820Sjeff} 585219820Sjeff 586219820Sjeffstatic int ibv_cmd_destroy_srq_v1(struct ibv_srq *srq) 587219820Sjeff{ 588219820Sjeff struct ibv_destroy_srq_v1 cmd; 589219820Sjeff 590219820Sjeff IBV_INIT_CMD(&cmd, sizeof cmd, DESTROY_SRQ); 591219820Sjeff cmd.srq_handle = srq->handle; 592219820Sjeff 593219820Sjeff if (write(srq->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) 594219820Sjeff return errno; 595219820Sjeff 596219820Sjeff return 0; 597219820Sjeff} 598219820Sjeff 599219820Sjeffint ibv_cmd_destroy_srq(struct ibv_srq *srq) 600219820Sjeff{ 601219820Sjeff struct ibv_destroy_srq cmd; 602219820Sjeff struct ibv_destroy_srq_resp resp; 603219820Sjeff 604219820Sjeff if (abi_ver == 1) 605219820Sjeff return ibv_cmd_destroy_srq_v1(srq); 606219820Sjeff 607219820Sjeff IBV_INIT_CMD_RESP(&cmd, sizeof cmd, DESTROY_SRQ, &resp, sizeof resp); 608219820Sjeff cmd.srq_handle = srq->handle; 609219820Sjeff cmd.reserved = 0; 610219820Sjeff 611219820Sjeff if (write(srq->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) 612219820Sjeff return errno; 613219820Sjeff 614219820Sjeff VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp); 615219820Sjeff 616219820Sjeff pthread_mutex_lock(&srq->mutex); 617219820Sjeff while (srq->events_completed != resp.events_reported) 618219820Sjeff pthread_cond_wait(&srq->cond, &srq->mutex); 619219820Sjeff pthread_mutex_unlock(&srq->mutex); 620219820Sjeff 621219820Sjeff return 0; 622219820Sjeff} 623219820Sjeff 624219820Sjeffint ibv_cmd_create_qp(struct ibv_pd *pd, 625219820Sjeff struct ibv_qp *qp, struct ibv_qp_init_attr *attr, 626219820Sjeff struct ibv_create_qp *cmd, size_t cmd_size, 627219820Sjeff struct ibv_create_qp_resp *resp, size_t resp_size) 628219820Sjeff{ 629219820Sjeff IBV_INIT_CMD_RESP(cmd, cmd_size, CREATE_QP, resp, resp_size); 630219820Sjeff 631219820Sjeff cmd->user_handle = (uintptr_t) qp; 632219820Sjeff cmd->pd_handle = pd->handle; 633219820Sjeff cmd->send_cq_handle = attr->send_cq->handle; 634219820Sjeff cmd->recv_cq_handle = attr->recv_cq->handle; 635219820Sjeff cmd->max_send_wr = attr->cap.max_send_wr; 636219820Sjeff cmd->max_recv_wr = attr->cap.max_recv_wr; 637219820Sjeff cmd->max_send_sge = attr->cap.max_send_sge; 638219820Sjeff cmd->max_recv_sge = attr->cap.max_recv_sge; 639219820Sjeff cmd->max_inline_data = attr->cap.max_inline_data; 640219820Sjeff cmd->sq_sig_all = attr->sq_sig_all; 641219820Sjeff cmd->qp_type = attr->qp_type; 642219820Sjeff cmd->is_srq = !!attr->srq; 643219820Sjeff cmd->srq_handle = attr->qp_type == IBV_QPT_XRC ? 644219820Sjeff (attr->xrc_domain ? attr->xrc_domain->handle : 0) : 645219820Sjeff (attr->srq ? attr->srq->handle : 0); 646219820Sjeff cmd->reserved = 0; 647219820Sjeff 648219820Sjeff if (write(pd->context->cmd_fd, cmd, cmd_size) != cmd_size) 649219820Sjeff return errno; 650219820Sjeff 651219820Sjeff VALGRIND_MAKE_MEM_DEFINED(resp, resp_size); 652219820Sjeff 653219820Sjeff qp->handle = resp->qp_handle; 654219820Sjeff qp->qp_num = resp->qpn; 655219820Sjeff qp->context = pd->context; 656219820Sjeff 657219820Sjeff if (abi_ver > 3) { 658219820Sjeff attr->cap.max_recv_sge = resp->max_recv_sge; 659219820Sjeff attr->cap.max_send_sge = resp->max_send_sge; 660219820Sjeff attr->cap.max_recv_wr = resp->max_recv_wr; 661219820Sjeff attr->cap.max_send_wr = resp->max_send_wr; 662219820Sjeff attr->cap.max_inline_data = resp->max_inline_data; 663219820Sjeff } 664219820Sjeff 665219820Sjeff if (abi_ver == 4) { 666219820Sjeff struct ibv_create_qp_resp_v4 *resp_v4 = 667219820Sjeff (struct ibv_create_qp_resp_v4 *) resp; 668219820Sjeff 669219820Sjeff memmove((void *) resp + sizeof *resp, 670219820Sjeff (void *) resp_v4 + sizeof *resp_v4, 671219820Sjeff resp_size - sizeof *resp); 672219820Sjeff } else if (abi_ver <= 3) { 673219820Sjeff struct ibv_create_qp_resp_v3 *resp_v3 = 674219820Sjeff (struct ibv_create_qp_resp_v3 *) resp; 675219820Sjeff 676219820Sjeff memmove((void *) resp + sizeof *resp, 677219820Sjeff (void *) resp_v3 + sizeof *resp_v3, 678219820Sjeff resp_size - sizeof *resp); 679219820Sjeff } 680219820Sjeff 681219820Sjeff return 0; 682219820Sjeff} 683219820Sjeff 684219820Sjeffint ibv_cmd_query_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, 685219820Sjeff int attr_mask, 686219820Sjeff struct ibv_qp_init_attr *init_attr, 687219820Sjeff struct ibv_query_qp *cmd, size_t cmd_size) 688219820Sjeff{ 689219820Sjeff struct ibv_query_qp_resp resp; 690219820Sjeff 691219820Sjeff IBV_INIT_CMD_RESP(cmd, cmd_size, QUERY_QP, &resp, sizeof resp); 692219820Sjeff cmd->qp_handle = qp->handle; 693219820Sjeff cmd->attr_mask = attr_mask; 694219820Sjeff 695219820Sjeff if (write(qp->context->cmd_fd, cmd, cmd_size) != cmd_size) 696219820Sjeff return errno; 697219820Sjeff 698219820Sjeff VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp); 699219820Sjeff 700219820Sjeff attr->qkey = resp.qkey; 701219820Sjeff attr->rq_psn = resp.rq_psn; 702219820Sjeff attr->sq_psn = resp.sq_psn; 703219820Sjeff attr->dest_qp_num = resp.dest_qp_num; 704219820Sjeff attr->qp_access_flags = resp.qp_access_flags; 705219820Sjeff attr->pkey_index = resp.pkey_index; 706219820Sjeff attr->alt_pkey_index = resp.alt_pkey_index; 707219820Sjeff attr->qp_state = resp.qp_state; 708219820Sjeff attr->cur_qp_state = resp.cur_qp_state; 709219820Sjeff attr->path_mtu = resp.path_mtu; 710219820Sjeff attr->path_mig_state = resp.path_mig_state; 711219820Sjeff attr->sq_draining = resp.sq_draining; 712219820Sjeff attr->max_rd_atomic = resp.max_rd_atomic; 713219820Sjeff attr->max_dest_rd_atomic = resp.max_dest_rd_atomic; 714219820Sjeff attr->min_rnr_timer = resp.min_rnr_timer; 715219820Sjeff attr->port_num = resp.port_num; 716219820Sjeff attr->timeout = resp.timeout; 717219820Sjeff attr->retry_cnt = resp.retry_cnt; 718219820Sjeff attr->rnr_retry = resp.rnr_retry; 719219820Sjeff attr->alt_port_num = resp.alt_port_num; 720219820Sjeff attr->alt_timeout = resp.alt_timeout; 721219820Sjeff attr->cap.max_send_wr = resp.max_send_wr; 722219820Sjeff attr->cap.max_recv_wr = resp.max_recv_wr; 723219820Sjeff attr->cap.max_send_sge = resp.max_send_sge; 724219820Sjeff attr->cap.max_recv_sge = resp.max_recv_sge; 725219820Sjeff attr->cap.max_inline_data = resp.max_inline_data; 726219820Sjeff 727219820Sjeff memcpy(attr->ah_attr.grh.dgid.raw, resp.dest.dgid, 16); 728219820Sjeff attr->ah_attr.grh.flow_label = resp.dest.flow_label; 729219820Sjeff attr->ah_attr.dlid = resp.dest.dlid; 730219820Sjeff attr->ah_attr.grh.sgid_index = resp.dest.sgid_index; 731219820Sjeff attr->ah_attr.grh.hop_limit = resp.dest.hop_limit; 732219820Sjeff attr->ah_attr.grh.traffic_class = resp.dest.traffic_class; 733219820Sjeff attr->ah_attr.sl = resp.dest.sl; 734219820Sjeff attr->ah_attr.src_path_bits = resp.dest.src_path_bits; 735219820Sjeff attr->ah_attr.static_rate = resp.dest.static_rate; 736219820Sjeff attr->ah_attr.is_global = resp.dest.is_global; 737219820Sjeff attr->ah_attr.port_num = resp.dest.port_num; 738219820Sjeff 739219820Sjeff memcpy(attr->alt_ah_attr.grh.dgid.raw, resp.alt_dest.dgid, 16); 740219820Sjeff attr->alt_ah_attr.grh.flow_label = resp.alt_dest.flow_label; 741219820Sjeff attr->alt_ah_attr.dlid = resp.alt_dest.dlid; 742219820Sjeff attr->alt_ah_attr.grh.sgid_index = resp.alt_dest.sgid_index; 743219820Sjeff attr->alt_ah_attr.grh.hop_limit = resp.alt_dest.hop_limit; 744219820Sjeff attr->alt_ah_attr.grh.traffic_class = resp.alt_dest.traffic_class; 745219820Sjeff attr->alt_ah_attr.sl = resp.alt_dest.sl; 746219820Sjeff attr->alt_ah_attr.src_path_bits = resp.alt_dest.src_path_bits; 747219820Sjeff attr->alt_ah_attr.static_rate = resp.alt_dest.static_rate; 748219820Sjeff attr->alt_ah_attr.is_global = resp.alt_dest.is_global; 749219820Sjeff attr->alt_ah_attr.port_num = resp.alt_dest.port_num; 750219820Sjeff 751219820Sjeff init_attr->qp_context = qp->qp_context; 752219820Sjeff init_attr->send_cq = qp->send_cq; 753219820Sjeff init_attr->recv_cq = qp->recv_cq; 754219820Sjeff init_attr->srq = qp->srq; 755219820Sjeff init_attr->qp_type = qp->qp_type; 756219820Sjeff if (qp->qp_type == IBV_QPT_XRC) 757219820Sjeff init_attr->xrc_domain = qp->xrc_domain; 758219820Sjeff init_attr->cap.max_send_wr = resp.max_send_wr; 759219820Sjeff init_attr->cap.max_recv_wr = resp.max_recv_wr; 760219820Sjeff init_attr->cap.max_send_sge = resp.max_send_sge; 761219820Sjeff init_attr->cap.max_recv_sge = resp.max_recv_sge; 762219820Sjeff init_attr->cap.max_inline_data = resp.max_inline_data; 763219820Sjeff init_attr->sq_sig_all = resp.sq_sig_all; 764219820Sjeff 765219820Sjeff return 0; 766219820Sjeff} 767219820Sjeff 768219820Sjeffint ibv_cmd_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr, 769219820Sjeff int attr_mask, 770219820Sjeff struct ibv_modify_qp *cmd, size_t cmd_size) 771219820Sjeff{ 772219820Sjeff IBV_INIT_CMD(cmd, cmd_size, MODIFY_QP); 773219820Sjeff 774219820Sjeff cmd->qp_handle = qp->handle; 775219820Sjeff cmd->attr_mask = attr_mask; 776219820Sjeff cmd->qkey = attr->qkey; 777219820Sjeff cmd->rq_psn = attr->rq_psn; 778219820Sjeff cmd->sq_psn = attr->sq_psn; 779219820Sjeff cmd->dest_qp_num = attr->dest_qp_num; 780219820Sjeff cmd->qp_access_flags = attr->qp_access_flags; 781219820Sjeff cmd->pkey_index = attr->pkey_index; 782219820Sjeff cmd->alt_pkey_index = attr->alt_pkey_index; 783219820Sjeff cmd->qp_state = attr->qp_state; 784219820Sjeff cmd->cur_qp_state = attr->cur_qp_state; 785219820Sjeff cmd->path_mtu = attr->path_mtu; 786219820Sjeff cmd->path_mig_state = attr->path_mig_state; 787219820Sjeff cmd->en_sqd_async_notify = attr->en_sqd_async_notify; 788219820Sjeff cmd->max_rd_atomic = attr->max_rd_atomic; 789219820Sjeff cmd->max_dest_rd_atomic = attr->max_dest_rd_atomic; 790219820Sjeff cmd->min_rnr_timer = attr->min_rnr_timer; 791219820Sjeff cmd->port_num = attr->port_num; 792219820Sjeff cmd->timeout = attr->timeout; 793219820Sjeff cmd->retry_cnt = attr->retry_cnt; 794219820Sjeff cmd->rnr_retry = attr->rnr_retry; 795219820Sjeff cmd->alt_port_num = attr->alt_port_num; 796219820Sjeff cmd->alt_timeout = attr->alt_timeout; 797219820Sjeff 798219820Sjeff memcpy(cmd->dest.dgid, attr->ah_attr.grh.dgid.raw, 16); 799219820Sjeff cmd->dest.flow_label = attr->ah_attr.grh.flow_label; 800219820Sjeff cmd->dest.dlid = attr->ah_attr.dlid; 801219820Sjeff cmd->dest.reserved = 0; 802219820Sjeff cmd->dest.sgid_index = attr->ah_attr.grh.sgid_index; 803219820Sjeff cmd->dest.hop_limit = attr->ah_attr.grh.hop_limit; 804219820Sjeff cmd->dest.traffic_class = attr->ah_attr.grh.traffic_class; 805219820Sjeff cmd->dest.sl = attr->ah_attr.sl; 806219820Sjeff cmd->dest.src_path_bits = attr->ah_attr.src_path_bits; 807219820Sjeff cmd->dest.static_rate = attr->ah_attr.static_rate; 808219820Sjeff cmd->dest.is_global = attr->ah_attr.is_global; 809219820Sjeff cmd->dest.port_num = attr->ah_attr.port_num; 810219820Sjeff 811219820Sjeff memcpy(cmd->alt_dest.dgid, attr->alt_ah_attr.grh.dgid.raw, 16); 812219820Sjeff cmd->alt_dest.flow_label = attr->alt_ah_attr.grh.flow_label; 813219820Sjeff cmd->alt_dest.dlid = attr->alt_ah_attr.dlid; 814219820Sjeff cmd->alt_dest.reserved = 0; 815219820Sjeff cmd->alt_dest.sgid_index = attr->alt_ah_attr.grh.sgid_index; 816219820Sjeff cmd->alt_dest.hop_limit = attr->alt_ah_attr.grh.hop_limit; 817219820Sjeff cmd->alt_dest.traffic_class = attr->alt_ah_attr.grh.traffic_class; 818219820Sjeff cmd->alt_dest.sl = attr->alt_ah_attr.sl; 819219820Sjeff cmd->alt_dest.src_path_bits = attr->alt_ah_attr.src_path_bits; 820219820Sjeff cmd->alt_dest.static_rate = attr->alt_ah_attr.static_rate; 821219820Sjeff cmd->alt_dest.is_global = attr->alt_ah_attr.is_global; 822219820Sjeff cmd->alt_dest.port_num = attr->alt_ah_attr.port_num; 823219820Sjeff 824219820Sjeff cmd->reserved[0] = cmd->reserved[1] = 0; 825219820Sjeff 826219820Sjeff if (write(qp->context->cmd_fd, cmd, cmd_size) != cmd_size) 827219820Sjeff return errno; 828219820Sjeff 829219820Sjeff return 0; 830219820Sjeff} 831219820Sjeff 832219820Sjeffint ibv_cmd_create_xrc_rcv_qp(struct ibv_qp_init_attr *init_attr, 833219820Sjeff uint32_t *xrc_rcv_qpn) 834219820Sjeff{ 835219820Sjeff struct ibv_create_xrc_rcv_qp cmd; 836219820Sjeff struct ibv_create_xrc_rcv_qp_resp resp; 837219820Sjeff 838219820Sjeff if (abi_ver < 6) 839219820Sjeff return ENOSYS; 840219820Sjeff 841219820Sjeff IBV_INIT_CMD_RESP(&cmd, sizeof cmd, CREATE_XRC_RCV_QP, &resp, 842219820Sjeff sizeof resp); 843219820Sjeff 844219820Sjeff cmd.xrc_domain_handle = init_attr->xrc_domain->handle; 845219820Sjeff cmd.max_send_wr = init_attr->cap.max_send_wr; 846219820Sjeff cmd.max_recv_wr = init_attr->cap.max_recv_wr; 847219820Sjeff cmd.max_send_sge = init_attr->cap.max_send_sge; 848219820Sjeff cmd.max_recv_sge = init_attr->cap.max_recv_sge; 849219820Sjeff cmd.max_inline_data = init_attr->cap.max_inline_data; 850219820Sjeff cmd.sq_sig_all = init_attr->sq_sig_all; 851219820Sjeff cmd.qp_type = init_attr->qp_type; 852219820Sjeff cmd.reserved[0] = cmd.reserved[1] = 0; 853219820Sjeff 854219820Sjeff if (write(init_attr->xrc_domain->context->cmd_fd, &cmd, sizeof cmd) != 855219820Sjeff sizeof cmd) 856219820Sjeff return errno; 857219820Sjeff 858219820Sjeff *xrc_rcv_qpn = resp.qpn; 859219820Sjeff 860219820Sjeff return 0; 861219820Sjeff} 862219820Sjeff 863219820Sjeffint ibv_cmd_modify_xrc_rcv_qp(struct ibv_xrc_domain *d, uint32_t xrc_qp_num, 864219820Sjeff struct ibv_qp_attr *attr, int attr_mask) 865219820Sjeff{ 866219820Sjeff struct ibv_modify_xrc_rcv_qp cmd; 867219820Sjeff 868219820Sjeff if (abi_ver < 6) 869219820Sjeff return ENOSYS; 870219820Sjeff 871219820Sjeff IBV_INIT_CMD(&cmd, sizeof cmd, MODIFY_XRC_RCV_QP); 872219820Sjeff 873219820Sjeff cmd.xrc_domain_handle = d->handle; 874219820Sjeff cmd.qp_num = xrc_qp_num; 875219820Sjeff cmd.attr_mask = attr_mask; 876219820Sjeff cmd.qkey = attr->qkey; 877219820Sjeff cmd.rq_psn = attr->rq_psn; 878219820Sjeff cmd.sq_psn = attr->sq_psn; 879219820Sjeff cmd.dest_qp_num = attr->dest_qp_num; 880219820Sjeff cmd.qp_access_flags = attr->qp_access_flags; 881219820Sjeff cmd.pkey_index = attr->pkey_index; 882219820Sjeff cmd.alt_pkey_index = attr->alt_pkey_index; 883219820Sjeff cmd.qp_state = attr->qp_state; 884219820Sjeff cmd.cur_qp_state = attr->cur_qp_state; 885219820Sjeff cmd.path_mtu = attr->path_mtu; 886219820Sjeff cmd.path_mig_state = attr->path_mig_state; 887219820Sjeff cmd.en_sqd_async_notify = attr->en_sqd_async_notify; 888219820Sjeff cmd.max_rd_atomic = attr->max_rd_atomic; 889219820Sjeff cmd.max_dest_rd_atomic = attr->max_dest_rd_atomic; 890219820Sjeff cmd.min_rnr_timer = attr->min_rnr_timer; 891219820Sjeff cmd.port_num = attr->port_num; 892219820Sjeff cmd.timeout = attr->timeout; 893219820Sjeff cmd.retry_cnt = attr->retry_cnt; 894219820Sjeff cmd.rnr_retry = attr->rnr_retry; 895219820Sjeff cmd.alt_port_num = attr->alt_port_num; 896219820Sjeff cmd.alt_timeout = attr->alt_timeout; 897219820Sjeff 898219820Sjeff memcpy(cmd.dest.dgid, attr->ah_attr.grh.dgid.raw, 16); 899219820Sjeff cmd.dest.flow_label = attr->ah_attr.grh.flow_label; 900219820Sjeff cmd.dest.dlid = attr->ah_attr.dlid; 901219820Sjeff cmd.dest.reserved = 0; 902219820Sjeff cmd.dest.sgid_index = attr->ah_attr.grh.sgid_index; 903219820Sjeff cmd.dest.hop_limit = attr->ah_attr.grh.hop_limit; 904219820Sjeff cmd.dest.traffic_class = attr->ah_attr.grh.traffic_class; 905219820Sjeff cmd.dest.sl = attr->ah_attr.sl; 906219820Sjeff cmd.dest.src_path_bits = attr->ah_attr.src_path_bits; 907219820Sjeff cmd.dest.static_rate = attr->ah_attr.static_rate; 908219820Sjeff cmd.dest.is_global = attr->ah_attr.is_global; 909219820Sjeff cmd.dest.port_num = attr->ah_attr.port_num; 910219820Sjeff 911219820Sjeff memcpy(cmd.alt_dest.dgid, attr->alt_ah_attr.grh.dgid.raw, 16); 912219820Sjeff cmd.alt_dest.flow_label = attr->alt_ah_attr.grh.flow_label; 913219820Sjeff cmd.alt_dest.dlid = attr->alt_ah_attr.dlid; 914219820Sjeff cmd.alt_dest.reserved = 0; 915219820Sjeff cmd.alt_dest.sgid_index = attr->alt_ah_attr.grh.sgid_index; 916219820Sjeff cmd.alt_dest.hop_limit = attr->alt_ah_attr.grh.hop_limit; 917219820Sjeff cmd.alt_dest.traffic_class = attr->alt_ah_attr.grh.traffic_class; 918219820Sjeff cmd.alt_dest.sl = attr->alt_ah_attr.sl; 919219820Sjeff cmd.alt_dest.src_path_bits = attr->alt_ah_attr.src_path_bits; 920219820Sjeff cmd.alt_dest.static_rate = attr->alt_ah_attr.static_rate; 921219820Sjeff cmd.alt_dest.is_global = attr->alt_ah_attr.is_global; 922219820Sjeff cmd.alt_dest.port_num = attr->alt_ah_attr.port_num; 923219820Sjeff 924219820Sjeff cmd.reserved[0] = cmd.reserved[1] = 0; 925219820Sjeff 926219820Sjeff if (write(d->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) 927219820Sjeff return errno; 928219820Sjeff 929219820Sjeff return 0; 930219820Sjeff} 931219820Sjeff 932219820Sjeffint ibv_cmd_query_xrc_rcv_qp(struct ibv_xrc_domain *d, uint32_t xrc_qp_num, 933219820Sjeff struct ibv_qp_attr *attr, int attr_mask, 934219820Sjeff struct ibv_qp_init_attr *init_attr) 935219820Sjeff{ 936219820Sjeff struct ibv_query_xrc_rcv_qp cmd; 937219820Sjeff struct ibv_query_qp_resp resp; 938219820Sjeff 939219820Sjeff if (abi_ver < 6) 940219820Sjeff return ENOSYS; 941219820Sjeff 942219820Sjeff IBV_INIT_CMD_RESP(&cmd, sizeof cmd, QUERY_XRC_RCV_QP, &resp, 943219820Sjeff sizeof resp); 944219820Sjeff cmd.xrc_domain_handle = d->handle; 945219820Sjeff cmd.qp_num = xrc_qp_num; 946219820Sjeff cmd.attr_mask = attr_mask; 947219820Sjeff 948219820Sjeff if (write(d->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) 949219820Sjeff return errno; 950219820Sjeff 951219820Sjeff VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp); 952219820Sjeff 953219820Sjeff attr->qkey = resp.qkey; 954219820Sjeff attr->rq_psn = resp.rq_psn; 955219820Sjeff attr->sq_psn = resp.sq_psn; 956219820Sjeff attr->dest_qp_num = resp.dest_qp_num; 957219820Sjeff attr->qp_access_flags = resp.qp_access_flags; 958219820Sjeff attr->pkey_index = resp.pkey_index; 959219820Sjeff attr->alt_pkey_index = resp.alt_pkey_index; 960219820Sjeff attr->qp_state = resp.qp_state; 961219820Sjeff attr->cur_qp_state = resp.cur_qp_state; 962219820Sjeff attr->path_mtu = resp.path_mtu; 963219820Sjeff attr->path_mig_state = resp.path_mig_state; 964219820Sjeff attr->sq_draining = resp.sq_draining; 965219820Sjeff attr->max_rd_atomic = resp.max_rd_atomic; 966219820Sjeff attr->max_dest_rd_atomic = resp.max_dest_rd_atomic; 967219820Sjeff attr->min_rnr_timer = resp.min_rnr_timer; 968219820Sjeff attr->port_num = resp.port_num; 969219820Sjeff attr->timeout = resp.timeout; 970219820Sjeff attr->retry_cnt = resp.retry_cnt; 971219820Sjeff attr->rnr_retry = resp.rnr_retry; 972219820Sjeff attr->alt_port_num = resp.alt_port_num; 973219820Sjeff attr->alt_timeout = resp.alt_timeout; 974219820Sjeff attr->cap.max_send_wr = resp.max_send_wr; 975219820Sjeff attr->cap.max_recv_wr = resp.max_recv_wr; 976219820Sjeff attr->cap.max_send_sge = resp.max_send_sge; 977219820Sjeff attr->cap.max_recv_sge = resp.max_recv_sge; 978219820Sjeff attr->cap.max_inline_data = resp.max_inline_data; 979219820Sjeff 980219820Sjeff memcpy(attr->ah_attr.grh.dgid.raw, resp.dest.dgid, 16); 981219820Sjeff attr->ah_attr.grh.flow_label = resp.dest.flow_label; 982219820Sjeff attr->ah_attr.dlid = resp.dest.dlid; 983219820Sjeff attr->ah_attr.grh.sgid_index = resp.dest.sgid_index; 984219820Sjeff attr->ah_attr.grh.hop_limit = resp.dest.hop_limit; 985219820Sjeff attr->ah_attr.grh.traffic_class = resp.dest.traffic_class; 986219820Sjeff attr->ah_attr.sl = resp.dest.sl; 987219820Sjeff attr->ah_attr.src_path_bits = resp.dest.src_path_bits; 988219820Sjeff attr->ah_attr.static_rate = resp.dest.static_rate; 989219820Sjeff attr->ah_attr.is_global = resp.dest.is_global; 990219820Sjeff attr->ah_attr.port_num = resp.dest.port_num; 991219820Sjeff 992219820Sjeff memcpy(attr->alt_ah_attr.grh.dgid.raw, resp.alt_dest.dgid, 16); 993219820Sjeff attr->alt_ah_attr.grh.flow_label = resp.alt_dest.flow_label; 994219820Sjeff attr->alt_ah_attr.dlid = resp.alt_dest.dlid; 995219820Sjeff attr->alt_ah_attr.grh.sgid_index = resp.alt_dest.sgid_index; 996219820Sjeff attr->alt_ah_attr.grh.hop_limit = resp.alt_dest.hop_limit; 997219820Sjeff attr->alt_ah_attr.grh.traffic_class = resp.alt_dest.traffic_class; 998219820Sjeff attr->alt_ah_attr.sl = resp.alt_dest.sl; 999219820Sjeff attr->alt_ah_attr.src_path_bits = resp.alt_dest.src_path_bits; 1000219820Sjeff attr->alt_ah_attr.static_rate = resp.alt_dest.static_rate; 1001219820Sjeff attr->alt_ah_attr.is_global = resp.alt_dest.is_global; 1002219820Sjeff attr->alt_ah_attr.port_num = resp.alt_dest.port_num; 1003219820Sjeff 1004219820Sjeff init_attr->cap.max_send_wr = resp.max_send_wr; 1005219820Sjeff init_attr->cap.max_recv_wr = resp.max_recv_wr; 1006219820Sjeff init_attr->cap.max_send_sge = resp.max_send_sge; 1007219820Sjeff init_attr->cap.max_recv_sge = resp.max_recv_sge; 1008219820Sjeff init_attr->cap.max_inline_data = resp.max_inline_data; 1009219820Sjeff init_attr->sq_sig_all = resp.sq_sig_all; 1010219820Sjeff 1011219820Sjeff return 0; 1012219820Sjeff} 1013219820Sjeff 1014219820Sjeffstatic int ibv_cmd_destroy_qp_v1(struct ibv_qp *qp) 1015219820Sjeff{ 1016219820Sjeff struct ibv_destroy_qp_v1 cmd; 1017219820Sjeff 1018219820Sjeff IBV_INIT_CMD(&cmd, sizeof cmd, DESTROY_QP); 1019219820Sjeff cmd.qp_handle = qp->handle; 1020219820Sjeff 1021219820Sjeff if (write(qp->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) 1022219820Sjeff return errno; 1023219820Sjeff 1024219820Sjeff return 0; 1025219820Sjeff} 1026219820Sjeff 1027219820Sjeffint ibv_cmd_post_send(struct ibv_qp *ibqp, struct ibv_send_wr *wr, 1028219820Sjeff struct ibv_send_wr **bad_wr) 1029219820Sjeff{ 1030219820Sjeff struct ibv_post_send *cmd; 1031219820Sjeff struct ibv_post_send_resp resp; 1032219820Sjeff struct ibv_send_wr *i; 1033219820Sjeff struct ibv_kern_send_wr *n, *tmp; 1034219820Sjeff struct ibv_sge *s; 1035219820Sjeff unsigned wr_count = 0; 1036219820Sjeff unsigned sge_count = 0; 1037219820Sjeff int cmd_size; 1038219820Sjeff int ret = 0; 1039219820Sjeff 1040219820Sjeff for (i = wr; i; i = i->next) { 1041219820Sjeff wr_count++; 1042219820Sjeff sge_count += i->num_sge; 1043219820Sjeff } 1044219820Sjeff 1045219820Sjeff cmd_size = sizeof *cmd + wr_count * sizeof *n + sge_count * sizeof *s; 1046219820Sjeff cmd = alloca(cmd_size); 1047219820Sjeff 1048219820Sjeff IBV_INIT_CMD_RESP(cmd, cmd_size, POST_SEND, &resp, sizeof resp); 1049219820Sjeff cmd->qp_handle = ibqp->handle; 1050219820Sjeff cmd->wr_count = wr_count; 1051219820Sjeff cmd->sge_count = sge_count; 1052219820Sjeff cmd->wqe_size = sizeof *n; 1053219820Sjeff 1054219820Sjeff n = (struct ibv_kern_send_wr *) ((void *) cmd + sizeof *cmd); 1055219820Sjeff s = (struct ibv_sge *) (n + wr_count); 1056219820Sjeff 1057219820Sjeff tmp = n; 1058219820Sjeff for (i = wr; i; i = i->next) { 1059219820Sjeff tmp->wr_id = i->wr_id; 1060219820Sjeff tmp->num_sge = i->num_sge; 1061219820Sjeff tmp->opcode = i->opcode; 1062219820Sjeff tmp->send_flags = i->send_flags; 1063219820Sjeff tmp->imm_data = i->imm_data; 1064219820Sjeff if (ibqp->qp_type == IBV_QPT_UD) { 1065219820Sjeff tmp->wr.ud.ah = i->wr.ud.ah->handle; 1066219820Sjeff tmp->wr.ud.remote_qpn = i->wr.ud.remote_qpn; 1067219820Sjeff tmp->wr.ud.remote_qkey = i->wr.ud.remote_qkey; 1068219820Sjeff } else { 1069219820Sjeff switch (i->opcode) { 1070219820Sjeff case IBV_WR_RDMA_WRITE: 1071219820Sjeff case IBV_WR_RDMA_WRITE_WITH_IMM: 1072219820Sjeff case IBV_WR_RDMA_READ: 1073219820Sjeff tmp->wr.rdma.remote_addr = 1074219820Sjeff i->wr.rdma.remote_addr; 1075219820Sjeff tmp->wr.rdma.rkey = i->wr.rdma.rkey; 1076219820Sjeff break; 1077219820Sjeff case IBV_WR_ATOMIC_CMP_AND_SWP: 1078219820Sjeff case IBV_WR_ATOMIC_FETCH_AND_ADD: 1079219820Sjeff tmp->wr.atomic.remote_addr = 1080219820Sjeff i->wr.atomic.remote_addr; 1081219820Sjeff tmp->wr.atomic.compare_add = 1082219820Sjeff i->wr.atomic.compare_add; 1083219820Sjeff tmp->wr.atomic.swap = i->wr.atomic.swap; 1084219820Sjeff tmp->wr.atomic.rkey = i->wr.atomic.rkey; 1085219820Sjeff break; 1086219820Sjeff default: 1087219820Sjeff break; 1088219820Sjeff } 1089219820Sjeff } 1090219820Sjeff 1091219820Sjeff if (tmp->num_sge) { 1092219820Sjeff memcpy(s, i->sg_list, tmp->num_sge * sizeof *s); 1093219820Sjeff s += tmp->num_sge; 1094219820Sjeff } 1095219820Sjeff 1096219820Sjeff tmp++; 1097219820Sjeff } 1098219820Sjeff 1099219820Sjeff resp.bad_wr = 0; 1100219820Sjeff if (write(ibqp->context->cmd_fd, cmd, cmd_size) != cmd_size) 1101219820Sjeff ret = errno; 1102219820Sjeff 1103219820Sjeff VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp); 1104219820Sjeff 1105219820Sjeff wr_count = resp.bad_wr; 1106219820Sjeff if (wr_count) { 1107219820Sjeff i = wr; 1108219820Sjeff while (--wr_count) 1109219820Sjeff i = i->next; 1110219820Sjeff *bad_wr = i; 1111219820Sjeff } else if (ret) 1112219820Sjeff *bad_wr = wr; 1113219820Sjeff 1114219820Sjeff return ret; 1115219820Sjeff} 1116219820Sjeff 1117219820Sjeffint ibv_cmd_post_recv(struct ibv_qp *ibqp, struct ibv_recv_wr *wr, 1118219820Sjeff struct ibv_recv_wr **bad_wr) 1119219820Sjeff{ 1120219820Sjeff struct ibv_post_recv *cmd; 1121219820Sjeff struct ibv_post_recv_resp resp; 1122219820Sjeff struct ibv_recv_wr *i; 1123219820Sjeff struct ibv_kern_recv_wr *n, *tmp; 1124219820Sjeff struct ibv_sge *s; 1125219820Sjeff unsigned wr_count = 0; 1126219820Sjeff unsigned sge_count = 0; 1127219820Sjeff int cmd_size; 1128219820Sjeff int ret = 0; 1129219820Sjeff 1130219820Sjeff for (i = wr; i; i = i->next) { 1131219820Sjeff wr_count++; 1132219820Sjeff sge_count += i->num_sge; 1133219820Sjeff } 1134219820Sjeff 1135219820Sjeff cmd_size = sizeof *cmd + wr_count * sizeof *n + sge_count * sizeof *s; 1136219820Sjeff cmd = alloca(cmd_size); 1137219820Sjeff 1138219820Sjeff IBV_INIT_CMD_RESP(cmd, cmd_size, POST_RECV, &resp, sizeof resp); 1139219820Sjeff cmd->qp_handle = ibqp->handle; 1140219820Sjeff cmd->wr_count = wr_count; 1141219820Sjeff cmd->sge_count = sge_count; 1142219820Sjeff cmd->wqe_size = sizeof *n; 1143219820Sjeff 1144219820Sjeff n = (struct ibv_kern_recv_wr *) ((void *) cmd + sizeof *cmd); 1145219820Sjeff s = (struct ibv_sge *) (n + wr_count); 1146219820Sjeff 1147219820Sjeff tmp = n; 1148219820Sjeff for (i = wr; i; i = i->next) { 1149219820Sjeff tmp->wr_id = i->wr_id; 1150219820Sjeff tmp->num_sge = i->num_sge; 1151219820Sjeff 1152219820Sjeff if (tmp->num_sge) { 1153219820Sjeff memcpy(s, i->sg_list, tmp->num_sge * sizeof *s); 1154219820Sjeff s += tmp->num_sge; 1155219820Sjeff } 1156219820Sjeff 1157219820Sjeff tmp++; 1158219820Sjeff } 1159219820Sjeff 1160219820Sjeff resp.bad_wr = 0; 1161219820Sjeff if (write(ibqp->context->cmd_fd, cmd, cmd_size) != cmd_size) 1162219820Sjeff ret = errno; 1163219820Sjeff 1164219820Sjeff VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp); 1165219820Sjeff 1166219820Sjeff wr_count = resp.bad_wr; 1167219820Sjeff if (wr_count) { 1168219820Sjeff i = wr; 1169219820Sjeff while (--wr_count) 1170219820Sjeff i = i->next; 1171219820Sjeff *bad_wr = i; 1172219820Sjeff } else if (ret) 1173219820Sjeff *bad_wr = wr; 1174219820Sjeff 1175219820Sjeff return ret; 1176219820Sjeff} 1177219820Sjeff 1178219820Sjeffint ibv_cmd_post_srq_recv(struct ibv_srq *srq, struct ibv_recv_wr *wr, 1179219820Sjeff struct ibv_recv_wr **bad_wr) 1180219820Sjeff{ 1181219820Sjeff struct ibv_post_srq_recv *cmd; 1182219820Sjeff struct ibv_post_srq_recv_resp resp; 1183219820Sjeff struct ibv_recv_wr *i; 1184219820Sjeff struct ibv_kern_recv_wr *n, *tmp; 1185219820Sjeff struct ibv_sge *s; 1186219820Sjeff unsigned wr_count = 0; 1187219820Sjeff unsigned sge_count = 0; 1188219820Sjeff int cmd_size; 1189219820Sjeff int ret = 0; 1190219820Sjeff 1191219820Sjeff for (i = wr; i; i = i->next) { 1192219820Sjeff wr_count++; 1193219820Sjeff sge_count += i->num_sge; 1194219820Sjeff } 1195219820Sjeff 1196219820Sjeff cmd_size = sizeof *cmd + wr_count * sizeof *n + sge_count * sizeof *s; 1197219820Sjeff cmd = alloca(cmd_size); 1198219820Sjeff 1199219820Sjeff IBV_INIT_CMD_RESP(cmd, cmd_size, POST_SRQ_RECV, &resp, sizeof resp); 1200219820Sjeff cmd->srq_handle = srq->handle; 1201219820Sjeff cmd->wr_count = wr_count; 1202219820Sjeff cmd->sge_count = sge_count; 1203219820Sjeff cmd->wqe_size = sizeof *n; 1204219820Sjeff 1205219820Sjeff n = (struct ibv_kern_recv_wr *) ((void *) cmd + sizeof *cmd); 1206219820Sjeff s = (struct ibv_sge *) (n + wr_count); 1207219820Sjeff 1208219820Sjeff tmp = n; 1209219820Sjeff for (i = wr; i; i = i->next) { 1210219820Sjeff tmp->wr_id = i->wr_id; 1211219820Sjeff tmp->num_sge = i->num_sge; 1212219820Sjeff 1213219820Sjeff if (tmp->num_sge) { 1214219820Sjeff memcpy(s, i->sg_list, tmp->num_sge * sizeof *s); 1215219820Sjeff s += tmp->num_sge; 1216219820Sjeff } 1217219820Sjeff 1218219820Sjeff tmp++; 1219219820Sjeff } 1220219820Sjeff 1221219820Sjeff resp.bad_wr = 0; 1222219820Sjeff if (write(srq->context->cmd_fd, cmd, cmd_size) != cmd_size) 1223219820Sjeff ret = errno; 1224219820Sjeff 1225219820Sjeff VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp); 1226219820Sjeff 1227219820Sjeff wr_count = resp.bad_wr; 1228219820Sjeff if (wr_count) { 1229219820Sjeff i = wr; 1230219820Sjeff while (--wr_count) 1231219820Sjeff i = i->next; 1232219820Sjeff *bad_wr = i; 1233219820Sjeff } else if (ret) 1234219820Sjeff *bad_wr = wr; 1235219820Sjeff 1236219820Sjeff return ret; 1237219820Sjeff} 1238219820Sjeff 1239219820Sjeffint ibv_cmd_create_ah(struct ibv_pd *pd, struct ibv_ah *ah, 1240219820Sjeff struct ibv_ah_attr *attr) 1241219820Sjeff{ 1242219820Sjeff struct ibv_create_ah cmd; 1243219820Sjeff struct ibv_create_ah_resp resp; 1244219820Sjeff 1245219820Sjeff IBV_INIT_CMD_RESP(&cmd, sizeof cmd, CREATE_AH, &resp, sizeof resp); 1246219820Sjeff cmd.user_handle = (uintptr_t) ah; 1247219820Sjeff cmd.pd_handle = pd->handle; 1248219820Sjeff cmd.attr.dlid = attr->dlid; 1249219820Sjeff cmd.attr.sl = attr->sl; 1250219820Sjeff cmd.attr.src_path_bits = attr->src_path_bits; 1251219820Sjeff cmd.attr.static_rate = attr->static_rate; 1252219820Sjeff cmd.attr.is_global = attr->is_global; 1253219820Sjeff cmd.attr.port_num = attr->port_num; 1254219820Sjeff cmd.attr.grh.flow_label = attr->grh.flow_label; 1255219820Sjeff cmd.attr.grh.sgid_index = attr->grh.sgid_index; 1256219820Sjeff cmd.attr.grh.hop_limit = attr->grh.hop_limit; 1257219820Sjeff cmd.attr.grh.traffic_class = attr->grh.traffic_class; 1258219820Sjeff memcpy(cmd.attr.grh.dgid, attr->grh.dgid.raw, 16); 1259219820Sjeff 1260219820Sjeff if (write(pd->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) 1261219820Sjeff return errno; 1262219820Sjeff 1263219820Sjeff VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp); 1264219820Sjeff 1265219820Sjeff ah->handle = resp.handle; 1266219820Sjeff ah->context = pd->context; 1267219820Sjeff 1268219820Sjeff return 0; 1269219820Sjeff} 1270219820Sjeff 1271219820Sjeffint ibv_cmd_destroy_ah(struct ibv_ah *ah) 1272219820Sjeff{ 1273219820Sjeff struct ibv_destroy_ah cmd; 1274219820Sjeff 1275219820Sjeff IBV_INIT_CMD(&cmd, sizeof cmd, DESTROY_AH); 1276219820Sjeff cmd.ah_handle = ah->handle; 1277219820Sjeff 1278219820Sjeff if (write(ah->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) 1279219820Sjeff return errno; 1280219820Sjeff 1281219820Sjeff return 0; 1282219820Sjeff} 1283219820Sjeff 1284219820Sjeffint ibv_cmd_destroy_qp(struct ibv_qp *qp) 1285219820Sjeff{ 1286219820Sjeff struct ibv_destroy_qp cmd; 1287219820Sjeff struct ibv_destroy_qp_resp resp; 1288219820Sjeff 1289219820Sjeff if (abi_ver == 1) 1290219820Sjeff return ibv_cmd_destroy_qp_v1(qp); 1291219820Sjeff 1292219820Sjeff IBV_INIT_CMD_RESP(&cmd, sizeof cmd, DESTROY_QP, &resp, sizeof resp); 1293219820Sjeff cmd.qp_handle = qp->handle; 1294219820Sjeff cmd.reserved = 0; 1295219820Sjeff 1296219820Sjeff if (write(qp->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) 1297219820Sjeff return errno; 1298219820Sjeff 1299219820Sjeff VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp); 1300219820Sjeff 1301219820Sjeff pthread_mutex_lock(&qp->mutex); 1302219820Sjeff while (qp->events_completed != resp.events_reported) 1303219820Sjeff pthread_cond_wait(&qp->cond, &qp->mutex); 1304219820Sjeff pthread_mutex_unlock(&qp->mutex); 1305219820Sjeff 1306219820Sjeff return 0; 1307219820Sjeff} 1308219820Sjeff 1309219820Sjeffint ibv_cmd_attach_mcast(struct ibv_qp *qp, const union ibv_gid *gid, uint16_t lid) 1310219820Sjeff{ 1311219820Sjeff struct ibv_attach_mcast cmd; 1312219820Sjeff 1313219820Sjeff IBV_INIT_CMD(&cmd, sizeof cmd, ATTACH_MCAST); 1314219820Sjeff memcpy(cmd.gid, gid->raw, sizeof cmd.gid); 1315219820Sjeff cmd.qp_handle = qp->handle; 1316219820Sjeff cmd.mlid = lid; 1317219820Sjeff cmd.reserved = 0; 1318219820Sjeff 1319219820Sjeff if (write(qp->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) 1320219820Sjeff return errno; 1321219820Sjeff 1322219820Sjeff return 0; 1323219820Sjeff} 1324219820Sjeff 1325219820Sjeffint ibv_cmd_detach_mcast(struct ibv_qp *qp, const union ibv_gid *gid, uint16_t lid) 1326219820Sjeff{ 1327219820Sjeff struct ibv_detach_mcast cmd; 1328219820Sjeff 1329219820Sjeff IBV_INIT_CMD(&cmd, sizeof cmd, DETACH_MCAST); 1330219820Sjeff memcpy(cmd.gid, gid->raw, sizeof cmd.gid); 1331219820Sjeff cmd.qp_handle = qp->handle; 1332219820Sjeff cmd.mlid = lid; 1333219820Sjeff cmd.reserved = 0; 1334219820Sjeff 1335219820Sjeff if (write(qp->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) 1336219820Sjeff return errno; 1337219820Sjeff 1338219820Sjeff return 0; 1339219820Sjeff} 1340219820Sjeff 1341219820Sjeffint ibv_cmd_open_xrc_domain(struct ibv_context *context, int fd, int oflag, 1342219820Sjeff struct ibv_xrc_domain *d, 1343219820Sjeff struct ibv_open_xrc_domain_resp *resp, 1344219820Sjeff size_t resp_size) 1345219820Sjeff{ 1346219820Sjeff struct ibv_open_xrc_domain cmd; 1347219820Sjeff 1348219820Sjeff if (abi_ver < 6) 1349219820Sjeff return ENOSYS; 1350219820Sjeff 1351219820Sjeff IBV_INIT_CMD_RESP(&cmd, sizeof cmd, OPEN_XRC_DOMAIN, resp, resp_size); 1352219820Sjeff cmd.fd = fd; 1353219820Sjeff cmd.oflags = oflag; 1354219820Sjeff 1355219820Sjeff if (write(context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) 1356219820Sjeff return errno; 1357219820Sjeff 1358219820Sjeff d->handle = resp->xrcd_handle; 1359219820Sjeff 1360219820Sjeff return 0; 1361219820Sjeff} 1362219820Sjeff 1363219820Sjeffint ibv_cmd_close_xrc_domain(struct ibv_xrc_domain *d) 1364219820Sjeff{ 1365219820Sjeff struct ibv_close_xrc_domain cmd; 1366219820Sjeff 1367219820Sjeff if (abi_ver < 6) 1368219820Sjeff return ENOSYS; 1369219820Sjeff 1370219820Sjeff IBV_INIT_CMD(&cmd, sizeof cmd, CLOSE_XRC_DOMAIN); 1371219820Sjeff cmd.xrcd_handle = d->handle; 1372219820Sjeff 1373219820Sjeff if (write(d->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) 1374219820Sjeff return errno; 1375219820Sjeff return 0; 1376219820Sjeff} 1377219820Sjeff 1378219820Sjeffint ibv_cmd_reg_xrc_rcv_qp(struct ibv_xrc_domain *d, uint32_t xrc_qp_num) 1379219820Sjeff{ 1380219820Sjeff struct ibv_reg_xrc_rcv_qp cmd; 1381219820Sjeff 1382219820Sjeff if (abi_ver < 6) 1383219820Sjeff return ENOSYS; 1384219820Sjeff 1385219820Sjeff IBV_INIT_CMD(&cmd, sizeof cmd, REG_XRC_RCV_QP); 1386219820Sjeff cmd.xrc_domain_handle = d->handle; 1387219820Sjeff cmd.qp_num = xrc_qp_num; 1388219820Sjeff 1389219820Sjeff if (write(d->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) 1390219820Sjeff return errno; 1391219820Sjeff return 0; 1392219820Sjeff} 1393219820Sjeff 1394219820Sjeffint ibv_cmd_unreg_xrc_rcv_qp(struct ibv_xrc_domain *d, uint32_t xrc_qp_num) 1395219820Sjeff{ 1396219820Sjeff struct ibv_unreg_xrc_rcv_qp cmd; 1397219820Sjeff 1398219820Sjeff if (abi_ver < 6) 1399219820Sjeff return ENOSYS; 1400219820Sjeff 1401219820Sjeff IBV_INIT_CMD(&cmd, sizeof cmd, UNREG_XRC_RCV_QP); 1402219820Sjeff cmd.xrc_domain_handle = d->handle; 1403219820Sjeff cmd.qp_num = xrc_qp_num; 1404219820Sjeff 1405219820Sjeff if (write(d->context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) 1406219820Sjeff return errno; 1407219820Sjeff return 0; 1408219820Sjeff} 1409219820Sjeff 1410