IB/mlx4: Add support for XRC domains
[deliverable/linux.git] / drivers / infiniband / hw / mlx4 / main.c
index fa643f4f4e28343ff08f1c38af5373a2c5bd719e..23e45df9ae36a7304ff1f9f059992a46e3c197a4 100644 (file)
@@ -566,6 +566,57 @@ static int mlx4_ib_dealloc_pd(struct ib_pd *pd)
        return 0;
 }
 
+static struct ib_xrcd *mlx4_ib_alloc_xrcd(struct ib_device *ibdev,
+                                         struct ib_ucontext *context,
+                                         struct ib_udata *udata)
+{
+       struct mlx4_ib_xrcd *xrcd;
+       int err;
+
+       if (!(to_mdev(ibdev)->dev->caps.flags & MLX4_DEV_CAP_FLAG_XRC))
+               return ERR_PTR(-ENOSYS);
+
+       xrcd = kmalloc(sizeof *xrcd, GFP_KERNEL);
+       if (!xrcd)
+               return ERR_PTR(-ENOMEM);
+
+       err = mlx4_xrcd_alloc(to_mdev(ibdev)->dev, &xrcd->xrcdn);
+       if (err)
+               goto err1;
+
+       xrcd->pd = ib_alloc_pd(ibdev);
+       if (IS_ERR(xrcd->pd)) {
+               err = PTR_ERR(xrcd->pd);
+               goto err2;
+       }
+
+       xrcd->cq = ib_create_cq(ibdev, NULL, NULL, xrcd, 1, 0);
+       if (IS_ERR(xrcd->cq)) {
+               err = PTR_ERR(xrcd->cq);
+               goto err3;
+       }
+
+       return &xrcd->ibxrcd;
+
+err3:
+       ib_dealloc_pd(xrcd->pd);
+err2:
+       mlx4_xrcd_free(to_mdev(ibdev)->dev, xrcd->xrcdn);
+err1:
+       kfree(xrcd);
+       return ERR_PTR(err);
+}
+
+static int mlx4_ib_dealloc_xrcd(struct ib_xrcd *xrcd)
+{
+       ib_destroy_cq(to_mxrcd(xrcd)->cq);
+       ib_dealloc_pd(to_mxrcd(xrcd)->pd);
+       mlx4_xrcd_free(to_mdev(xrcd->device)->dev, to_mxrcd(xrcd)->xrcdn);
+       kfree(xrcd);
+
+       return 0;
+}
+
 static int add_gid_entry(struct ib_qp *ibqp, union ib_gid *gid)
 {
        struct mlx4_ib_qp *mqp = to_mqp(ibqp);
@@ -1093,6 +1144,14 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
        ibdev->ib_dev.unmap_fmr         = mlx4_ib_unmap_fmr;
        ibdev->ib_dev.dealloc_fmr       = mlx4_ib_fmr_dealloc;
 
+       if (dev->caps.flags & MLX4_DEV_CAP_FLAG_XRC) {
+               ibdev->ib_dev.alloc_xrcd = mlx4_ib_alloc_xrcd;
+               ibdev->ib_dev.dealloc_xrcd = mlx4_ib_dealloc_xrcd;
+               ibdev->ib_dev.uverbs_cmd_mask |=
+                       (1ull << IB_USER_VERBS_CMD_OPEN_XRCD) |
+                       (1ull << IB_USER_VERBS_CMD_CLOSE_XRCD);
+       }
+
        spin_lock_init(&iboe->lock);
 
        if (init_node_data(ibdev))
This page took 0.041842 seconds and 5 git commands to generate.