drivers/infiniband/hw/irdma/ig3rdma_if.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/irdma/ig3rdma_if.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/hw/irdma/ig3rdma_if.c
Extension
.c
Size
5945 bytes
Lines
236
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 or Linux-OpenIB
/* Copyright (c) 2023 - 2024 Intel Corporation */

#include "main.h"
#include <linux/net/intel/iidc_rdma_idpf.h>
#include "ig3rdma_hw.h"

static void ig3rdma_idc_core_event_handler(struct iidc_rdma_core_dev_info *cdev_info,
					   struct iidc_rdma_event *event)
{
	struct irdma_pci_f *rf = auxiliary_get_drvdata(cdev_info->adev);

	if (*event->type & BIT(IIDC_RDMA_EVENT_WARN_RESET)) {
		rf->reset = true;
		rf->sc_dev.vchnl_up = false;
	}
}

int ig3rdma_vchnl_send_sync(struct irdma_sc_dev *dev, u8 *msg, u16 len,
			    u8 *recv_msg, u16 *recv_len)
{
	struct iidc_rdma_core_dev_info *cdev_info = dev_to_rf(dev)->cdev;
	int ret;

	ret = idpf_idc_rdma_vc_send_sync(cdev_info, msg, len, recv_msg,
					 recv_len);
	if (ret == -ETIMEDOUT) {
		ibdev_err(&(dev_to_rf(dev)->iwdev->ibdev),
			  "Virtual channel Req <-> Resp completion timeout\n");
		dev->vchnl_up = false;
	}

	return ret;
}

static int ig3rdma_vchnl_init(struct irdma_pci_f *rf,
			      struct iidc_rdma_core_dev_info *cdev_info,
			      u8 *rdma_ver)
{
	struct iidc_rdma_priv_dev_info *idc_priv = cdev_info->iidc_priv;
	struct irdma_vchnl_init_info virt_info;
	u8 gen = rf->rdma_ver;
	int ret;

	rf->vchnl_wq = alloc_ordered_workqueue("irdma-virtchnl-wq", 0);
	if (!rf->vchnl_wq)
		return -ENOMEM;

	mutex_init(&rf->sc_dev.vchnl_mutex);

	virt_info.is_pf = !idc_priv->ftype;
	virt_info.hw_rev = gen;
	virt_info.privileged = gen == IRDMA_GEN_2;
	virt_info.vchnl_wq = rf->vchnl_wq;
	ret = irdma_sc_vchnl_init(&rf->sc_dev, &virt_info);
	if (ret) {
		destroy_workqueue(rf->vchnl_wq);
		mutex_destroy(&rf->sc_dev.vchnl_mutex);
		return ret;
	}

	*rdma_ver = rf->sc_dev.hw_attrs.uk_attrs.hw_rev;

	return 0;
}

/**
 * ig3rdma_request_reset - Request a reset
 * @rf: RDMA PCI function
 */
static void ig3rdma_request_reset(struct irdma_pci_f *rf)
{
	ibdev_warn(&rf->iwdev->ibdev, "Requesting a reset\n");
	idpf_idc_request_reset(rf->cdev, IIDC_FUNC_RESET);
}

static int ig3rdma_cfg_regions(struct irdma_hw *hw,
			       struct iidc_rdma_core_dev_info *cdev_info)
{
	struct iidc_rdma_priv_dev_info *idc_priv = cdev_info->iidc_priv;
	struct pci_dev *pdev = cdev_info->pdev;
	int i;

	switch (idc_priv->ftype) {
	case IIDC_FUNCTION_TYPE_PF:
		hw->rdma_reg.len = IG3_PF_RDMA_REGION_LEN;
		hw->rdma_reg.offset = IG3_PF_RDMA_REGION_OFFSET;
		break;
	case IIDC_FUNCTION_TYPE_VF:
		hw->rdma_reg.len = IG3_VF_RDMA_REGION_LEN;

Annotation

Implementation Notes