blob: c5fa761f7945671cc1e1205ac15dbe18dfe6b558 [file] [log] [blame] [edit]
/*
* Copyright (c) 2006-2009 QLogic Corp. All rights reserved.
* Copyright (c) 2005. PathScale, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Patent licenses, if any, provided herein do not apply to
* combinations of this program with other software, or any other
* product whatsoever.
*/
#ifndef IPATH_H
#define IPATH_H
#include <endian.h>
#include <pthread.h>
#include <stddef.h>
#include <stdatomic.h>
#include <infiniband/driver.h>
#include <infiniband/verbs.h>
#define PFX "ipath: "
struct ipath_device {
struct verbs_device ibv_dev;
int abi_version;
};
struct ipath_context {
struct verbs_context ibv_ctx;
};
/*
* This structure needs to have the same size and offsets as
* the kernel's ib_wc structure since it is memory mapped.
*/
struct ipath_wc {
uint64_t wr_id;
enum ibv_wc_status status;
enum ibv_wc_opcode opcode;
uint32_t vendor_err;
uint32_t byte_len;
uint32_t imm_data; /* in network byte order */
uint32_t qp_num;
uint32_t src_qp;
enum ibv_wc_flags wc_flags;
uint16_t pkey_index;
uint16_t slid;
uint8_t sl;
uint8_t dlid_path_bits;
uint8_t port_num;
};
struct ipath_cq_wc {
_Atomic(uint32_t) head;
_Atomic(uint32_t) tail;
struct ipath_wc queue[1];
};
struct ipath_cq {
struct ibv_cq ibv_cq;
struct ipath_cq_wc *queue;
pthread_spinlock_t lock;
};
/*
* Receive work request queue entry.
* The size of the sg_list is determined when the QP is created and stored
* in qp->r_max_sge.
*/
struct ipath_rwqe {
uint64_t wr_id;
uint8_t num_sge;
uint8_t padding[7];
struct ibv_sge sg_list[0];
};
/*
* This struture is used to contain the head pointer, tail pointer,
* and receive work queue entries as a single memory allocation so
* it can be mmap'ed into user space.
* Note that the wq array elements are variable size so you can't
* just index into the array to get the N'th element;
* use get_rwqe_ptr() instead.
*/
struct ipath_rwq {
_Atomic(uint32_t) head; /* new requests posted to the head. */
_Atomic(uint32_t) tail; /* receives pull requests from here. */
struct ipath_rwqe wq[0];
};
struct ipath_rq {
struct ipath_rwq *rwq;
pthread_spinlock_t lock;
uint32_t size;
uint32_t max_sge;
};
struct ipath_qp {
struct ibv_qp ibv_qp;
struct ipath_rq rq;
};
struct ipath_srq {
struct ibv_srq ibv_srq;
struct ipath_rq rq;
};
#define to_ixxx(xxx, type) container_of(ib##xxx, struct ipath_##type, ibv_##xxx)
static inline struct ipath_context *to_ictx(struct ibv_context *ibctx)
{
return container_of(ibctx, struct ipath_context, ibv_ctx.context);
}
static inline struct ipath_device *to_idev(struct ibv_device *ibdev)
{
return container_of(ibdev, struct ipath_device, ibv_dev.device);
}
static inline struct ipath_cq *to_icq(struct ibv_cq *ibcq)
{
return to_ixxx(cq, cq);
}
static inline struct ipath_qp *to_iqp(struct ibv_qp *ibqp)
{
return to_ixxx(qp, qp);
}
static inline struct ipath_srq *to_isrq(struct ibv_srq *ibsrq)
{
return to_ixxx(srq, srq);
}
/*
* Since struct ipath_rwqe is not a fixed size, we can't simply index into
* struct ipath_rq.wq. This function does the array index computation.
*/
static inline struct ipath_rwqe *get_rwqe_ptr(struct ipath_rq *rq,
unsigned n)
{
return (struct ipath_rwqe *)
((char *) rq->rwq->wq +
(sizeof(struct ipath_rwqe) +
rq->max_sge * sizeof(struct ibv_sge)) * n);
}
int ipath_query_device(struct ibv_context *context,
const struct ibv_query_device_ex_input *input,
struct ibv_device_attr_ex *attr, size_t attr_size);
extern int ipath_query_port(struct ibv_context *context, uint8_t port,
struct ibv_port_attr *attr);
struct ibv_pd *ipath_alloc_pd(struct ibv_context *pd);
int ipath_free_pd(struct ibv_pd *pd);
struct ibv_mr *ipath_reg_mr(struct ibv_pd *pd, void *addr, size_t length,
uint64_t hca_va, int access);
int ipath_dereg_mr(struct verbs_mr *vmr);
struct ibv_cq *ipath_create_cq(struct ibv_context *context, int cqe,
struct ibv_comp_channel *channel,
int comp_vector);
struct ibv_cq *ipath_create_cq_v1(struct ibv_context *context, int cqe,
struct ibv_comp_channel *channel,
int comp_vector);
int ipath_resize_cq(struct ibv_cq *cq, int cqe);
int ipath_resize_cq_v1(struct ibv_cq *cq, int cqe);
int ipath_destroy_cq(struct ibv_cq *cq);
int ipath_destroy_cq_v1(struct ibv_cq *cq);
int ipath_poll_cq(struct ibv_cq *cq, int ne, struct ibv_wc *wc);
struct ibv_qp *ipath_create_qp(struct ibv_pd *pd,
struct ibv_qp_init_attr *attr);
struct ibv_qp *ipath_create_qp_v1(struct ibv_pd *pd,
struct ibv_qp_init_attr *attr);
int ipath_query_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr,
int attr_mask,
struct ibv_qp_init_attr *init_attr);
int ipath_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr,
int attr_mask);
int ipath_destroy_qp(struct ibv_qp *qp);
int ipath_destroy_qp_v1(struct ibv_qp *qp);
int ipath_post_send(struct ibv_qp *ibqp, struct ibv_send_wr *wr,
struct ibv_send_wr **bad_wr);
int ipath_post_recv(struct ibv_qp *ibqp, struct ibv_recv_wr *wr,
struct ibv_recv_wr **bad_wr);
struct ibv_srq *ipath_create_srq(struct ibv_pd *pd,
struct ibv_srq_init_attr *attr);
struct ibv_srq *ipath_create_srq_v1(struct ibv_pd *pd,
struct ibv_srq_init_attr *attr);
int ipath_modify_srq(struct ibv_srq *srq,
struct ibv_srq_attr *attr,
int attr_mask);
int ipath_modify_srq_v1(struct ibv_srq *srq,
struct ibv_srq_attr *attr,
int attr_mask);
int ipath_query_srq(struct ibv_srq *srq, struct ibv_srq_attr *attr);
int ipath_destroy_srq(struct ibv_srq *srq);
int ipath_destroy_srq_v1(struct ibv_srq *srq);
int ipath_post_srq_recv(struct ibv_srq *srq, struct ibv_recv_wr *wr,
struct ibv_recv_wr **bad_wr);
struct ibv_ah *ipath_create_ah(struct ibv_pd *pd, struct ibv_ah_attr *attr);
int ipath_destroy_ah(struct ibv_ah *ah);
#endif /* IPATH_H */