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