1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2023 Intel Corporation 4 */ 5 6 #include <linux/fault-inject.h> 7 8 #include <drm/drm_managed.h> 9 10 #include "regs/xe_regs.h" 11 12 #include "xe_assert.h" 13 #include "xe_device.h" 14 #include "xe_mmio.h" 15 #include "xe_sriov.h" 16 #include "xe_sriov_pf.h" 17 #include "xe_sriov_vf.h" 18 #include "xe_sriov_vf_ccs.h" 19 20 /** 21 * xe_sriov_mode_to_string - Convert enum value to string. 22 * @mode: the &xe_sriov_mode to convert 23 * 24 * Returns: SR-IOV mode as a user friendly string. 25 */ 26 const char *xe_sriov_mode_to_string(enum xe_sriov_mode mode) 27 { 28 switch (mode) { 29 case XE_SRIOV_MODE_NONE: 30 return "none"; 31 case XE_SRIOV_MODE_PF: 32 return "SR-IOV PF"; 33 case XE_SRIOV_MODE_VF: 34 return "SR-IOV VF"; 35 default: 36 return "<invalid>"; 37 } 38 } 39 40 static bool test_is_vf(struct xe_device *xe) 41 { 42 u32 value = xe_mmio_read32(xe_root_tile_mmio(xe), VF_CAP_REG); 43 44 return value & VF_CAP; 45 } 46 47 /** 48 * xe_sriov_probe_early - Probe a SR-IOV mode. 49 * @xe: the &xe_device to probe mode on 50 * 51 * This function should be called only once and as soon as possible during 52 * driver probe to detect whether we are running a SR-IOV Physical Function 53 * (PF) or a Virtual Function (VF) device. 54 * 55 * SR-IOV PF mode detection is based on PCI @dev_is_pf() function. 56 * SR-IOV VF mode detection is based on dedicated MMIO register read. 57 */ 58 void xe_sriov_probe_early(struct xe_device *xe) 59 { 60 struct pci_dev *pdev = to_pci_dev(xe->drm.dev); 61 enum xe_sriov_mode mode = XE_SRIOV_MODE_NONE; 62 bool has_sriov = xe->info.has_sriov; 63 64 if (has_sriov) { 65 if (test_is_vf(xe)) 66 mode = XE_SRIOV_MODE_VF; 67 else if (xe_sriov_pf_readiness(xe)) 68 mode = XE_SRIOV_MODE_PF; 69 } else if (pci_sriov_get_totalvfs(pdev)) { 70 /* 71 * Even if we have not enabled SR-IOV support using the 72 * platform specific has_sriov flag, the hardware may still 73 * report SR-IOV capability and the PCI layer may wrongly 74 * advertise driver support to enable VFs. Explicitly reset 75 * the number of supported VFs to zero to avoid confusion. 76 */ 77 drm_info(&xe->drm, "Support for SR-IOV is not available\n"); 78 pci_sriov_set_totalvfs(pdev, 0); 79 } 80 81 xe_assert(xe, !xe->sriov.__mode); 82 xe->sriov.__mode = mode; 83 xe_assert(xe, xe->sriov.__mode); 84 85 if (IS_SRIOV(xe)) 86 drm_info(&xe->drm, "Running in %s mode\n", 87 xe_sriov_mode_to_string(xe_device_sriov_mode(xe))); 88 } 89 90 static void fini_sriov(struct drm_device *drm, void *arg) 91 { 92 struct xe_device *xe = arg; 93 94 destroy_workqueue(xe->sriov.wq); 95 xe->sriov.wq = NULL; 96 } 97 98 /** 99 * xe_sriov_init - Initialize SR-IOV specific data. 100 * @xe: the &xe_device to initialize 101 * 102 * In this function we create dedicated workqueue that will be used 103 * by the SR-IOV specific workers. 104 * 105 * Return: 0 on success or a negative error code on failure. 106 */ 107 int xe_sriov_init(struct xe_device *xe) 108 { 109 if (!IS_SRIOV(xe)) 110 return 0; 111 112 if (IS_SRIOV_PF(xe)) { 113 int err = xe_sriov_pf_init_early(xe); 114 115 if (err) 116 return err; 117 } 118 119 if (IS_SRIOV_VF(xe)) 120 xe_sriov_vf_init_early(xe); 121 122 xe_assert(xe, !xe->sriov.wq); 123 xe->sriov.wq = alloc_workqueue("xe-sriov-wq", 0, 0); 124 if (!xe->sriov.wq) 125 return -ENOMEM; 126 127 return drmm_add_action_or_reset(&xe->drm, fini_sriov, xe); 128 } 129 ALLOW_ERROR_INJECTION(xe_sriov_init, ERRNO); /* See xe_pci_probe() */ 130 131 /** 132 * xe_sriov_print_info - Print basic SR-IOV information. 133 * @xe: the &xe_device to print info from 134 * @p: the &drm_printer 135 * 136 * Print SR-IOV related information into provided DRM printer. 137 */ 138 void xe_sriov_print_info(struct xe_device *xe, struct drm_printer *p) 139 { 140 drm_printf(p, "supported: %s\n", str_yes_no(xe_device_has_sriov(xe))); 141 drm_printf(p, "enabled: %s\n", str_yes_no(IS_SRIOV(xe))); 142 drm_printf(p, "mode: %s\n", xe_sriov_mode_to_string(xe_device_sriov_mode(xe))); 143 } 144 145 /** 146 * xe_sriov_function_name() - Get SR-IOV Function name. 147 * @n: the Function number (identifier) to get name of 148 * @buf: the buffer to format to 149 * @size: size of the buffer (shall be at least 5 bytes) 150 * 151 * Return: formatted function name ("PF" or "VF%u"). 152 */ 153 const char *xe_sriov_function_name(unsigned int n, char *buf, size_t size) 154 { 155 if (n) 156 snprintf(buf, size, "VF%u", n); 157 else 158 strscpy(buf, "PF", size); 159 return buf; 160 } 161 162 /** 163 * xe_sriov_init_late() - SR-IOV late initialization functions. 164 * @xe: the &xe_device to initialize 165 * 166 * Return: 0 on success or a negative error code on failure. 167 */ 168 int xe_sriov_init_late(struct xe_device *xe) 169 { 170 if (IS_SRIOV_VF(xe)) 171 return xe_sriov_vf_init_late(xe); 172 173 return 0; 174 } 175