116 lines
2.7 KiB
C
116 lines
2.7 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* Copyright (c) 2022, Microsoft Corporation. All rights reserved.
|
|
*/
|
|
|
|
#include "mana_ib.h"
|
|
|
|
struct ib_wq *mana_ib_create_wq(struct ib_pd *pd,
|
|
struct ib_wq_init_attr *init_attr,
|
|
struct ib_udata *udata)
|
|
{
|
|
struct mana_ib_dev *mdev =
|
|
container_of(pd->device, struct mana_ib_dev, ib_dev);
|
|
struct mana_ib_create_wq ucmd = {};
|
|
struct mana_ib_wq *wq;
|
|
struct ib_umem *umem;
|
|
int err;
|
|
|
|
if (udata->inlen < sizeof(ucmd))
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
err = ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen));
|
|
if (err) {
|
|
ibdev_dbg(&mdev->ib_dev,
|
|
"Failed to copy from udata for create wq, %d\n", err);
|
|
return ERR_PTR(err);
|
|
}
|
|
|
|
wq = kzalloc(sizeof(*wq), GFP_KERNEL);
|
|
if (!wq)
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
ibdev_dbg(&mdev->ib_dev, "ucmd wq_buf_addr 0x%llx\n", ucmd.wq_buf_addr);
|
|
|
|
umem = ib_umem_get(pd->device, ucmd.wq_buf_addr, ucmd.wq_buf_size,
|
|
IB_ACCESS_LOCAL_WRITE);
|
|
if (IS_ERR(umem)) {
|
|
err = PTR_ERR(umem);
|
|
ibdev_dbg(&mdev->ib_dev,
|
|
"Failed to get umem for create wq, err %d\n", err);
|
|
goto err_free_wq;
|
|
}
|
|
|
|
wq->umem = umem;
|
|
wq->wqe = init_attr->max_wr;
|
|
wq->wq_buf_size = ucmd.wq_buf_size;
|
|
wq->rx_object = INVALID_MANA_HANDLE;
|
|
|
|
err = mana_ib_create_zero_offset_dma_region(mdev, wq->umem, &wq->gdma_region);
|
|
if (err) {
|
|
ibdev_dbg(&mdev->ib_dev,
|
|
"Failed to create dma region for create wq, %d\n",
|
|
err);
|
|
goto err_release_umem;
|
|
}
|
|
|
|
ibdev_dbg(&mdev->ib_dev,
|
|
"create_dma_region ret %d gdma_region 0x%llx\n",
|
|
err, wq->gdma_region);
|
|
|
|
/* WQ ID is returned at wq_create time, doesn't know the value yet */
|
|
|
|
return &wq->ibwq;
|
|
|
|
err_release_umem:
|
|
ib_umem_release(umem);
|
|
|
|
err_free_wq:
|
|
kfree(wq);
|
|
|
|
return ERR_PTR(err);
|
|
}
|
|
|
|
int mana_ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr,
|
|
u32 wq_attr_mask, struct ib_udata *udata)
|
|
{
|
|
/* modify_wq is not supported by this version of the driver */
|
|
return -EOPNOTSUPP;
|
|
}
|
|
|
|
int mana_ib_destroy_wq(struct ib_wq *ibwq, struct ib_udata *udata)
|
|
{
|
|
struct mana_ib_wq *wq = container_of(ibwq, struct mana_ib_wq, ibwq);
|
|
struct ib_device *ib_dev = ibwq->device;
|
|
struct mana_ib_dev *mdev;
|
|
|
|
mdev = container_of(ib_dev, struct mana_ib_dev, ib_dev);
|
|
|
|
mana_ib_gd_destroy_dma_region(mdev, wq->gdma_region);
|
|
ib_umem_release(wq->umem);
|
|
|
|
kfree(wq);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int 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)
|
|
{
|
|
/*
|
|
* There is no additional data in ind_table to be maintained by this
|
|
* driver, do nothing
|
|
*/
|
|
return 0;
|
|
}
|
|
|
|
int mana_ib_destroy_rwq_ind_table(struct ib_rwq_ind_table *ib_rwq_ind_tbl)
|
|
{
|
|
/*
|
|
* There is no additional data in ind_table to be maintained by this
|
|
* driver, do nothing
|
|
*/
|
|
return 0;
|
|
}
|