summaryrefslogtreecommitdiff
path: root/drivers/infiniband/hw/mlx5/qp.c
diff options
context:
space:
mode:
authorJason Gunthorpe <jgg@nvidia.com>2021-06-22 21:08:39 +0300
committerJason Gunthorpe <jgg@nvidia.com>2021-06-22 21:08:39 +0300
commit2833c977c3049f521784e8954d4c90e4941187db (patch)
tree3525a0d9c208577b852a460052290c3afa3406ef /drivers/infiniband/hw/mlx5/qp.c
parentfdcebbc2ac2cfd82a18857b0c85067fa7e8f5233 (diff)
parent336529518e9724d4cecabc622e57bcdce02e7c61 (diff)
downloadlinux-2833c977c3049f521784e8954d4c90e4941187db.tar.xz
Merge branch 'mlx5_realtime_ts' into rdma.git for-next
Aharon Landau says: ==================== In case device supports only real-time timestamp, the kernel will fail to create QP despite rdma-core requested such timestamp type. It is because device returns free-running timestamp, and the conversion from free-running to real-time is performed in the user space. This series fixes it, by returning real-time timestamp. ==================== * mlx5_realtime_ts: RDMA/mlx5: Support real-time timestamp directly from the device RDMA/mlx5: Refactor get_ts_format functions to simplify code Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Diffstat (limited to 'drivers/infiniband/hw/mlx5/qp.c')
-rw-r--r--drivers/infiniband/hw/mlx5/qp.c102
1 files changed, 56 insertions, 46 deletions
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 8dd953af323e..a77db29f8391 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -1173,69 +1173,79 @@ 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)
+static bool fr_supported(int ts_cap)
{
- 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;
+ return ts_cap == MLX5_TIMESTAMP_FORMAT_CAP_FREE_RUNNING ||
+ ts_cap == MLX5_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");
+static int get_ts_format(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq,
+ bool fr_sup, bool rt_sup)
+{
+ if (cq->private_flags & MLX5_IB_CQ_PR_FLAGS_REAL_TIME_TS) {
+ if (!rt_sup) {
+ mlx5_ib_dbg(dev,
+ "Real time TS format is not supported\n");
+ return -EOPNOTSUPP;
+ }
+ return MLX5_TIMESTAMP_FORMAT_REAL_TIME;
+ }
+ if (cq->create_flags & IB_UVERBS_CQ_FLAGS_TIMESTAMP_COMPLETION) {
+ if (!fr_sup) {
+ mlx5_ib_dbg(dev,
+ "Free running TS format is not supported\n");
return -EOPNOTSUPP;
}
- return MLX5_RQC_TIMESTAMP_FORMAT_FREE_RUNNING;
+ return MLX5_TIMESTAMP_FORMAT_FREE_RUNNING;
}
- return fr_supported ? MLX5_RQC_TIMESTAMP_FORMAT_FREE_RUNNING :
- MLX5_RQC_TIMESTAMP_FORMAT_DEFAULT;
+ return fr_sup ? MLX5_TIMESTAMP_FORMAT_FREE_RUNNING :
+ MLX5_TIMESTAMP_FORMAT_DEFAULT;
+}
+
+static int get_rq_ts_format(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *recv_cq)
+{
+ u8 ts_cap = MLX5_CAP_GEN(dev->mdev, rq_ts_format);
+
+ return get_ts_format(dev, recv_cq, fr_supported(ts_cap),
+ rt_supported(ts_cap));
}
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;
+ u8 ts_cap = MLX5_CAP_GEN(dev->mdev, sq_ts_format);
- 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 fr_supported ? MLX5_SQC_TIMESTAMP_FORMAT_FREE_RUNNING :
- MLX5_SQC_TIMESTAMP_FORMAT_DEFAULT;
+ return get_ts_format(dev, send_cq, fr_supported(ts_cap),
+ rt_supported(ts_cap));
}
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 = fr_supported ? MLX5_QPC_TIMESTAMP_FORMAT_FREE_RUNNING :
- 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");
+ u8 ts_cap = MLX5_CAP_ROCE(dev->mdev, qp_ts_format);
+ bool fr_sup = fr_supported(ts_cap);
+ bool rt_sup = rt_supported(ts_cap);
+ u8 default_ts = fr_sup ? MLX5_TIMESTAMP_FORMAT_FREE_RUNNING :
+ MLX5_TIMESTAMP_FORMAT_DEFAULT;
+ int send_ts_format =
+ send_cq ? get_ts_format(dev, send_cq, fr_sup, rt_sup) :
+ default_ts;
+ int recv_ts_format =
+ recv_cq ? get_ts_format(dev, recv_cq, fr_sup, rt_sup) :
+ default_ts;
+
+ if (send_ts_format < 0 || recv_ts_format < 0)
+ return -EOPNOTSUPP;
+
+ if (send_ts_format != MLX5_TIMESTAMP_FORMAT_DEFAULT &&
+ recv_ts_format != MLX5_TIMESTAMP_FORMAT_DEFAULT &&
+ send_ts_format != recv_ts_format) {
+ mlx5_ib_dbg(
+ dev,
+ "The send ts_format does not match the receive ts_format\n");
return -EOPNOTSUPP;
}
- return ts_format;
+
+ return send_ts_format == default_ts ? recv_ts_format : send_ts_format;
}
static int create_raw_packet_qp_sq(struct mlx5_ib_dev *dev,