xref: /OK3568_Linux_fs/kernel/Documentation/PCI/pci-iov-howto.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun.. SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun.. include:: <isonum.txt>
3*4882a593Smuzhiyun
4*4882a593Smuzhiyun====================================
5*4882a593SmuzhiyunPCI Express I/O Virtualization Howto
6*4882a593Smuzhiyun====================================
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun:Copyright: |copy| 2009 Intel Corporation
9*4882a593Smuzhiyun:Authors: - Yu Zhao <yu.zhao@intel.com>
10*4882a593Smuzhiyun          - Donald Dutile <ddutile@redhat.com>
11*4882a593Smuzhiyun
12*4882a593SmuzhiyunOverview
13*4882a593Smuzhiyun========
14*4882a593Smuzhiyun
15*4882a593SmuzhiyunWhat is SR-IOV
16*4882a593Smuzhiyun--------------
17*4882a593Smuzhiyun
18*4882a593SmuzhiyunSingle Root I/O Virtualization (SR-IOV) is a PCI Express Extended
19*4882a593Smuzhiyuncapability which makes one physical device appear as multiple virtual
20*4882a593Smuzhiyundevices. The physical device is referred to as Physical Function (PF)
21*4882a593Smuzhiyunwhile the virtual devices are referred to as Virtual Functions (VF).
22*4882a593SmuzhiyunAllocation of the VF can be dynamically controlled by the PF via
23*4882a593Smuzhiyunregisters encapsulated in the capability. By default, this feature is
24*4882a593Smuzhiyunnot enabled and the PF behaves as traditional PCIe device. Once it's
25*4882a593Smuzhiyunturned on, each VF's PCI configuration space can be accessed by its own
26*4882a593SmuzhiyunBus, Device and Function Number (Routing ID). And each VF also has PCI
27*4882a593SmuzhiyunMemory Space, which is used to map its register set. VF device driver
28*4882a593Smuzhiyunoperates on the register set so it can be functional and appear as a
29*4882a593Smuzhiyunreal existing PCI device.
30*4882a593Smuzhiyun
31*4882a593SmuzhiyunUser Guide
32*4882a593Smuzhiyun==========
33*4882a593Smuzhiyun
34*4882a593SmuzhiyunHow can I enable SR-IOV capability
35*4882a593Smuzhiyun----------------------------------
36*4882a593Smuzhiyun
37*4882a593SmuzhiyunMultiple methods are available for SR-IOV enablement.
38*4882a593SmuzhiyunIn the first method, the device driver (PF driver) will control the
39*4882a593Smuzhiyunenabling and disabling of the capability via API provided by SR-IOV core.
40*4882a593SmuzhiyunIf the hardware has SR-IOV capability, loading its PF driver would
41*4882a593Smuzhiyunenable it and all VFs associated with the PF.  Some PF drivers require
42*4882a593Smuzhiyuna module parameter to be set to determine the number of VFs to enable.
43*4882a593SmuzhiyunIn the second method, a write to the sysfs file sriov_numvfs will
44*4882a593Smuzhiyunenable and disable the VFs associated with a PCIe PF.  This method
45*4882a593Smuzhiyunenables per-PF, VF enable/disable values versus the first method,
46*4882a593Smuzhiyunwhich applies to all PFs of the same device.  Additionally, the
47*4882a593SmuzhiyunPCI SRIOV core support ensures that enable/disable operations are
48*4882a593Smuzhiyunvalid to reduce duplication in multiple drivers for the same
49*4882a593Smuzhiyunchecks, e.g., check numvfs == 0 if enabling VFs, ensure
50*4882a593Smuzhiyunnumvfs <= totalvfs.
51*4882a593SmuzhiyunThe second method is the recommended method for new/future VF devices.
52*4882a593Smuzhiyun
53*4882a593SmuzhiyunHow can I use the Virtual Functions
54*4882a593Smuzhiyun-----------------------------------
55*4882a593Smuzhiyun
56*4882a593SmuzhiyunThe VF is treated as hot-plugged PCI devices in the kernel, so they
57*4882a593Smuzhiyunshould be able to work in the same way as real PCI devices. The VF
58*4882a593Smuzhiyunrequires device driver that is same as a normal PCI device's.
59*4882a593Smuzhiyun
60*4882a593SmuzhiyunDeveloper Guide
61*4882a593Smuzhiyun===============
62*4882a593Smuzhiyun
63*4882a593SmuzhiyunSR-IOV API
64*4882a593Smuzhiyun----------
65*4882a593Smuzhiyun
66*4882a593SmuzhiyunTo enable SR-IOV capability:
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun(a) For the first method, in the driver::
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun	int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn);
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun'nr_virtfn' is number of VFs to be enabled.
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun(b) For the second method, from sysfs::
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun	echo 'nr_virtfn' > \
77*4882a593Smuzhiyun        /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs
78*4882a593Smuzhiyun
79*4882a593SmuzhiyunTo disable SR-IOV capability:
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun(a) For the first method, in the driver::
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun	void pci_disable_sriov(struct pci_dev *dev);
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun(b) For the second method, from sysfs::
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun	echo  0 > \
88*4882a593Smuzhiyun        /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs
89*4882a593Smuzhiyun
90*4882a593SmuzhiyunTo enable auto probing VFs by a compatible driver on the host, run
91*4882a593Smuzhiyuncommand below before enabling SR-IOV capabilities. This is the
92*4882a593Smuzhiyundefault behavior.
93*4882a593Smuzhiyun::
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun	echo 1 > \
96*4882a593Smuzhiyun        /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_drivers_autoprobe
97*4882a593Smuzhiyun
98*4882a593SmuzhiyunTo disable auto probing VFs by a compatible driver on the host, run
99*4882a593Smuzhiyuncommand below before enabling SR-IOV capabilities. Updating this
100*4882a593Smuzhiyunentry will not affect VFs which are already probed.
101*4882a593Smuzhiyun::
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun	echo  0 > \
104*4882a593Smuzhiyun        /sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_drivers_autoprobe
105*4882a593Smuzhiyun
106*4882a593SmuzhiyunUsage example
107*4882a593Smuzhiyun-------------
108*4882a593Smuzhiyun
109*4882a593SmuzhiyunFollowing piece of code illustrates the usage of the SR-IOV API.
110*4882a593Smuzhiyun::
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun	static int dev_probe(struct pci_dev *dev, const struct pci_device_id *id)
113*4882a593Smuzhiyun	{
114*4882a593Smuzhiyun		pci_enable_sriov(dev, NR_VIRTFN);
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun		...
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun		return 0;
119*4882a593Smuzhiyun	}
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun	static void dev_remove(struct pci_dev *dev)
122*4882a593Smuzhiyun	{
123*4882a593Smuzhiyun		pci_disable_sriov(dev);
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun		...
126*4882a593Smuzhiyun	}
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun	static int dev_suspend(struct pci_dev *dev, pm_message_t state)
129*4882a593Smuzhiyun	{
130*4882a593Smuzhiyun		...
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun		return 0;
133*4882a593Smuzhiyun	}
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun	static int dev_resume(struct pci_dev *dev)
136*4882a593Smuzhiyun	{
137*4882a593Smuzhiyun		...
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun		return 0;
140*4882a593Smuzhiyun	}
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun	static void dev_shutdown(struct pci_dev *dev)
143*4882a593Smuzhiyun	{
144*4882a593Smuzhiyun		...
145*4882a593Smuzhiyun	}
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun	static int dev_sriov_configure(struct pci_dev *dev, int numvfs)
148*4882a593Smuzhiyun	{
149*4882a593Smuzhiyun		if (numvfs > 0) {
150*4882a593Smuzhiyun			...
151*4882a593Smuzhiyun			pci_enable_sriov(dev, numvfs);
152*4882a593Smuzhiyun			...
153*4882a593Smuzhiyun			return numvfs;
154*4882a593Smuzhiyun		}
155*4882a593Smuzhiyun		if (numvfs == 0) {
156*4882a593Smuzhiyun			....
157*4882a593Smuzhiyun			pci_disable_sriov(dev);
158*4882a593Smuzhiyun			...
159*4882a593Smuzhiyun			return 0;
160*4882a593Smuzhiyun		}
161*4882a593Smuzhiyun	}
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun	static struct pci_driver dev_driver = {
164*4882a593Smuzhiyun		.name =		"SR-IOV Physical Function driver",
165*4882a593Smuzhiyun		.id_table =	dev_id_table,
166*4882a593Smuzhiyun		.probe =	dev_probe,
167*4882a593Smuzhiyun		.remove =	dev_remove,
168*4882a593Smuzhiyun		.suspend =	dev_suspend,
169*4882a593Smuzhiyun		.resume =	dev_resume,
170*4882a593Smuzhiyun		.shutdown =	dev_shutdown,
171*4882a593Smuzhiyun		.sriov_configure = dev_sriov_configure,
172*4882a593Smuzhiyun	};
173