RDMA/mlx5: Return ECE data after modify QP
After users sets the ECE option, FW will return the agreed/supported bits through an output structures of modify QP stages for regular QPs or through create QP for the DCT. Link: https://lore.kernel.org/r/20200526115440.205922-9-leon@kernel.org Reviewed-by: Mark Zhang <markz@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
This commit is contained in:
parent
5f62a521ff
commit
50aec2c313
|
@ -3708,6 +3708,7 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
|
|||
enum ib_qp_state cur_state,
|
||||
enum ib_qp_state new_state,
|
||||
const struct mlx5_ib_modify_qp *ucmd,
|
||||
struct mlx5_ib_modify_qp_resp *resp,
|
||||
struct ib_udata *udata)
|
||||
{
|
||||
static const u16 optab[MLX5_QP_NUM_STATE][MLX5_QP_NUM_STATE] = {
|
||||
|
@ -3978,10 +3979,15 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
|
|||
|
||||
err = modify_raw_packet_qp(dev, qp, &raw_qp_param, tx_affinity);
|
||||
} else {
|
||||
u32 ece = MLX5_CAP_GEN(dev->mdev, ece_support) ?
|
||||
ucmd->ece_options : 0;
|
||||
if (udata) {
|
||||
/* For the kernel flows, the resp will stay zero */
|
||||
resp->ece_options =
|
||||
MLX5_CAP_GEN(dev->mdev, ece_support) ?
|
||||
ucmd->ece_options : 0;
|
||||
resp->response_length = sizeof(*resp);
|
||||
}
|
||||
err = mlx5_core_qp_modify(dev, op, optpar, qpc, &base->mqp,
|
||||
&ece);
|
||||
&resp->ece_options);
|
||||
}
|
||||
|
||||
if (err)
|
||||
|
@ -4180,6 +4186,7 @@ int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
|
|||
int attr_mask, struct ib_udata *udata)
|
||||
{
|
||||
struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
|
||||
struct mlx5_ib_modify_qp_resp resp = {};
|
||||
struct mlx5_ib_qp *qp = to_mqp(ibqp);
|
||||
struct mlx5_ib_modify_qp ucmd = {};
|
||||
enum ib_qp_type qp_type;
|
||||
|
@ -4292,7 +4299,17 @@ int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
|
|||
}
|
||||
|
||||
err = __mlx5_ib_modify_qp(ibqp, attr, attr_mask, cur_state,
|
||||
new_state, &ucmd, udata);
|
||||
new_state, &ucmd, &resp, udata);
|
||||
|
||||
/* resp.response_length is set in ECE supported flows only */
|
||||
if (!err && resp.response_length &&
|
||||
udata->outlen >= resp.response_length)
|
||||
/*
|
||||
* We don't check return value of the function below
|
||||
* on purpose, because it is unclear how to unwind the
|
||||
* error flow after QP was modified to the new state.
|
||||
*/
|
||||
ib_copy_to_udata(udata, &resp, resp.response_length);
|
||||
|
||||
out:
|
||||
mutex_unlock(&qp->mutex);
|
||||
|
|
|
@ -341,6 +341,27 @@ static void mbox_free(struct mbox_info *mbox)
|
|||
kfree(mbox->out);
|
||||
}
|
||||
|
||||
static int get_ece_from_mbox(void *out, u16 opcode)
|
||||
{
|
||||
int ece = 0;
|
||||
|
||||
switch (opcode) {
|
||||
case MLX5_CMD_OP_INIT2RTR_QP:
|
||||
ece = MLX5_GET(init2rtr_qp_out, out, ece);
|
||||
break;
|
||||
case MLX5_CMD_OP_RTR2RTS_QP:
|
||||
ece = MLX5_GET(rtr2rts_qp_out, out, ece);
|
||||
break;
|
||||
case MLX5_CMD_OP_RTS2RTS_QP:
|
||||
ece = MLX5_GET(rts2rts_qp_out, out, ece);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ece;
|
||||
}
|
||||
|
||||
static int modify_qp_mbox_alloc(struct mlx5_core_dev *dev, u16 opcode, int qpn,
|
||||
u32 opt_param_mask, void *qpc,
|
||||
struct mbox_info *mbox, u16 uid, u32 ece)
|
||||
|
@ -438,6 +459,10 @@ int mlx5_core_qp_modify(struct mlx5_ib_dev *dev, u16 opcode, u32 opt_param_mask,
|
|||
|
||||
err = mlx5_cmd_exec(dev->mdev, mbox.in, mbox.inlen, mbox.out,
|
||||
mbox.outlen);
|
||||
|
||||
if (ece)
|
||||
*ece = get_ece_from_mbox(mbox.out, opcode);
|
||||
|
||||
mbox_free(&mbox);
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -429,6 +429,8 @@ struct mlx5_ib_modify_qp {
|
|||
struct mlx5_ib_modify_qp_resp {
|
||||
__u32 response_length;
|
||||
__u32 dctn;
|
||||
__u32 ece_options;
|
||||
__u32 reserved;
|
||||
};
|
||||
|
||||
struct mlx5_ib_create_wq_resp {
|
||||
|
|
Loading…
Reference in New Issue