[openib-general] [PATCH][2/4] Low-level driver QP API
Roland Dreier
roland at topspin.com
Fri Aug 13 10:49:25 PDT 2004
Index: src/linux-kernel/infiniband/hw/mthca/mthca_dev.h
===================================================================
--- src/linux-kernel/infiniband/hw/mthca/mthca_dev.h (revision 621)
+++ src/linux-kernel/infiniband/hw/mthca/mthca_dev.h (working copy)
@@ -229,7 +229,7 @@
#define MTHCA_GET(dest, source, offset) \
do { \
- void *__p = (void *) (source) + (offset); \
+ void *__p = (char *) (source) + (offset); \
switch (sizeof (dest)) { \
case 1: (dest) = *(u8 *) __p; break; \
case 2: (dest) = be16_to_cpup(__p); break; \
@@ -241,7 +241,8 @@
#define MTHCA_PUT(dest, source, offset) \
do { \
- __typeof__(source) *__p = (void *) (dest) + (offset); \
+ __typeof__(source) *__p = \
+ (__typeof__(source) *) ((char *) (dest) + (offset)); \
switch (sizeof(source)) { \
case 1: *__p = (source); break; \
case 2: *__p = cpu_to_be16(source); break; \
@@ -307,28 +308,29 @@
void mthca_qp_event(struct mthca_dev *dev, u32 qpn,
enum ib_async_event event);
-int mthca_modify_qp(struct ib_qp *qp, struct ib_qp_attribute *attr);
-int mthca_post_send(struct ib_qp *ibqp, struct ib_send_param *param,
- int nreq);
-int mthca_post_receive(struct ib_qp *ibqp, struct ib_receive_param *param,
- int nreq);
+int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ int attr_mask, struct ib_qp_cap *qp_cap);
+int mthca_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
+ struct ib_send_wr **bad_wr);
+int mthca_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
+ struct ib_recv_wr **bad_wr);
int mthca_free_err_wqe(struct mthca_qp *qp, int is_send,
int index, int *dbd, u32 *new_wqe);
int mthca_alloc_qp(struct mthca_dev *dev,
struct mthca_pd *pd,
struct mthca_cq *send_cq,
struct mthca_cq *recv_cq,
- enum ib_transport transport,
- enum ib_wq_signal_policy send_policy,
- enum ib_wq_signal_policy recv_policy,
+ enum ib_qp_type type,
+ enum ib_sig_type send_policy,
+ enum ib_sig_type recv_policy,
struct mthca_qp *qp);
int mthca_alloc_sqp(struct mthca_dev *dev,
struct mthca_pd *pd,
struct mthca_cq *send_cq,
struct mthca_cq *recv_cq,
- enum ib_wq_signal_policy send_policy,
- enum ib_wq_signal_policy recv_policy,
- enum ib_special_qp_type type,
+ enum ib_sig_type send_policy,
+ enum ib_sig_type recv_policy,
+ int qpn,
int port,
struct mthca_sqp *sqp);
void mthca_free_qp(struct mthca_dev *dev, struct mthca_qp *qp);
Index: src/linux-kernel/infiniband/hw/mthca/mthca_provider.c
===================================================================
--- src/linux-kernel/infiniband/hw/mthca/mthca_provider.c (revision 621)
+++ src/linux-kernel/infiniband/hw/mthca/mthca_provider.c (working copy)
@@ -295,87 +295,77 @@
return 0;
}
-static int mthca_qp_create(struct ib_pd *pd,
- struct ib_qp_create_param *param,
- struct ib_qp *ibqp)
+static struct ib_qp *mthca_create_qp(struct ib_pd *pd,
+ struct ib_qp_init_attr *init_attr,
+ struct ib_qp_cap *qp_cap)
{
+ struct mthca_qp *qp;
int err;
- struct mthca_qp *qp = kmalloc(sizeof *qp, GFP_KERNEL);
- if (!qp)
- return -ENOMEM;
- qp->ib_qp = ibqp;
+ switch (init_attr->qp_type) {
+ case IB_QPT_RC:
+ case IB_QPT_UC:
+ case IB_QPT_UD:
+ {
+ qp = kmalloc(sizeof *qp, GFP_KERNEL);
+ if (!qp)
+ return ERR_PTR(-ENOMEM);
- qp->sq.max = param->limit.max_outstanding_send_request;
- qp->rq.max = param->limit.max_outstanding_receive_request;
- qp->sq.max_gs = param->limit.max_send_gather_element;
- qp->rq.max_gs = param->limit.max_receive_scatter_element;
+ qp->sq.max = init_attr->cap.max_send_wr;
+ qp->rq.max = init_attr->cap.max_recv_wr;
+ qp->sq.max_gs = init_attr->cap.max_send_sge;
+ qp->rq.max_gs = init_attr->cap.max_recv_sge;
- err = mthca_alloc_qp(to_mdev(pd->device), (struct mthca_pd *) pd,
- (struct mthca_cq *) param->send_queue,
- (struct mthca_cq *) param->receive_queue,
- param->transport, param->send_policy,
- param->receive_policy, qp);
- if (err) {
- kfree(qp);
- return err;
+ err = mthca_alloc_qp(to_mdev(pd->device), (struct mthca_pd *) pd,
+ (struct mthca_cq *) init_attr->send_cq,
+ (struct mthca_cq *) init_attr->recv_cq,
+ init_attr->qp_type, init_attr->sq_sig_type,
+ init_attr->rq_sig_type, qp);
+ qp->ibqp.qp_num = qp->qpn;
+ break;
}
+ case IB_QPT_SMI:
+ case IB_QPT_GSI:
+ {
+ qp = kmalloc(sizeof (struct mthca_sqp), GFP_KERNEL);
+ if (!qp)
+ return ERR_PTR(-ENOMEM);
- ibqp->private = qp;
- ibqp->qpn = qp->qpn;
+ qp->sq.max = init_attr->cap.max_send_wr;
+ qp->rq.max = init_attr->cap.max_recv_wr;
+ qp->sq.max_gs = init_attr->cap.max_send_sge;
+ qp->rq.max_gs = init_attr->cap.max_recv_sge;
- return 0;
-}
+ qp->ibqp.qp_num = init_attr->qp_type == IB_QPT_SMI ? 0 : 1;
-static int mthca_special_qp_create(struct ib_pd *pd,
- struct ib_qp_create_param *param,
- u8 port,
- enum ib_special_qp_type qp_type,
- struct ib_qp *ibqp)
-{
- struct mthca_qp *qp;
- int err;
+ err = mthca_alloc_sqp(to_mdev(pd->device), (struct mthca_pd *) pd,
+ (struct mthca_cq *) init_attr->send_cq,
+ (struct mthca_cq *) init_attr->recv_cq,
+ init_attr->sq_sig_type, init_attr->rq_sig_type,
+ qp->ibqp.qp_num, init_attr->port_num,
+ (struct mthca_sqp *) qp);
+ break;
+ }
+ default:
+ /* Don't support raw QPs */
+ return ERR_PTR(-ENOSYS);
+ }
- /* Don't support raw QPs */
- if (qp_type != IB_SMI_QP && qp_type != IB_GSI_QP)
- return -ENOSYS;
-
- ibqp->private = kmalloc(sizeof (struct mthca_sqp), GFP_KERNEL);
- if (!ibqp->private)
- return -ENOMEM;
-
- ((struct mthca_qp *) ibqp->private)->ib_qp = ibqp;
-
- if (port < 1 || port > to_mdev(pd->device)->limits.num_ports)
- return -EINVAL;
-
- qp = ibqp->private;
-
- qp->sq.max = param->limit.max_outstanding_send_request;
- qp->rq.max = param->limit.max_outstanding_receive_request;
- qp->sq.max_gs = param->limit.max_send_gather_element;
- qp->rq.max_gs = param->limit.max_receive_scatter_element;
-
- err = mthca_alloc_sqp(to_mdev(pd->device), (struct mthca_pd *) pd,
- (struct mthca_cq *) param->send_queue,
- (struct mthca_cq *) param->receive_queue,
- param->send_policy, param->receive_policy,
- qp_type, port, ibqp->private);
-
if (err) {
- kfree(ibqp->private);
- return err;
+ kfree(qp);
+ return ERR_PTR(err);
}
- ibqp->qpn = qp_type == IB_SMI_QP ? 0 : 1;
+ *qp_cap = init_attr->cap;
+ qp_cap->max_inline_data = 0;
- return 0;
+ return (struct ib_qp *) qp;
}
-static int mthca_qp_destroy(struct ib_qp *qp)
+static int mthca_destroy_qp(struct ib_qp *qp)
{
- mthca_free_qp(to_mdev(qp->device), qp->private);
- kfree(qp->private);
+ mthca_free_qp(to_mdev(qp->device), (struct mthca_qp *) qp);
+ kfree(qp);
return 0;
}
@@ -495,10 +485,10 @@
page_list[n++] = buffer_list[i].addr + ((u64) j << shift);
access =
- (acc & IB_MR_REMOTE_ATOMIC ? MTHCA_MPT_FLAG_ATOMIC : 0) |
- (acc & IB_MR_REMOTE_WRITE ? MTHCA_MPT_FLAG_REMOTE_WRITE : 0) |
- (acc & IB_MR_REMOTE_READ ? MTHCA_MPT_FLAG_REMOTE_READ : 0) |
- (acc & IB_MR_LOCAL_WRITE ? MTHCA_MPT_FLAG_LOCAL_WRITE : 0) |
+ (acc & IB_ACCESS_REMOTE_ATOMIC ? MTHCA_MPT_FLAG_ATOMIC : 0) |
+ (acc & IB_ACCESS_REMOTE_WRITE ? MTHCA_MPT_FLAG_REMOTE_WRITE : 0) |
+ (acc & IB_ACCESS_REMOTE_READ ? MTHCA_MPT_FLAG_REMOTE_READ : 0) |
+ (acc & IB_ACCESS_LOCAL_WRITE ? MTHCA_MPT_FLAG_LOCAL_WRITE : 0) |
MTHCA_MPT_FLAG_LOCAL_READ;
mthca_dbg(to_mdev(pd->device), "Registering memory at %llx (iova %llx) "
@@ -547,12 +537,11 @@
dev->ib_dev.dealloc_pd = mthca_dealloc_pd;
dev->ib_dev.create_ah = mthca_ah_create;
dev->ib_dev.destroy_ah = mthca_ah_destroy;
- dev->ib_dev.qp_create = mthca_qp_create;
- dev->ib_dev.special_qp_create = mthca_special_qp_create;
- dev->ib_dev.qp_modify = mthca_modify_qp;
- dev->ib_dev.qp_destroy = mthca_qp_destroy;
- dev->ib_dev.send_post = mthca_post_send;
- dev->ib_dev.receive_post = mthca_post_receive;
+ dev->ib_dev.create_qp = mthca_create_qp;
+ dev->ib_dev.modify_qp = mthca_modify_qp;
+ dev->ib_dev.destroy_qp = mthca_destroy_qp;
+ dev->ib_dev.post_send = mthca_post_send;
+ dev->ib_dev.post_recv = mthca_post_receive;
dev->ib_dev.create_cq = mthca_create_cq;
dev->ib_dev.destroy_cq = mthca_destroy_cq;
dev->ib_dev.poll_cq = mthca_poll_cq;
Index: src/linux-kernel/infiniband/hw/mthca/mthca_provider.h
===================================================================
--- src/linux-kernel/infiniband/hw/mthca/mthca_provider.h (revision 607)
+++ src/linux-kernel/infiniband/hw/mthca/mthca_provider.h (working copy)
@@ -141,19 +141,16 @@
void *last;
int max_gs;
int wqe_shift;
- enum ib_wq_signal_policy policy;
+ enum ib_sig_type policy;
};
struct mthca_qp {
+ struct ib_qp ibqp;
spinlock_t lock;
atomic_t refcount;
- struct ib_qp *ib_qp;
- int qpn;
+ u32 qpn;
int transport;
- struct mthca_pd *pd;
enum ib_qp_state state;
- u32 cqn_send;
- u32 cqn_recv;
int is_direct;
struct mthca_mr mr;
@@ -172,7 +169,6 @@
struct mthca_sqp {
struct mthca_qp qp;
- int sqpn;
int port;
int pkey_index;
u32 qkey;
Index: src/linux-kernel/infiniband/hw/mthca/mthca_cmd.c
===================================================================
--- src/linux-kernel/infiniband/hw/mthca/mthca_cmd.c (revision 576)
+++ src/linux-kernel/infiniband/hw/mthca/mthca_cmd.c (working copy)
@@ -1240,16 +1240,16 @@
u8 op_mod;
switch (type) {
- case IB_SMI_QP:
+ case IB_QPT_SMI:
op_mod = 0;
break;
- case IB_GSI_QP:
+ case IB_QPT_GSI:
op_mod = 1;
break;
- case IB_RAW_IPV6_QP:
+ case IB_QPT_RAW_IPV6:
op_mod = 2;
break;
- case IB_RAW_ETHERTYPE_QP:
+ case IB_QPT_RAW_ETY:
op_mod = 3;
break;
default:
Index: src/linux-kernel/infiniband/hw/mthca/mthca_mcg.c
===================================================================
--- src/linux-kernel/infiniband/hw/mthca/mthca_mcg.c (revision 621)
+++ src/linux-kernel/infiniband/hw/mthca/mthca_mcg.c (working copy)
@@ -174,7 +174,7 @@
for (i = 0; i < MTHCA_QP_PER_MGM; ++i)
if (!(mgm->qp[i] & cpu_to_be32(1 << 31))) {
- mgm->qp[i] = cpu_to_be32(ibqp->qpn | (1 << 31));
+ mgm->qp[i] = cpu_to_be32(ibqp->qp_num | (1 << 31));
break;
}
@@ -259,14 +259,14 @@
}
for (loc = -1, i = 0; i < MTHCA_QP_PER_MGM; ++i) {
- if (mgm->qp[i] == cpu_to_be32(ibqp->qpn | (1 << 31)))
+ if (mgm->qp[i] == cpu_to_be32(ibqp->qp_num | (1 << 31)))
loc = i;
if (!(mgm->qp[i] & cpu_to_be32(1 << 31)))
break;
}
if (loc == -1) {
- mthca_err(dev, "QP %06x not found in MGM\n", ibqp->qpn);
+ mthca_err(dev, "QP %06x not found in MGM\n", ibqp->qp_num);
err = -EINVAL;
goto out;
}
Index: src/linux-kernel/infiniband/hw/mthca/mthca_qp.c
===================================================================
--- src/linux-kernel/infiniband/hw/mthca/mthca_qp.c (revision 607)
+++ src/linux-kernel/infiniband/hw/mthca/mthca_qp.c (working copy)
@@ -279,7 +279,7 @@
event_record.device = &dev->ib_dev;
event_record.event = event;
- event_record.modifier.qp = qp->ib_qp;
+ event_record.modifier.qp = (struct ib_qp *) qp;
ib_async_event_dispatch(&event_record);
if (atomic_dec_and_test(&qp->refcount))
@@ -289,13 +289,13 @@
static int to_mthca_state(enum ib_qp_state ib_state)
{
switch (ib_state) {
- case IB_QP_STATE_RESET: return MTHCA_QP_STATE_RST;
- case IB_QP_STATE_INIT: return MTHCA_QP_STATE_INIT;
- case IB_QP_STATE_RTR: return MTHCA_QP_STATE_RTR;
- case IB_QP_STATE_RTS: return MTHCA_QP_STATE_RTS;
- case IB_QP_STATE_SQD: return MTHCA_QP_STATE_SQD;
- case IB_QP_STATE_SQE: return MTHCA_QP_STATE_SQE;
- case IB_QP_STATE_ERROR: return MTHCA_QP_STATE_ERR;
+ case IB_QPS_RESET: return MTHCA_QP_STATE_RST;
+ case IB_QPS_INIT: return MTHCA_QP_STATE_INIT;
+ case IB_QPS_RTR: return MTHCA_QP_STATE_RTR;
+ case IB_QPS_RTS: return MTHCA_QP_STATE_RTS;
+ case IB_QPS_SQD: return MTHCA_QP_STATE_SQD;
+ case IB_QPS_SQE: return MTHCA_QP_STATE_SQE;
+ case IB_QPS_ERR: return MTHCA_QP_STATE_ERR;
default: return -1;
}
}
@@ -318,148 +318,140 @@
int trans;
u32 req_param[NUM_TRANS];
u32 opt_param[NUM_TRANS];
-} state_table[IB_QP_STATE_ERROR + 1][IB_QP_STATE_ERROR + 1] = {
- [IB_QP_STATE_RESET] = {
- [IB_QP_STATE_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
- [IB_QP_STATE_ERROR] = { .trans = MTHCA_TRANS_ANY2ERR },
- [IB_QP_STATE_INIT] = {
+} state_table[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = {
+ [IB_QPS_RESET] = {
+ [IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
+ [IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR },
+ [IB_QPS_INIT] = {
.trans = MTHCA_TRANS_RST2INIT,
.req_param = {
- [UD] = (IB_QP_ATTRIBUTE_PKEY_INDEX |
- IB_QP_ATTRIBUTE_PORT |
- IB_QP_ATTRIBUTE_QKEY),
- [RC] = (IB_QP_ATTRIBUTE_PKEY_INDEX |
- IB_QP_ATTRIBUTE_PORT |
- IB_QP_ATTRIBUTE_RDMA_ATOMIC_ENABLE),
- [MLX] = (IB_QP_ATTRIBUTE_PKEY_INDEX |
- IB_QP_ATTRIBUTE_QKEY),
+ [UD] = (IB_QP_PKEY_INDEX |
+ IB_QP_PORT |
+ IB_QP_QKEY),
+ [RC] = (IB_QP_PKEY_INDEX |
+ IB_QP_PORT |
+ IB_QP_ACCESS_FLAGS),
+ [MLX] = (IB_QP_PKEY_INDEX |
+ IB_QP_QKEY),
},
/* bug-for-bug compatibility with VAPI: */
.opt_param = {
- [MLX] = IB_QP_ATTRIBUTE_PORT
+ [MLX] = IB_QP_PORT
}
},
},
- [IB_QP_STATE_INIT] = {
- [IB_QP_STATE_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
- [IB_QP_STATE_ERROR] = { .trans = MTHCA_TRANS_ANY2ERR },
- [IB_QP_STATE_INIT] = {
+ [IB_QPS_INIT] = {
+ [IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
+ [IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR },
+ [IB_QPS_INIT] = {
.trans = MTHCA_TRANS_INIT2INIT,
.opt_param = {
- [UD] = (IB_QP_ATTRIBUTE_PKEY_INDEX |
- IB_QP_ATTRIBUTE_PORT |
- IB_QP_ATTRIBUTE_QKEY),
- [RC] = (IB_QP_ATTRIBUTE_PKEY_INDEX |
- IB_QP_ATTRIBUTE_PORT |
- IB_QP_ATTRIBUTE_RDMA_ATOMIC_ENABLE),
- [MLX] = (IB_QP_ATTRIBUTE_PKEY_INDEX |
- IB_QP_ATTRIBUTE_QKEY),
+ [UD] = (IB_QP_PKEY_INDEX |
+ IB_QP_PORT |
+ IB_QP_QKEY),
+ [RC] = (IB_QP_PKEY_INDEX |
+ IB_QP_PORT |
+ IB_QP_ACCESS_FLAGS),
+ [MLX] = (IB_QP_PKEY_INDEX |
+ IB_QP_QKEY),
}
},
- [IB_QP_STATE_RTR] = {
+ [IB_QPS_RTR] = {
.trans = MTHCA_TRANS_INIT2RTR,
.req_param = {
- [RC] = (IB_QP_ATTRIBUTE_ADDRESS |
- IB_QP_ATTRIBUTE_PATH_MTU |
- IB_QP_ATTRIBUTE_DESTINATION_QPN |
- IB_QP_ATTRIBUTE_RECEIVE_PSN |
- IB_QP_ATTRIBUTE_RESPONDER_RESOURCES |
- IB_QP_ATTRIBUTE_RNR_TIMEOUT),
+ [RC] = (IB_QP_AV |
+ IB_QP_PATH_MTU |
+ IB_QP_DEST_QPN |
+ IB_QP_RQ_PSN |
+ IB_QP_MAX_DEST_RD_ATOMIC |
+ IB_QP_MIN_RNR_TIMER),
},
.opt_param = {
- [UD] = (IB_QP_ATTRIBUTE_PKEY_INDEX |
- IB_QP_ATTRIBUTE_QKEY),
- [RC] = (IB_QP_ATTRIBUTE_ALT_ADDRESS |
- IB_QP_ATTRIBUTE_ALT_PKEY_INDEX |
- IB_QP_ATTRIBUTE_ALT_PORT |
- IB_QP_ATTRIBUTE_ALT_LOCAL_ACK_TIMEOUT |
- IB_QP_ATTRIBUTE_RDMA_ATOMIC_ENABLE |
- IB_QP_ATTRIBUTE_PKEY_INDEX),
- [MLX] = (IB_QP_ATTRIBUTE_PKEY_INDEX |
- IB_QP_ATTRIBUTE_QKEY),
+ [UD] = (IB_QP_PKEY_INDEX |
+ IB_QP_QKEY),
+ [RC] = (IB_QP_ALT_PATH |
+ IB_QP_ACCESS_FLAGS |
+ IB_QP_PKEY_INDEX),
+ [MLX] = (IB_QP_PKEY_INDEX |
+ IB_QP_QKEY),
}
}
},
- [IB_QP_STATE_RTR] = {
- [IB_QP_STATE_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
- [IB_QP_STATE_ERROR] = { .trans = MTHCA_TRANS_ANY2ERR },
- [IB_QP_STATE_RTS] = {
+ [IB_QPS_RTR] = {
+ [IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
+ [IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR },
+ [IB_QPS_RTS] = {
.trans = MTHCA_TRANS_RTR2RTS,
.req_param = {
- [UD] = IB_QP_ATTRIBUTE_SEND_PSN,
- [RC] = (IB_QP_ATTRIBUTE_LOCAL_ACK_TIMEOUT |
- IB_QP_ATTRIBUTE_RETRY_COUNT |
- IB_QP_ATTRIBUTE_RNR_RETRY_COUNT |
- IB_QP_ATTRIBUTE_SEND_PSN |
- IB_QP_ATTRIBUTE_INITIATOR_DEPTH),
- [MLX] = IB_QP_ATTRIBUTE_SEND_PSN,
+ [UD] = IB_QP_SQ_PSN,
+ [RC] = (IB_QP_TIMEOUT |
+ IB_QP_RETRY_CNT |
+ IB_QP_RNR_RETRY |
+ IB_QP_SQ_PSN |
+ IB_QP_MAX_QP_RD_ATOMIC),
+ [MLX] = IB_QP_SQ_PSN,
},
.opt_param = {
- [UD] = IB_QP_ATTRIBUTE_QKEY,
- [RC] = (IB_QP_ATTRIBUTE_ALT_ADDRESS |
- IB_QP_ATTRIBUTE_ALT_PKEY_INDEX |
- IB_QP_ATTRIBUTE_ALT_PORT |
- IB_QP_ATTRIBUTE_ALT_LOCAL_ACK_TIMEOUT |
- IB_QP_ATTRIBUTE_RDMA_ATOMIC_ENABLE |
- IB_QP_ATTRIBUTE_PKEY_INDEX |
- IB_QP_ATTRIBUTE_RNR_TIMEOUT |
- IB_QP_ATTRIBUTE_MIGRATION_STATE),
- [MLX] = IB_QP_ATTRIBUTE_QKEY,
+ [UD] = IB_QP_QKEY,
+ [RC] = (IB_QP_ALT_PATH |
+ IB_QP_ACCESS_FLAGS |
+ IB_QP_PKEY_INDEX |
+ IB_QP_MIN_RNR_TIMER |
+ IB_QP_PATH_MIG_STATE),
+ [MLX] = IB_QP_QKEY,
}
}
},
- [IB_QP_STATE_RTS] = {
- [IB_QP_STATE_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
- [IB_QP_STATE_ERROR] = { .trans = MTHCA_TRANS_ANY2ERR },
- [IB_QP_STATE_RTS] = {
+ [IB_QPS_RTS] = {
+ [IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
+ [IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR },
+ [IB_QPS_RTS] = {
.trans = MTHCA_TRANS_RTS2RTS,
.opt_param = {
- [UD] = IB_QP_ATTRIBUTE_QKEY,
- [RC] = (IB_QP_ATTRIBUTE_RDMA_ATOMIC_ENABLE |
- IB_QP_ATTRIBUTE_ALT_ADDRESS |
- IB_QP_ATTRIBUTE_ALT_PKEY_INDEX |
- IB_QP_ATTRIBUTE_ALT_PORT |
- IB_QP_ATTRIBUTE_ALT_LOCAL_ACK_TIMEOUT |
- IB_QP_ATTRIBUTE_MIGRATION_STATE |
- IB_QP_ATTRIBUTE_RNR_TIMEOUT),
- [MLX] = IB_QP_ATTRIBUTE_QKEY,
+ [UD] = IB_QP_QKEY,
+ [RC] = (IB_QP_ACCESS_FLAGS |
+ IB_QP_ALT_PATH |
+ IB_QP_PATH_MIG_STATE |
+ IB_QP_MIN_RNR_TIMER),
+ [MLX] = IB_QP_QKEY,
}
},
- [IB_QP_STATE_SQD] = {
+ [IB_QPS_SQD] = {
.trans = MTHCA_TRANS_RTS2SQD,
},
},
- [IB_QP_STATE_SQD] = {
- [IB_QP_STATE_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
- [IB_QP_STATE_ERROR] = { .trans = MTHCA_TRANS_ANY2ERR },
- [IB_QP_STATE_RTS] = {
+ [IB_QPS_SQD] = {
+ [IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
+ [IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR },
+ [IB_QPS_RTS] = {
.trans = MTHCA_TRANS_SQD2RTS,
},
- [IB_QP_STATE_SQD] = {
+ [IB_QPS_SQD] = {
.trans = MTHCA_TRANS_SQD2SQD,
}
},
- [IB_QP_STATE_SQE] = {
- [IB_QP_STATE_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
- [IB_QP_STATE_ERROR] = { .trans = MTHCA_TRANS_ANY2ERR },
- [IB_QP_STATE_RTS] = {
+ [IB_QPS_SQE] = {
+ [IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
+ [IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR },
+ [IB_QPS_RTS] = {
.trans = MTHCA_TRANS_SQERR2RTS,
}
},
- [IB_QP_STATE_ERROR] = {
- [IB_QP_STATE_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
- [IB_QP_STATE_ERROR] = { .trans = MTHCA_TRANS_ANY2ERR }
+ [IB_QPS_ERR] = {
+ [IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
+ [IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR }
}
};
-static void store_attrs(struct mthca_sqp *sqp, struct ib_qp_attribute *attr)
+static void store_attrs(struct mthca_sqp *sqp, struct ib_qp_attr *attr,
+ int attr_mask)
{
- if (attr->valid_fields & IB_QP_ATTRIBUTE_PKEY_INDEX)
+ if (attr_mask & IB_QP_PKEY_INDEX)
sqp->pkey_index = attr->pkey_index;
- if (attr->valid_fields & IB_QP_ATTRIBUTE_QKEY)
+ if (attr_mask & IB_QP_QKEY)
sqp->qkey = attr->qkey;
- if (attr->valid_fields & IB_QP_ATTRIBUTE_SEND_PSN)
- sqp->send_psn = attr->send_psn;
+ if (attr_mask & IB_QP_SQ_PSN)
+ sqp->send_psn = attr->sq_psn;
}
static void init_port(struct mthca_dev *dev, int port)
@@ -484,10 +476,11 @@
mthca_warn(dev, "INIT_IB returned status %02x.\n", status);
}
-int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attribute *attr)
+int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
+ int attr_mask, struct ib_qp_cap *qp_cap)
{
struct mthca_dev *dev = to_mdev(ibqp->device);
- struct mthca_qp *qp = ibqp->private;
+ struct mthca_qp *qp = (struct mthca_qp *) ibqp;
enum ib_qp_state cur_state, new_state;
void *mailbox = NULL;
struct mthca_qp_param *qp_param;
@@ -500,10 +493,10 @@
cur_state = qp->state;
spin_unlock_irq(&qp->lock);
- if (attr->valid_fields & IB_QP_ATTRIBUTE_STATE) {
- if (attr->state <= 0 || attr->state > IB_QP_STATE_ERROR)
+ if (attr_mask & IB_QP_STATE) {
+ if (attr->qp_state <= 0 || attr->qp_state > IB_QPS_ERR)
return -EINVAL;
- new_state = attr->state;
+ new_state = attr->qp_state;
} else
new_state = cur_state;
@@ -516,22 +509,21 @@
req_param = state_table[cur_state][new_state].req_param[qp->transport];
opt_param = state_table[cur_state][new_state].opt_param[qp->transport];
- if ((req_param & attr->valid_fields) != req_param) {
+ if ((req_param & attr_mask) != req_param) {
mthca_dbg(dev, "QP transition "
"%d->%d missing req attr 0x%08x\n",
cur_state, new_state,
- req_param & ~attr->valid_fields);
+ req_param & ~attr_mask);
return -EINVAL;
}
- if (attr->valid_fields & ~(req_param | opt_param |
- IB_QP_ATTRIBUTE_STATE)) {
+ if (attr_mask & ~(req_param | opt_param | IB_QP_STATE)) {
mthca_dbg(dev, "QP transition (transport %d) "
"%d->%d has extra attr 0x%08x\n",
qp->transport,
cur_state, new_state,
- attr->valid_fields & ~(req_param | opt_param |
- IB_QP_ATTRIBUTE_STATE));
+ attr_mask & ~(req_param | opt_param |
+ IB_QP_STATE));
return -EINVAL;
}
@@ -545,18 +537,18 @@
qp_context->flags = cpu_to_be32((to_mthca_state(new_state) << 28) |
(to_mthca_st(qp->transport) << 16));
qp_context->flags |= cpu_to_be32(MTHCA_QP_BIT_DE);
- if (!(attr->valid_fields & IB_QP_ATTRIBUTE_MIGRATION_STATE))
+ if (!(attr_mask & IB_QP_PATH_MIG_STATE))
qp_context->flags |= cpu_to_be32(MTHCA_QP_PM_MIGRATED << 11);
else {
qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PM_STATE);
- switch (attr->migration_state) {
- case IB_MIGRATED:
+ switch (attr->path_mig_state) {
+ case IB_MIG_MIGRATED:
qp_context->flags |= cpu_to_be32(MTHCA_QP_PM_MIGRATED << 11);
break;
- case IB_REARM:
+ case IB_MIG_REARM:
qp_context->flags |= cpu_to_be32(MTHCA_QP_PM_REARM << 11);
break;
- case IB_ARMED:
+ case IB_MIG_ARMED:
qp_context->flags |= cpu_to_be32(MTHCA_QP_PM_ARMED << 11);
break;
}
@@ -565,66 +557,68 @@
if (qp->transport == MLX || qp->transport == UD)
qp_context->mtu_msgmax = cpu_to_be32((IB_MTU_2048 << 29) |
(11 << 24));
- else if (attr->valid_fields & IB_QP_ATTRIBUTE_PATH_MTU) {
+ else if (attr_mask & IB_QP_PATH_MTU) {
qp_context->mtu_msgmax = cpu_to_be32((attr->path_mtu << 29) |
(31 << 24));
}
qp_context->usr_page = cpu_to_be32(MTHCA_KAR_PAGE);
qp_context->local_qpn = cpu_to_be32(qp->qpn);
- if (attr->valid_fields & IB_QP_ATTRIBUTE_DESTINATION_QPN) {
- qp_context->remote_qpn = cpu_to_be32(attr->destination_qpn);
+ if (attr_mask & IB_QP_DEST_QPN) {
+ qp_context->remote_qpn = cpu_to_be32(attr->dest_qp_num);
}
if (qp->transport == MLX)
qp_context->pri_path.port_pkey |=
cpu_to_be32(((struct mthca_sqp *) qp)->port << 24);
else {
- if (attr->valid_fields & IB_QP_ATTRIBUTE_PORT) {
+ if (attr_mask & IB_QP_PORT) {
qp_context->pri_path.port_pkey |=
cpu_to_be32(attr->port << 24);
qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PORT_NUM);
}
}
- if (attr->valid_fields & IB_QP_ATTRIBUTE_PKEY_INDEX) {
+ if (attr_mask & IB_QP_PKEY_INDEX) {
qp_context->pri_path.port_pkey |=
cpu_to_be32(attr->pkey_index);
qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PKEY_INDEX);
}
- if (attr->valid_fields & IB_QP_ATTRIBUTE_RNR_RETRY_COUNT) {
- qp_context->pri_path.rnr_retry = attr->rnr_retry_count << 5;
+ if (attr_mask & IB_QP_RNR_RETRY) {
+ qp_context->pri_path.rnr_retry = attr->rnr_retry << 5;
qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RNR_RETRY);
}
- if (attr->valid_fields & IB_QP_ATTRIBUTE_ADDRESS) {
- qp_context->pri_path.g_mylmc = attr->address.source_path_bits & 0x7f;
- qp_context->pri_path.rlid = cpu_to_be16(attr->address.dlid);
- qp_context->pri_path.static_rate = (!!attr->address.static_rate) << 3;
- if (attr->address.use_grh) {
+ if (attr_mask & IB_QP_AV) {
+ qp_context->pri_path.g_mylmc = attr->ah_attr.src_path_bits & 0x7f;
+ qp_context->pri_path.rlid = cpu_to_be16(attr->ah_attr.dlid);
+ qp_context->pri_path.static_rate = (!!attr->ah_attr.static_rate) << 3;
+ if (attr->ah_attr.grh_flag) {
qp_context->pri_path.g_mylmc |= 1 << 7;
- qp_context->pri_path.mgid_index = attr->address.source_gid_index;
- qp_context->pri_path.hop_limit = attr->address.hop_limit;
+ qp_context->pri_path.mgid_index = attr->ah_attr.grh.sgid_index;
+ qp_context->pri_path.hop_limit = attr->ah_attr.grh.hop_limit;
qp_context->pri_path.sl_tclass_flowlabel =
- cpu_to_be32((attr->address.service_level << 28) |
- (attr->address.traffic_class << 20) |
- (attr->address.flow_label));
+ cpu_to_be32((attr->ah_attr.sl << 28) |
+ (attr->ah_attr.grh.traffic_class << 20) |
+ (attr->ah_attr.grh.flow_label));
memcpy(qp_context->pri_path.rgid,
- attr->address.dgid, 16);
+ attr->ah_attr.grh.dgid.raw, 16);
+ } else {
+ qp_context->pri_path.sl_tclass_flowlabel =
+ cpu_to_be32(attr->ah_attr.sl << 28);
}
-
qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PRIMARY_ADDR_PATH);
}
- if (attr->valid_fields & IB_QP_ATTRIBUTE_LOCAL_ACK_TIMEOUT) {
- qp_context->pri_path.ackto = attr->local_ack_timeout;
+ if (attr_mask & IB_QP_TIMEOUT) {
+ qp_context->pri_path.ackto = attr->timeout;
qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_ACK_TIMEOUT);
}
/* XXX alt_path */
/* leave rdd as 0 */
- qp_context->pd = cpu_to_be32(qp->pd->pd_num);
+ qp_context->pd = cpu_to_be32(((struct mthca_pd *) ibqp->pd)->pd_num);
/* leave wqe_base as 0 (we always create an MR based at 0 for WQs) */
qp_context->wqe_lkey = cpu_to_be32(qp->mr.ibmr.lkey);
qp_context->params1 = cpu_to_be32((MTHCA_ACK_REQ_FREQ << 28) |
@@ -632,34 +626,34 @@
MTHCA_QP_BIT_SRE |
MTHCA_QP_BIT_SWE |
MTHCA_QP_BIT_SAE);
- if (qp->sq.policy == IB_WQ_SIGNAL_ALL)
+ if (qp->sq.policy == IB_SIGNAL_ALL_WR)
qp_context->params1 |= cpu_to_be32(MTHCA_QP_BIT_SSC);
- if (attr->valid_fields & IB_QP_ATTRIBUTE_RETRY_COUNT) {
- qp_context->params1 |= cpu_to_be32(attr->retry_count << 16);
+ if (attr_mask & IB_QP_RETRY_CNT) {
+ qp_context->params1 |= cpu_to_be32(attr->retry_cnt << 16);
qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RETRY_COUNT);
}
/* XXX initiator resources */
- if (attr->valid_fields & IB_QP_ATTRIBUTE_SEND_PSN)
- qp_context->next_send_psn = cpu_to_be32(attr->send_psn);
- qp_context->cqn_snd = cpu_to_be32(qp->cqn_send);
+ if (attr_mask & IB_QP_SQ_PSN)
+ qp_context->next_send_psn = cpu_to_be32(attr->sq_psn);
+ qp_context->cqn_snd = cpu_to_be32(((struct mthca_cq *) ibqp->send_cq)->cqn);
/* XXX RDMA/atomic enable, responder resources */
- if (qp->rq.policy == IB_WQ_SIGNAL_ALL)
+ if (qp->rq.policy == IB_SIGNAL_ALL_WR)
qp_context->params2 |= cpu_to_be32(MTHCA_QP_BIT_RSC);
- if (attr->valid_fields & IB_QP_ATTRIBUTE_RNR_TIMEOUT) {
- qp_context->rnr_nextrecvpsn |= cpu_to_be32(attr->rnr_timeout << 24);
+ if (attr_mask & IB_QP_MIN_RNR_TIMER) {
+ qp_context->rnr_nextrecvpsn |= cpu_to_be32(attr->min_rnr_timer << 24);
qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RNR_TIMEOUT);
}
- if (attr->valid_fields & IB_QP_ATTRIBUTE_RECEIVE_PSN)
- qp_context->rnr_nextrecvpsn |= cpu_to_be32(attr->receive_psn);
+ if (attr_mask & IB_QP_RQ_PSN)
+ qp_context->rnr_nextrecvpsn |= cpu_to_be32(attr->rq_psn);
/* XXX ra_buff_indx */
- qp_context->cqn_rcv = cpu_to_be32(qp->cqn_recv);
+ qp_context->cqn_rcv = cpu_to_be32(((struct mthca_cq *) ibqp->recv_cq)->cqn);
- if (attr->valid_fields & IB_QP_ATTRIBUTE_QKEY) {
+ if (attr_mask & IB_QP_QKEY) {
qp_context->qkey = cpu_to_be32(attr->qkey);
qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_Q_KEY);
}
@@ -682,21 +676,21 @@
kfree(mailbox);
if (is_sqp(dev, qp))
- store_attrs((struct mthca_sqp *) qp, attr);
+ store_attrs((struct mthca_sqp *) qp, attr, attr_mask);
/*
* If we are moving QP0 to RTR, bring the IB link up; if we
* are moving QP0 to RESET or ERROR, bring the link back down.
*/
if (is_qp0(dev, qp)) {
- if (cur_state != IB_QP_STATE_RTR &&
- new_state == IB_QP_STATE_RTR)
+ if (cur_state != IB_QPS_RTR &&
+ new_state == IB_QPS_RTR)
init_port(dev, ((struct mthca_sqp *) qp)->port);
- if (cur_state != IB_QP_STATE_RESET &&
- cur_state != IB_QP_STATE_ERROR &&
- (new_state == IB_QP_STATE_RESET ||
- new_state == IB_QP_STATE_ERROR))
+ if (cur_state != IB_QPS_RESET &&
+ cur_state != IB_QPS_ERR &&
+ (new_state == IB_QPS_RESET ||
+ new_state == IB_QPS_ERR))
mthca_CLOSE_IB(dev, ((struct mthca_sqp *) qp)->port, &status);
}
@@ -711,6 +705,7 @@
* queue)
*/
static int mthca_alloc_wqe_buf(struct mthca_dev *dev,
+ struct mthca_pd *pd,
struct mthca_qp *qp)
{
int size;
@@ -809,9 +804,8 @@
}
}
- err = mthca_mr_alloc_phys(dev, qp->pd->pd_num,
- dma_list, shift, npages,
- 0, size,
+ err = mthca_mr_alloc_phys(dev, pd->pd_num, dma_list, shift,
+ npages, 0, size,
MTHCA_MPT_FLAG_LOCAL_WRITE |
MTHCA_MPT_FLAG_LOCAL_READ,
&qp->mr);
@@ -846,18 +840,15 @@
struct mthca_pd *pd,
struct mthca_cq *send_cq,
struct mthca_cq *recv_cq,
- enum ib_wq_signal_policy send_policy,
- enum ib_wq_signal_policy recv_policy,
+ enum ib_sig_type send_policy,
+ enum ib_sig_type recv_policy,
struct mthca_qp *qp)
{
int err;
spin_lock_init(&qp->lock);
atomic_set(&qp->refcount, 1);
- qp->pd = pd;
- qp->cqn_send = send_cq->cqn;
- qp->cqn_recv = recv_cq->cqn;
- qp->state = IB_QP_STATE_RESET;
+ qp->state = IB_QPS_RESET;
qp->sq.policy = send_policy;
qp->rq.policy = recv_policy;
qp->rq.cur = 0;
@@ -869,7 +860,7 @@
qp->rq.last = NULL;
qp->sq.last = NULL;
- err = mthca_alloc_wqe_buf(dev, qp);
+ err = mthca_alloc_wqe_buf(dev, pd, qp);
return err;
}
@@ -877,18 +868,17 @@
struct mthca_pd *pd,
struct mthca_cq *send_cq,
struct mthca_cq *recv_cq,
- enum ib_transport transport,
- enum ib_wq_signal_policy send_policy,
- enum ib_wq_signal_policy recv_policy,
+ enum ib_qp_type type,
+ enum ib_sig_type send_policy,
+ enum ib_sig_type recv_policy,
struct mthca_qp *qp)
{
int err;
- switch (transport) {
- case IB_TRANSPORT_RC: qp->transport = RC; break;
- case IB_TRANSPORT_UC: qp->transport = UC; break;
- case IB_TRANSPORT_RD: qp->transport = RD; break;
- case IB_TRANSPORT_UD: qp->transport = UD; break;
+ switch (type) {
+ case IB_QPT_RC: qp->transport = RC; break;
+ case IB_QPT_UC: qp->transport = UC; break;
+ case IB_QPT_UD: qp->transport = UD; break;
default: return -EINVAL;
}
@@ -915,15 +905,14 @@
struct mthca_pd *pd,
struct mthca_cq *send_cq,
struct mthca_cq *recv_cq,
- enum ib_wq_signal_policy send_policy,
- enum ib_wq_signal_policy recv_policy,
- enum ib_special_qp_type type,
+ enum ib_sig_type send_policy,
+ enum ib_sig_type recv_policy,
+ int qpn,
int port,
struct mthca_sqp *sqp)
{
int err = 0;
- u32 mqpn = (type == IB_SMI_QP ? 0 : 2)
- + dev->qp_table.sqp_start + port - 1;
+ u32 mqpn = qpn * 2 + dev->qp_table.sqp_start + port - 1;
sqp->header_buf_size = sqp->qp.sq.max * MTHCA_UD_HEADER_SIZE;
sqp->header_buf = pci_alloc_consistent(dev->pdev, sqp->header_buf_size,
@@ -941,7 +930,6 @@
if (err)
goto err_out;
- sqp->sqpn = type == IB_SMI_QP ? 0 : 1;
sqp->port = port;
sqp->qp.qpn = mqpn;
sqp->qp.transport = MLX;
@@ -985,9 +973,10 @@
mthca_MODIFY_QP(dev, MTHCA_TRANS_ANY2RST, qp->qpn, 0, NULL, 0, &status);
- mthca_cq_clean(dev, qp->cqn_send, qp->qpn);
- if (qp->cqn_recv != qp->cqn_send)
- mthca_cq_clean(dev, qp->cqn_recv, qp->qpn);
+ mthca_cq_clean(dev, ((struct mthca_cq *) qp->ibqp.send_cq)->cqn, qp->qpn);
+ if (qp->ibqp.send_cq != qp->ibqp.recv_cq)
+ mthca_cq_clean(dev, ((struct mthca_cq *) qp->ibqp.recv_cq)->cqn,
+ qp->qpn);
mthca_free_mr(dev, &qp->mr);
@@ -1010,7 +999,7 @@
kfree(qp->wrid);
if (is_sqp(dev, qp)) {
- atomic_dec(&qp->pd->sqp_count);
+ atomic_dec(&((struct mthca_pd *) &qp->ibqp.pd)->sqp_count);
pci_free_consistent(dev->pdev,
((struct mthca_sqp *) qp)->header_buf_size,
((struct mthca_sqp *) qp)->header_buf,
@@ -1022,19 +1011,19 @@
/* Create UD header for an MLX send and build a data segment for it */
static int build_mlx_header(struct mthca_dev *dev, struct mthca_sqp *sqp,
- int ind, struct ib_send_param *param,
+ int ind, struct ib_send_wr *wr,
struct mthca_mlx_seg *mlx,
struct mthca_data_seg *data)
{
int header_size;
int err;
- err = mthca_read_ah(dev, (struct mthca_ah *) param->dest_address,
+ err = mthca_read_ah(dev, (struct mthca_ah *) wr->wr.ud.ah,
&sqp->ud_header);
if (err)
return err;
mlx->flags &= ~cpu_to_be32(MTHCA_NEXT_SOLICIT | 1);
- mlx->flags |= cpu_to_be32((!sqp->sqpn ? MTHCA_MLX_VL15 : 0) |
+ mlx->flags |= cpu_to_be32((!sqp->qp.ibqp.qp_num ? MTHCA_MLX_VL15 : 0) |
(sqp->ud_header.lrh.destination_lid == 0xffff ?
MTHCA_MLX_SLR : 0) |
(sqp->ud_header.lrh.service_level << 8));
@@ -1045,102 +1034,92 @@
sqp->ud_header.grh_present,
&sqp->ud_header);
- switch (param->op) {
- case IB_OP_SEND:
+ switch (wr->opcode) {
+ case IB_WR_SEND:
sqp->ud_header.bth.opcode = IB_OPCODE_UD_SEND_ONLY;
sqp->ud_header.immediate_present = 0;
break;
- case IB_OP_SEND_IMMEDIATE:
+ case IB_WR_SEND_WITH_IMM:
sqp->ud_header.bth.opcode = IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE;
sqp->ud_header.immediate_present = 1;
- sqp->ud_header.immediate_data = param->immediate_data;
+ sqp->ud_header.immediate_data = wr->imm_data;
break;
default:
return -EINVAL;
}
- sqp->ud_header.lrh.virtual_lane = !sqp->sqpn ? 15 : 0;
+ sqp->ud_header.lrh.virtual_lane = !sqp->qp.ibqp.qp_num ? 15 : 0;
if (sqp->ud_header.lrh.destination_lid == 0xffff)
sqp->ud_header.lrh.source_lid = 0xffff;
- sqp->ud_header.bth.solicited_event = param->solicited_event;
- if (!sqp->sqpn)
+ sqp->ud_header.bth.solicited_event = !!(wr->send_flags & IB_SEND_SOLICITED);
+ if (!sqp->qp.ibqp.qp_num)
ib_cached_pkey_get(&dev->ib_dev, sqp->port,
sqp->pkey_index,
&sqp->ud_header.bth.pkey);
else
ib_cached_pkey_get(&dev->ib_dev, sqp->port,
- param->pkey_index,
+ wr->wr.ud.pkey_index,
&sqp->ud_header.bth.pkey);
- sqp->ud_header.bth.destination_qpn = param->dest_qpn;
+ sqp->ud_header.bth.destination_qpn = wr->wr.ud.remote_qpn;
sqp->ud_header.bth.psn = (sqp->send_psn++) & ((1 << 24) - 1);
- sqp->ud_header.deth.qkey = param->dest_qkey & 0x80000000 ?
- sqp->qkey : param->dest_qkey;
- sqp->ud_header.deth.source_qpn = sqp->sqpn;
+ sqp->ud_header.deth.qkey = wr->wr.ud.remote_qkey & 0x80000000 ?
+ sqp->qkey : wr->wr.ud.remote_qkey;
+ sqp->ud_header.deth.source_qpn = sqp->qp.ibqp.qp_num;
header_size = ib_ud_header_pack(&sqp->ud_header,
sqp->header_buf +
ind * MTHCA_UD_HEADER_SIZE);
data->byte_count = cpu_to_be32(header_size);
- data->lkey = cpu_to_be32(sqp->qp.pd->ntmr.ibmr.lkey);
+ data->lkey = cpu_to_be32(((struct mthca_pd *) sqp->qp.ibqp.pd)->ntmr.ibmr.lkey);
data->addr = cpu_to_be64(sqp->header_dma +
ind * MTHCA_UD_HEADER_SIZE);
return 0;
}
-int mthca_post_send(struct ib_qp *ibqp, struct ib_send_param *param,
- int nreq)
+int mthca_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
+ struct ib_send_wr **bad_wr)
{
struct mthca_dev *dev = to_mdev(ibqp->device);
- struct mthca_qp *qp = ibqp->private;
+ struct mthca_qp *qp = (struct mthca_qp *) ibqp;
+ void *wqe;
+ void *prev_wqe;
unsigned long flags;
int err = 0;
- int i, j;
+ int nreq;
+ int i;
int size;
int size0 = 0;
- u8 op0 = 0;
u32 f0 = 0;
int ind;
- void *wqe;
- void *prev_wqe;
+ u8 op0 = 0;
static const u8 opcode[] = {
- [IB_OP_RECEIVE] = MTHCA_OPCODE_INVALID,
- [IB_OP_SEND] = MTHCA_OPCODE_SEND,
- [IB_OP_SEND_IMMEDIATE] = MTHCA_OPCODE_SEND_IMM,
- [IB_OP_RDMA_WRITE] = MTHCA_OPCODE_RDMA_WRITE,
- [IB_OP_RDMA_WRITE_IMMEDIATE] = MTHCA_OPCODE_RDMA_WRITE_IMM,
- [IB_OP_RDMA_READ] = MTHCA_OPCODE_RDMA_READ,
- [IB_OP_COMPARE_SWAP] = MTHCA_OPCODE_ATOMIC_CS,
- [IB_OP_FETCH_ADD] = MTHCA_OPCODE_ATOMIC_FA,
- [IB_OP_MEMORY_WINDOW_BIND] = MTHCA_OPCODE_BIND_MW
+ [IB_WR_SEND] = MTHCA_OPCODE_SEND,
+ [IB_WR_SEND_WITH_IMM] = MTHCA_OPCODE_SEND_IMM,
+ [IB_WR_RDMA_WRITE] = MTHCA_OPCODE_RDMA_WRITE,
+ [IB_WR_RDMA_WRITE_WITH_IMM] = MTHCA_OPCODE_RDMA_WRITE_IMM,
+ [IB_WR_RDMA_READ] = MTHCA_OPCODE_RDMA_READ,
+ [IB_WR_ATOMIC_CMP_AND_SWP] = MTHCA_OPCODE_ATOMIC_CS,
+ [IB_WR_ATOMIC_FETCH_AND_ADD] = MTHCA_OPCODE_ATOMIC_FA,
};
- if (nreq <= 0)
- return -EINVAL;
-
spin_lock_irqsave(&qp->lock, flags);
/* XXX check that state is OK to post send */
- if (qp->sq.cur + nreq > qp->sq.max) {
- mthca_err(dev, "SQ full (%d posted, %d max, %d nreq)\n",
- qp->sq.cur, qp->sq.max, nreq);
- err = -EINVAL;
- goto out;
- }
-
ind = qp->sq.next;
- /*
- * XXX our semantics are wrong according to the verbs
- * extensions spec: an immediate error with one work request
- * should only cause that and subsequent requests not to be
- * posted, rather than all of the requests to be thrown out.
- */
+ for (nreq = 0; wr; ++nreq, wr = wr->next) {
+ if (qp->sq.cur + nreq >= qp->sq.max) {
+ mthca_err(dev, "SQ full (%d posted, %d max, %d nreq)\n",
+ qp->sq.cur, qp->sq.max, nreq);
+ err = -ENOMEM;
+ *bad_wr = wr;
+ goto out;
+ }
- for (i = 0; i < nreq; ++i) {
wqe = get_send_wqe(qp, ind);
prev_wqe = qp->sq.last;
qp->sq.last = wqe;
@@ -1148,53 +1127,58 @@
((struct mthca_next_seg *) wqe)->nda_op = 0;
((struct mthca_next_seg *) wqe)->ee_nds = 0;
((struct mthca_next_seg *) wqe)->flags =
- cpu_to_be32((param->signaled ? MTHCA_NEXT_CQ_UPDATE : 0) |
- (param->solicited_event ? MTHCA_NEXT_SOLICIT : 0) |
- 1);
- if (param[i].op == IB_OP_SEND_IMMEDIATE ||
- param[i].op == IB_OP_RDMA_WRITE_IMMEDIATE)
+ ((wr->send_flags & IB_SEND_SIGNALED) ?
+ cpu_to_be32(MTHCA_NEXT_CQ_UPDATE) : 0) |
+ ((wr->send_flags & IB_SEND_SOLICITED) ?
+ cpu_to_be32(MTHCA_NEXT_SOLICIT) : 0) |
+ cpu_to_be32(1);
+ if (wr->opcode == IB_WR_SEND_WITH_IMM ||
+ wr->opcode == IB_WR_RDMA_WRITE_WITH_IMM)
((struct mthca_next_seg *) wqe)->flags =
- cpu_to_be32(param->immediate_data);
+ cpu_to_be32(wr->imm_data);
wqe += sizeof (struct mthca_next_seg);
size = sizeof (struct mthca_next_seg) / 16;
if (qp->transport == UD) {
((struct mthca_ud_seg *) wqe)->lkey =
- cpu_to_be32(((struct mthca_ah *) param->dest_address)->key);
+ cpu_to_be32(((struct mthca_ah *) wr->wr.ud.ah)->key);
((struct mthca_ud_seg *) wqe)->av_addr =
- cpu_to_be64(((struct mthca_ah *) param->dest_address)->avdma);
+ cpu_to_be64(((struct mthca_ah *) wr->wr.ud.ah)->avdma);
((struct mthca_ud_seg *) wqe)->dqpn =
- cpu_to_be32(param->dest_qpn);
+ cpu_to_be32(wr->wr.ud.remote_qpn);
((struct mthca_ud_seg *) wqe)->qkey =
- cpu_to_be32(param->dest_qkey);
+ cpu_to_be32(wr->wr.ud.remote_qkey);
wqe += sizeof (struct mthca_ud_seg);
size += sizeof (struct mthca_ud_seg) / 16;
} else if (qp->transport == MLX) {
err = build_mlx_header(dev, (struct mthca_sqp *) qp,
- ind, param + i,
+ ind, wr,
wqe - sizeof (struct mthca_next_seg),
wqe);
- if (err)
+ if (err) {
+ *bad_wr = wr;
goto out;
+ }
wqe += sizeof (struct mthca_data_seg);
size += sizeof (struct mthca_data_seg) / 16;
}
- if (param[i].num_gather_entries > qp->sq.max_gs) {
+ if (wr->num_sge > qp->sq.max_gs) {
mthca_err(dev, "too many gathers\n");
err = -EINVAL;
+ *bad_wr = wr;
goto out;
}
- for (j = 0; j < param[i].num_gather_entries; ++j) {
+ for (i = 0; i < wr->num_sge; ++i) {
((struct mthca_data_seg *) wqe)->byte_count =
- cpu_to_be32(param[i].gather_list[j].length);
+ cpu_to_be32(wr->sg_list[i].length);
((struct mthca_data_seg *) wqe)->lkey =
- cpu_to_be32(param[i].gather_list[j].key);
+ cpu_to_be32(wr->sg_list[i].lkey);
((struct mthca_data_seg *) wqe)->addr =
- cpu_to_be64(param[i].gather_list[j].address);
+ cpu_to_be64(wr->sg_list[i].addr);
wqe += sizeof (struct mthca_data_seg);
size += sizeof (struct mthca_data_seg) / 16;
}
@@ -1208,12 +1192,12 @@
size += sizeof (struct mthca_data_seg) / 16;
}
- qp->wrid[ind + qp->rq.max] = param[i].work_request_id;
+ qp->wrid[ind + qp->rq.max] = wr->wr_id;
- if (param[i].op >= ARRAY_SIZE(opcode) ||
- opcode[param[i].op] == MTHCA_OPCODE_INVALID) {
+ if (wr->opcode >= ARRAY_SIZE(opcode)) {
mthca_err(dev, "opcode invalid\n");
err = -EINVAL;
+ *bad_wr = wr;
goto out;
}
@@ -1221,15 +1205,15 @@
((struct mthca_next_seg *) prev_wqe)->nda_op =
cpu_to_be32(((ind << qp->sq.wqe_shift) +
qp->send_wqe_offset) |
- opcode[param[i].op]);
+ opcode[wr->opcode]);
smp_wmb();
((struct mthca_next_seg *) prev_wqe)->ee_nds =
- cpu_to_be32((i ? 0 : MTHCA_NEXT_DBD) | size);
+ cpu_to_be32((size0 ? 0 : MTHCA_NEXT_DBD) | size);
}
- if (!i) {
+ if (!size0) {
size0 = size;
- op0 = opcode[param[i].op];
+ op0 = opcode[wr->opcode];
}
++ind;
@@ -1237,7 +1221,8 @@
ind -= qp->sq.max;
}
- {
+out:
+ if (nreq) {
u32 doorbell[2];
doorbell[0] = cpu_to_be32(((qp->sq.next << qp->sq.wqe_shift) +
@@ -1254,48 +1239,39 @@
qp->sq.cur += nreq;
qp->sq.next = ind;
- out:
spin_unlock_irqrestore(&qp->lock, flags);
return err;
}
-int mthca_post_receive(struct ib_qp *ibqp, struct ib_receive_param *param,
- int nreq)
+int mthca_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
+ struct ib_recv_wr **bad_wr)
{
struct mthca_dev *dev = to_mdev(ibqp->device);
- struct mthca_qp *qp = ibqp->private;
+ struct mthca_qp *qp = (struct mthca_qp *) ibqp;
unsigned long flags;
int err = 0;
- int i, j;
+ int nreq;
+ int i;
int size;
int size0 = 0;
int ind;
void *wqe;
void *prev_wqe;
- if (nreq <= 0)
- return -EINVAL;
-
spin_lock_irqsave(&qp->lock, flags);
/* XXX check that state is OK to post receive */
- if (qp->rq.cur + nreq > qp->rq.max) {
- mthca_err(dev, "RQ %06x full\n", qp->qpn);
- err = -EINVAL;
- goto out;
- }
-
ind = qp->rq.next;
- /*
- * XXX our semantics are wrong according to the verbs
- * extensions spec: an immediate error with one work request
- * should only cause that and subsequent requests not to be
- * posted, rather than all of the requests to be thrown out.
- */
+ for (nreq = 0; wr; ++nreq, wr = wr->next) {
+ if (qp->rq.cur + nreq >= qp->rq.max) {
+ mthca_err(dev, "RQ %06x full\n", qp->qpn);
+ err = -ENOMEM;
+ *bad_wr = wr;
+ goto out;
+ }
- for (i = 0; i < nreq; ++i) {
wqe = get_recv_wqe(qp, ind);
prev_wqe = qp->rq.last;
qp->rq.last = wqe;
@@ -1304,28 +1280,30 @@
((struct mthca_next_seg *) wqe)->ee_nds =
cpu_to_be32(MTHCA_NEXT_DBD);
((struct mthca_next_seg *) wqe)->flags =
- cpu_to_be32(param->signaled ? MTHCA_NEXT_CQ_UPDATE : 0);
+ (wr->recv_flags & IB_RECV_SIGNALED) ?
+ cpu_to_be32(MTHCA_NEXT_CQ_UPDATE) : 0;
wqe += sizeof (struct mthca_next_seg);
size = sizeof (struct mthca_next_seg) / 16;
- if (param[i].num_scatter_entries > qp->rq.max_gs) {
+ if (wr->num_sge > qp->rq.max_gs) {
err = -EINVAL;
+ *bad_wr = wr;
goto out;
}
- for (j = 0; j < param[i].num_scatter_entries; ++j) {
+ for (i = 0; i < wr->num_sge; ++i) {
((struct mthca_data_seg *) wqe)->byte_count =
- cpu_to_be32(param[i].scatter_list[j].length);
+ cpu_to_be32(wr->sg_list[i].length);
((struct mthca_data_seg *) wqe)->lkey =
- cpu_to_be32(param[i].scatter_list[j].key);
+ cpu_to_be32(wr->sg_list[i].lkey);
((struct mthca_data_seg *) wqe)->addr =
- cpu_to_be64(param[i].scatter_list[j].address);
+ cpu_to_be64(wr->sg_list[i].addr);
wqe += sizeof (struct mthca_data_seg);
size += sizeof (struct mthca_data_seg) / 16;
}
- qp->wrid[ind] = param[i].work_request_id;
+ qp->wrid[ind] = wr->wr_id;
if (prev_wqe) {
((struct mthca_next_seg *) prev_wqe)->nda_op =
@@ -1335,7 +1313,7 @@
cpu_to_be32(MTHCA_NEXT_DBD | size);
}
- if (!i)
+ if (!size0)
size0 = size;
++ind;
@@ -1343,7 +1321,8 @@
ind -= qp->rq.max;
}
- {
+out:
+ if (nreq) {
u32 doorbell[2];
doorbell[0] = cpu_to_be32((qp->rq.next << qp->rq.wqe_shift) | size0);
@@ -1359,7 +1338,6 @@
qp->rq.cur += nreq;
qp->rq.next = ind;
- out:
spin_unlock_irqrestore(&qp->lock, flags);
return err;
}
@@ -1413,7 +1391,7 @@
}
for (i = 0; i < 2; ++i) {
- err = mthca_CONF_SPECIAL_QP(dev, i,
+ err = mthca_CONF_SPECIAL_QP(dev, i ? IB_QPT_GSI : IB_QPT_SMI,
dev->qp_table.sqp_start + i * 2,
&status);
if (err)
More information about the general
mailing list