1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
/* SPDX-License-Identifier: MIT */
/*
* Copyright(c) 2023 Intel Corporation. All rights reserved.
*/
#ifndef __IGT_SRIOV_DEVICE_H__
#define __IGT_SRIOV_DEVICE_H__
#include <stdbool.h>
#include <stddef.h>
/* Library for managing SR-IOV (Single Root I/O Virtualization)
* devices.
*
* SR-IOV is a specification that allows a single PCIe physical
* device to appear as a physical function (PF) and multiple virtual
* functions (VFs) to the operating system.
*/
bool igt_sriov_is_pf(int device);
bool igt_sriov_vfs_supported(int pf);
unsigned int igt_sriov_get_total_vfs(int pf);
unsigned int igt_sriov_get_enabled_vfs(int pf);
void igt_sriov_enable_vfs(int pf, unsigned int num_vfs);
void igt_sriov_disable_vfs(int pf);
bool igt_sriov_is_driver_autoprobe_enabled(int pf);
void igt_sriov_enable_driver_autoprobe(int pf);
void igt_sriov_disable_driver_autoprobe(int pf);
int igt_sriov_open_vf_drm_device(int pf, unsigned int vf_num);
bool igt_sriov_is_vf_drm_driver_probed(int pf, unsigned int vf_num);
void igt_sriov_bind_vf_drm_driver(int pf, unsigned int vf_num);
void igt_sriov_unbind_vf_drm_driver(int pf, unsigned int vf_num);
int igt_sriov_device_sysfs_open(int pf, unsigned int vf_num);
bool igt_sriov_device_reset_exists(int pf, unsigned int vf_num);
bool igt_sriov_device_reset(int pf, unsigned int vf_num);
bool intel_is_vf_device(int device);
/**
* __is_valid_range - Helper to check VF range is valid
* @start_vf: Starting VF number
* @end_vf: Ending VF number
* @total_vfs: Total number of VFs
*
* Return: true if the range is valid, false otherwise.
*/
static inline bool __is_valid_range(unsigned int start_vf, unsigned int end_vf,
unsigned int total_vfs)
{
return !igt_warn_on_f(start_vf > end_vf || end_vf > total_vfs || start_vf == 0,
"start_vf=%u, end_vf=%u, total_vfs=%u\n",
start_vf, end_vf, total_vfs);
}
/**
* igt_sriov_random_vf_in_range - Get a random VF number within a specified range
* @pf_fd: PF device file descriptor
* @start: Starting VF number in the range
* @end: Ending VF number in the range
*
* Returns a random VF number within the specified range [start, end].
* If the range is invalid (start > end, end > total VFs,
* or start == 0), the function returns 0.
*
* Return: A random VF number within the range, or 0 if the range is invalid.
*/
static inline unsigned int
igt_sriov_random_vf_in_range(int pf_fd, unsigned int start, unsigned int end)
{
unsigned int total_vfs = igt_sriov_get_total_vfs(pf_fd);
if (!__is_valid_range(start, end, total_vfs))
return 0;
return start + random() % (end - start + 1);
}
/**
* for_each_sriov_vf - Helper for running code on each VF
* @__pf_fd: PF device file descriptor
* @__vf_num: VFs iterator
*
* For loop that iterates over all VFs associated with given PF @__pf_fd.
*/
#define for_each_sriov_vf(__pf_fd, __vf_num) \
for (unsigned int __vf_num = 1, __total_vfs = igt_sriov_get_total_vfs(__pf_fd); \
__vf_num <= __total_vfs; \
++__vf_num)
#define for_each_sriov_num_vfs for_each_sriov_vf
/**
* for_each_sriov_vf_in_range - Iterate over VFs in a specified range
* @__pf_fd: PF device file descriptor
* @__start: Starting VF number in the range
* @__end: Ending VF number in the range
* @__vf_num: Variable to store the random VF number
*
* For loop that iterates over VFs associated with given PF @__pf_fd,
* within the specified range [__start, __end]. The loop runs only if
* the range is valid.
*/
#define for_each_sriov_vf_in_range(__pf_fd, __start, __end, __vf_num) \
for (unsigned int __vf_num = __is_valid_range((__start), (__end), \
igt_sriov_get_total_vfs(__pf_fd)) ? \
(__start) : 0; \
__vf_num && __vf_num <= (__end); \
++__vf_num)
#define for_each_sriov_num_vfs_in_range for_each_sriov_vf_in_range
/**
* for_random_sriov_vf_in_range - Iterate over a random VF in a specified range
* @__pf_fd: PF device file descriptor
* @__start: Starting VF number in the range
* @__end: Ending VF number in the range
* @__vf_num: Variable to store the random VF number
*
* Iterates over a random VF number within the specified range [__start, __end].
* The loop runs only if the range is valid and a random
* VF number is successfully selected.
*/
#define for_random_sriov_vf_in_range(__pf_fd, __start, __end, __vf_num) \
for (unsigned int __vf_num = igt_sriov_random_vf_in_range(__pf_fd, __start, __end); \
__vf_num != 0; __vf_num = 0)
/**
* for_random_sriov_vf_starting_from - Iterate over a random VF starting from a specified VF
* @__pf_fd: PF device file descriptor
* @__start: Starting VF number
* @__vf_num: Variable to store the random VF number
*
* This macro iterates over a random VF number starting from the specified
* VF number @__start to the total number of VFs associated with the given
* PF @__pf_fd.
*/
#define for_random_sriov_vf_starting_from(__pf_fd, __start, __vf_num) \
for_random_sriov_vf_in_range(__pf_fd, __start, igt_sriov_get_total_vfs(__pf_fd), __vf_num)
/**
* for_random_sriov_vf - Iterate over a random VF for a given PF
* @__pf_fd: PF device file descriptor
* @__vf_num: Variable to store the random VF number
*
* Iterates over a random VF number selected from the range
* of all VFs associated with the given PF @__pf_fd. The loop runs only
* if a random VF number is successfully selected.
*/
#define for_random_sriov_vf(__pf_fd, __vf_num) \
for_random_sriov_vf_in_range(__pf_fd, 1, igt_sriov_get_total_vfs(__pf_fd), __vf_num)
/* for_random_sriov_num_vfs - Alias for for_random_sriov_vf */
#define for_random_sriov_num_vfs for_random_sriov_vf
/**
* for_last_sriov_vf - Helper for running code on last VF
* @__pf_fd: PF device file descriptor
* @__vf_num: stores last VF number
*
* Helper allows to run code using last VF number (stored in @__vf_num)
* associated with given PF @__pf_fd.
*/
#define for_last_sriov_vf(__pf_fd, __vf_num) \
for (unsigned int __vf_num = igt_sriov_get_total_vfs(__pf_fd), __tmp = 0; \
__tmp < 1; \
++__tmp)
#define for_max_sriov_num_vfs for_last_sriov_vf
#endif /* __IGT_SRIOV_DEVICE_H__ */
|