drivers/infiniband/hw/bng_re/bng_sp.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/bng_re/bng_sp.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/hw/bng_re/bng_sp.c
Extension
.c
Size
4212 bytes
Lines
132
Domain
Driver Families
Bucket
drivers/infiniband
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2025 Broadcom.
#include <linux/interrupt.h>
#include <linux/pci.h>

#include "bng_res.h"
#include "bng_fw.h"
#include "bng_sp.h"
#include "bng_tlv.h"

static bool bng_re_is_atomic_cap(struct bng_re_rcfw *rcfw)
{
	u16 pcie_ctl2 = 0;

	pcie_capability_read_word(rcfw->pdev, PCI_EXP_DEVCTL2, &pcie_ctl2);
	return (pcie_ctl2 & PCI_EXP_DEVCTL2_ATOMIC_REQ);
}

static void bng_re_query_version(struct bng_re_rcfw *rcfw,
				 char *fw_ver)
{
	struct creq_query_version_resp resp = {};
	struct bng_re_cmdqmsg msg = {};
	struct cmdq_query_version req = {};
	int rc;

	bng_re_rcfw_cmd_prep((struct cmdq_base *)&req,
			     CMDQ_BASE_OPCODE_QUERY_VERSION,
			     sizeof(req));

	bng_re_fill_cmdqmsg(&msg, &req, &resp, NULL, sizeof(req), sizeof(resp), 0);
	rc = bng_re_rcfw_send_message(rcfw, &msg);
	if (rc)
		return;
	fw_ver[0] = resp.fw_maj;
	fw_ver[1] = resp.fw_minor;
	fw_ver[2] = resp.fw_bld;
	fw_ver[3] = resp.fw_rsvd;
}

int bng_re_get_dev_attr(struct bng_re_rcfw *rcfw)
{
	struct bng_re_dev_attr *attr = rcfw->res->dattr;
	struct creq_query_func_resp resp = {};
	struct bng_re_cmdqmsg msg = {};
	struct creq_query_func_resp_sb *sb;
	struct bng_re_rcfw_sbuf sbuf;
	struct cmdq_query_func req = {};
	u8 *tqm_alloc;
	int i, rc;
	u32 temp;

	bng_re_rcfw_cmd_prep((struct cmdq_base *)&req,
			     CMDQ_BASE_OPCODE_QUERY_FUNC,
			     sizeof(req));

	sbuf.size = ALIGN(sizeof(*sb), BNG_FW_CMDQE_UNITS);
	sbuf.sb = dma_alloc_coherent(&rcfw->pdev->dev, sbuf.size,
				     &sbuf.dma_addr, GFP_KERNEL);
	if (!sbuf.sb)
		return -ENOMEM;
	sb = sbuf.sb;
	req.resp_size = sbuf.size / BNG_FW_CMDQE_UNITS;
	bng_re_fill_cmdqmsg(&msg, &req, &resp, &sbuf, sizeof(req),
			    sizeof(resp), 0);
	rc = bng_re_rcfw_send_message(rcfw, &msg);
	if (rc)
		goto bail;
	/* Extract the context from the side buffer */
	attr->max_qp = le32_to_cpu(sb->max_qp);
	/* max_qp value reported by FW doesn't include the QP1 */
	attr->max_qp += 1;
	attr->max_qp_rd_atom =
		sb->max_qp_rd_atom > BNG_RE_MAX_OUT_RD_ATOM ?
		BNG_RE_MAX_OUT_RD_ATOM : sb->max_qp_rd_atom;
	attr->max_qp_init_rd_atom =
		sb->max_qp_init_rd_atom > BNG_RE_MAX_OUT_RD_ATOM ?
		BNG_RE_MAX_OUT_RD_ATOM : sb->max_qp_init_rd_atom;
	attr->max_qp_wqes = le16_to_cpu(sb->max_qp_wr) - 1;

	/* Adjust for max_qp_wqes for variable wqe */
	attr->max_qp_wqes = min_t(u32, attr->max_qp_wqes, BNG_VAR_MAX_WQE - 1);

	attr->max_qp_sges = min_t(u32, sb->max_sge_var_wqe, BNG_VAR_MAX_SGE);
	attr->max_cq = le32_to_cpu(sb->max_cq);
	attr->max_cq_wqes = le32_to_cpu(sb->max_cqe);
	attr->max_cq_sges = attr->max_qp_sges;
	attr->max_mr = le32_to_cpu(sb->max_mr);
	attr->max_mw = le32_to_cpu(sb->max_mw);

Annotation

Implementation Notes