1 /* SPDX-License-Identifier: GPL-2.0 */ 2 3 #include <linux/pci.h> 4 #include <linux/msi.h> 5 6 #define msix_table_size(flags) ((flags & PCI_MSIX_FLAGS_QSIZE) + 1) 7 8 int pci_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type); 9 void pci_msi_teardown_msi_irqs(struct pci_dev *dev); 10 11 /* Mask/unmask helpers */ 12 void pci_msi_update_mask(struct msi_desc *desc, u32 clear, u32 set); 13 14 static inline void pci_msi_mask(struct msi_desc *desc, u32 mask) 15 { 16 pci_msi_update_mask(desc, 0, mask); 17 } 18 19 static inline void pci_msi_unmask(struct msi_desc *desc, u32 mask) 20 { 21 pci_msi_update_mask(desc, mask, 0); 22 } 23 24 static inline void __iomem *pci_msix_desc_addr(struct msi_desc *desc) 25 { 26 return desc->pci.mask_base + desc->msi_index * PCI_MSIX_ENTRY_SIZE; 27 } 28 29 /* 30 * This internal function does not flush PCI writes to the device. All 31 * users must ensure that they read from the device before either assuming 32 * that the device state is up to date, or returning out of this file. 33 * It does not affect the msi_desc::msix_ctrl cache either. Use with care! 34 */ 35 static inline void pci_msix_write_vector_ctrl(struct msi_desc *desc, u32 ctrl) 36 { 37 void __iomem *desc_addr = pci_msix_desc_addr(desc); 38 39 /* The Table is unreachable while the Link is down */ 40 if (pci_channel_offline(msi_desc_to_pci_dev(desc))) 41 return; 42 43 if (desc->pci.msi_attrib.can_mask) 44 writel(ctrl, desc_addr + PCI_MSIX_ENTRY_VECTOR_CTRL); 45 } 46 47 static inline void pci_msix_mask(struct msi_desc *desc) 48 { 49 desc->pci.msix_ctrl |= PCI_MSIX_ENTRY_CTRL_MASKBIT; 50 51 if (pci_channel_offline(msi_desc_to_pci_dev(desc))) 52 return; 53 54 pci_msix_write_vector_ctrl(desc, desc->pci.msix_ctrl); 55 /* Flush write to device */ 56 readl(desc->pci.mask_base); 57 } 58 59 static inline void pci_msix_unmask(struct msi_desc *desc) 60 { 61 desc->pci.msix_ctrl &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; 62 pci_msix_write_vector_ctrl(desc, desc->pci.msix_ctrl); 63 } 64 65 static inline void __pci_msi_mask_desc(struct msi_desc *desc, u32 mask) 66 { 67 if (desc->pci.msi_attrib.is_msix) 68 pci_msix_mask(desc); 69 else 70 pci_msi_mask(desc, mask); 71 } 72 73 static inline void __pci_msi_unmask_desc(struct msi_desc *desc, u32 mask) 74 { 75 if (desc->pci.msi_attrib.is_msix) 76 pci_msix_unmask(desc); 77 else 78 pci_msi_unmask(desc, mask); 79 } 80 81 /* 82 * PCI 2.3 does not specify mask bits for each MSI interrupt. Attempting to 83 * mask all MSI interrupts by clearing the MSI enable bit does not work 84 * reliably as devices without an INTx disable bit will then generate a 85 * level IRQ which will never be cleared. 86 */ 87 static inline __attribute_const__ u32 msi_multi_mask(struct msi_desc *desc) 88 { 89 /* Don't shift by >= width of type */ 90 if (desc->pci.msi_attrib.multi_cap >= 5) 91 return 0xffffffff; 92 return (1 << (1 << desc->pci.msi_attrib.multi_cap)) - 1; 93 } 94 95 void msix_prepare_msi_desc(struct pci_dev *dev, struct msi_desc *desc); 96 97 /* Subsystem variables */ 98 extern bool pci_msi_enable; 99 100 /* MSI internal functions invoked from the public APIs */ 101 void pci_msi_shutdown(struct pci_dev *dev); 102 void pci_msix_shutdown(struct pci_dev *dev); 103 void pci_free_msi_irqs(struct pci_dev *dev); 104 int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec, struct irq_affinity *affd); 105 int __pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, int minvec, 106 int maxvec, struct irq_affinity *affd, int flags); 107 void __pci_restore_msi_state(struct pci_dev *dev); 108 void __pci_restore_msix_state(struct pci_dev *dev); 109 110 /* irq_domain related functionality */ 111 112 enum support_mode { 113 ALLOW_LEGACY, 114 DENY_LEGACY, 115 }; 116 117 bool pci_msi_domain_supports(struct pci_dev *dev, unsigned int feature_mask, enum support_mode mode); 118 bool pci_setup_msi_device_domain(struct pci_dev *pdev, unsigned int hwsize); 119 bool pci_setup_msix_device_domain(struct pci_dev *pdev, unsigned int hwsize); 120 121 /* Legacy (!IRQDOMAIN) fallbacks */ 122 123 #ifdef CONFIG_PCI_MSI_ARCH_FALLBACKS 124 int pci_msi_legacy_setup_msi_irqs(struct pci_dev *dev, int nvec, int type); 125 void pci_msi_legacy_teardown_msi_irqs(struct pci_dev *dev); 126 #else 127 static inline int pci_msi_legacy_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) 128 { 129 WARN_ON_ONCE(1); 130 return -ENODEV; 131 } 132 133 static inline void pci_msi_legacy_teardown_msi_irqs(struct pci_dev *dev) 134 { 135 WARN_ON_ONCE(1); 136 } 137 #endif 138