1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2023-2024 Intel Corporation 4 */ 5 6 #include <linux/debugfs.h> 7 #include <drm/drm_debugfs.h> 8 #include <drm/drm_managed.h> 9 10 #include "xe_assert.h" 11 #include "xe_configfs.h" 12 #include "xe_device.h" 13 #include "xe_gt_sriov_pf.h" 14 #include "xe_module.h" 15 #include "xe_sriov.h" 16 #include "xe_sriov_pf.h" 17 #include "xe_sriov_pf_helpers.h" 18 #include "xe_sriov_pf_service.h" 19 #include "xe_sriov_printk.h" 20 21 static unsigned int wanted_max_vfs(struct xe_device *xe) 22 { 23 if (IS_ENABLED(CONFIG_CONFIGFS_FS)) 24 return xe_configfs_get_max_vfs(to_pci_dev(xe->drm.dev)); 25 return xe_modparam.max_vfs; 26 } 27 28 static int pf_reduce_totalvfs(struct xe_device *xe, int limit) 29 { 30 struct device *dev = xe->drm.dev; 31 struct pci_dev *pdev = to_pci_dev(dev); 32 int err; 33 34 err = pci_sriov_set_totalvfs(pdev, limit); 35 if (err) 36 xe_sriov_notice(xe, "Failed to set number of VFs to %d (%pe)\n", 37 limit, ERR_PTR(err)); 38 return err; 39 } 40 41 static bool pf_continue_as_native(struct xe_device *xe, const char *why) 42 { 43 xe_sriov_dbg(xe, "%s, continuing as native\n", why); 44 pf_reduce_totalvfs(xe, 0); 45 return false; 46 } 47 48 /** 49 * xe_sriov_pf_readiness - Check if PF functionality can be enabled. 50 * @xe: the &xe_device to check 51 * 52 * This function is called as part of the SR-IOV probe to validate if all 53 * PF prerequisites are satisfied and we can continue with enabling PF mode. 54 * 55 * Return: true if the PF mode can be turned on. 56 */ 57 bool xe_sriov_pf_readiness(struct xe_device *xe) 58 { 59 struct device *dev = xe->drm.dev; 60 struct pci_dev *pdev = to_pci_dev(dev); 61 int totalvfs = pci_sriov_get_totalvfs(pdev); 62 int newlimit = min_t(u16, wanted_max_vfs(xe), totalvfs); 63 64 xe_assert(xe, totalvfs <= U16_MAX); 65 66 if (!dev_is_pf(dev)) 67 return false; 68 69 if (!xe_device_uc_enabled(xe)) 70 return pf_continue_as_native(xe, "Guc submission disabled"); 71 72 if (!newlimit) 73 return pf_continue_as_native(xe, "all VFs disabled"); 74 75 pf_reduce_totalvfs(xe, newlimit); 76 77 xe->sriov.pf.device_total_vfs = totalvfs; 78 xe->sriov.pf.driver_max_vfs = newlimit; 79 80 return true; 81 } 82 83 /** 84 * xe_sriov_pf_init_early - Initialize SR-IOV PF specific data. 85 * @xe: the &xe_device to initialize 86 * 87 * Return: 0 on success or a negative error code on failure. 88 */ 89 int xe_sriov_pf_init_early(struct xe_device *xe) 90 { 91 int err; 92 93 xe_assert(xe, IS_SRIOV_PF(xe)); 94 95 xe->sriov.pf.vfs = drmm_kcalloc(&xe->drm, 1 + xe_sriov_pf_get_totalvfs(xe), 96 sizeof(*xe->sriov.pf.vfs), GFP_KERNEL); 97 if (!xe->sriov.pf.vfs) 98 return -ENOMEM; 99 100 err = drmm_mutex_init(&xe->drm, &xe->sriov.pf.master_lock); 101 if (err) 102 return err; 103 104 xe_sriov_pf_service_init(xe); 105 106 return 0; 107 } 108 109 /** 110 * xe_sriov_pf_init_late() - Late initialization of the SR-IOV PF. 111 * @xe: the &xe_device to initialize 112 * 113 * This function can only be called on PF. 114 * 115 * Return: 0 on success or a negative error code on failure. 116 */ 117 int xe_sriov_pf_init_late(struct xe_device *xe) 118 { 119 struct xe_gt *gt; 120 unsigned int id; 121 int err; 122 123 xe_assert(xe, IS_SRIOV_PF(xe)); 124 125 for_each_gt(gt, xe, id) { 126 err = xe_gt_sriov_pf_init(gt); 127 if (err) 128 return err; 129 } 130 131 return 0; 132 } 133 134 /** 135 * xe_sriov_pf_wait_ready() - Wait until PF is ready to operate. 136 * @xe: the &xe_device to test 137 * 138 * This function can only be called on PF. 139 * 140 * Return: 0 on success or a negative error code on failure. 141 */ 142 int xe_sriov_pf_wait_ready(struct xe_device *xe) 143 { 144 struct xe_gt *gt; 145 unsigned int id; 146 int err; 147 148 if (xe_device_wedged(xe)) 149 return -ECANCELED; 150 151 for_each_gt(gt, xe, id) { 152 err = xe_gt_sriov_pf_wait_ready(gt); 153 if (err) 154 return err; 155 } 156 157 return 0; 158 } 159 160 /** 161 * xe_sriov_pf_print_vfs_summary - Print SR-IOV PF information. 162 * @xe: the &xe_device to print info from 163 * @p: the &drm_printer 164 * 165 * Print SR-IOV PF related information into provided DRM printer. 166 */ 167 void xe_sriov_pf_print_vfs_summary(struct xe_device *xe, struct drm_printer *p) 168 { 169 struct pci_dev *pdev = to_pci_dev(xe->drm.dev); 170 171 xe_assert(xe, IS_SRIOV_PF(xe)); 172 173 drm_printf(p, "total: %u\n", xe->sriov.pf.device_total_vfs); 174 drm_printf(p, "supported: %u\n", xe->sriov.pf.driver_max_vfs); 175 drm_printf(p, "enabled: %u\n", pci_num_vf(pdev)); 176 } 177