129 lines
2.9 KiB
C
129 lines
2.9 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
// Copyright(c) 2024 Huawei Technologies Co., Ltd
|
|
|
|
#include <linux/slab.h>
|
|
|
|
#include "roce.h"
|
|
#include "roce_main_extension.h"
|
|
#include "roce_xrc.h"
|
|
|
|
static int roce3_rdma_xrcd_alloc(void *hwdev, u32 *xrcdn)
|
|
{
|
|
struct rdma_comp_priv *comp_priv = NULL;
|
|
|
|
if ((hwdev == NULL) || (xrcdn == NULL)) {
|
|
pr_err("%s: Hwdev or xrcdn is null\n", __func__);
|
|
return -EINVAL;
|
|
}
|
|
|
|
comp_priv = get_rdma_comp_priv(hwdev);
|
|
if (comp_priv == NULL) {
|
|
pr_err("%s: Comp_priv is null\n", __func__);
|
|
return -EINVAL;
|
|
}
|
|
|
|
*xrcdn = rdma_bitmap_alloc(&comp_priv->xrcd_bitmap);
|
|
if (*xrcdn == RDMA_INVALID_INDEX) {
|
|
pr_err("%s: Can't get valid xrcdn, err(%d)\n", __func__, -ENOMEM);
|
|
return -ENOMEM;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void roce3_rdma_xrcd_free(void *hwdev, u32 xrcdn)
|
|
{
|
|
struct rdma_comp_priv *comp_priv = NULL;
|
|
|
|
if (hwdev == NULL) {
|
|
pr_err("%s: Hwdev is null\n", __func__);
|
|
return;
|
|
}
|
|
|
|
comp_priv = get_rdma_comp_priv(hwdev);
|
|
if (comp_priv == NULL) {
|
|
pr_err("%s: Comp_priv is null\n", __func__);
|
|
return;
|
|
}
|
|
|
|
rdma_bitmap_free(&comp_priv->xrcd_bitmap, xrcdn);
|
|
}
|
|
|
|
static int roce3_init_xrcd(struct ib_device *ibdev, struct roce3_device *rdev,
|
|
struct roce3_xrcd *xrcd)
|
|
{
|
|
int ret = 0;
|
|
struct ib_cq_init_attr cq_attr = { 0 };
|
|
|
|
ret = roce3_rdma_xrcd_alloc(rdev->hwdev, &xrcd->xrcdn);
|
|
if (ret != 0) {
|
|
dev_err(rdev->hwdev_hdl,
|
|
"[ROCE, ERR] %s: Failed to alloc rdma xrcd, func_id(%d)\n",
|
|
__func__, rdev->glb_func_id);
|
|
goto err_alloc_xrcdn;
|
|
}
|
|
|
|
xrcd->pd = ib_alloc_pd(ibdev, 0); /*lint !e119*/
|
|
|
|
if (IS_ERR(xrcd->pd)) {
|
|
ret = (int)PTR_ERR(xrcd->pd);
|
|
dev_err(rdev->hwdev_hdl,
|
|
"[ROCE, ERR] %s: Failed to alloc pd, func_id(%d)\n",
|
|
__func__, rdev->glb_func_id);
|
|
goto err_alloc_pd;
|
|
}
|
|
|
|
cq_attr.cqe = 1;
|
|
xrcd->cq = ib_create_cq(ibdev, NULL, NULL, xrcd, &cq_attr);
|
|
if (IS_ERR(xrcd->cq)) {
|
|
ret = (int)PTR_ERR(xrcd->cq);
|
|
dev_err(rdev->hwdev_hdl,
|
|
"[ROCE, ERR] %s: Failed to create cq, func_id(%d)\n",
|
|
__func__, rdev->glb_func_id);
|
|
goto err_create_cq;
|
|
}
|
|
return 0;
|
|
|
|
err_create_cq:
|
|
ib_dealloc_pd(xrcd->pd);
|
|
|
|
err_alloc_pd:
|
|
roce3_rdma_xrcd_free(rdev->hwdev, xrcd->xrcdn);
|
|
|
|
err_alloc_xrcdn:
|
|
return ret;
|
|
}
|
|
|
|
int roce3_alloc_xrcd(struct ib_xrcd *ibxrcd, struct ib_udata *udata)
|
|
{
|
|
struct roce3_device *rdev = to_roce3_dev(ibxrcd->device);
|
|
struct roce3_xrcd *xrcd = to_roce3_xrcd(ibxrcd);
|
|
|
|
if (roce3_hca_is_present(rdev) == 0) {
|
|
dev_err(rdev->hwdev_hdl, "[ROCE] %s: HCA not present(return fail), func_id(%u)\n",
|
|
__func__, rdev->glb_func_id);
|
|
return -EPERM;
|
|
}
|
|
|
|
return roce3_init_xrcd(ibxrcd->device, rdev, xrcd);
|
|
}
|
|
|
|
int roce3_dealloc_xrcd(struct ib_xrcd *ibxrcd, struct ib_udata *udata)
|
|
{
|
|
struct roce3_device *rdev = NULL;
|
|
struct roce3_xrcd *xrcd = NULL;
|
|
|
|
if (ibxrcd == NULL) {
|
|
pr_err("[ROCE, ERR] %s: Ibxrcd is null\n", __func__);
|
|
return -EINVAL;
|
|
}
|
|
|
|
rdev = to_roce3_dev(ibxrcd->device);
|
|
xrcd = to_roce3_xrcd(ibxrcd);
|
|
ib_destroy_cq(xrcd->cq);
|
|
|
|
ib_dealloc_pd(xrcd->pd);
|
|
roce3_rdma_xrcd_free(rdev->hwdev, xrcd->xrcdn);
|
|
return 0;
|
|
}
|