drivers/crypto/intel/qat/qat_common/adf_gen4_pfvf.c

Source file repositories/reference/linux-study-clean/drivers/crypto/intel/qat/qat_common/adf_gen4_pfvf.c

File Facts

System
Linux kernel
Corpus path
drivers/crypto/intel/qat/qat_common/adf_gen4_pfvf.c
Extension
.c
Size
4540 bytes
Lines
146
Domain
Driver Families
Bucket
drivers/crypto
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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: (BSD-3-Clause OR GPL-2.0-only)
/* Copyright(c) 2021 Intel Corporation */
#include <linux/iopoll.h>
#include <linux/mutex.h>
#include <linux/types.h>
#include "adf_accel_devices.h"
#include "adf_common_drv.h"
#include "adf_gen4_pfvf.h"
#include "adf_gen4_hw_data.h"
#include "adf_pfvf_pf_proto.h"
#include "adf_pfvf_utils.h"

/* VF2PF interrupt source registers */
#define ADF_4XXX_VM2PF_SOU		0x41A180
#define ADF_4XXX_VM2PF_MSK		0x41A1C0
#define ADF_GEN4_VF_MSK			0xFFFF

#define ADF_PFVF_GEN4_MSGTYPE_SHIFT	2
#define ADF_PFVF_GEN4_MSGTYPE_MASK	0x3F
#define ADF_PFVF_GEN4_MSGDATA_SHIFT	8
#define ADF_PFVF_GEN4_MSGDATA_MASK	0xFFFFFF

static const struct pfvf_csr_format csr_gen4_fmt = {
	{ ADF_PFVF_GEN4_MSGTYPE_SHIFT, ADF_PFVF_GEN4_MSGTYPE_MASK },
	{ ADF_PFVF_GEN4_MSGDATA_SHIFT, ADF_PFVF_GEN4_MSGDATA_MASK },
};

static u32 adf_gen4_pf_get_pf2vf_offset(u32 i)
{
	return ADF_GEN4_PF2VM_OFFSET(i);
}

static u32 adf_gen4_pf_get_vf2pf_offset(u32 i)
{
	return ADF_GEN4_VM2PF_OFFSET(i);
}

static void adf_gen4_enable_vf2pf_interrupts(void __iomem *pmisc_addr, u32 vf_mask)
{
	u32 val;

	val = ADF_CSR_RD(pmisc_addr, ADF_4XXX_VM2PF_MSK) & ~vf_mask;
	ADF_CSR_WR(pmisc_addr, ADF_4XXX_VM2PF_MSK, val);
}

static void adf_gen4_disable_all_vf2pf_interrupts(void __iomem *pmisc_addr)
{
	ADF_CSR_WR(pmisc_addr, ADF_4XXX_VM2PF_MSK, ADF_GEN4_VF_MSK);
}

static u32 adf_gen4_disable_pending_vf2pf_interrupts(void __iomem *pmisc_addr)
{
	u32 sources, disabled, pending;

	/* Get the interrupt sources triggered by VFs */
	sources = ADF_CSR_RD(pmisc_addr, ADF_4XXX_VM2PF_SOU);
	if (!sources)
		return 0;

	/* Get the already disabled interrupts */
	disabled = ADF_CSR_RD(pmisc_addr, ADF_4XXX_VM2PF_MSK);

	pending = sources & ~disabled;
	if (!pending)
		return 0;

	/* Due to HW limitations, when disabling the interrupts, we can't
	 * just disable the requested sources, as this would lead to missed
	 * interrupts if VM2PF_SOU changes just before writing to VM2PF_MSK.
	 * To work around it, disable all and re-enable only the sources that
	 * are not in vf_mask and were not already disabled. Re-enabling will
	 * trigger a new interrupt for the sources that have changed in the
	 * meantime, if any.
	 */
	ADF_CSR_WR(pmisc_addr, ADF_4XXX_VM2PF_MSK, ADF_GEN4_VF_MSK);
	ADF_CSR_WR(pmisc_addr, ADF_4XXX_VM2PF_MSK, disabled | sources);

	/* Return the sources of the (new) interrupt(s) */
	return pending;
}

static int adf_gen4_pfvf_send(struct adf_accel_dev *accel_dev,
			      struct pfvf_message msg, u32 pfvf_offset,
			      struct mutex *csr_lock)
{
	void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
	u32 csr_val;
	int ret;

	csr_val = adf_pfvf_csr_msg_of(accel_dev, msg, &csr_gen4_fmt);

Annotation

Implementation Notes