xref: /OK3568_Linux_fs/kernel/drivers/pci/ats.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * PCI Express I/O Virtualization (IOV) support
4*4882a593Smuzhiyun  *   Address Translation Service 1.0
5*4882a593Smuzhiyun  *   Page Request Interface added by Joerg Roedel <joerg.roedel@amd.com>
6*4882a593Smuzhiyun  *   PASID support added by Joerg Roedel <joerg.roedel@amd.com>
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  * Copyright (C) 2009 Intel Corporation, Yu Zhao <yu.zhao@intel.com>
9*4882a593Smuzhiyun  * Copyright (C) 2011 Advanced Micro Devices,
10*4882a593Smuzhiyun  */
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include <linux/export.h>
13*4882a593Smuzhiyun #include <linux/pci-ats.h>
14*4882a593Smuzhiyun #include <linux/pci.h>
15*4882a593Smuzhiyun #include <linux/slab.h>
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #include "pci.h"
18*4882a593Smuzhiyun 
pci_ats_init(struct pci_dev * dev)19*4882a593Smuzhiyun void pci_ats_init(struct pci_dev *dev)
20*4882a593Smuzhiyun {
21*4882a593Smuzhiyun 	int pos;
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun 	if (pci_ats_disabled())
24*4882a593Smuzhiyun 		return;
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun 	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ATS);
27*4882a593Smuzhiyun 	if (!pos)
28*4882a593Smuzhiyun 		return;
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun 	dev->ats_cap = pos;
31*4882a593Smuzhiyun }
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun /**
34*4882a593Smuzhiyun  * pci_ats_supported - check if the device can use ATS
35*4882a593Smuzhiyun  * @dev: the PCI device
36*4882a593Smuzhiyun  *
37*4882a593Smuzhiyun  * Returns true if the device supports ATS and is allowed to use it, false
38*4882a593Smuzhiyun  * otherwise.
39*4882a593Smuzhiyun  */
pci_ats_supported(struct pci_dev * dev)40*4882a593Smuzhiyun bool pci_ats_supported(struct pci_dev *dev)
41*4882a593Smuzhiyun {
42*4882a593Smuzhiyun 	if (!dev->ats_cap)
43*4882a593Smuzhiyun 		return false;
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun 	return (dev->untrusted == 0);
46*4882a593Smuzhiyun }
47*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pci_ats_supported);
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun /**
50*4882a593Smuzhiyun  * pci_enable_ats - enable the ATS capability
51*4882a593Smuzhiyun  * @dev: the PCI device
52*4882a593Smuzhiyun  * @ps: the IOMMU page shift
53*4882a593Smuzhiyun  *
54*4882a593Smuzhiyun  * Returns 0 on success, or negative on failure.
55*4882a593Smuzhiyun  */
pci_enable_ats(struct pci_dev * dev,int ps)56*4882a593Smuzhiyun int pci_enable_ats(struct pci_dev *dev, int ps)
57*4882a593Smuzhiyun {
58*4882a593Smuzhiyun 	u16 ctrl;
59*4882a593Smuzhiyun 	struct pci_dev *pdev;
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun 	if (!pci_ats_supported(dev))
62*4882a593Smuzhiyun 		return -EINVAL;
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun 	if (WARN_ON(dev->ats_enabled))
65*4882a593Smuzhiyun 		return -EBUSY;
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun 	if (ps < PCI_ATS_MIN_STU)
68*4882a593Smuzhiyun 		return -EINVAL;
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun 	/*
71*4882a593Smuzhiyun 	 * Note that enabling ATS on a VF fails unless it's already enabled
72*4882a593Smuzhiyun 	 * with the same STU on the PF.
73*4882a593Smuzhiyun 	 */
74*4882a593Smuzhiyun 	ctrl = PCI_ATS_CTRL_ENABLE;
75*4882a593Smuzhiyun 	if (dev->is_virtfn) {
76*4882a593Smuzhiyun 		pdev = pci_physfn(dev);
77*4882a593Smuzhiyun 		if (pdev->ats_stu != ps)
78*4882a593Smuzhiyun 			return -EINVAL;
79*4882a593Smuzhiyun 	} else {
80*4882a593Smuzhiyun 		dev->ats_stu = ps;
81*4882a593Smuzhiyun 		ctrl |= PCI_ATS_CTRL_STU(dev->ats_stu - PCI_ATS_MIN_STU);
82*4882a593Smuzhiyun 	}
83*4882a593Smuzhiyun 	pci_write_config_word(dev, dev->ats_cap + PCI_ATS_CTRL, ctrl);
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 	dev->ats_enabled = 1;
86*4882a593Smuzhiyun 	return 0;
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pci_enable_ats);
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun /**
91*4882a593Smuzhiyun  * pci_disable_ats - disable the ATS capability
92*4882a593Smuzhiyun  * @dev: the PCI device
93*4882a593Smuzhiyun  */
pci_disable_ats(struct pci_dev * dev)94*4882a593Smuzhiyun void pci_disable_ats(struct pci_dev *dev)
95*4882a593Smuzhiyun {
96*4882a593Smuzhiyun 	u16 ctrl;
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun 	if (WARN_ON(!dev->ats_enabled))
99*4882a593Smuzhiyun 		return;
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun 	pci_read_config_word(dev, dev->ats_cap + PCI_ATS_CTRL, &ctrl);
102*4882a593Smuzhiyun 	ctrl &= ~PCI_ATS_CTRL_ENABLE;
103*4882a593Smuzhiyun 	pci_write_config_word(dev, dev->ats_cap + PCI_ATS_CTRL, ctrl);
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun 	dev->ats_enabled = 0;
106*4882a593Smuzhiyun }
107*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pci_disable_ats);
108*4882a593Smuzhiyun 
pci_restore_ats_state(struct pci_dev * dev)109*4882a593Smuzhiyun void pci_restore_ats_state(struct pci_dev *dev)
110*4882a593Smuzhiyun {
111*4882a593Smuzhiyun 	u16 ctrl;
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun 	if (!dev->ats_enabled)
114*4882a593Smuzhiyun 		return;
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	ctrl = PCI_ATS_CTRL_ENABLE;
117*4882a593Smuzhiyun 	if (!dev->is_virtfn)
118*4882a593Smuzhiyun 		ctrl |= PCI_ATS_CTRL_STU(dev->ats_stu - PCI_ATS_MIN_STU);
119*4882a593Smuzhiyun 	pci_write_config_word(dev, dev->ats_cap + PCI_ATS_CTRL, ctrl);
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun /**
123*4882a593Smuzhiyun  * pci_ats_queue_depth - query the ATS Invalidate Queue Depth
124*4882a593Smuzhiyun  * @dev: the PCI device
125*4882a593Smuzhiyun  *
126*4882a593Smuzhiyun  * Returns the queue depth on success, or negative on failure.
127*4882a593Smuzhiyun  *
128*4882a593Smuzhiyun  * The ATS spec uses 0 in the Invalidate Queue Depth field to
129*4882a593Smuzhiyun  * indicate that the function can accept 32 Invalidate Request.
130*4882a593Smuzhiyun  * But here we use the `real' values (i.e. 1~32) for the Queue
131*4882a593Smuzhiyun  * Depth; and 0 indicates the function shares the Queue with
132*4882a593Smuzhiyun  * other functions (doesn't exclusively own a Queue).
133*4882a593Smuzhiyun  */
pci_ats_queue_depth(struct pci_dev * dev)134*4882a593Smuzhiyun int pci_ats_queue_depth(struct pci_dev *dev)
135*4882a593Smuzhiyun {
136*4882a593Smuzhiyun 	u16 cap;
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 	if (!dev->ats_cap)
139*4882a593Smuzhiyun 		return -EINVAL;
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 	if (dev->is_virtfn)
142*4882a593Smuzhiyun 		return 0;
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun 	pci_read_config_word(dev, dev->ats_cap + PCI_ATS_CAP, &cap);
145*4882a593Smuzhiyun 	return PCI_ATS_CAP_QDEP(cap) ? PCI_ATS_CAP_QDEP(cap) : PCI_ATS_MAX_QDEP;
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun /**
149*4882a593Smuzhiyun  * pci_ats_page_aligned - Return Page Aligned Request bit status.
150*4882a593Smuzhiyun  * @pdev: the PCI device
151*4882a593Smuzhiyun  *
152*4882a593Smuzhiyun  * Returns 1, if the Untranslated Addresses generated by the device
153*4882a593Smuzhiyun  * are always aligned or 0 otherwise.
154*4882a593Smuzhiyun  *
155*4882a593Smuzhiyun  * Per PCIe spec r4.0, sec 10.5.1.2, if the Page Aligned Request bit
156*4882a593Smuzhiyun  * is set, it indicates the Untranslated Addresses generated by the
157*4882a593Smuzhiyun  * device are always aligned to a 4096 byte boundary.
158*4882a593Smuzhiyun  */
pci_ats_page_aligned(struct pci_dev * pdev)159*4882a593Smuzhiyun int pci_ats_page_aligned(struct pci_dev *pdev)
160*4882a593Smuzhiyun {
161*4882a593Smuzhiyun 	u16 cap;
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	if (!pdev->ats_cap)
164*4882a593Smuzhiyun 		return 0;
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun 	pci_read_config_word(pdev, pdev->ats_cap + PCI_ATS_CAP, &cap);
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun 	if (cap & PCI_ATS_CAP_PAGE_ALIGNED)
169*4882a593Smuzhiyun 		return 1;
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun 	return 0;
172*4882a593Smuzhiyun }
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun #ifdef CONFIG_PCI_PRI
pci_pri_init(struct pci_dev * pdev)175*4882a593Smuzhiyun void pci_pri_init(struct pci_dev *pdev)
176*4882a593Smuzhiyun {
177*4882a593Smuzhiyun 	u16 status;
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun 	pdev->pri_cap = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 	if (!pdev->pri_cap)
182*4882a593Smuzhiyun 		return;
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 	pci_read_config_word(pdev, pdev->pri_cap + PCI_PRI_STATUS, &status);
185*4882a593Smuzhiyun 	if (status & PCI_PRI_STATUS_PASID)
186*4882a593Smuzhiyun 		pdev->pasid_required = 1;
187*4882a593Smuzhiyun }
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun /**
190*4882a593Smuzhiyun  * pci_enable_pri - Enable PRI capability
191*4882a593Smuzhiyun  * @pdev: PCI device structure
192*4882a593Smuzhiyun  * @reqs: outstanding requests
193*4882a593Smuzhiyun  *
194*4882a593Smuzhiyun  * Returns 0 on success, negative value on error
195*4882a593Smuzhiyun  */
pci_enable_pri(struct pci_dev * pdev,u32 reqs)196*4882a593Smuzhiyun int pci_enable_pri(struct pci_dev *pdev, u32 reqs)
197*4882a593Smuzhiyun {
198*4882a593Smuzhiyun 	u16 control, status;
199*4882a593Smuzhiyun 	u32 max_requests;
200*4882a593Smuzhiyun 	int pri = pdev->pri_cap;
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun 	/*
203*4882a593Smuzhiyun 	 * VFs must not implement the PRI Capability.  If their PF
204*4882a593Smuzhiyun 	 * implements PRI, it is shared by the VFs, so if the PF PRI is
205*4882a593Smuzhiyun 	 * enabled, it is also enabled for the VF.
206*4882a593Smuzhiyun 	 */
207*4882a593Smuzhiyun 	if (pdev->is_virtfn) {
208*4882a593Smuzhiyun 		if (pci_physfn(pdev)->pri_enabled)
209*4882a593Smuzhiyun 			return 0;
210*4882a593Smuzhiyun 		return -EINVAL;
211*4882a593Smuzhiyun 	}
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 	if (WARN_ON(pdev->pri_enabled))
214*4882a593Smuzhiyun 		return -EBUSY;
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun 	if (!pri)
217*4882a593Smuzhiyun 		return -EINVAL;
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 	pci_read_config_word(pdev, pri + PCI_PRI_STATUS, &status);
220*4882a593Smuzhiyun 	if (!(status & PCI_PRI_STATUS_STOPPED))
221*4882a593Smuzhiyun 		return -EBUSY;
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun 	pci_read_config_dword(pdev, pri + PCI_PRI_MAX_REQ, &max_requests);
224*4882a593Smuzhiyun 	reqs = min(max_requests, reqs);
225*4882a593Smuzhiyun 	pdev->pri_reqs_alloc = reqs;
226*4882a593Smuzhiyun 	pci_write_config_dword(pdev, pri + PCI_PRI_ALLOC_REQ, reqs);
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 	control = PCI_PRI_CTRL_ENABLE;
229*4882a593Smuzhiyun 	pci_write_config_word(pdev, pri + PCI_PRI_CTRL, control);
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun 	pdev->pri_enabled = 1;
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 	return 0;
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun /**
237*4882a593Smuzhiyun  * pci_disable_pri - Disable PRI capability
238*4882a593Smuzhiyun  * @pdev: PCI device structure
239*4882a593Smuzhiyun  *
240*4882a593Smuzhiyun  * Only clears the enabled-bit, regardless of its former value
241*4882a593Smuzhiyun  */
pci_disable_pri(struct pci_dev * pdev)242*4882a593Smuzhiyun void pci_disable_pri(struct pci_dev *pdev)
243*4882a593Smuzhiyun {
244*4882a593Smuzhiyun 	u16 control;
245*4882a593Smuzhiyun 	int pri = pdev->pri_cap;
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	/* VFs share the PF PRI */
248*4882a593Smuzhiyun 	if (pdev->is_virtfn)
249*4882a593Smuzhiyun 		return;
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun 	if (WARN_ON(!pdev->pri_enabled))
252*4882a593Smuzhiyun 		return;
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	if (!pri)
255*4882a593Smuzhiyun 		return;
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun 	pci_read_config_word(pdev, pri + PCI_PRI_CTRL, &control);
258*4882a593Smuzhiyun 	control &= ~PCI_PRI_CTRL_ENABLE;
259*4882a593Smuzhiyun 	pci_write_config_word(pdev, pri + PCI_PRI_CTRL, control);
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun 	pdev->pri_enabled = 0;
262*4882a593Smuzhiyun }
263*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pci_disable_pri);
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun /**
266*4882a593Smuzhiyun  * pci_restore_pri_state - Restore PRI
267*4882a593Smuzhiyun  * @pdev: PCI device structure
268*4882a593Smuzhiyun  */
pci_restore_pri_state(struct pci_dev * pdev)269*4882a593Smuzhiyun void pci_restore_pri_state(struct pci_dev *pdev)
270*4882a593Smuzhiyun {
271*4882a593Smuzhiyun 	u16 control = PCI_PRI_CTRL_ENABLE;
272*4882a593Smuzhiyun 	u32 reqs = pdev->pri_reqs_alloc;
273*4882a593Smuzhiyun 	int pri = pdev->pri_cap;
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun 	if (pdev->is_virtfn)
276*4882a593Smuzhiyun 		return;
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun 	if (!pdev->pri_enabled)
279*4882a593Smuzhiyun 		return;
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun 	if (!pri)
282*4882a593Smuzhiyun 		return;
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun 	pci_write_config_dword(pdev, pri + PCI_PRI_ALLOC_REQ, reqs);
285*4882a593Smuzhiyun 	pci_write_config_word(pdev, pri + PCI_PRI_CTRL, control);
286*4882a593Smuzhiyun }
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun /**
289*4882a593Smuzhiyun  * pci_reset_pri - Resets device's PRI state
290*4882a593Smuzhiyun  * @pdev: PCI device structure
291*4882a593Smuzhiyun  *
292*4882a593Smuzhiyun  * The PRI capability must be disabled before this function is called.
293*4882a593Smuzhiyun  * Returns 0 on success, negative value on error.
294*4882a593Smuzhiyun  */
pci_reset_pri(struct pci_dev * pdev)295*4882a593Smuzhiyun int pci_reset_pri(struct pci_dev *pdev)
296*4882a593Smuzhiyun {
297*4882a593Smuzhiyun 	u16 control;
298*4882a593Smuzhiyun 	int pri = pdev->pri_cap;
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun 	if (pdev->is_virtfn)
301*4882a593Smuzhiyun 		return 0;
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 	if (WARN_ON(pdev->pri_enabled))
304*4882a593Smuzhiyun 		return -EBUSY;
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun 	if (!pri)
307*4882a593Smuzhiyun 		return -EINVAL;
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun 	control = PCI_PRI_CTRL_RESET;
310*4882a593Smuzhiyun 	pci_write_config_word(pdev, pri + PCI_PRI_CTRL, control);
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun 	return 0;
313*4882a593Smuzhiyun }
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun /**
316*4882a593Smuzhiyun  * pci_prg_resp_pasid_required - Return PRG Response PASID Required bit
317*4882a593Smuzhiyun  *				 status.
318*4882a593Smuzhiyun  * @pdev: PCI device structure
319*4882a593Smuzhiyun  *
320*4882a593Smuzhiyun  * Returns 1 if PASID is required in PRG Response Message, 0 otherwise.
321*4882a593Smuzhiyun  */
pci_prg_resp_pasid_required(struct pci_dev * pdev)322*4882a593Smuzhiyun int pci_prg_resp_pasid_required(struct pci_dev *pdev)
323*4882a593Smuzhiyun {
324*4882a593Smuzhiyun 	if (pdev->is_virtfn)
325*4882a593Smuzhiyun 		pdev = pci_physfn(pdev);
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun 	return pdev->pasid_required;
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun /**
331*4882a593Smuzhiyun  * pci_pri_supported - Check if PRI is supported.
332*4882a593Smuzhiyun  * @pdev: PCI device structure
333*4882a593Smuzhiyun  *
334*4882a593Smuzhiyun  * Returns true if PRI capability is present, false otherwise.
335*4882a593Smuzhiyun  */
pci_pri_supported(struct pci_dev * pdev)336*4882a593Smuzhiyun bool pci_pri_supported(struct pci_dev *pdev)
337*4882a593Smuzhiyun {
338*4882a593Smuzhiyun 	/* VFs share the PF PRI */
339*4882a593Smuzhiyun 	if (pci_physfn(pdev)->pri_cap)
340*4882a593Smuzhiyun 		return true;
341*4882a593Smuzhiyun 	return false;
342*4882a593Smuzhiyun }
343*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pci_pri_supported);
344*4882a593Smuzhiyun #endif /* CONFIG_PCI_PRI */
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun #ifdef CONFIG_PCI_PASID
pci_pasid_init(struct pci_dev * pdev)347*4882a593Smuzhiyun void pci_pasid_init(struct pci_dev *pdev)
348*4882a593Smuzhiyun {
349*4882a593Smuzhiyun 	pdev->pasid_cap = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID);
350*4882a593Smuzhiyun }
351*4882a593Smuzhiyun 
352*4882a593Smuzhiyun /**
353*4882a593Smuzhiyun  * pci_enable_pasid - Enable the PASID capability
354*4882a593Smuzhiyun  * @pdev: PCI device structure
355*4882a593Smuzhiyun  * @features: Features to enable
356*4882a593Smuzhiyun  *
357*4882a593Smuzhiyun  * Returns 0 on success, negative value on error. This function checks
358*4882a593Smuzhiyun  * whether the features are actually supported by the device and returns
359*4882a593Smuzhiyun  * an error if not.
360*4882a593Smuzhiyun  */
pci_enable_pasid(struct pci_dev * pdev,int features)361*4882a593Smuzhiyun int pci_enable_pasid(struct pci_dev *pdev, int features)
362*4882a593Smuzhiyun {
363*4882a593Smuzhiyun 	u16 control, supported;
364*4882a593Smuzhiyun 	int pasid = pdev->pasid_cap;
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun 	/*
367*4882a593Smuzhiyun 	 * VFs must not implement the PASID Capability, but if a PF
368*4882a593Smuzhiyun 	 * supports PASID, its VFs share the PF PASID configuration.
369*4882a593Smuzhiyun 	 */
370*4882a593Smuzhiyun 	if (pdev->is_virtfn) {
371*4882a593Smuzhiyun 		if (pci_physfn(pdev)->pasid_enabled)
372*4882a593Smuzhiyun 			return 0;
373*4882a593Smuzhiyun 		return -EINVAL;
374*4882a593Smuzhiyun 	}
375*4882a593Smuzhiyun 
376*4882a593Smuzhiyun 	if (WARN_ON(pdev->pasid_enabled))
377*4882a593Smuzhiyun 		return -EBUSY;
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun 	if (!pdev->eetlp_prefix_path)
380*4882a593Smuzhiyun 		return -EINVAL;
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun 	if (!pasid)
383*4882a593Smuzhiyun 		return -EINVAL;
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun 	pci_read_config_word(pdev, pasid + PCI_PASID_CAP, &supported);
386*4882a593Smuzhiyun 	supported &= PCI_PASID_CAP_EXEC | PCI_PASID_CAP_PRIV;
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun 	/* User wants to enable anything unsupported? */
389*4882a593Smuzhiyun 	if ((supported & features) != features)
390*4882a593Smuzhiyun 		return -EINVAL;
391*4882a593Smuzhiyun 
392*4882a593Smuzhiyun 	control = PCI_PASID_CTRL_ENABLE | features;
393*4882a593Smuzhiyun 	pdev->pasid_features = features;
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun 	pci_write_config_word(pdev, pasid + PCI_PASID_CTRL, control);
396*4882a593Smuzhiyun 
397*4882a593Smuzhiyun 	pdev->pasid_enabled = 1;
398*4882a593Smuzhiyun 
399*4882a593Smuzhiyun 	return 0;
400*4882a593Smuzhiyun }
401*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pci_enable_pasid);
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun /**
404*4882a593Smuzhiyun  * pci_disable_pasid - Disable the PASID capability
405*4882a593Smuzhiyun  * @pdev: PCI device structure
406*4882a593Smuzhiyun  */
pci_disable_pasid(struct pci_dev * pdev)407*4882a593Smuzhiyun void pci_disable_pasid(struct pci_dev *pdev)
408*4882a593Smuzhiyun {
409*4882a593Smuzhiyun 	u16 control = 0;
410*4882a593Smuzhiyun 	int pasid = pdev->pasid_cap;
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun 	/* VFs share the PF PASID configuration */
413*4882a593Smuzhiyun 	if (pdev->is_virtfn)
414*4882a593Smuzhiyun 		return;
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun 	if (WARN_ON(!pdev->pasid_enabled))
417*4882a593Smuzhiyun 		return;
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun 	if (!pasid)
420*4882a593Smuzhiyun 		return;
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun 	pci_write_config_word(pdev, pasid + PCI_PASID_CTRL, control);
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun 	pdev->pasid_enabled = 0;
425*4882a593Smuzhiyun }
426*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pci_disable_pasid);
427*4882a593Smuzhiyun 
428*4882a593Smuzhiyun /**
429*4882a593Smuzhiyun  * pci_restore_pasid_state - Restore PASID capabilities
430*4882a593Smuzhiyun  * @pdev: PCI device structure
431*4882a593Smuzhiyun  */
pci_restore_pasid_state(struct pci_dev * pdev)432*4882a593Smuzhiyun void pci_restore_pasid_state(struct pci_dev *pdev)
433*4882a593Smuzhiyun {
434*4882a593Smuzhiyun 	u16 control;
435*4882a593Smuzhiyun 	int pasid = pdev->pasid_cap;
436*4882a593Smuzhiyun 
437*4882a593Smuzhiyun 	if (pdev->is_virtfn)
438*4882a593Smuzhiyun 		return;
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun 	if (!pdev->pasid_enabled)
441*4882a593Smuzhiyun 		return;
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun 	if (!pasid)
444*4882a593Smuzhiyun 		return;
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun 	control = PCI_PASID_CTRL_ENABLE | pdev->pasid_features;
447*4882a593Smuzhiyun 	pci_write_config_word(pdev, pasid + PCI_PASID_CTRL, control);
448*4882a593Smuzhiyun }
449*4882a593Smuzhiyun 
450*4882a593Smuzhiyun /**
451*4882a593Smuzhiyun  * pci_pasid_features - Check which PASID features are supported
452*4882a593Smuzhiyun  * @pdev: PCI device structure
453*4882a593Smuzhiyun  *
454*4882a593Smuzhiyun  * Returns a negative value when no PASI capability is present.
455*4882a593Smuzhiyun  * Otherwise is returns a bitmask with supported features. Current
456*4882a593Smuzhiyun  * features reported are:
457*4882a593Smuzhiyun  * PCI_PASID_CAP_EXEC - Execute permission supported
458*4882a593Smuzhiyun  * PCI_PASID_CAP_PRIV - Privileged mode supported
459*4882a593Smuzhiyun  */
pci_pasid_features(struct pci_dev * pdev)460*4882a593Smuzhiyun int pci_pasid_features(struct pci_dev *pdev)
461*4882a593Smuzhiyun {
462*4882a593Smuzhiyun 	u16 supported;
463*4882a593Smuzhiyun 	int pasid;
464*4882a593Smuzhiyun 
465*4882a593Smuzhiyun 	if (pdev->is_virtfn)
466*4882a593Smuzhiyun 		pdev = pci_physfn(pdev);
467*4882a593Smuzhiyun 
468*4882a593Smuzhiyun 	pasid = pdev->pasid_cap;
469*4882a593Smuzhiyun 	if (!pasid)
470*4882a593Smuzhiyun 		return -EINVAL;
471*4882a593Smuzhiyun 
472*4882a593Smuzhiyun 	pci_read_config_word(pdev, pasid + PCI_PASID_CAP, &supported);
473*4882a593Smuzhiyun 
474*4882a593Smuzhiyun 	supported &= PCI_PASID_CAP_EXEC | PCI_PASID_CAP_PRIV;
475*4882a593Smuzhiyun 
476*4882a593Smuzhiyun 	return supported;
477*4882a593Smuzhiyun }
478*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pci_pasid_features);
479*4882a593Smuzhiyun 
480*4882a593Smuzhiyun #define PASID_NUMBER_SHIFT	8
481*4882a593Smuzhiyun #define PASID_NUMBER_MASK	(0x1f << PASID_NUMBER_SHIFT)
482*4882a593Smuzhiyun /**
483*4882a593Smuzhiyun  * pci_max_pasid - Get maximum number of PASIDs supported by device
484*4882a593Smuzhiyun  * @pdev: PCI device structure
485*4882a593Smuzhiyun  *
486*4882a593Smuzhiyun  * Returns negative value when PASID capability is not present.
487*4882a593Smuzhiyun  * Otherwise it returns the number of supported PASIDs.
488*4882a593Smuzhiyun  */
pci_max_pasids(struct pci_dev * pdev)489*4882a593Smuzhiyun int pci_max_pasids(struct pci_dev *pdev)
490*4882a593Smuzhiyun {
491*4882a593Smuzhiyun 	u16 supported;
492*4882a593Smuzhiyun 	int pasid;
493*4882a593Smuzhiyun 
494*4882a593Smuzhiyun 	if (pdev->is_virtfn)
495*4882a593Smuzhiyun 		pdev = pci_physfn(pdev);
496*4882a593Smuzhiyun 
497*4882a593Smuzhiyun 	pasid = pdev->pasid_cap;
498*4882a593Smuzhiyun 	if (!pasid)
499*4882a593Smuzhiyun 		return -EINVAL;
500*4882a593Smuzhiyun 
501*4882a593Smuzhiyun 	pci_read_config_word(pdev, pasid + PCI_PASID_CAP, &supported);
502*4882a593Smuzhiyun 
503*4882a593Smuzhiyun 	supported = (supported & PASID_NUMBER_MASK) >> PASID_NUMBER_SHIFT;
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun 	return (1 << supported);
506*4882a593Smuzhiyun }
507*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pci_max_pasids);
508*4882a593Smuzhiyun #endif /* CONFIG_PCI_PASID */
509