mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 01:55:51 +02:00
Merge branch 'pci/enumeration'
- Remove MPS/MRRS Kconfig settings (CONFIG_PCIE_BUS_*) that worked around a WiFi device defect (Bjorn Helgaas) - Always lift 2.5GT/s restriction in PCIe failed link retraining to avoid clamping a link to 2.5GT/s after hot-plug changes the device (Maciej W. Rozycki) - Don't bother trying to retrain a 2.5GT/s link at 2.5GT/s since nothing would be gained by the retrain (Maciej W. Rozycki) * pci/enumeration: PCI: Bail out early for 2.5GT/s devices in PCIe failed link retraining PCI: Use pcie_get_speed_cap() in PCIe failed link retraining PCI: Always lift 2.5GT/s restriction in PCIe failed link retraining PCI: Remove MPS/MRRS Kconfig settings (CONFIG_PCIE_BUS_*)
This commit is contained in:
commit
1eaa2b8d4c
|
|
@ -251,63 +251,6 @@ config PCI_DYNAMIC_OF_NODES
|
|||
Once this option is selected, the device tree nodes will be generated
|
||||
for all PCI bridges.
|
||||
|
||||
choice
|
||||
prompt "PCI Express hierarchy optimization setting"
|
||||
default PCIE_BUS_DEFAULT
|
||||
depends on EXPERT
|
||||
help
|
||||
MPS (Max Payload Size) and MRRS (Max Read Request Size) are PCIe
|
||||
device parameters that affect performance and the ability to
|
||||
support hotplug and peer-to-peer DMA.
|
||||
|
||||
The following choices set the MPS and MRRS optimization strategy
|
||||
at compile-time. The choices are the same as those offered for
|
||||
the kernel command-line parameter 'pci', i.e.,
|
||||
'pci=pcie_bus_tune_off', 'pci=pcie_bus_safe',
|
||||
'pci=pcie_bus_perf', and 'pci=pcie_bus_peer2peer'.
|
||||
|
||||
This is a compile-time setting and can be overridden by the above
|
||||
command-line parameters. If unsure, choose PCIE_BUS_DEFAULT.
|
||||
|
||||
config PCIE_BUS_TUNE_OFF
|
||||
bool "Tune Off"
|
||||
help
|
||||
Use the BIOS defaults; don't touch MPS at all. This is the same
|
||||
as booting with 'pci=pcie_bus_tune_off'.
|
||||
|
||||
config PCIE_BUS_DEFAULT
|
||||
bool "Default"
|
||||
help
|
||||
Default choice; ensure that the MPS matches upstream bridge.
|
||||
|
||||
config PCIE_BUS_SAFE
|
||||
bool "Safe"
|
||||
help
|
||||
Use largest MPS that boot-time devices support. If you have a
|
||||
closed system with no possibility of adding new devices, this
|
||||
will use the largest MPS that's supported by all devices. This
|
||||
is the same as booting with 'pci=pcie_bus_safe'.
|
||||
|
||||
config PCIE_BUS_PERFORMANCE
|
||||
bool "Performance"
|
||||
help
|
||||
Use MPS and MRRS for best performance. Ensure that a given
|
||||
device's MPS is no larger than its parent MPS, which allows us to
|
||||
keep all switches/bridges to the max MPS supported by their
|
||||
parent. This is the same as booting with 'pci=pcie_bus_perf'.
|
||||
|
||||
config PCIE_BUS_PEER2PEER
|
||||
bool "Peer2peer"
|
||||
help
|
||||
Set MPS = 128 for all devices. MPS configuration effected by the
|
||||
other options could cause the MPS on one root port to be
|
||||
different than that of the MPS on another, which may cause
|
||||
hot-added devices or peer-to-peer DMA to fail. Set MPS to the
|
||||
smallest possible value (128B) system-wide to avoid these issues.
|
||||
This is the same as booting with 'pci=pcie_bus_peer2peer'.
|
||||
|
||||
endchoice
|
||||
|
||||
config VGA_ARB
|
||||
bool "VGA Arbitration" if EXPERT
|
||||
default y
|
||||
|
|
|
|||
|
|
@ -120,17 +120,7 @@ unsigned long pci_hotplug_bus_size = DEFAULT_HOTPLUG_BUS_SIZE;
|
|||
|
||||
|
||||
/* PCIe MPS/MRRS strategy; can be overridden by kernel command-line param */
|
||||
#ifdef CONFIG_PCIE_BUS_TUNE_OFF
|
||||
enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_TUNE_OFF;
|
||||
#elif defined CONFIG_PCIE_BUS_SAFE
|
||||
enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_SAFE;
|
||||
#elif defined CONFIG_PCIE_BUS_PERFORMANCE
|
||||
enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_PERFORMANCE;
|
||||
#elif defined CONFIG_PCIE_BUS_PEER2PEER
|
||||
enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_PEER2PEER;
|
||||
#else
|
||||
enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_DEFAULT;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The default CLS is used if arch didn't set CLS explicitly and not
|
||||
|
|
|
|||
|
|
@ -80,11 +80,10 @@ static bool pcie_lbms_seen(struct pci_dev *dev, u16 lnksta)
|
|||
* Restrict the speed to 2.5GT/s then with the Target Link Speed field,
|
||||
* request a retrain and check the result.
|
||||
*
|
||||
* If this turns out successful and we know by the Vendor:Device ID it is
|
||||
* safe to do so, then lift the restriction, letting the devices negotiate
|
||||
* a higher speed. Also check for a similar 2.5GT/s speed restriction the
|
||||
* firmware may have already arranged and lift it with ports that already
|
||||
* report their data link being up.
|
||||
* If this turns out successful, or where a 2.5GT/s speed restriction has
|
||||
* been previously arranged by the firmware and the port reports its link
|
||||
* already being up, lift the restriction, in a hope it is safe to do so,
|
||||
* letting the devices negotiate a higher speed.
|
||||
*
|
||||
* Otherwise revert the speed to the original setting and request a retrain
|
||||
* again to remove any residual state, ignoring the result as it's supposed
|
||||
|
|
@ -95,51 +94,39 @@ static bool pcie_lbms_seen(struct pci_dev *dev, u16 lnksta)
|
|||
*/
|
||||
int pcie_failed_link_retrain(struct pci_dev *dev)
|
||||
{
|
||||
static const struct pci_device_id ids[] = {
|
||||
{ PCI_VDEVICE(ASMEDIA, 0x2824) }, /* ASMedia ASM2824 */
|
||||
{}
|
||||
};
|
||||
u16 lnksta, lnkctl2;
|
||||
u16 lnksta, lnkctl2, oldlnkctl2;
|
||||
enum pci_bus_speed speed_cap;
|
||||
int ret = -ENOTTY;
|
||||
|
||||
if (!pci_is_pcie(dev) || !pcie_downstream_port(dev) ||
|
||||
!pcie_cap_has_lnkctl2(dev) || !dev->link_active_reporting)
|
||||
return ret;
|
||||
|
||||
speed_cap = pcie_get_speed_cap(dev);
|
||||
if (speed_cap <= PCIE_SPEED_2_5GT)
|
||||
return ret;
|
||||
|
||||
pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta);
|
||||
pcie_capability_read_word(dev, PCI_EXP_LNKCTL2, &oldlnkctl2);
|
||||
if (!(lnksta & PCI_EXP_LNKSTA_DLLLA) && pcie_lbms_seen(dev, lnksta)) {
|
||||
u16 oldlnkctl2;
|
||||
|
||||
pci_info(dev, "broken device, retraining non-functional downstream link at 2.5GT/s\n");
|
||||
|
||||
pcie_capability_read_word(dev, PCI_EXP_LNKCTL2, &oldlnkctl2);
|
||||
ret = pcie_set_target_speed(dev, PCIE_SPEED_2_5GT, false);
|
||||
if (ret) {
|
||||
pci_info(dev, "retraining failed\n");
|
||||
pcie_set_target_speed(dev, PCIE_LNKCTL2_TLS2SPEED(oldlnkctl2),
|
||||
true);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
pcie_capability_read_word(dev, PCI_EXP_LNKCTL2, &lnkctl2);
|
||||
|
||||
if ((lnksta & PCI_EXP_LNKSTA_DLLLA) &&
|
||||
(lnkctl2 & PCI_EXP_LNKCTL2_TLS) == PCI_EXP_LNKCTL2_TLS_2_5GT &&
|
||||
pci_match_id(ids, dev)) {
|
||||
u32 lnkcap;
|
||||
|
||||
if ((lnkctl2 & PCI_EXP_LNKCTL2_TLS) == PCI_EXP_LNKCTL2_TLS_2_5GT) {
|
||||
pci_info(dev, "removing 2.5GT/s downstream link speed restriction\n");
|
||||
pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnkcap);
|
||||
ret = pcie_set_target_speed(dev, PCIE_LNKCAP_SLS2SPEED(lnkcap), false);
|
||||
if (ret) {
|
||||
pci_info(dev, "retraining failed\n");
|
||||
return ret;
|
||||
}
|
||||
ret = pcie_set_target_speed(dev, speed_cap, false);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
return ret;
|
||||
err:
|
||||
pci_info(dev, "retraining failed\n");
|
||||
pcie_set_target_speed(dev, PCIE_LNKCTL2_TLS2SPEED(oldlnkctl2), true);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user