1 // SPDX-License-Identifier: MIT
2 /*
3 * Copyright © 2023-2024 Intel Corporation
4 */
5
6 #include <drm/drm_managed.h>
7
8 #include "xe_assert.h"
9 #include "xe_device.h"
10 #include "xe_module.h"
11 #include "xe_sriov.h"
12 #include "xe_sriov_pf.h"
13 #include "xe_sriov_printk.h"
14
wanted_max_vfs(struct xe_device * xe)15 static unsigned int wanted_max_vfs(struct xe_device *xe)
16 {
17 return xe_modparam.max_vfs;
18 }
19
pf_reduce_totalvfs(struct xe_device * xe,int limit)20 static int pf_reduce_totalvfs(struct xe_device *xe, int limit)
21 {
22 struct device *dev = xe->drm.dev;
23 struct pci_dev *pdev = to_pci_dev(dev);
24 int err;
25
26 err = pci_sriov_set_totalvfs(pdev, limit);
27 if (err)
28 xe_sriov_notice(xe, "Failed to set number of VFs to %d (%pe)\n",
29 limit, ERR_PTR(err));
30 return err;
31 }
32
pf_continue_as_native(struct xe_device * xe,const char * why)33 static bool pf_continue_as_native(struct xe_device *xe, const char *why)
34 {
35 xe_sriov_dbg(xe, "%s, continuing as native\n", why);
36 pf_reduce_totalvfs(xe, 0);
37 return false;
38 }
39
40 /**
41 * xe_sriov_pf_readiness - Check if PF functionality can be enabled.
42 * @xe: the &xe_device to check
43 *
44 * This function is called as part of the SR-IOV probe to validate if all
45 * PF prerequisites are satisfied and we can continue with enabling PF mode.
46 *
47 * Return: true if the PF mode can be turned on.
48 */
xe_sriov_pf_readiness(struct xe_device * xe)49 bool xe_sriov_pf_readiness(struct xe_device *xe)
50 {
51 struct device *dev = xe->drm.dev;
52 struct pci_dev *pdev = to_pci_dev(dev);
53 int totalvfs = pci_sriov_get_totalvfs(pdev);
54 int newlimit = min_t(u16, wanted_max_vfs(xe), totalvfs);
55
56 xe_assert(xe, totalvfs <= U16_MAX);
57
58 if (!dev_is_pf(dev))
59 return false;
60
61 if (!xe_device_uc_enabled(xe))
62 return pf_continue_as_native(xe, "Guc submission disabled");
63
64 if (!newlimit)
65 return pf_continue_as_native(xe, "all VFs disabled");
66
67 pf_reduce_totalvfs(xe, newlimit);
68
69 xe->sriov.pf.device_total_vfs = totalvfs;
70 xe->sriov.pf.driver_max_vfs = newlimit;
71
72 return true;
73 }
74
75 /**
76 * xe_sriov_pf_init_early - Initialize SR-IOV PF specific data.
77 * @xe: the &xe_device to initialize
78 *
79 * Return: 0 on success or a negative error code on failure.
80 */
xe_sriov_pf_init_early(struct xe_device * xe)81 int xe_sriov_pf_init_early(struct xe_device *xe)
82 {
83 xe_assert(xe, IS_SRIOV_PF(xe));
84
85 return drmm_mutex_init(&xe->drm, &xe->sriov.pf.master_lock);
86 }
87
88 /**
89 * xe_sriov_pf_print_vfs_summary - Print SR-IOV PF information.
90 * @xe: the &xe_device to print info from
91 * @p: the &drm_printer
92 *
93 * Print SR-IOV PF related information into provided DRM printer.
94 */
xe_sriov_pf_print_vfs_summary(struct xe_device * xe,struct drm_printer * p)95 void xe_sriov_pf_print_vfs_summary(struct xe_device *xe, struct drm_printer *p)
96 {
97 struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
98
99 xe_assert(xe, IS_SRIOV_PF(xe));
100
101 drm_printf(p, "total: %u\n", xe->sriov.pf.device_total_vfs);
102 drm_printf(p, "supported: %u\n", xe->sriov.pf.driver_max_vfs);
103 drm_printf(p, "enabled: %u\n", pci_num_vf(pdev));
104 }
105