RDMA/mana_ib: query device capabilities
[linux-2.6-block.git] / drivers / infiniband / hw / mana / cq.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2022, Microsoft Corporation. All rights reserved.
4  */
5
6 #include "mana_ib.h"
7
8 int mana_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
9                       struct ib_udata *udata)
10 {
11         struct mana_ib_cq *cq = container_of(ibcq, struct mana_ib_cq, ibcq);
12         struct ib_device *ibdev = ibcq->device;
13         struct mana_ib_create_cq ucmd = {};
14         struct mana_ib_dev *mdev;
15         int err;
16
17         mdev = container_of(ibdev, struct mana_ib_dev, ib_dev);
18
19         if (udata->inlen < sizeof(ucmd))
20                 return -EINVAL;
21
22         err = ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen));
23         if (err) {
24                 ibdev_dbg(ibdev,
25                           "Failed to copy from udata for create cq, %d\n", err);
26                 return err;
27         }
28
29         if (attr->cqe > mdev->adapter_caps.max_qp_wr) {
30                 ibdev_dbg(ibdev, "CQE %d exceeding limit\n", attr->cqe);
31                 return -EINVAL;
32         }
33
34         cq->cqe = attr->cqe;
35         cq->umem = ib_umem_get(ibdev, ucmd.buf_addr, cq->cqe * COMP_ENTRY_SIZE,
36                                IB_ACCESS_LOCAL_WRITE);
37         if (IS_ERR(cq->umem)) {
38                 err = PTR_ERR(cq->umem);
39                 ibdev_dbg(ibdev, "Failed to get umem for create cq, err %d\n",
40                           err);
41                 return err;
42         }
43
44         err = mana_ib_gd_create_dma_region(mdev, cq->umem, &cq->gdma_region);
45         if (err) {
46                 ibdev_dbg(ibdev,
47                           "Failed to create dma region for create cq, %d\n",
48                           err);
49                 goto err_release_umem;
50         }
51
52         ibdev_dbg(ibdev,
53                   "mana_ib_gd_create_dma_region ret %d gdma_region 0x%llx\n",
54                   err, cq->gdma_region);
55
56         /*
57          * The CQ ID is not known at this time. The ID is generated at create_qp
58          */
59
60         return 0;
61
62 err_release_umem:
63         ib_umem_release(cq->umem);
64         return err;
65 }
66
67 int mana_ib_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
68 {
69         struct mana_ib_cq *cq = container_of(ibcq, struct mana_ib_cq, ibcq);
70         struct ib_device *ibdev = ibcq->device;
71         struct mana_ib_dev *mdev;
72
73         mdev = container_of(ibdev, struct mana_ib_dev, ib_dev);
74
75         mana_ib_gd_destroy_dma_region(mdev, cq->gdma_region);
76         ib_umem_release(cq->umem);
77
78         return 0;
79 }