162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2022, Microsoft Corporation. All rights reserved. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include "mana_ib.h" 762306a36Sopenharmony_ci 862306a36Sopenharmony_cistruct ib_wq *mana_ib_create_wq(struct ib_pd *pd, 962306a36Sopenharmony_ci struct ib_wq_init_attr *init_attr, 1062306a36Sopenharmony_ci struct ib_udata *udata) 1162306a36Sopenharmony_ci{ 1262306a36Sopenharmony_ci struct mana_ib_dev *mdev = 1362306a36Sopenharmony_ci container_of(pd->device, struct mana_ib_dev, ib_dev); 1462306a36Sopenharmony_ci struct mana_ib_create_wq ucmd = {}; 1562306a36Sopenharmony_ci struct mana_ib_wq *wq; 1662306a36Sopenharmony_ci struct ib_umem *umem; 1762306a36Sopenharmony_ci int err; 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci if (udata->inlen < sizeof(ucmd)) 2062306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci err = ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen)); 2362306a36Sopenharmony_ci if (err) { 2462306a36Sopenharmony_ci ibdev_dbg(&mdev->ib_dev, 2562306a36Sopenharmony_ci "Failed to copy from udata for create wq, %d\n", err); 2662306a36Sopenharmony_ci return ERR_PTR(err); 2762306a36Sopenharmony_ci } 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci wq = kzalloc(sizeof(*wq), GFP_KERNEL); 3062306a36Sopenharmony_ci if (!wq) 3162306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci ibdev_dbg(&mdev->ib_dev, "ucmd wq_buf_addr 0x%llx\n", ucmd.wq_buf_addr); 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci umem = ib_umem_get(pd->device, ucmd.wq_buf_addr, ucmd.wq_buf_size, 3662306a36Sopenharmony_ci IB_ACCESS_LOCAL_WRITE); 3762306a36Sopenharmony_ci if (IS_ERR(umem)) { 3862306a36Sopenharmony_ci err = PTR_ERR(umem); 3962306a36Sopenharmony_ci ibdev_dbg(&mdev->ib_dev, 4062306a36Sopenharmony_ci "Failed to get umem for create wq, err %d\n", err); 4162306a36Sopenharmony_ci goto err_free_wq; 4262306a36Sopenharmony_ci } 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci wq->umem = umem; 4562306a36Sopenharmony_ci wq->wqe = init_attr->max_wr; 4662306a36Sopenharmony_ci wq->wq_buf_size = ucmd.wq_buf_size; 4762306a36Sopenharmony_ci wq->rx_object = INVALID_MANA_HANDLE; 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci err = mana_ib_gd_create_dma_region(mdev, wq->umem, &wq->gdma_region); 5062306a36Sopenharmony_ci if (err) { 5162306a36Sopenharmony_ci ibdev_dbg(&mdev->ib_dev, 5262306a36Sopenharmony_ci "Failed to create dma region for create wq, %d\n", 5362306a36Sopenharmony_ci err); 5462306a36Sopenharmony_ci goto err_release_umem; 5562306a36Sopenharmony_ci } 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci ibdev_dbg(&mdev->ib_dev, 5862306a36Sopenharmony_ci "mana_ib_gd_create_dma_region ret %d gdma_region 0x%llx\n", 5962306a36Sopenharmony_ci err, wq->gdma_region); 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci /* WQ ID is returned at wq_create time, doesn't know the value yet */ 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci return &wq->ibwq; 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_cierr_release_umem: 6662306a36Sopenharmony_ci ib_umem_release(umem); 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_cierr_free_wq: 6962306a36Sopenharmony_ci kfree(wq); 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci return ERR_PTR(err); 7262306a36Sopenharmony_ci} 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ciint mana_ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr, 7562306a36Sopenharmony_ci u32 wq_attr_mask, struct ib_udata *udata) 7662306a36Sopenharmony_ci{ 7762306a36Sopenharmony_ci /* modify_wq is not supported by this version of the driver */ 7862306a36Sopenharmony_ci return -EOPNOTSUPP; 7962306a36Sopenharmony_ci} 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ciint mana_ib_destroy_wq(struct ib_wq *ibwq, struct ib_udata *udata) 8262306a36Sopenharmony_ci{ 8362306a36Sopenharmony_ci struct mana_ib_wq *wq = container_of(ibwq, struct mana_ib_wq, ibwq); 8462306a36Sopenharmony_ci struct ib_device *ib_dev = ibwq->device; 8562306a36Sopenharmony_ci struct mana_ib_dev *mdev; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci mdev = container_of(ib_dev, struct mana_ib_dev, ib_dev); 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci mana_ib_gd_destroy_dma_region(mdev, wq->gdma_region); 9062306a36Sopenharmony_ci ib_umem_release(wq->umem); 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci kfree(wq); 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci return 0; 9562306a36Sopenharmony_ci} 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ciint mana_ib_create_rwq_ind_table(struct ib_rwq_ind_table *ib_rwq_ind_table, 9862306a36Sopenharmony_ci struct ib_rwq_ind_table_init_attr *init_attr, 9962306a36Sopenharmony_ci struct ib_udata *udata) 10062306a36Sopenharmony_ci{ 10162306a36Sopenharmony_ci /* 10262306a36Sopenharmony_ci * There is no additional data in ind_table to be maintained by this 10362306a36Sopenharmony_ci * driver, do nothing 10462306a36Sopenharmony_ci */ 10562306a36Sopenharmony_ci return 0; 10662306a36Sopenharmony_ci} 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ciint mana_ib_destroy_rwq_ind_table(struct ib_rwq_ind_table *ib_rwq_ind_tbl) 10962306a36Sopenharmony_ci{ 11062306a36Sopenharmony_ci /* 11162306a36Sopenharmony_ci * There is no additional data in ind_table to be maintained by this 11262306a36Sopenharmony_ci * driver, do nothing 11362306a36Sopenharmony_ci */ 11462306a36Sopenharmony_ci return 0; 11562306a36Sopenharmony_ci} 116