diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2017-07-02 19:48:47 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2017-07-02 19:48:47 -0400 |
commit | f9bfeccd6603484563b00462480c9b32f5ae43bd (patch) | |
tree | 02007afd15934627b74a601daa4aa996d0e0df89 | |
parent | 397ee434c5bf813db33632957ae50ae3b30226ed (diff) | |
parent | 675734baa361cf044033bb60594dea33d8d8da36 (diff) |
Merge branch 'pci/enumeration' into next
* pci/enumeration:
PCI: Enable ECRC only if device supports it
PCI: Add sysfs max_link_speed/width, current_link_speed/width, etc
PCI: Test INTx masking during enumeration, not at run-time
-rw-r--r-- | drivers/pci/pci-sysfs.c | 199 | ||||
-rw-r--r-- | drivers/pci/pci.c | 42 | ||||
-rw-r--r-- | drivers/pci/probe.c | 35 | ||||
-rw-r--r-- | include/linux/pci.h | 12 | ||||
-rw-r--r-- | include/uapi/linux/pci_regs.h | 1 |
5 files changed, 242 insertions, 47 deletions
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 31e99613a12e..a3537cf58a20 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -154,6 +154,129 @@ static ssize_t resource_show(struct device *dev, struct device_attribute *attr, | |||
154 | } | 154 | } |
155 | static DEVICE_ATTR_RO(resource); | 155 | static DEVICE_ATTR_RO(resource); |
156 | 156 | ||
157 | static ssize_t max_link_speed_show(struct device *dev, | ||
158 | struct device_attribute *attr, char *buf) | ||
159 | { | ||
160 | struct pci_dev *pci_dev = to_pci_dev(dev); | ||
161 | u32 linkcap; | ||
162 | int err; | ||
163 | const char *speed; | ||
164 | |||
165 | err = pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, &linkcap); | ||
166 | if (err) | ||
167 | return -EINVAL; | ||
168 | |||
169 | switch (linkcap & PCI_EXP_LNKCAP_SLS) { | ||
170 | case PCI_EXP_LNKCAP_SLS_8_0GB: | ||
171 | speed = "8 GT/s"; | ||
172 | break; | ||
173 | case PCI_EXP_LNKCAP_SLS_5_0GB: | ||
174 | speed = "5 GT/s"; | ||
175 | break; | ||
176 | case PCI_EXP_LNKCAP_SLS_2_5GB: | ||
177 | speed = "2.5 GT/s"; | ||
178 | break; | ||
179 | default: | ||
180 | speed = "Unknown speed"; | ||
181 | } | ||
182 | |||
183 | return sprintf(buf, "%s\n", speed); | ||
184 | } | ||
185 | static DEVICE_ATTR_RO(max_link_speed); | ||
186 | |||
187 | static ssize_t max_link_width_show(struct device *dev, | ||
188 | struct device_attribute *attr, char *buf) | ||
189 | { | ||
190 | struct pci_dev *pci_dev = to_pci_dev(dev); | ||
191 | u32 linkcap; | ||
192 | int err; | ||
193 | |||
194 | err = pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, &linkcap); | ||
195 | if (err) | ||
196 | return -EINVAL; | ||
197 | |||
198 | return sprintf(buf, "%u\n", (linkcap & PCI_EXP_LNKCAP_MLW) >> 4); | ||
199 | } | ||
200 | static DEVICE_ATTR_RO(max_link_width); | ||
201 | |||
202 | static ssize_t current_link_speed_show(struct device *dev, | ||
203 | struct device_attribute *attr, char *buf) | ||
204 | { | ||
205 | struct pci_dev *pci_dev = to_pci_dev(dev); | ||
206 | u16 linkstat; | ||
207 | int err; | ||
208 | const char *speed; | ||
209 | |||
210 | err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, &linkstat); | ||
211 | if (err) | ||
212 | return -EINVAL; | ||
213 | |||
214 | switch (linkstat & PCI_EXP_LNKSTA_CLS) { | ||
215 | case PCI_EXP_LNKSTA_CLS_8_0GB: | ||
216 | speed = "8 GT/s"; | ||
217 | break; | ||
218 | case PCI_EXP_LNKSTA_CLS_5_0GB: | ||
219 | speed = "5 GT/s"; | ||
220 | break; | ||
221 | case PCI_EXP_LNKSTA_CLS_2_5GB: | ||
222 | speed = "2.5 GT/s"; | ||
223 | break; | ||
224 | default: | ||
225 | speed = "Unknown speed"; | ||
226 | } | ||
227 | |||
228 | return sprintf(buf, "%s\n", speed); | ||
229 | } | ||
230 | static DEVICE_ATTR_RO(current_link_speed); | ||
231 | |||
232 | static ssize_t current_link_width_show(struct device *dev, | ||
233 | struct device_attribute *attr, char *buf) | ||
234 | { | ||
235 | struct pci_dev *pci_dev = to_pci_dev(dev); | ||
236 | u16 linkstat; | ||
237 | int err; | ||
238 | |||
239 | err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, &linkstat); | ||
240 | if (err) | ||
241 | return -EINVAL; | ||
242 | |||
243 | return sprintf(buf, "%u\n", | ||
244 | (linkstat & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT); | ||
245 | } | ||
246 | static DEVICE_ATTR_RO(current_link_width); | ||
247 | |||
248 | static ssize_t secondary_bus_number_show(struct device *dev, | ||
249 | struct device_attribute *attr, | ||
250 | char *buf) | ||
251 | { | ||
252 | struct pci_dev *pci_dev = to_pci_dev(dev); | ||
253 | u8 sec_bus; | ||
254 | int err; | ||
255 | |||
256 | err = pci_read_config_byte(pci_dev, PCI_SECONDARY_BUS, &sec_bus); | ||
257 | if (err) | ||
258 | return -EINVAL; | ||
259 | |||
260 | return sprintf(buf, "%u\n", sec_bus); | ||
261 | } | ||
262 | static DEVICE_ATTR_RO(secondary_bus_number); | ||
263 | |||
264 | static ssize_t subordinate_bus_number_show(struct device *dev, | ||
265 | struct device_attribute *attr, | ||
266 | char *buf) | ||
267 | { | ||
268 | struct pci_dev *pci_dev = to_pci_dev(dev); | ||
269 | u8 sub_bus; | ||
270 | int err; | ||
271 | |||
272 | err = pci_read_config_byte(pci_dev, PCI_SUBORDINATE_BUS, &sub_bus); | ||
273 | if (err) | ||
274 | return -EINVAL; | ||
275 | |||
276 | return sprintf(buf, "%u\n", sub_bus); | ||
277 | } | ||
278 | static DEVICE_ATTR_RO(subordinate_bus_number); | ||
279 | |||
157 | static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, | 280 | static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, |
158 | char *buf) | 281 | char *buf) |
159 | { | 282 | { |
@@ -629,12 +752,17 @@ static struct attribute *pci_dev_attrs[] = { | |||
629 | NULL, | 752 | NULL, |
630 | }; | 753 | }; |
631 | 754 | ||
632 | static const struct attribute_group pci_dev_group = { | 755 | static struct attribute *pci_bridge_attrs[] = { |
633 | .attrs = pci_dev_attrs, | 756 | &dev_attr_subordinate_bus_number.attr, |
757 | &dev_attr_secondary_bus_number.attr, | ||
758 | NULL, | ||
634 | }; | 759 | }; |
635 | 760 | ||
636 | const struct attribute_group *pci_dev_groups[] = { | 761 | static struct attribute *pcie_dev_attrs[] = { |
637 | &pci_dev_group, | 762 | &dev_attr_current_link_speed.attr, |
763 | &dev_attr_current_link_width.attr, | ||
764 | &dev_attr_max_link_width.attr, | ||
765 | &dev_attr_max_link_speed.attr, | ||
638 | NULL, | 766 | NULL, |
639 | }; | 767 | }; |
640 | 768 | ||
@@ -1557,6 +1685,57 @@ static umode_t pci_dev_hp_attrs_are_visible(struct kobject *kobj, | |||
1557 | return a->mode; | 1685 | return a->mode; |
1558 | } | 1686 | } |
1559 | 1687 | ||
1688 | static umode_t pci_bridge_attrs_are_visible(struct kobject *kobj, | ||
1689 | struct attribute *a, int n) | ||
1690 | { | ||
1691 | struct device *dev = kobj_to_dev(kobj); | ||
1692 | struct pci_dev *pdev = to_pci_dev(dev); | ||
1693 | |||
1694 | if (pci_is_bridge(pdev)) | ||
1695 | return a->mode; | ||
1696 | |||
1697 | return 0; | ||
1698 | } | ||
1699 | |||
1700 | static umode_t pcie_dev_attrs_are_visible(struct kobject *kobj, | ||
1701 | struct attribute *a, int n) | ||
1702 | { | ||
1703 | struct device *dev = kobj_to_dev(kobj); | ||
1704 | struct pci_dev *pdev = to_pci_dev(dev); | ||
1705 | |||
1706 | if (pci_is_pcie(pdev)) | ||
1707 | return a->mode; | ||
1708 | |||
1709 | return 0; | ||
1710 | } | ||
1711 | |||
1712 | static const struct attribute_group pci_dev_group = { | ||
1713 | .attrs = pci_dev_attrs, | ||
1714 | }; | ||
1715 | |||
1716 | const struct attribute_group *pci_dev_groups[] = { | ||
1717 | &pci_dev_group, | ||
1718 | NULL, | ||
1719 | }; | ||
1720 | |||
1721 | static const struct attribute_group pci_bridge_group = { | ||
1722 | .attrs = pci_bridge_attrs, | ||
1723 | }; | ||
1724 | |||
1725 | const struct attribute_group *pci_bridge_groups[] = { | ||
1726 | &pci_bridge_group, | ||
1727 | NULL, | ||
1728 | }; | ||
1729 | |||
1730 | static const struct attribute_group pcie_dev_group = { | ||
1731 | .attrs = pcie_dev_attrs, | ||
1732 | }; | ||
1733 | |||
1734 | const struct attribute_group *pcie_dev_groups[] = { | ||
1735 | &pcie_dev_group, | ||
1736 | NULL, | ||
1737 | }; | ||
1738 | |||
1560 | static struct attribute_group pci_dev_hp_attr_group = { | 1739 | static struct attribute_group pci_dev_hp_attr_group = { |
1561 | .attrs = pci_dev_hp_attrs, | 1740 | .attrs = pci_dev_hp_attrs, |
1562 | .is_visible = pci_dev_hp_attrs_are_visible, | 1741 | .is_visible = pci_dev_hp_attrs_are_visible, |
@@ -1592,12 +1771,24 @@ static struct attribute_group pci_dev_attr_group = { | |||
1592 | .is_visible = pci_dev_attrs_are_visible, | 1771 | .is_visible = pci_dev_attrs_are_visible, |
1593 | }; | 1772 | }; |
1594 | 1773 | ||
1774 | static struct attribute_group pci_bridge_attr_group = { | ||
1775 | .attrs = pci_bridge_attrs, | ||
1776 | .is_visible = pci_bridge_attrs_are_visible, | ||
1777 | }; | ||
1778 | |||
1779 | static struct attribute_group pcie_dev_attr_group = { | ||
1780 | .attrs = pcie_dev_attrs, | ||
1781 | .is_visible = pcie_dev_attrs_are_visible, | ||
1782 | }; | ||
1783 | |||
1595 | static const struct attribute_group *pci_dev_attr_groups[] = { | 1784 | static const struct attribute_group *pci_dev_attr_groups[] = { |
1596 | &pci_dev_attr_group, | 1785 | &pci_dev_attr_group, |
1597 | &pci_dev_hp_attr_group, | 1786 | &pci_dev_hp_attr_group, |
1598 | #ifdef CONFIG_PCI_IOV | 1787 | #ifdef CONFIG_PCI_IOV |
1599 | &sriov_dev_attr_group, | 1788 | &sriov_dev_attr_group, |
1600 | #endif | 1789 | #endif |
1790 | &pci_bridge_attr_group, | ||
1791 | &pcie_dev_attr_group, | ||
1601 | NULL, | 1792 | NULL, |
1602 | }; | 1793 | }; |
1603 | 1794 | ||
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index b01bd5bba8e6..7c4e1aa67c67 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -3708,46 +3708,6 @@ void pci_intx(struct pci_dev *pdev, int enable) | |||
3708 | } | 3708 | } |
3709 | EXPORT_SYMBOL_GPL(pci_intx); | 3709 | EXPORT_SYMBOL_GPL(pci_intx); |
3710 | 3710 | ||
3711 | /** | ||
3712 | * pci_intx_mask_supported - probe for INTx masking support | ||
3713 | * @dev: the PCI device to operate on | ||
3714 | * | ||
3715 | * Check if the device dev support INTx masking via the config space | ||
3716 | * command word. | ||
3717 | */ | ||
3718 | bool pci_intx_mask_supported(struct pci_dev *dev) | ||
3719 | { | ||
3720 | bool mask_supported = false; | ||
3721 | u16 orig, new; | ||
3722 | |||
3723 | if (dev->broken_intx_masking) | ||
3724 | return false; | ||
3725 | |||
3726 | pci_cfg_access_lock(dev); | ||
3727 | |||
3728 | pci_read_config_word(dev, PCI_COMMAND, &orig); | ||
3729 | pci_write_config_word(dev, PCI_COMMAND, | ||
3730 | orig ^ PCI_COMMAND_INTX_DISABLE); | ||
3731 | pci_read_config_word(dev, PCI_COMMAND, &new); | ||
3732 | |||
3733 | /* | ||
3734 | * There's no way to protect against hardware bugs or detect them | ||
3735 | * reliably, but as long as we know what the value should be, let's | ||
3736 | * go ahead and check it. | ||
3737 | */ | ||
3738 | if ((new ^ orig) & ~PCI_COMMAND_INTX_DISABLE) { | ||
3739 | dev_err(&dev->dev, "Command register changed from 0x%x to 0x%x: driver or hardware bug?\n", | ||
3740 | orig, new); | ||
3741 | } else if ((new ^ orig) & PCI_COMMAND_INTX_DISABLE) { | ||
3742 | mask_supported = true; | ||
3743 | pci_write_config_word(dev, PCI_COMMAND, orig); | ||
3744 | } | ||
3745 | |||
3746 | pci_cfg_access_unlock(dev); | ||
3747 | return mask_supported; | ||
3748 | } | ||
3749 | EXPORT_SYMBOL_GPL(pci_intx_mask_supported); | ||
3750 | |||
3751 | static bool pci_check_and_set_intx_mask(struct pci_dev *dev, bool mask) | 3711 | static bool pci_check_and_set_intx_mask(struct pci_dev *dev, bool mask) |
3752 | { | 3712 | { |
3753 | struct pci_bus *bus = dev->bus; | 3713 | struct pci_bus *bus = dev->bus; |
@@ -3798,7 +3758,7 @@ done: | |||
3798 | * @dev: the PCI device to operate on | 3758 | * @dev: the PCI device to operate on |
3799 | * | 3759 | * |
3800 | * Check if the device dev has its INTx line asserted, mask it and | 3760 | * Check if the device dev has its INTx line asserted, mask it and |
3801 | * return true in that case. False is returned if not interrupt was | 3761 | * return true in that case. False is returned if no interrupt was |
3802 | * pending. | 3762 | * pending. |
3803 | */ | 3763 | */ |
3804 | bool pci_check_and_mask_intx(struct pci_dev *dev) | 3764 | bool pci_check_and_mask_intx(struct pci_dev *dev) |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 19c8950c6c38..7fedfeb0871d 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -1330,6 +1330,34 @@ static void pci_msi_setup_pci_dev(struct pci_dev *dev) | |||
1330 | } | 1330 | } |
1331 | 1331 | ||
1332 | /** | 1332 | /** |
1333 | * pci_intx_mask_broken - test PCI_COMMAND_INTX_DISABLE writability | ||
1334 | * @dev: PCI device | ||
1335 | * | ||
1336 | * Test whether PCI_COMMAND_INTX_DISABLE is writable for @dev. Check this | ||
1337 | * at enumeration-time to avoid modifying PCI_COMMAND at run-time. | ||
1338 | */ | ||
1339 | static int pci_intx_mask_broken(struct pci_dev *dev) | ||
1340 | { | ||
1341 | u16 orig, toggle, new; | ||
1342 | |||
1343 | pci_read_config_word(dev, PCI_COMMAND, &orig); | ||
1344 | toggle = orig ^ PCI_COMMAND_INTX_DISABLE; | ||
1345 | pci_write_config_word(dev, PCI_COMMAND, toggle); | ||
1346 | pci_read_config_word(dev, PCI_COMMAND, &new); | ||
1347 | |||
1348 | pci_write_config_word(dev, PCI_COMMAND, orig); | ||
1349 | |||
1350 | /* | ||
1351 | * PCI_COMMAND_INTX_DISABLE was reserved and read-only prior to PCI | ||
1352 | * r2.3, so strictly speaking, a device is not *broken* if it's not | ||
1353 | * writable. But we'll live with the misnomer for now. | ||
1354 | */ | ||
1355 | if (new != toggle) | ||
1356 | return 1; | ||
1357 | return 0; | ||
1358 | } | ||
1359 | |||
1360 | /** | ||
1333 | * pci_setup_device - fill in class and map information of a device | 1361 | * pci_setup_device - fill in class and map information of a device |
1334 | * @dev: the device structure to fill | 1362 | * @dev: the device structure to fill |
1335 | * | 1363 | * |
@@ -1399,6 +1427,8 @@ int pci_setup_device(struct pci_dev *dev) | |||
1399 | } | 1427 | } |
1400 | } | 1428 | } |
1401 | 1429 | ||
1430 | dev->broken_intx_masking = pci_intx_mask_broken(dev); | ||
1431 | |||
1402 | switch (dev->hdr_type) { /* header type */ | 1432 | switch (dev->hdr_type) { /* header type */ |
1403 | case PCI_HEADER_TYPE_NORMAL: /* standard header */ | 1433 | case PCI_HEADER_TYPE_NORMAL: /* standard header */ |
1404 | if (class == PCI_CLASS_BRIDGE_PCI) | 1434 | if (class == PCI_CLASS_BRIDGE_PCI) |
@@ -1674,6 +1704,11 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp) | |||
1674 | /* Initialize Advanced Error Capabilities and Control Register */ | 1704 | /* Initialize Advanced Error Capabilities and Control Register */ |
1675 | pci_read_config_dword(dev, pos + PCI_ERR_CAP, ®32); | 1705 | pci_read_config_dword(dev, pos + PCI_ERR_CAP, ®32); |
1676 | reg32 = (reg32 & hpp->adv_err_cap_and) | hpp->adv_err_cap_or; | 1706 | reg32 = (reg32 & hpp->adv_err_cap_and) | hpp->adv_err_cap_or; |
1707 | /* Don't enable ECRC generation or checking if unsupported */ | ||
1708 | if (!(reg32 & PCI_ERR_CAP_ECRC_GENC)) | ||
1709 | reg32 &= ~PCI_ERR_CAP_ECRC_GENE; | ||
1710 | if (!(reg32 & PCI_ERR_CAP_ECRC_CHKC)) | ||
1711 | reg32 &= ~PCI_ERR_CAP_ECRC_CHKE; | ||
1677 | pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32); | 1712 | pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32); |
1678 | 1713 | ||
1679 | /* | 1714 | /* |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 33c2b0b77429..4f0613d5d2d9 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -366,7 +366,7 @@ struct pci_dev { | |||
366 | unsigned int is_thunderbolt:1; /* Thunderbolt controller */ | 366 | unsigned int is_thunderbolt:1; /* Thunderbolt controller */ |
367 | unsigned int __aer_firmware_first_valid:1; | 367 | unsigned int __aer_firmware_first_valid:1; |
368 | unsigned int __aer_firmware_first:1; | 368 | unsigned int __aer_firmware_first:1; |
369 | unsigned int broken_intx_masking:1; | 369 | unsigned int broken_intx_masking:1; /* INTx masking can't be used */ |
370 | unsigned int io_window_1k:1; /* Intel P2P bridge 1K I/O windows */ | 370 | unsigned int io_window_1k:1; /* Intel P2P bridge 1K I/O windows */ |
371 | unsigned int irq_managed:1; | 371 | unsigned int irq_managed:1; |
372 | unsigned int has_secondary_link:1; | 372 | unsigned int has_secondary_link:1; |
@@ -1003,6 +1003,15 @@ int __must_check pci_reenable_device(struct pci_dev *); | |||
1003 | int __must_check pcim_enable_device(struct pci_dev *pdev); | 1003 | int __must_check pcim_enable_device(struct pci_dev *pdev); |
1004 | void pcim_pin_device(struct pci_dev *pdev); | 1004 | void pcim_pin_device(struct pci_dev *pdev); |
1005 | 1005 | ||
1006 | static inline bool pci_intx_mask_supported(struct pci_dev *pdev) | ||
1007 | { | ||
1008 | /* | ||
1009 | * INTx masking is supported if PCI_COMMAND_INTX_DISABLE is | ||
1010 | * writable and no quirk has marked the feature broken. | ||
1011 | */ | ||
1012 | return !pdev->broken_intx_masking; | ||
1013 | } | ||
1014 | |||
1006 | static inline int pci_is_enabled(struct pci_dev *pdev) | 1015 | static inline int pci_is_enabled(struct pci_dev *pdev) |
1007 | { | 1016 | { |
1008 | return (atomic_read(&pdev->enable_cnt) > 0); | 1017 | return (atomic_read(&pdev->enable_cnt) > 0); |
@@ -1026,7 +1035,6 @@ int __must_check pci_set_mwi(struct pci_dev *dev); | |||
1026 | int pci_try_set_mwi(struct pci_dev *dev); | 1035 | int pci_try_set_mwi(struct pci_dev *dev); |
1027 | void pci_clear_mwi(struct pci_dev *dev); | 1036 | void pci_clear_mwi(struct pci_dev *dev); |
1028 | void pci_intx(struct pci_dev *dev, int enable); | 1037 | void pci_intx(struct pci_dev *dev, int enable); |
1029 | bool pci_intx_mask_supported(struct pci_dev *dev); | ||
1030 | bool pci_check_and_mask_intx(struct pci_dev *dev); | 1038 | bool pci_check_and_mask_intx(struct pci_dev *dev); |
1031 | bool pci_check_and_unmask_intx(struct pci_dev *dev); | 1039 | bool pci_check_and_unmask_intx(struct pci_dev *dev); |
1032 | int pci_wait_for_pending(struct pci_dev *dev, int pos, u16 mask); | 1040 | int pci_wait_for_pending(struct pci_dev *dev, int pos, u16 mask); |
diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index d56bb0051009..c22d3ebaca20 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h | |||
@@ -517,6 +517,7 @@ | |||
517 | #define PCI_EXP_LNKCAP_SLS 0x0000000f /* Supported Link Speeds */ | 517 | #define PCI_EXP_LNKCAP_SLS 0x0000000f /* Supported Link Speeds */ |
518 | #define PCI_EXP_LNKCAP_SLS_2_5GB 0x00000001 /* LNKCAP2 SLS Vector bit 0 */ | 518 | #define PCI_EXP_LNKCAP_SLS_2_5GB 0x00000001 /* LNKCAP2 SLS Vector bit 0 */ |
519 | #define PCI_EXP_LNKCAP_SLS_5_0GB 0x00000002 /* LNKCAP2 SLS Vector bit 1 */ | 519 | #define PCI_EXP_LNKCAP_SLS_5_0GB 0x00000002 /* LNKCAP2 SLS Vector bit 1 */ |
520 | #define PCI_EXP_LNKCAP_SLS_8_0GB 0x00000003 /* LNKCAP2 SLS Vector bit 2 */ | ||
520 | #define PCI_EXP_LNKCAP_MLW 0x000003f0 /* Maximum Link Width */ | 521 | #define PCI_EXP_LNKCAP_MLW 0x000003f0 /* Maximum Link Width */ |
521 | #define PCI_EXP_LNKCAP_ASPMS 0x00000c00 /* ASPM Support */ | 522 | #define PCI_EXP_LNKCAP_ASPMS 0x00000c00 /* ASPM Support */ |
522 | #define PCI_EXP_LNKCAP_L0SEL 0x00007000 /* L0s Exit Latency */ | 523 | #define PCI_EXP_LNKCAP_L0SEL 0x00007000 /* L0s Exit Latency */ |