1146e4384SMichal Wajdeczko // SPDX-License-Identifier: MIT
2146e4384SMichal Wajdeczko /*
3146e4384SMichal Wajdeczko * Copyright © 2023-2024 Intel Corporation
4146e4384SMichal Wajdeczko */
5146e4384SMichal Wajdeczko
6*0bdd5b16SMichal Wajdeczko #include <drm/drm_managed.h>
7*0bdd5b16SMichal Wajdeczko
8146e4384SMichal Wajdeczko #include "xe_assert.h"
9146e4384SMichal Wajdeczko #include "xe_device.h"
10146e4384SMichal Wajdeczko #include "xe_module.h"
11146e4384SMichal Wajdeczko #include "xe_sriov.h"
12146e4384SMichal Wajdeczko #include "xe_sriov_pf.h"
13146e4384SMichal Wajdeczko #include "xe_sriov_printk.h"
14146e4384SMichal Wajdeczko
wanted_max_vfs(struct xe_device * xe)15146e4384SMichal Wajdeczko static unsigned int wanted_max_vfs(struct xe_device *xe)
16146e4384SMichal Wajdeczko {
17146e4384SMichal Wajdeczko return xe_modparam.max_vfs;
18146e4384SMichal Wajdeczko }
19146e4384SMichal Wajdeczko
pf_reduce_totalvfs(struct xe_device * xe,int limit)20146e4384SMichal Wajdeczko static int pf_reduce_totalvfs(struct xe_device *xe, int limit)
21146e4384SMichal Wajdeczko {
22146e4384SMichal Wajdeczko struct device *dev = xe->drm.dev;
23146e4384SMichal Wajdeczko struct pci_dev *pdev = to_pci_dev(dev);
24146e4384SMichal Wajdeczko int err;
25146e4384SMichal Wajdeczko
26146e4384SMichal Wajdeczko err = pci_sriov_set_totalvfs(pdev, limit);
27146e4384SMichal Wajdeczko if (err)
28146e4384SMichal Wajdeczko xe_sriov_notice(xe, "Failed to set number of VFs to %d (%pe)\n",
29146e4384SMichal Wajdeczko limit, ERR_PTR(err));
30146e4384SMichal Wajdeczko return err;
31146e4384SMichal Wajdeczko }
32146e4384SMichal Wajdeczko
pf_continue_as_native(struct xe_device * xe,const char * why)33146e4384SMichal Wajdeczko static bool pf_continue_as_native(struct xe_device *xe, const char *why)
34146e4384SMichal Wajdeczko {
35146e4384SMichal Wajdeczko xe_sriov_dbg(xe, "%s, continuing as native\n", why);
36146e4384SMichal Wajdeczko pf_reduce_totalvfs(xe, 0);
37146e4384SMichal Wajdeczko return false;
38146e4384SMichal Wajdeczko }
39146e4384SMichal Wajdeczko
40146e4384SMichal Wajdeczko /**
41146e4384SMichal Wajdeczko * xe_sriov_pf_readiness - Check if PF functionality can be enabled.
42146e4384SMichal Wajdeczko * @xe: the &xe_device to check
43146e4384SMichal Wajdeczko *
44146e4384SMichal Wajdeczko * This function is called as part of the SR-IOV probe to validate if all
45146e4384SMichal Wajdeczko * PF prerequisites are satisfied and we can continue with enabling PF mode.
46146e4384SMichal Wajdeczko *
47146e4384SMichal Wajdeczko * Return: true if the PF mode can be turned on.
48146e4384SMichal Wajdeczko */
xe_sriov_pf_readiness(struct xe_device * xe)49146e4384SMichal Wajdeczko bool xe_sriov_pf_readiness(struct xe_device *xe)
50146e4384SMichal Wajdeczko {
51146e4384SMichal Wajdeczko struct device *dev = xe->drm.dev;
52146e4384SMichal Wajdeczko struct pci_dev *pdev = to_pci_dev(dev);
53146e4384SMichal Wajdeczko int totalvfs = pci_sriov_get_totalvfs(pdev);
54146e4384SMichal Wajdeczko int newlimit = min_t(u16, wanted_max_vfs(xe), totalvfs);
55146e4384SMichal Wajdeczko
56146e4384SMichal Wajdeczko xe_assert(xe, totalvfs <= U16_MAX);
57146e4384SMichal Wajdeczko
58146e4384SMichal Wajdeczko if (!dev_is_pf(dev))
59146e4384SMichal Wajdeczko return false;
60146e4384SMichal Wajdeczko
61146e4384SMichal Wajdeczko if (!xe_device_uc_enabled(xe))
62146e4384SMichal Wajdeczko return pf_continue_as_native(xe, "Guc submission disabled");
63146e4384SMichal Wajdeczko
64146e4384SMichal Wajdeczko if (!newlimit)
65146e4384SMichal Wajdeczko return pf_continue_as_native(xe, "all VFs disabled");
66146e4384SMichal Wajdeczko
67146e4384SMichal Wajdeczko pf_reduce_totalvfs(xe, newlimit);
68146e4384SMichal Wajdeczko
69146e4384SMichal Wajdeczko xe->sriov.pf.device_total_vfs = totalvfs;
70146e4384SMichal Wajdeczko xe->sriov.pf.driver_max_vfs = newlimit;
71146e4384SMichal Wajdeczko
72146e4384SMichal Wajdeczko return true;
73146e4384SMichal Wajdeczko }
74146e4384SMichal Wajdeczko
75146e4384SMichal Wajdeczko /**
76*0bdd5b16SMichal Wajdeczko * xe_sriov_pf_init_early - Initialize SR-IOV PF specific data.
77*0bdd5b16SMichal Wajdeczko * @xe: the &xe_device to initialize
78*0bdd5b16SMichal Wajdeczko *
79*0bdd5b16SMichal Wajdeczko * Return: 0 on success or a negative error code on failure.
80*0bdd5b16SMichal Wajdeczko */
xe_sriov_pf_init_early(struct xe_device * xe)81*0bdd5b16SMichal Wajdeczko int xe_sriov_pf_init_early(struct xe_device *xe)
82*0bdd5b16SMichal Wajdeczko {
83*0bdd5b16SMichal Wajdeczko xe_assert(xe, IS_SRIOV_PF(xe));
84*0bdd5b16SMichal Wajdeczko
85*0bdd5b16SMichal Wajdeczko return drmm_mutex_init(&xe->drm, &xe->sriov.pf.master_lock);
86*0bdd5b16SMichal Wajdeczko }
87*0bdd5b16SMichal Wajdeczko
88*0bdd5b16SMichal Wajdeczko /**
89146e4384SMichal Wajdeczko * xe_sriov_pf_print_vfs_summary - Print SR-IOV PF information.
90146e4384SMichal Wajdeczko * @xe: the &xe_device to print info from
91146e4384SMichal Wajdeczko * @p: the &drm_printer
92146e4384SMichal Wajdeczko *
93146e4384SMichal Wajdeczko * Print SR-IOV PF related information into provided DRM printer.
94146e4384SMichal Wajdeczko */
xe_sriov_pf_print_vfs_summary(struct xe_device * xe,struct drm_printer * p)95146e4384SMichal Wajdeczko void xe_sriov_pf_print_vfs_summary(struct xe_device *xe, struct drm_printer *p)
96146e4384SMichal Wajdeczko {
97146e4384SMichal Wajdeczko struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
98146e4384SMichal Wajdeczko
99146e4384SMichal Wajdeczko xe_assert(xe, IS_SRIOV_PF(xe));
100146e4384SMichal Wajdeczko
101146e4384SMichal Wajdeczko drm_printf(p, "total: %u\n", xe->sriov.pf.device_total_vfs);
102146e4384SMichal Wajdeczko drm_printf(p, "supported: %u\n", xe->sriov.pf.driver_max_vfs);
103146e4384SMichal Wajdeczko drm_printf(p, "enabled: %u\n", pci_num_vf(pdev));
104146e4384SMichal Wajdeczko }
105