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