Commit 50aec2c3 authored by Leon Romanovsky's avatar Leon Romanovsky Committed by Jason Gunthorpe
Browse files

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: default avatarMark Zhang <markz@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leonro@mellanox.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent 5f62a521
Loading
Loading
Loading
Loading
+21 −4
Original line number Diff line number Diff line
@@ -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) ?
		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);
+25 −0
Original line number Diff line number Diff line
@@ -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;
}
+2 −0
Original line number Diff line number Diff line
@@ -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 {