提交 d844183d 编写于 作者: R Roland Dreier

IB/mthca: Convert to use ib_modify_qp_is_ok()

Use ib_modify_qp_is_ok() in mthca, and delete the big table of
attributes for queue pair state transitions.
Signed-off-by: NRoland Dreier <rolandd@cisco.com>
上级 8a51866f
......@@ -1566,31 +1566,56 @@ int mthca_ARM_SRQ(struct mthca_dev *dev, int srq_num, int limit, u8 *status)
CMD_TIME_CLASS_B, status);
}
int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num,
int is_ee, struct mthca_mailbox *mailbox, u32 optmask,
int mthca_MODIFY_QP(struct mthca_dev *dev, enum ib_qp_state cur,
enum ib_qp_state next, u32 num, int is_ee,
struct mthca_mailbox *mailbox, u32 optmask,
u8 *status)
{
static const u16 op[] = {
[MTHCA_TRANS_RST2INIT] = CMD_RST2INIT_QPEE,
[MTHCA_TRANS_INIT2INIT] = CMD_INIT2INIT_QPEE,
[MTHCA_TRANS_INIT2RTR] = CMD_INIT2RTR_QPEE,
[MTHCA_TRANS_RTR2RTS] = CMD_RTR2RTS_QPEE,
[MTHCA_TRANS_RTS2RTS] = CMD_RTS2RTS_QPEE,
[MTHCA_TRANS_SQERR2RTS] = CMD_SQERR2RTS_QPEE,
[MTHCA_TRANS_ANY2ERR] = CMD_2ERR_QPEE,
[MTHCA_TRANS_RTS2SQD] = CMD_RTS2SQD_QPEE,
[MTHCA_TRANS_SQD2SQD] = CMD_SQD2SQD_QPEE,
[MTHCA_TRANS_SQD2RTS] = CMD_SQD2RTS_QPEE,
[MTHCA_TRANS_ANY2RST] = CMD_ERR2RST_QPEE
static const u16 op[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = {
[IB_QPS_RESET] = {
[IB_QPS_RESET] = CMD_ERR2RST_QPEE,
[IB_QPS_ERR] = CMD_2ERR_QPEE,
[IB_QPS_INIT] = CMD_RST2INIT_QPEE,
},
[IB_QPS_INIT] = {
[IB_QPS_RESET] = CMD_ERR2RST_QPEE,
[IB_QPS_ERR] = CMD_2ERR_QPEE,
[IB_QPS_INIT] = CMD_INIT2INIT_QPEE,
[IB_QPS_RTR] = CMD_INIT2RTR_QPEE,
},
[IB_QPS_RTR] = {
[IB_QPS_RESET] = CMD_ERR2RST_QPEE,
[IB_QPS_ERR] = CMD_2ERR_QPEE,
[IB_QPS_RTS] = CMD_RTR2RTS_QPEE,
},
[IB_QPS_RTS] = {
[IB_QPS_RESET] = CMD_ERR2RST_QPEE,
[IB_QPS_ERR] = CMD_2ERR_QPEE,
[IB_QPS_RTS] = CMD_RTS2RTS_QPEE,
[IB_QPS_SQD] = CMD_RTS2SQD_QPEE,
},
[IB_QPS_SQD] = {
[IB_QPS_RESET] = CMD_ERR2RST_QPEE,
[IB_QPS_ERR] = CMD_2ERR_QPEE,
[IB_QPS_RTS] = CMD_SQD2RTS_QPEE,
[IB_QPS_SQD] = CMD_SQD2SQD_QPEE,
},
[IB_QPS_SQE] = {
[IB_QPS_RESET] = CMD_ERR2RST_QPEE,
[IB_QPS_ERR] = CMD_2ERR_QPEE,
[IB_QPS_RTS] = CMD_SQERR2RTS_QPEE,
},
[IB_QPS_ERR] = {
[IB_QPS_RESET] = CMD_ERR2RST_QPEE,
[IB_QPS_ERR] = CMD_2ERR_QPEE,
}
};
u8 op_mod = 0;
int my_mailbox = 0;
int err;
if (trans < 0 || trans >= ARRAY_SIZE(op))
return -EINVAL;
if (trans == MTHCA_TRANS_ANY2RST) {
if (op[cur][next] == CMD_ERR2RST_QPEE) {
op_mod = 3; /* don't write outbox, any->reset */
/* For debugging */
......@@ -1602,34 +1627,35 @@ int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num,
} else
mailbox = NULL;
}
} else {
if (0) {
err = mthca_cmd_box(dev, 0, mailbox ? mailbox->dma : 0,
(!!is_ee << 24) | num, op_mod,
op[cur][next], CMD_TIME_CLASS_C, status);
if (0 && mailbox) {
int i;
mthca_dbg(dev, "Dumping QP context:\n");
printk(" opt param mask: %08x\n", be32_to_cpup(mailbox->buf));
printk(" %08x\n", be32_to_cpup(mailbox->buf));
for (i = 0; i < 0x100 / 4; ++i) {
if (i % 8 == 0)
printk(" [%02x] ", i * 4);
printk("[%02x] ", i * 4);
printk(" %08x",
be32_to_cpu(((__be32 *) mailbox->buf)[i + 2]));
if ((i + 1) % 8 == 0)
printk("\n");
}
}
}
if (trans == MTHCA_TRANS_ANY2RST) {
err = mthca_cmd_box(dev, 0, mailbox ? mailbox->dma : 0,
(!!is_ee << 24) | num, op_mod,
op[trans], CMD_TIME_CLASS_C, status);
if (0 && mailbox) {
if (my_mailbox)
mthca_free_mailbox(dev, mailbox);
} else {
if (0) {
int i;
mthca_dbg(dev, "Dumping QP context:\n");
printk(" %08x\n", be32_to_cpup(mailbox->buf));
printk(" opt param mask: %08x\n", be32_to_cpup(mailbox->buf));
for (i = 0; i < 0x100 / 4; ++i) {
if (i % 8 == 0)
printk("[%02x] ", i * 4);
printk(" [%02x] ", i * 4);
printk(" %08x",
be32_to_cpu(((__be32 *) mailbox->buf)[i + 2]));
if ((i + 1) % 8 == 0)
......@@ -1637,13 +1663,9 @@ int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num,
}
}
} else
err = mthca_cmd(dev, mailbox->dma,
optmask | (!!is_ee << 24) | num,
op_mod, op[trans], CMD_TIME_CLASS_C, status);
if (my_mailbox)
mthca_free_mailbox(dev, mailbox);
err = mthca_cmd(dev, mailbox->dma, optmask | (!!is_ee << 24) | num,
op_mod, op[cur][next], CMD_TIME_CLASS_C, status);
}
return err;
}
......
......@@ -306,8 +306,9 @@ int mthca_SW2HW_SRQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
int mthca_HW2SW_SRQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
int srq_num, u8 *status);
int mthca_ARM_SRQ(struct mthca_dev *dev, int srq_num, int limit, u8 *status);
int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num,
int is_ee, struct mthca_mailbox *mailbox, u32 optmask,
int mthca_MODIFY_QP(struct mthca_dev *dev, enum ib_qp_state cur,
enum ib_qp_state next, u32 num, int is_ee,
struct mthca_mailbox *mailbox, u32 optmask,
u8 *status);
int mthca_QUERY_QP(struct mthca_dev *dev, u32 num, int is_ee,
struct mthca_mailbox *mailbox, u8 *status);
......
......@@ -286,213 +286,6 @@ static int to_mthca_st(int transport)
}
}
static const struct {
int trans;
u32 req_param[NUM_TRANS];
u32 opt_param[NUM_TRANS];
} 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_PKEY_INDEX |
IB_QP_PORT |
IB_QP_QKEY),
[UC] = (IB_QP_PKEY_INDEX |
IB_QP_PORT |
IB_QP_ACCESS_FLAGS),
[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_PORT
}
},
},
[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_PKEY_INDEX |
IB_QP_PORT |
IB_QP_QKEY),
[UC] = (IB_QP_PKEY_INDEX |
IB_QP_PORT |
IB_QP_ACCESS_FLAGS),
[RC] = (IB_QP_PKEY_INDEX |
IB_QP_PORT |
IB_QP_ACCESS_FLAGS),
[MLX] = (IB_QP_PKEY_INDEX |
IB_QP_QKEY),
}
},
[IB_QPS_RTR] = {
.trans = MTHCA_TRANS_INIT2RTR,
.req_param = {
[UC] = (IB_QP_AV |
IB_QP_PATH_MTU |
IB_QP_DEST_QPN |
IB_QP_RQ_PSN),
[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_PKEY_INDEX |
IB_QP_QKEY),
[UC] = (IB_QP_ALT_PATH |
IB_QP_ACCESS_FLAGS |
IB_QP_PKEY_INDEX),
[RC] = (IB_QP_ALT_PATH |
IB_QP_ACCESS_FLAGS |
IB_QP_PKEY_INDEX),
[MLX] = (IB_QP_PKEY_INDEX |
IB_QP_QKEY),
}
}
},
[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_SQ_PSN,
[UC] = 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_CUR_STATE |
IB_QP_QKEY),
[UC] = (IB_QP_CUR_STATE |
IB_QP_ALT_PATH |
IB_QP_ACCESS_FLAGS |
IB_QP_PATH_MIG_STATE),
[RC] = (IB_QP_CUR_STATE |
IB_QP_ALT_PATH |
IB_QP_ACCESS_FLAGS |
IB_QP_MIN_RNR_TIMER |
IB_QP_PATH_MIG_STATE),
[MLX] = (IB_QP_CUR_STATE |
IB_QP_QKEY),
}
}
},
[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_CUR_STATE |
IB_QP_QKEY),
[UC] = (IB_QP_ACCESS_FLAGS |
IB_QP_ALT_PATH |
IB_QP_PATH_MIG_STATE),
[RC] = (IB_QP_ACCESS_FLAGS |
IB_QP_ALT_PATH |
IB_QP_PATH_MIG_STATE |
IB_QP_MIN_RNR_TIMER),
[MLX] = (IB_QP_CUR_STATE |
IB_QP_QKEY),
}
},
[IB_QPS_SQD] = {
.trans = MTHCA_TRANS_RTS2SQD,
.opt_param = {
[UD] = IB_QP_EN_SQD_ASYNC_NOTIFY,
[UC] = IB_QP_EN_SQD_ASYNC_NOTIFY,
[RC] = IB_QP_EN_SQD_ASYNC_NOTIFY,
[MLX] = IB_QP_EN_SQD_ASYNC_NOTIFY
}
},
},
[IB_QPS_SQD] = {
[IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
[IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR },
[IB_QPS_RTS] = {
.trans = MTHCA_TRANS_SQD2RTS,
.opt_param = {
[UD] = (IB_QP_CUR_STATE |
IB_QP_QKEY),
[UC] = (IB_QP_CUR_STATE |
IB_QP_ALT_PATH |
IB_QP_ACCESS_FLAGS |
IB_QP_PATH_MIG_STATE),
[RC] = (IB_QP_CUR_STATE |
IB_QP_ALT_PATH |
IB_QP_ACCESS_FLAGS |
IB_QP_MIN_RNR_TIMER |
IB_QP_PATH_MIG_STATE),
[MLX] = (IB_QP_CUR_STATE |
IB_QP_QKEY),
}
},
[IB_QPS_SQD] = {
.trans = MTHCA_TRANS_SQD2SQD,
.opt_param = {
[UD] = (IB_QP_PKEY_INDEX |
IB_QP_QKEY),
[UC] = (IB_QP_AV |
IB_QP_CUR_STATE |
IB_QP_ALT_PATH |
IB_QP_ACCESS_FLAGS |
IB_QP_PKEY_INDEX |
IB_QP_PATH_MIG_STATE),
[RC] = (IB_QP_AV |
IB_QP_TIMEOUT |
IB_QP_RETRY_CNT |
IB_QP_RNR_RETRY |
IB_QP_MAX_QP_RD_ATOMIC |
IB_QP_MAX_DEST_RD_ATOMIC |
IB_QP_CUR_STATE |
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_PKEY_INDEX |
IB_QP_QKEY),
}
}
},
[IB_QPS_SQE] = {
[IB_QPS_RESET] = { .trans = MTHCA_TRANS_ANY2RST },
[IB_QPS_ERR] = { .trans = MTHCA_TRANS_ANY2ERR },
[IB_QPS_RTS] = {
.trans = MTHCA_TRANS_SQERR2RTS,
.opt_param = {
[UD] = (IB_QP_CUR_STATE |
IB_QP_QKEY),
[UC] = (IB_QP_CUR_STATE |
IB_QP_ACCESS_FLAGS),
[MLX] = (IB_QP_CUR_STATE |
IB_QP_QKEY),
}
}
},
[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_attr *attr,
int attr_mask)
{
......@@ -582,19 +375,12 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
struct mthca_mailbox *mailbox;
struct mthca_qp_param *qp_param;
struct mthca_qp_context *qp_context;
u32 req_param, opt_param;
u32 sqd_event = 0;
u8 status;
int err;
if (attr_mask & IB_QP_CUR_STATE) {
if (attr->cur_qp_state != IB_QPS_RTR &&
attr->cur_qp_state != IB_QPS_RTS &&
attr->cur_qp_state != IB_QPS_SQD &&
attr->cur_qp_state != IB_QPS_SQE)
return -EINVAL;
else
cur_state = attr->cur_qp_state;
cur_state = attr->cur_qp_state;
} else {
spin_lock_irq(&qp->sq.lock);
spin_lock(&qp->rq.lock);
......@@ -603,37 +389,13 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
spin_unlock_irq(&qp->sq.lock);
}
if (attr_mask & IB_QP_STATE) {
if (attr->qp_state < 0 || attr->qp_state > IB_QPS_ERR)
return -EINVAL;
new_state = attr->qp_state;
} else
new_state = cur_state;
if (state_table[cur_state][new_state].trans == MTHCA_TRANS_INVALID) {
mthca_dbg(dev, "Illegal QP transition "
"%d->%d\n", cur_state, new_state);
return -EINVAL;
}
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_mask) != req_param) {
mthca_dbg(dev, "QP transition "
"%d->%d missing req attr 0x%08x\n",
cur_state, new_state,
req_param & ~attr_mask);
return -EINVAL;
}
new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_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_mask & ~(req_param | opt_param |
IB_QP_STATE));
if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type, attr_mask)) {
mthca_dbg(dev, "Bad QP transition (transport %d) "
"%d->%d with attr 0x%08x\n",
qp->transport, cur_state, new_state,
attr_mask);
return -EINVAL;
}
......@@ -853,11 +615,11 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
attr->en_sqd_async_notify)
sqd_event = 1 << 31;
err = mthca_MODIFY_QP(dev, state_table[cur_state][new_state].trans,
qp->qpn, 0, mailbox, sqd_event, &status);
err = mthca_MODIFY_QP(dev, cur_state, new_state, qp->qpn, 0,
mailbox, sqd_event, &status);
if (status) {
mthca_warn(dev, "modify QP %d returned status %02x.\n",
state_table[cur_state][new_state].trans, status);
mthca_warn(dev, "modify QP %d->%d returned status %02x.\n",
cur_state, new_state, status);
err = -EINVAL;
}
......@@ -1405,7 +1167,8 @@ void mthca_free_qp(struct mthca_dev *dev,
wait_event(qp->wait, !atomic_read(&qp->refcount));
if (qp->state != IB_QPS_RESET)
mthca_MODIFY_QP(dev, MTHCA_TRANS_ANY2RST, qp->qpn, 0, NULL, 0, &status);
mthca_MODIFY_QP(dev, qp->state, IB_QPS_RESET, qp->qpn, 0,
NULL, 0, &status);
/*
* If this is a userspace QP, the buffers, MR, CQs and so on
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册