Commit 68ad4d1c authored by Jason Gunthorpe's avatar Jason Gunthorpe
Browse files

Merge branch 'mlx5_timestamp' into rdma.git for-next

Leon Romanovsky says:

====================
Add an extra timestamp format for mlx5_ib device.
====================

Based on the mlx5-next branch at
     git://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux


due to dependencies.

Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>

* branch 'mlx5_timestamp':
  RDMA/mlx5: Fail QP creation if the device can not support the CQE TS
  net/mlx5: Add new timestamp mode bits
parents 7232c132 2fe8d4b8
Loading
Loading
Loading
Loading
+96 −8
Original line number Diff line number Diff line
@@ -1078,6 +1078,7 @@ static int _create_kernel_qp(struct mlx5_ib_dev *dev,

	qpc = MLX5_ADDR_OF(create_qp_in, *in, qpc);
	MLX5_SET(qpc, qpc, uar_page, uar_index);
	MLX5_SET(qpc, qpc, ts_format, MLX5_QPC_TIMESTAMP_FORMAT_DEFAULT);
	MLX5_SET(qpc, qpc, log_page_size, qp->buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT);

	/* Set "fast registration enabled" for all kernel QPs */
@@ -1172,10 +1173,72 @@ static void destroy_flow_rule_vport_sq(struct mlx5_ib_sq *sq)
	sq->flow_rule = NULL;
}

static int get_rq_ts_format(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *send_cq)
{
	bool fr_supported =
		MLX5_CAP_GEN(dev->mdev, rq_ts_format) ==
			MLX5_RQ_TIMESTAMP_FORMAT_CAP_FREE_RUNNING ||
		MLX5_CAP_GEN(dev->mdev, rq_ts_format) ==
			MLX5_RQ_TIMESTAMP_FORMAT_CAP_FREE_RUNNING_AND_REAL_TIME;

	if (send_cq->create_flags & IB_UVERBS_CQ_FLAGS_TIMESTAMP_COMPLETION) {
		if (!fr_supported) {
			mlx5_ib_dbg(dev, "Free running TS format is not supported\n");
			return -EOPNOTSUPP;
		}
		return MLX5_RQC_TIMESTAMP_FORMAT_FREE_RUNNING;
	}
	return MLX5_RQC_TIMESTAMP_FORMAT_DEFAULT;
}

static int get_sq_ts_format(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *send_cq)
{
	bool fr_supported =
		MLX5_CAP_GEN(dev->mdev, sq_ts_format) ==
			MLX5_SQ_TIMESTAMP_FORMAT_CAP_FREE_RUNNING ||
		MLX5_CAP_GEN(dev->mdev, sq_ts_format) ==
			MLX5_SQ_TIMESTAMP_FORMAT_CAP_FREE_RUNNING_AND_REAL_TIME;

	if (send_cq->create_flags & IB_UVERBS_CQ_FLAGS_TIMESTAMP_COMPLETION) {
		if (!fr_supported) {
			mlx5_ib_dbg(dev, "Free running TS format is not supported\n");
			return -EOPNOTSUPP;
		}
		return MLX5_SQC_TIMESTAMP_FORMAT_FREE_RUNNING;
	}
	return MLX5_SQC_TIMESTAMP_FORMAT_DEFAULT;
}

static int get_qp_ts_format(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *send_cq,
			    struct mlx5_ib_cq *recv_cq)
{
	bool fr_supported =
		MLX5_CAP_ROCE(dev->mdev, qp_ts_format) ==
			MLX5_QP_TIMESTAMP_FORMAT_CAP_FREE_RUNNING ||
		MLX5_CAP_ROCE(dev->mdev, qp_ts_format) ==
			MLX5_QP_TIMESTAMP_FORMAT_CAP_FREE_RUNNING_AND_REAL_TIME;
	int ts_format = MLX5_QPC_TIMESTAMP_FORMAT_DEFAULT;

	if (recv_cq &&
	    recv_cq->create_flags & IB_UVERBS_CQ_FLAGS_TIMESTAMP_COMPLETION)
		ts_format = MLX5_QPC_TIMESTAMP_FORMAT_FREE_RUNNING;

	if (send_cq &&
	    send_cq->create_flags & IB_UVERBS_CQ_FLAGS_TIMESTAMP_COMPLETION)
		ts_format = MLX5_QPC_TIMESTAMP_FORMAT_FREE_RUNNING;

