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
mana_ib_create_wq(struct ib_pd * pd,struct ib_wq_init_attr * init_attr,struct ib_udata * udata)8 struct ib_wq *mana_ib_create_wq(struct ib_pd *pd,
9 struct ib_wq_init_attr *init_attr,
10 struct ib_udata *udata)
11 {
12 struct mana_ib_dev *mdev =
13 container_of(pd->device, struct mana_ib_dev, ib_dev);
14 struct mana_ib_create_wq ucmd = {};
15 struct mana_ib_wq *wq;
16 struct ib_umem *umem;
17 int err;
18
19 if (udata->inlen < sizeof(ucmd))
20 return ERR_PTR(-EINVAL);
21
22 err = ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen));
23 if (err) {
24 ibdev_dbg(&mdev->ib_dev,
25 "Failed to copy from udata for create wq, %d\n", err);
26 return ERR_PTR(err);
27 }
28
29 wq = kzalloc(sizeof(*wq), GFP_KERNEL);
30 if (!wq)
31 return ERR_PTR(-ENOMEM);
32
33 ibdev_dbg(&mdev->ib_dev, "ucmd wq_buf_addr 0x%llx\n", ucmd.wq_buf_addr);
34
35 umem = ib_umem_get(pd->device, ucmd.wq_buf_addr, ucmd.wq_buf_size,
36 IB_ACCESS_LOCAL_WRITE);
37 if (IS_ERR(umem)) {
38 err = PTR_ERR(umem);
39 ibdev_dbg(&mdev->ib_dev,
40 "Failed to get umem for create wq, err %d\n", err);
41 goto err_free_wq;
42 }
43
44 wq->umem = umem;
45 wq->wqe = init_attr->max_wr;
46 wq->wq_buf_size = ucmd.wq_buf_size;
47 wq->rx_object = INVALID_MANA_HANDLE;
48
49 err = mana_ib_gd_create_dma_region(mdev, wq->umem, &wq->gdma_region);
50 if (err) {
51 ibdev_dbg(&mdev->ib_dev,
52 "Failed to create dma region for create wq, %d\n",
53 err);
54 goto err_release_umem;
55 }
56
57 ibdev_dbg(&mdev->ib_dev,
58 "mana_ib_gd_create_dma_region ret %d gdma_region 0x%llx\n",
59 err, wq->gdma_region);
60
61 /* WQ ID is returned at wq_create time, doesn't know the value yet */
62
63 return &wq->ibwq;
64
65 err_release_umem:
66 ib_umem_release(umem);
67
68 err_free_wq:
69 kfree(wq);
70
71 return ERR_PTR(err);
72 }
73
mana_ib_modify_wq(struct ib_wq * wq,struct ib_wq_attr * wq_attr,u32 wq_attr_mask,struct ib_udata * udata)74 int mana_ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr,
75 u32 wq_attr_mask, struct ib_udata *udata)
76 {
77 /* modify_wq is not supported by this version of the driver */
78 return -EOPNOTSUPP;
79 }
80
mana_ib_destroy_wq(struct ib_wq * ibwq,struct ib_udata * udata)81 int mana_ib_destroy_wq(struct ib_wq *ibwq, struct ib_udata *udata)
82 {
83 struct mana_ib_wq *wq = container_of(ibwq, struct mana_ib_wq, ibwq);
84 struct ib_device *ib_dev = ibwq->device;
85 struct mana_ib_dev *mdev;
86
87 mdev = container_of(ib_dev, struct mana_ib_dev, ib_dev);
88
89 mana_ib_gd_destroy_dma_region(mdev, wq->gdma_region);
90 ib_umem_release(wq->umem);
91
92 kfree(wq);
93
94 return 0;
95 }
96
mana_ib_create_rwq_ind_table(struct ib_rwq_ind_table * ib_rwq_ind_table,struct ib_rwq_ind_table_init_attr * init_attr,struct ib_udata * udata)97 int mana_ib_create_rwq_ind_table(struct ib_rwq_ind_table *ib_rwq_ind_table,
98 struct ib_rwq_ind_table_init_attr *init_attr,
99 struct ib_udata *udata)
100 {
101 /*
102 * There is no additional data in ind_table to be maintained by this
103 * driver, do nothing
104 */
105 return 0;
106 }
107
mana_ib_destroy_rwq_ind_table(struct ib_rwq_ind_table * ib_rwq_ind_tbl)108 int mana_ib_destroy_rwq_ind_table(struct ib_rwq_ind_table *ib_rwq_ind_tbl)
109 {
110 /*
111 * There is no additional data in ind_table to be maintained by this
112 * driver, do nothing
113 */
114 return 0;
115 }
116