Commit 53310b69 authored by Siva Reddy Kallam's avatar Siva Reddy Kallam Committed by Leon Romanovsky
Browse files

RDMA/bng_re: Allocate required memory resources for Firmware channel

parent 74506577
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0

ccflags-y := -I $(srctree)/drivers/net/ethernet/broadcom/bnge
ccflags-y := -I $(srctree)/drivers/net/ethernet/broadcom/bnge -I $(srctree)/drivers/infiniband/hw/bnxt_re

obj-$(CONFIG_INFINIBAND_BNG_RE) += bng_re.o

bng_re-y := bng_dev.o
bng_re-y := bng_dev.o bng_fw.o \
	    bng_res.o
+25 −7
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
#include <rdma/ib_verbs.h>

#include "bng_res.h"
#include "bng_fw.h"
#include "bng_re.h"
#include "bnge.h"
#include "bnge_hwrm.h"
@@ -56,6 +57,9 @@ static void bng_re_destroy_chip_ctx(struct bng_re_dev *rdev)

	chip_ctx = rdev->chip_ctx;
	rdev->chip_ctx = NULL;
	rdev->rcfw.res = NULL;
	rdev->bng_res.cctx = NULL;
	rdev->bng_res.pdev = NULL;
	kfree(chip_ctx);
}

@@ -65,7 +69,8 @@ static int bng_re_setup_chip_ctx(struct bng_re_dev *rdev)
	struct bnge_auxr_dev *aux_dev;

	aux_dev = rdev->aux_dev;

	rdev->bng_res.pdev = aux_dev->pdev;
	rdev->rcfw.res = &rdev->bng_res;
	chip_ctx = kzalloc(sizeof(*chip_ctx), GFP_KERNEL);
	if (!chip_ctx)
		return -ENOMEM;
@@ -73,6 +78,7 @@ static int bng_re_setup_chip_ctx(struct bng_re_dev *rdev)
	chip_ctx->hw_stats_size = aux_dev->hw_ring_stats_size;

	rdev->chip_ctx = chip_ctx;
	rdev->bng_res.cctx = rdev->chip_ctx;

	return 0;
}
@@ -131,6 +137,14 @@ static void bng_re_query_hwrm_version(struct bng_re_dev *rdev)
		cctx->hwrm_cmd_max_timeout = BNG_ROCE_FW_MAX_TIMEOUT;
}

static void bng_re_dev_uninit(struct bng_re_dev *rdev)
{
	bng_re_free_rcfw_channel(&rdev->rcfw);
	bng_re_destroy_chip_ctx(rdev);
	if (test_and_clear_bit(BNG_RE_FLAG_NETDEV_REGISTERED, &rdev->flags))
		bnge_unregister_dev(rdev->aux_dev);
}