	if (ts_format == MLX5_QPC_TIMESTAMP_FORMAT_FREE_RUNNING &&
	    !fr_supported) {
		mlx5_ib_dbg(dev, "Free running TS format is not supported\n");
		return -EOPNOTSUPP;
	}
	return ts_format;
}

static int create_raw_packet_qp_sq(struct mlx5_ib_dev *dev,
				   struct ib_udata *udata,
				   struct mlx5_ib_sq *sq, void *qpin,
				   struct ib_pd *pd)
				   struct ib_pd *pd, struct mlx5_ib_cq *cq)
{
	struct mlx5_ib_ubuffer *ubuffer = &sq->ubuffer;
	__be64 *pas;
@@ -1187,6 +1250,11 @@ static int create_raw_packet_qp_sq(struct mlx5_ib_dev *dev,
	int err;
	unsigned int page_offset_quantized;
	unsigned long page_size;
	int ts_format;

	ts_format = get_sq_ts_format(dev, cq);
	if (ts_format < 0)
		return ts_format;

	sq->ubuffer.umem = ib_umem_get(&dev->ib_dev, ubuffer->buf_addr,
				       ubuffer->buf_size, 0);
@@ -1215,6 +1283,7 @@ static int create_raw_packet_qp_sq(struct mlx5_ib_dev *dev,
	if (MLX5_CAP_ETH(dev->mdev, multi_pkt_send_wqe))
		MLX5_SET(sqc, sqc, allow_multi_pkt_send_wqe, 1);
	MLX5_SET(sqc, sqc, state, MLX5_SQC_STATE_RST);
	MLX5_SET(sqc, sqc, ts_format, ts_format);
	MLX5_SET(sqc, sqc, user_index, MLX5_GET(qpc, qpc, user_index));
	MLX5_SET(sqc, sqc, cqn, MLX5_GET(qpc, qpc, cqn_snd));
	MLX5_SET(sqc, sqc, tis_lst_sz, 1);
@@ -1263,7 +1332,7 @@ static void destroy_raw_packet_qp_sq(struct mlx5_ib_dev *dev,

static int create_raw_packet_qp_rq(struct mlx5_ib_dev *dev,
				   struct mlx5_ib_rq *rq, void *qpin,
				   struct ib_pd *pd)
				   struct ib_pd *pd, struct mlx5_ib_cq *cq)
{
	struct mlx5_ib_qp *mqp = rq->base.container_mibqp;
	__be64 *pas;
@@ -1274,9 +1343,14 @@ static int create_raw_packet_qp_rq(struct mlx5_ib_dev *dev,
	struct ib_umem *umem = rq->base.ubuffer.umem;
	unsigned int page_offset_quantized;
	unsigned long page_size = 0;
	int ts_format;
	size_t inlen;
	int err;

	ts_format = get_rq_ts_format(dev, cq);
	if (ts_format < 0)
		return ts_format;

	page_size = mlx5_umem_find_best_quantized_pgoff(umem, wq, log_wq_pg_sz,
							MLX5_ADAPTER_PAGE_SHIFT,
							page_offset, 64,
@@ -1296,6 +1370,7 @@ static int create_raw_packet_qp_rq(struct mlx5_ib_dev *dev,
		MLX5_SET(rqc, rqc, vsd, 1);
	MLX5_SET(rqc, rqc, mem_rq_type, MLX5_RQC_MEM_RQ_TYPE_MEMORY_RQ_INLINE);
	MLX5_SET(rqc, rqc, state, MLX5_RQC_STATE_RST);
	MLX5_SET(rqc, rqc, ts_format, ts_format);
	MLX5_SET(rqc, rqc, flush_in_error_en, 1);
	MLX5_SET(rqc, rqc, user_index, MLX5_GET(qpc, qpc, user_index));
	MLX5_SET(rqc, rqc, cqn, MLX5_GET(qpc, qpc, cqn_rcv));
@@ -1393,10 +1468,10 @@ static int create_raw_packet_qp_tir(struct mlx5_ib_dev *dev,
}

static int create_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
				u32 *in, size_t inlen,
				struct ib_pd *pd,
				u32 *in, size_t inlen, struct ib_pd *pd,
				struct ib_udata *udata,
				struct mlx5_ib_create_qp_resp *resp)
				struct mlx5_ib_create_qp_resp *resp,
				struct ib_qp_init_attr *init_attr)
{
	struct mlx5_ib_raw_packet_qp *raw_packet_qp = &qp->raw_packet_qp;
	struct mlx5_ib_sq *sq = &raw_packet_qp->sq;
@@ -1415,7 +1490,8 @@ static int create_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
		if (err)
			return err;

		err = create_raw_packet_qp_sq(dev, udata, sq, in, pd);
		err = create_raw_packet_qp_sq(dev, udata, sq, in, pd,
					      to_mcq(init_attr->send_cq));
		if (err)
			goto err_destroy_tis;

@@ -1437,7 +1513,8 @@ static int create_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
			rq->flags |= MLX5_IB_RQ_CVLAN_STRIPPING;
		if (qp->flags & IB_QP_CREATE_PCI_WRITE_END_PADDING)
			rq->flags |= MLX5_IB_RQ_PCI_WRITE_END_PADDING;
		err = create_raw_packet_qp_rq(dev, rq, in, pd);
		err = create_raw_packet_qp_rq(dev, rq, in, pd,
					      to_mcq(init_attr->recv_cq));
		if (err)
			goto err_destroy_sq;

@@ -1907,6 +1984,7 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
	struct mlx5_ib_cq *recv_cq;
	unsigned long flags;
	struct mlx5_ib_qp_base *base;
	int ts_format;
	int mlx5_st;
	void *qpc;
	u32 *in;
@@ -1944,6 +2022,13 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
	if (ucmd->sq_wqe_count > (1 << MLX5_CAP_GEN(mdev, log_max_qp_sz)))
		return -EINVAL;

	if (init_attr->qp_type != IB_QPT_RAW_PACKET) {
		ts_format = get_qp_ts_format(dev, to_mcq(init_attr->send_cq),
					     to_mcq(init_attr->recv_cq));
		if (ts_format < 0)
			return ts_format;
	}

	err = _create_user_qp(dev, pd, qp, udata, init_attr, &in, &params->resp,
			      &inlen, base, ucmd);
	if (err)
@@ -1992,6 +2077,9 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
		MLX5_SET(qpc, qpc, log_rq_size, ilog2(qp->rq.wqe_cnt));
	}

	if (init_attr->qp_type != IB_QPT_RAW_PACKET)
		MLX5_SET(qpc, qpc, ts_format, ts_format);

	MLX5_SET(qpc, qpc, rq_type, get_rx_type(qp, init_attr));

	if (qp->sq.wqe_cnt) {
@@ -2046,7 +2134,7 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
		qp->raw_packet_qp.sq.ubuffer.buf_addr = ucmd->sq_buf_addr;
		raw_packet_qp_copy_info(qp, &qp->raw_packet_qp);
		err = create_raw_packet_qp(dev, qp, in, inlen, pd, udata,
					   &params->resp);
					   &params->resp, init_attr);
	} else
		err = mlx5_qpc_create_qp(dev, &base->mqp, in, inlen, out);

+49 −5
Original line number Diff line number Diff line
@@ -932,11 +932,18 @@ struct mlx5_ifc_per_protocol_networking_offload_caps_bits {
	u8         reserved_at_200[0x600];
};

enum {
	MLX5_QP_TIMESTAMP_FORMAT_CAP_FREE_RUNNING               = 0x0,
	MLX5_QP_TIMESTAMP_FORMAT_CAP_REAL_TIME                  = 0x1,
	MLX5_QP_TIMESTAMP_FORMAT_CAP_FREE_RUNNING_AND_REAL_TIME = 0x2,
};

struct mlx5_ifc_roce_cap_bits {
	u8         roce_apm[0x1];
	u8         reserved_at_1[0x3];
	u8         sw_r_roce_src_udp_port[0x1];
	u8         reserved_at_5[0x1b];
	u8         reserved_at_5[0x19];
	u8	   qp_ts_format[0x2];

	u8         reserved_at_20[0x60];

@@ -1253,6 +1260,18 @@ enum {
	MLX5_STEERING_FORMAT_CONNECTX_6DX = 1,
};

enum {
	MLX5_SQ_TIMESTAMP_FORMAT_CAP_FREE_RUNNING               = 0x0,
	MLX5_SQ_TIMESTAMP_FORMAT_CAP_REAL_TIME                  = 0x1,
	MLX5_SQ_TIMESTAMP_FORMAT_CAP_FREE_RUNNING_AND_REAL_TIME = 0x2,
};

enum {
	MLX5_RQ_TIMESTAMP_FORMAT_CAP_FREE_RUNNING               = 0x0,
	MLX5_RQ_TIMESTAMP_FORMAT_CAP_REAL_TIME                  = 0x1,
	MLX5_RQ_TIMESTAMP_FORMAT_CAP_FREE_RUNNING_AND_REAL_TIME = 0x2,
};

struct mlx5_ifc_cmd_hca_cap_bits {
	u8         reserved_at_0[0x1f];
	u8         vhca_resource_manager[0x1];
@@ -1564,7 +1583,8 @@ struct mlx5_ifc_cmd_hca_cap_bits {

	u8         general_obj_types[0x40];

	u8         reserved_at_440[0x4];
	u8         sq_ts_format[0x2];
	u8         rq_ts_format[0x2];
	u8         steering_format_version[0x4];
	u8         create_qp_start_hint[0x18];

@@ -2869,6 +2889,12 @@ enum {
	MLX5_QPC_CS_RES_UP_TO_64B  = 0x2,
};

enum {
	MLX5_QPC_TIMESTAMP_FORMAT_FREE_RUNNING = 0x0,
	MLX5_QPC_TIMESTAMP_FORMAT_DEFAULT      = 0x1,
	MLX5_QPC_TIMESTAMP_FORMAT_REAL_TIME    = 0x2,
};

struct mlx5_ifc_qpc_bits {
	u8         state[0x4];
	u8         lag_tx_port_affinity[0x4];
@@ -2897,7 +2923,9 @@ struct mlx5_ifc_qpc_bits {
	u8         log_rq_stride[0x3];
	u8         no_sq[0x1];
	u8         log_sq_size[0x4];
	u8         reserved_at_55[0x6];
	u8         reserved_at_55[0x3];
	u8	   ts_format[0x2];
	u8         reserved_at_5a[0x1];
	u8         rlky[0x1];
	u8         ulp_stateless_offload_mode[0x4];

@@ -3313,6 +3341,12 @@ enum {
	MLX5_SQC_STATE_ERR  = 0x3,
};

enum {
	MLX5_SQC_TIMESTAMP_FORMAT_FREE_RUNNING = 0x0,
	MLX5_SQC_TIMESTAMP_FORMAT_DEFAULT      = 0x1,
	MLX5_SQC_TIMESTAMP_FORMAT_REAL_TIME    = 0x2,
};

struct mlx5_ifc_sqc_bits {
	u8         rlky[0x1];
	u8         cd_master[0x1];
@@ -3324,7 +3358,9 @@ struct mlx5_ifc_sqc_bits {
	u8         reg_umr[0x1];
	u8         allow_swp[0x1];
	u8         hairpin[0x1];
	u8         reserved_at_f[0x11];
	u8         reserved_at_f[0xb];
	u8	   ts_format[0x2];
	u8	   reserved_at_1c[0x4];

	u8         reserved_at_20[0x8];
	u8         user_index[0x18];
@@ -3415,6 +3451,12 @@ enum {
	MLX5_RQC_STATE_ERR  = 0x3,
};

enum {
	MLX5_RQC_TIMESTAMP_FORMAT_FREE_RUNNING = 0x0,
	MLX5_RQC_TIMESTAMP_FORMAT_DEFAULT      = 0x1,
	MLX5_RQC_TIMESTAMP_FORMAT_REAL_TIME    = 0x2,
};

struct mlx5_ifc_rqc_bits {
	u8         rlky[0x1];
	u8	   delay_drop_en[0x1];
@@ -3425,7 +3467,9 @@ struct mlx5_ifc_rqc_bits {
	u8         reserved_at_c[0x1];
	u8         flush_in_error_en[0x1];
	u8         hairpin[0x1];
	u8         reserved_at_f[0x11];
	u8         reserved_at_f[0xb];
	u8	   ts_format[0x2];
	u8	   reserved_at_1c[0x4];

	u8         reserved_at_20[0x8];
	u8         user_index[0x18];