Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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