xref: /linux/drivers/infiniband/hw/mana/wq.c (revision 25f4874662fb0d43fc1d934dd7802b740ed2ab5f)
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 	int err;
17 
18 	if (udata->inlen < sizeof(ucmd))
19 		return ERR_PTR(-EINVAL);
20 
21 	err = ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen));
22 	if (err) {
23 		ibdev_dbg(&mdev->ib_dev,
24 			  "Failed to copy from udata for create wq, %d\n", err);
25 		return ERR_PTR(err);
26 	}
27 
28 	wq = kzalloc(sizeof(*wq), GFP_KERNEL);
29 	if (!wq)
30 		return ERR_PTR(-ENOMEM);
31 
32 	ibdev_dbg(&mdev->ib_dev, "ucmd wq_buf_addr 0x%llx\n", ucmd.wq_buf_addr);
33 
34 	err = mana_ib_create_queue(mdev, ucmd.wq_buf_addr, ucmd.wq_buf_size, &wq->queue);
35 	if (err) {
36 		ibdev_dbg(&mdev->ib_dev,
37 			  "Failed to create queue for create wq, %d\n", err);
38 		goto err_free_wq;
39 	}
40 
41 	wq->wqe = init_attr->max_wr;
42 	wq->wq_buf_size = ucmd.wq_buf_size;
43 	wq->rx_object = INVALID_MANA_HANDLE;
44 	return &wq->ibwq;
45 
46 err_free_wq:
47 	kfree(wq);
48 
49 	return ERR_PTR(err);
50 }
51 
mana_ib_modify_wq(struct ib_wq * wq,struct ib_wq_attr * wq_attr,u32 wq_attr_mask,struct ib_udata * udata)52 int mana_ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr,
53 		      u32 wq_attr_mask, struct ib_udata *udata)
54 {
55 	/* modify_wq is not supported by this version of the driver */
56 	return -EOPNOTSUPP;
57 }
58 
mana_ib_destroy_wq(struct ib_wq * ibwq,struct ib_udata * udata)59 int mana_ib_destroy_wq(struct ib_wq *ibwq, struct ib_udata *udata)
60 {
61 	struct mana_ib_wq *wq = container_of(ibwq, struct mana_ib_wq, ibwq);
62 	struct ib_device *ib_dev = ibwq->device;
63 	struct mana_ib_dev *mdev;
64 
65 	mdev = container_of(ib_dev, struct mana_ib_dev, ib_dev);
66 
67 	mana_ib_destroy_queue(mdev, &wq->queue);
68 
69 	kfree(wq);
70 
71 	return 0;
72 }
73 
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)74 int mana_ib_create_rwq_ind_table(struct ib_rwq_ind_table *ib_rwq_ind_table,
75 				 struct ib_rwq_ind_table_init_attr *init_attr,
76 				 struct ib_udata *udata)
77 {
78 	/*
79 	 * There is no additional data in ind_table to be maintained by this
80 	 * driver, do nothing
81 	 */
82 	return 0;
83 }
84 
mana_ib_destroy_rwq_ind_table(struct ib_rwq_ind_table * ib_rwq_ind_tbl)85 int mana_ib_destroy_rwq_ind_table(struct ib_rwq_ind_table *ib_rwq_ind_tbl)
86 {
87 	/*
88 	 * There is no additional data in ind_table to be maintained by this
89 	 * driver, do nothing
90 	 */
91 	return 0;
92 }
93