drivers/gpu/drm/xe/xe_sriov_pf_service.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/xe/xe_sriov_pf_service.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/xe/xe_sriov_pf_service.c
Extension
.c
Size
6426 bytes
Lines
217
Domain
Driver Families
Bucket
drivers/gpu
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: MIT
/*
 * Copyright © 2023-2025 Intel Corporation
 */

#include "abi/guc_relay_actions_abi.h"

#include "xe_device_types.h"
#include "xe_sriov.h"
#include "xe_sriov_pf_helpers.h"
#include "xe_sriov_printk.h"

#include "xe_sriov_pf_service.h"
#include "xe_sriov_pf_service_types.h"

/**
 * xe_sriov_pf_service_init - Early initialization of the SR-IOV PF service.
 * @xe: the &xe_device to initialize
 *
 * Performs early initialization of the SR-IOV PF service.
 *
 * This function can only be called on PF.
 */
void xe_sriov_pf_service_init(struct xe_device *xe)
{
	BUILD_BUG_ON(!GUC_RELAY_VERSION_BASE_MAJOR && !GUC_RELAY_VERSION_BASE_MINOR);
	BUILD_BUG_ON(GUC_RELAY_VERSION_BASE_MAJOR > GUC_RELAY_VERSION_LATEST_MAJOR);

	xe_assert(xe, IS_SRIOV_PF(xe));

	/* base versions may differ between platforms */
	xe->sriov.pf.service.version.base.major = GUC_RELAY_VERSION_BASE_MAJOR;
	xe->sriov.pf.service.version.base.minor = GUC_RELAY_VERSION_BASE_MINOR;

	/* latest version is same for all platforms */
	xe->sriov.pf.service.version.latest.major = GUC_RELAY_VERSION_LATEST_MAJOR;
	xe->sriov.pf.service.version.latest.minor = GUC_RELAY_VERSION_LATEST_MINOR;
}

/* Return: 0 on success or a negative error code on failure. */
static int pf_negotiate_version(struct xe_device *xe,
				u32 wanted_major, u32 wanted_minor,
				u32 *major, u32 *minor)
{
	struct xe_sriov_pf_service_version base = xe->sriov.pf.service.version.base;
	struct xe_sriov_pf_service_version latest = xe->sriov.pf.service.version.latest;

	xe_assert(xe, IS_SRIOV_PF(xe));
	xe_assert(xe, base.major);
	xe_assert(xe, base.major <= latest.major);
	xe_assert(xe, (base.major < latest.major) || (base.minor <= latest.minor));

	/* VF doesn't care - return our latest  */
	if (wanted_major == VF2PF_HANDSHAKE_MAJOR_ANY &&
	    wanted_minor == VF2PF_HANDSHAKE_MINOR_ANY) {
		*major = latest.major;
		*minor = latest.minor;
		return 0;
	}

	/* VF wants newer than our - return our latest  */
	if (wanted_major > latest.major) {
		*major = latest.major;
		*minor = latest.minor;
		return 0;
	}

	/* VF wants older than min required - reject */
	if (wanted_major < base.major ||
	    (wanted_major == base.major && wanted_minor < base.minor)) {
		return -EPERM;
	}

	/* previous major - return wanted, as we should still support it */
	if (wanted_major < latest.major) {
		/* XXX: we are not prepared for multi-versions yet */
		xe_assert(xe, base.major == latest.major);
		return -ENOPKG;
	}

	/* same major - return common minor */
	*major = wanted_major;
	*minor = min_t(u32, latest.minor, wanted_minor);
	return 0;
}

static void pf_connect(struct xe_device *xe, u32 vfid, u32 major, u32 minor)
{
	xe_sriov_pf_assert_vfid(xe, vfid);
	xe_assert(xe, major || minor);

Annotation

Implementation Notes