static int bng_re_dev_init(struct bng_re_dev *rdev)
{
	int rc;
@@ -166,14 +180,18 @@ static int bng_re_dev_init(struct bng_re_dev *rdev)

	bng_re_query_hwrm_version(rdev);

	return 0;
	rc = bng_re_alloc_fw_channel(&rdev->bng_res, &rdev->rcfw);
	if (rc) {
		ibdev_err(&rdev->ibdev,
			  "Failed to allocate RCFW Channel: %#x\n", rc);
		goto fail;
	}

static void bng_re_dev_uninit(struct bng_re_dev *rdev)
{
	bng_re_destroy_chip_ctx(rdev);
	if (test_and_clear_bit(BNG_RE_FLAG_NETDEV_REGISTERED, &rdev->flags))
		bnge_unregister_dev(rdev->aux_dev);
	return 0;

fail:
	bng_re_dev_uninit(rdev);
	return rc;
}

static int bng_re_add_device(struct auxiliary_device *adev)
+70 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2025 Broadcom.
#include <linux/pci.h>

#include "bng_res.h"
#include "bng_fw.h"

void bng_re_free_rcfw_channel(struct bng_re_rcfw *rcfw)
{
	kfree(rcfw->crsqe_tbl);
	bng_re_free_hwq(rcfw->res, &rcfw->cmdq.hwq);
	bng_re_free_hwq(rcfw->res, &rcfw->creq.hwq);
	rcfw->pdev = NULL;
}

int bng_re_alloc_fw_channel(struct bng_re_res *res,
			    struct bng_re_rcfw *rcfw)
{
	struct bng_re_hwq_attr hwq_attr = {};
	struct bng_re_sg_info sginfo = {};
	struct bng_re_cmdq_ctx *cmdq;
	struct bng_re_creq_ctx *creq;

	rcfw->pdev = res->pdev;
	cmdq = &rcfw->cmdq;
	creq = &rcfw->creq;
	rcfw->res = res;

	sginfo.pgsize = PAGE_SIZE;
	sginfo.pgshft = PAGE_SHIFT;

	hwq_attr.sginfo = &sginfo;
	hwq_attr.res = rcfw->res;
	hwq_attr.depth = BNG_FW_CREQE_MAX_CNT;
	hwq_attr.stride = BNG_FW_CREQE_UNITS;
	hwq_attr.type = BNG_HWQ_TYPE_QUEUE;

	if (bng_re_alloc_init_hwq(&creq->hwq, &hwq_attr)) {
		dev_err(&rcfw->pdev->dev,
			"HW channel CREQ allocation failed\n");
		goto fail;
	}

	rcfw->cmdq_depth = BNG_FW_CMDQE_MAX_CNT;

	sginfo.pgsize = bng_fw_cmdqe_page_size(rcfw->cmdq_depth);
	hwq_attr.depth = rcfw->cmdq_depth & 0x7FFFFFFF;
	hwq_attr.stride = BNG_FW_CMDQE_UNITS;
	hwq_attr.type = BNG_HWQ_TYPE_CTX;
	if (bng_re_alloc_init_hwq(&cmdq->hwq, &hwq_attr)) {
		dev_err(&rcfw->pdev->dev,
			"HW channel CMDQ allocation failed\n");
		goto fail;
	}

	rcfw->crsqe_tbl = kcalloc(cmdq->hwq.max_elements,
				  sizeof(*rcfw->crsqe_tbl), GFP_KERNEL);
	if (!rcfw->crsqe_tbl)
		goto fail;

	spin_lock_init(&rcfw->tbl_lock);

	rcfw->max_timeout = res->cctx->hwrm_cmd_max_timeout;

	return 0;

fail:
	bng_re_free_rcfw_channel(rcfw);
	return -ENOMEM;
}
+69 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
// Copyright (c) 2025 Broadcom.

#ifndef __BNG_FW_H__
#define __BNG_FW_H__

/* CREQ */
#define BNG_FW_CREQE_MAX_CNT	(64 * 1024)
#define BNG_FW_CREQE_UNITS	16

/* CMDQ */
struct bng_fw_cmdqe {
	u8	data[16];
};

#define BNG_FW_CMDQE_MAX_CNT		8192
#define BNG_FW_CMDQE_UNITS		sizeof(struct bng_fw_cmdqe)
#define BNG_FW_CMDQE_BYTES(depth)	((depth) * BNG_FW_CMDQE_UNITS)

static inline u32 bng_fw_cmdqe_npages(u32 depth)
{
	u32 npages;

	npages = BNG_FW_CMDQE_BYTES(depth) / PAGE_SIZE;
	if (BNG_FW_CMDQE_BYTES(depth) % PAGE_SIZE)
		npages++;
	return npages;
}

static inline u32 bng_fw_cmdqe_page_size(u32 depth)
{
	return (bng_fw_cmdqe_npages(depth) * PAGE_SIZE);
}

/* HWQ */
struct bng_re_cmdq_ctx {
	struct bng_re_hwq		hwq;
};

struct bng_re_creq_ctx {
	struct bng_re_hwq		hwq;
};

struct bng_re_crsqe {
	struct creq_qp_event	*resp;
	u32			req_size;
	/* Free slots at the time of submission */
	u32			free_slots;
	u8			opcode;
};

/* RoCE FW Communication Channels */
struct bng_re_rcfw {
	struct pci_dev		*pdev;
	struct bng_re_res	*res;
	struct bng_re_cmdq_ctx	cmdq;
	struct bng_re_creq_ctx	creq;
	struct bng_re_crsqe	*crsqe_tbl;
	/* To synchronize the qp-handle hash table */
	spinlock_t		tbl_lock;
	u32			cmdq_depth;
	/* cached from chip cctx for quick reference in slow path */
	u16			max_timeout;
};

void bng_re_free_rcfw_channel(struct bng_re_rcfw *rcfw);
int bng_re_alloc_fw_channel(struct bng_re_res *res,
			    struct bng_re_rcfw *rcfw);
#endif
+2 −0
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@ struct bng_re_dev {
	struct bnge_auxr_dev		*aux_dev;
	struct bng_re_chip_ctx		*chip_ctx;
	int				fn_id;
	struct bng_re_res		bng_res;
	struct bng_re_rcfw		rcfw;
};

#endif
Loading