^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 */