xref: /linux/drivers/infiniband/hw/mana/wq.c (revision 71dfa617ea9f18e4585fe78364217cd32b1fc382)
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 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_create_zero_offset_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 		  "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 
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 
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 
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 
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