2 * Copyright (c) 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved.
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
36 #endif /* HAVE_CONFIG_H */
39 #include <netinet/in.h>
47 int ibv_rate_to_mult(enum ibv_rate rate)
50 case IBV_RATE_2_5_GBPS: return 1;
51 case IBV_RATE_5_GBPS: return 2;
52 case IBV_RATE_10_GBPS: return 4;
53 case IBV_RATE_20_GBPS: return 8;
54 case IBV_RATE_30_GBPS: return 12;
55 case IBV_RATE_40_GBPS: return 16;
56 case IBV_RATE_60_GBPS: return 24;
57 case IBV_RATE_80_GBPS: return 32;
58 case IBV_RATE_120_GBPS: return 48;
63 enum ibv_rate mult_to_ibv_rate(int mult)
66 case 1: return IBV_RATE_2_5_GBPS;
67 case 2: return IBV_RATE_5_GBPS;
68 case 4: return IBV_RATE_10_GBPS;
69 case 8: return IBV_RATE_20_GBPS;
70 case 12: return IBV_RATE_30_GBPS;
71 case 16: return IBV_RATE_40_GBPS;
72 case 24: return IBV_RATE_60_GBPS;
73 case 32: return IBV_RATE_80_GBPS;
74 case 48: return IBV_RATE_120_GBPS;
75 default: return IBV_RATE_MAX;
79 int __ibv_query_device(struct ibv_context *context,
80 struct ibv_device_attr *device_attr)
82 return context->ops.query_device(context, device_attr);
84 default_symver(__ibv_query_device, ibv_query_device);
86 int __ibv_query_port(struct ibv_context *context, uint8_t port_num,
87 struct ibv_port_attr *port_attr)
89 return context->ops.query_port(context, port_num, port_attr);
91 default_symver(__ibv_query_port, ibv_query_port);
93 int __ibv_query_gid(struct ibv_context *context, uint8_t port_num,
94 int index, union ibv_gid *gid)
101 snprintf(name, sizeof name, "ports/%d/gids/%d", port_num, index);
103 if (ibv_read_sysfs_file(context->device->ibdev_path, name,
104 attr, sizeof attr) < 0)
107 for (i = 0; i < 8; ++i) {
108 if (sscanf(attr + i * 5, "%hx", &val) != 1)
110 gid->raw[i * 2 ] = val >> 8;
111 gid->raw[i * 2 + 1] = val & 0xff;
116 default_symver(__ibv_query_gid, ibv_query_gid);
118 int __ibv_query_pkey(struct ibv_context *context, uint8_t port_num,
119 int index, uint16_t *pkey)
125 snprintf(name, sizeof name, "ports/%d/pkeys/%d", port_num, index);
127 if (ibv_read_sysfs_file(context->device->ibdev_path, name,
128 attr, sizeof attr) < 0)
131 if (sscanf(attr, "%hx", &val) != 1)
137 default_symver(__ibv_query_pkey, ibv_query_pkey);
139 struct ibv_pd *__ibv_alloc_pd(struct ibv_context *context)
143 pd = context->ops.alloc_pd(context);
145 pd->context = context;
149 default_symver(__ibv_alloc_pd, ibv_alloc_pd);
151 int __ibv_dealloc_pd(struct ibv_pd *pd)
153 return pd->context->ops.dealloc_pd(pd);
155 default_symver(__ibv_dealloc_pd, ibv_dealloc_pd);
157 struct ibv_mr *__ibv_reg_mr(struct ibv_pd *pd, void *addr,
158 size_t length, int access)
162 if (ibv_dontfork_range(addr, length))
165 mr = pd->context->ops.reg_mr(pd, addr, length, access);
167 mr->context = pd->context;
172 ibv_dofork_range(addr, length);
176 default_symver(__ibv_reg_mr, ibv_reg_mr);
178 int __ibv_dereg_mr(struct ibv_mr *mr)
181 void *addr = mr->addr;
182 size_t length = mr->length;
184 ret = mr->context->ops.dereg_mr(mr);
186 ibv_dofork_range(addr, length);
190 default_symver(__ibv_dereg_mr, ibv_dereg_mr);
192 static struct ibv_comp_channel *ibv_create_comp_channel_v2(struct ibv_context *context)
194 struct ibv_abi_compat_v2 *t = context->abi_compat;
197 if (!pthread_mutex_trylock(&t->in_use))
201 fprintf(stderr, PFX "Warning: kernel's ABI version %d limits capacity.\n"
202 " Only one completion channel can be created per context.\n",
210 struct ibv_comp_channel *ibv_create_comp_channel(struct ibv_context *context)
212 struct ibv_comp_channel *channel;
213 struct ibv_create_comp_channel cmd;
214 struct ibv_create_comp_channel_resp resp;
217 return ibv_create_comp_channel_v2(context);
219 channel = malloc(sizeof *channel);
223 IBV_INIT_CMD_RESP(&cmd, sizeof cmd, CREATE_COMP_CHANNEL, &resp, sizeof resp);
224 if (write(context->cmd_fd, &cmd, sizeof cmd) != sizeof cmd) {
229 VALGRIND_MAKE_MEM_DEFINED(&resp, sizeof resp);
231 channel->context = context;
232 channel->fd = resp.fd;
238 static int ibv_destroy_comp_channel_v2(struct ibv_comp_channel *channel)
240 struct ibv_abi_compat_v2 *t = (struct ibv_abi_compat_v2 *) channel;
241 pthread_mutex_unlock(&t->in_use);
245 int ibv_destroy_comp_channel(struct ibv_comp_channel *channel)
247 struct ibv_context *context;
250 context = channel->context;
251 pthread_mutex_lock(&context->mutex);
253 if (channel->refcnt) {
259 ret = ibv_destroy_comp_channel_v2(channel);
268 pthread_mutex_unlock(&context->mutex);
273 struct ibv_cq *__ibv_create_cq(struct ibv_context *context, int cqe, void *cq_context,
274 struct ibv_comp_channel *channel, int comp_vector)
278 pthread_mutex_lock(&context->mutex);
280 cq = context->ops.create_cq(context, cqe, channel, comp_vector);
283 cq->context = context;
284 cq->channel = channel;
287 cq->cq_context = cq_context;
288 cq->comp_events_completed = 0;
289 cq->async_events_completed = 0;
290 pthread_mutex_init(&cq->mutex, NULL);
291 pthread_cond_init(&cq->cond, NULL);
294 pthread_mutex_unlock(&context->mutex);
298 default_symver(__ibv_create_cq, ibv_create_cq);
300 int __ibv_resize_cq(struct ibv_cq *cq, int cqe)
302 if (!cq->context->ops.resize_cq)
305 return cq->context->ops.resize_cq(cq, cqe);
307 default_symver(__ibv_resize_cq, ibv_resize_cq);
309 int __ibv_destroy_cq(struct ibv_cq *cq)
311 struct ibv_comp_channel *channel = cq->channel;
315 pthread_mutex_lock(&channel->context->mutex);
317 ret = cq->context->ops.destroy_cq(cq);
322 pthread_mutex_unlock(&channel->context->mutex);
327 default_symver(__ibv_destroy_cq, ibv_destroy_cq);
329 int __ibv_get_cq_event(struct ibv_comp_channel *channel,
330 struct ibv_cq **cq, void **cq_context)
332 struct ibv_comp_event ev;
334 if (read(channel->fd, &ev, sizeof ev) != sizeof ev)
337 *cq = (struct ibv_cq *) (uintptr_t) ev.cq_handle;
338 *cq_context = (*cq)->cq_context;
340 if ((*cq)->context->ops.cq_event)
341 (*cq)->context->ops.cq_event(*cq);
345 default_symver(__ibv_get_cq_event, ibv_get_cq_event);
347 void __ibv_ack_cq_events(struct ibv_cq *cq, unsigned int nevents)
349 pthread_mutex_lock(&cq->mutex);
350 cq->comp_events_completed += nevents;
351 pthread_cond_signal(&cq->cond);
352 pthread_mutex_unlock(&cq->mutex);
354 default_symver(__ibv_ack_cq_events, ibv_ack_cq_events);
356 struct ibv_srq *__ibv_create_srq(struct ibv_pd *pd,
357 struct ibv_srq_init_attr *srq_init_attr)
361 if (!pd->context->ops.create_srq)
364 srq = pd->context->ops.create_srq(pd, srq_init_attr);
366 srq->context = pd->context;
367 srq->srq_context = srq_init_attr->srq_context;
369 srq->xrc_domain = NULL;
371 srq->xrc_srq_num = 0;
372 srq->events_completed = 0;
373 pthread_mutex_init(&srq->mutex, NULL);
374 pthread_cond_init(&srq->cond, NULL);
379 default_symver(__ibv_create_srq, ibv_create_srq);
381 struct ibv_srq *ibv_create_xrc_srq(struct ibv_pd *pd,
382 struct ibv_xrc_domain *xrc_domain,
383 struct ibv_cq *xrc_cq,
384 struct ibv_srq_init_attr *srq_init_attr)
388 if (!pd->context->more_ops)
391 srq = pd->context->more_ops->create_xrc_srq(pd, xrc_domain,
392 xrc_cq, srq_init_attr);
394 srq->context = pd->context;
395 srq->srq_context = srq_init_attr->srq_context;
397 srq->xrc_domain = xrc_domain;
398 srq->xrc_cq = xrc_cq;
399 srq->events_completed = 0;
400 pthread_mutex_init(&srq->mutex, NULL);
401 pthread_cond_init(&srq->cond, NULL);
407 int __ibv_modify_srq(struct ibv_srq *srq,
408 struct ibv_srq_attr *srq_attr,
411 return srq->context->ops.modify_srq(srq, srq_attr, srq_attr_mask);
413 default_symver(__ibv_modify_srq, ibv_modify_srq);
415 int __ibv_query_srq(struct ibv_srq *srq, struct ibv_srq_attr *srq_attr)
417 return srq->context->ops.query_srq(srq, srq_attr);
419 default_symver(__ibv_query_srq, ibv_query_srq);
421 int __ibv_destroy_srq(struct ibv_srq *srq)
423 return srq->context->ops.destroy_srq(srq);
425 default_symver(__ibv_destroy_srq, ibv_destroy_srq);
427 struct ibv_qp *__ibv_create_qp(struct ibv_pd *pd,
428 struct ibv_qp_init_attr *qp_init_attr)
430 struct ibv_qp *qp = pd->context->ops.create_qp(pd, qp_init_attr);
433 qp->context = pd->context;
434 qp->qp_context = qp_init_attr->qp_context;
436 qp->send_cq = qp_init_attr->send_cq;
437 qp->recv_cq = qp_init_attr->recv_cq;
438 qp->srq = qp_init_attr->srq;
439 qp->qp_type = qp_init_attr->qp_type;
440 qp->state = IBV_QPS_RESET;
441 qp->events_completed = 0;
442 qp->xrc_domain = qp_init_attr->qp_type == IBV_QPT_XRC ?
443 qp_init_attr->xrc_domain : NULL;
444 pthread_mutex_init(&qp->mutex, NULL);
445 pthread_cond_init(&qp->cond, NULL);
450 default_symver(__ibv_create_qp, ibv_create_qp);
452 int __ibv_query_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr,
454 struct ibv_qp_init_attr *init_attr)
458 ret = qp->context->ops.query_qp(qp, attr, attr_mask, init_attr);
462 if (attr_mask & IBV_QP_STATE)
463 qp->state = attr->qp_state;
467 default_symver(__ibv_query_qp, ibv_query_qp);
469 int __ibv_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr,
474 ret = qp->context->ops.modify_qp(qp, attr, attr_mask);
478 if (attr_mask & IBV_QP_STATE)
479 qp->state = attr->qp_state;
483 default_symver(__ibv_modify_qp, ibv_modify_qp);
485 int __ibv_destroy_qp(struct ibv_qp *qp)
487 return qp->context->ops.destroy_qp(qp);
489 default_symver(__ibv_destroy_qp, ibv_destroy_qp);
491 struct ibv_ah *__ibv_create_ah(struct ibv_pd *pd, struct ibv_ah_attr *attr)
493 struct ibv_ah *ah = pd->context->ops.create_ah(pd, attr);
496 ah->context = pd->context;
502 default_symver(__ibv_create_ah, ibv_create_ah);
504 static int ibv_find_gid_index(struct ibv_context *context, uint8_t port_num,
511 ret = ibv_query_gid(context, port_num, i++, &sgid);
512 } while (!ret && memcmp(&sgid, gid, sizeof *gid));
514 return ret ? ret : i - 1;
517 int ibv_init_ah_from_wc(struct ibv_context *context, uint8_t port_num,
518 struct ibv_wc *wc, struct ibv_grh *grh,
519 struct ibv_ah_attr *ah_attr)
524 memset(ah_attr, 0, sizeof *ah_attr);
525 ah_attr->dlid = wc->slid;
526 ah_attr->sl = wc->sl;
527 ah_attr->src_path_bits = wc->dlid_path_bits;
528 ah_attr->port_num = port_num;
530 if (wc->wc_flags & IBV_WC_GRH) {
531 ah_attr->is_global = 1;
532 ah_attr->grh.dgid = grh->sgid;
534 ret = ibv_find_gid_index(context, port_num, &grh->dgid);
538 ah_attr->grh.sgid_index = (uint8_t) ret;
539 flow_class = ntohl(grh->version_tclass_flow);
540 ah_attr->grh.flow_label = flow_class & 0xFFFFF;
541 ah_attr->grh.hop_limit = grh->hop_limit;
542 ah_attr->grh.traffic_class = (flow_class >> 20) & 0xFF;
547 struct ibv_ah *ibv_create_ah_from_wc(struct ibv_pd *pd, struct ibv_wc *wc,
548 struct ibv_grh *grh, uint8_t port_num)
550 struct ibv_ah_attr ah_attr;
553 ret = ibv_init_ah_from_wc(pd->context, port_num, wc, grh, &ah_attr);
557 return ibv_create_ah(pd, &ah_attr);
560 int __ibv_destroy_ah(struct ibv_ah *ah)
562 return ah->context->ops.destroy_ah(ah);
564 default_symver(__ibv_destroy_ah, ibv_destroy_ah);
566 int __ibv_attach_mcast(struct ibv_qp *qp, const union ibv_gid *gid, uint16_t lid)
568 return qp->context->ops.attach_mcast(qp, gid, lid);
570 default_symver(__ibv_attach_mcast, ibv_attach_mcast);
572 int __ibv_detach_mcast(struct ibv_qp *qp, const union ibv_gid *gid, uint16_t lid)
574 return qp->context->ops.detach_mcast(qp, gid, lid);
576 default_symver(__ibv_detach_mcast, ibv_detach_mcast);
578 struct ibv_xrc_domain *ibv_open_xrc_domain(struct ibv_context *context,
581 struct ibv_xrc_domain *d;
583 if (!context->more_ops)
586 d = context->more_ops->open_xrc_domain(context, fd, oflag);
588 d->context = context;
593 int ibv_close_xrc_domain(struct ibv_xrc_domain *d)
595 if (!d->context->more_ops)
598 return d->context->more_ops->close_xrc_domain(d);
601 int ibv_create_xrc_rcv_qp(struct ibv_qp_init_attr *init_attr,
602 uint32_t *xrc_rcv_qpn)
604 struct ibv_context *c;
605 if (!init_attr || !(init_attr->xrc_domain))
608 c = init_attr->xrc_domain->context;
612 return c->more_ops->create_xrc_rcv_qp(init_attr,
616 int ibv_modify_xrc_rcv_qp(struct ibv_xrc_domain *d,
617 uint32_t xrc_rcv_qpn,
618 struct ibv_qp_attr *attr,
624 if (!d->context->more_ops)
627 return d->context->more_ops->modify_xrc_rcv_qp(d, xrc_rcv_qpn, attr,
631 int ibv_query_xrc_rcv_qp(struct ibv_xrc_domain *d,
632 uint32_t xrc_rcv_qpn,
633 struct ibv_qp_attr *attr,
635 struct ibv_qp_init_attr *init_attr)
640 if (!d->context->more_ops)
643 return d->context->more_ops->query_xrc_rcv_qp(d, xrc_rcv_qpn, attr,
644 attr_mask, init_attr);
647 int ibv_reg_xrc_rcv_qp(struct ibv_xrc_domain *d,
648 uint32_t xrc_rcv_qpn)
650 return d->context->more_ops->reg_xrc_rcv_qp(d, xrc_rcv_qpn);
653 int ibv_unreg_xrc_rcv_qp(struct ibv_xrc_domain *d,
654 uint32_t xrc_rcv_qpn)
656 return d->context->more_ops->unreg_xrc_rcv_qp(d, xrc_rcv_qpn);
660 static uint16_t get_vlan_id(const union ibv_gid *dgid)
662 return dgid->raw[11] << 8 | dgid->raw[12];
665 static void get_ll_mac(const union ibv_gid *gid, uint8_t *mac)
667 memcpy(mac, &gid->raw[8], 3);
668 memcpy(mac + 3, &gid->raw[13], 3);
672 static int is_multicast_gid(const union ibv_gid *gid)
674 return gid->raw[0] == 0xff;
677 static void get_mcast_mac(const union ibv_gid *gid, uint8_t *mac)
683 for (i = 2; i < 6; ++i)
684 mac[i] = gid->raw[i + 10];
687 static int is_link_local_gid(const union ibv_gid *gid)
689 uint32_t hi = *(uint32_t *)(gid->raw);
690 uint32_t lo = *(uint32_t *)(gid->raw + 4);
691 if (hi == htonl(0xfe800000) && lo == 0)
697 static int resolve_gid(const union ibv_gid *dgid, uint8_t *mac, uint8_t *is_mcast)
699 if (is_link_local_gid(dgid)) {
700 get_ll_mac(dgid, mac);
702 } else if (is_multicast_gid(dgid)) {
703 get_mcast_mac(dgid, mac);
711 static int is_tagged_vlan(const union ibv_gid *gid)
715 tag = gid->raw[11] << 8 | gid->raw[12];
720 int __ibv_resolve_eth_gid(const struct ibv_pd *pd, uint8_t port_num,
721 union ibv_gid *dgid, uint8_t sgid_index,
722 uint8_t mac[], uint16_t *vlan, uint8_t *tagged,
729 err = resolve_gid(dgid, mac, is_mcast);
733 err = ibv_query_gid(pd->context, port_num, sgid_index, &sgid);
737 stagged = is_tagged_vlan(&sgid);
739 if (!is_tagged_vlan(dgid) && !is_mcast)
742 svlan = get_vlan_id(&sgid);
743 if (svlan != get_vlan_id(dgid) && !is_mcast)
753 default_symver(__ibv_resolve_eth_gid, ibv_resolve_eth_gid);