Skip to content

Commit 39a8ddd

Browse files
committed
Merge: PCI: Update bandwidth management subsystem
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/6615 ``` JIRA: https://issues.redhat.com/browse/RHEL-81906 This series includes a set of key fixes related to PCIe's bandwidth link training from upstream v6.13 by taking in content from upstream merge request d957ff7 "Merge branch 'pci/bwctrl'". Signed-off-by: Myron Stowe <[email protected]> ``` Approved-by: John W. Linville <[email protected]> Approved-by: Desnes Nunes <[email protected]> Approved-by: CKI KWF Bot <[email protected]> Approved-by: Tony Camuso <[email protected]> Merged-by: Augusto Caringi <[email protected]>
2 parents 0f3144b + 7860f8f commit 39a8ddd

File tree

14 files changed

+529
-56
lines changed

14 files changed

+529
-56
lines changed

Documentation/PCI/pciebus-howto.rst

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,12 @@ capability structure except the PCI Express capability structure,
217217
that is shared between many drivers including the service drivers.
218218
RMW Capability accessors (pcie_capability_clear_and_set_word(),
219219
pcie_capability_set_word(), and pcie_capability_clear_word()) protect
220-
a selected set of PCI Express Capability Registers (Link Control
221-
Register and Root Control Register). Any change to those registers
222-
should be performed using RMW accessors to avoid problems due to
223-
concurrent updates. For the up-to-date list of protected registers,
224-
see pcie_capability_clear_and_set_word().
220+
a selected set of PCI Express Capability Registers:
221+
222+
* Link Control Register
223+
* Root Control Register
224+
* Link Control 2 Register
225+
226+
Any change to those registers should be performed using RMW accessors to
227+
avoid problems due to concurrent updates. For the up-to-date list of
228+
protected registers, see pcie_capability_clear_and_set_word().

MAINTAINERS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15035,6 +15035,12 @@ F: include/linux/of_pci.h
1503515035
F: include/linux/pci*
1503615036
F: include/uapi/linux/pci*
1503715037

15038+
PCIE BANDWIDTH CONTROLLER
15039+
M: Ilpo Järvinen <[email protected]>
15040+
15041+
S: Supported
15042+
F: drivers/pci/pcie/bwctrl.c
15043+
1503815044
PCIE DRIVER FOR AMAZON ANNAPURNA LABS
1503915045
M: Jonathan Chocron <[email protected]>
1504015046

drivers/pci/hotplug/pciehp_ctrl.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include <linux/types.h>
2020
#include <linux/pm_runtime.h>
2121
#include <linux/pci.h>
22+
23+
#include "../pci.h"
2224
#include "pciehp.h"
2325

2426
/* The following routines constitute the bulk of the
@@ -127,6 +129,9 @@ static void remove_board(struct controller *ctrl, bool safe_removal)
127129

128130
pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF,
129131
INDICATOR_NOOP);
132+
133+
/* Don't carry LBMS indications across */
134+
pcie_reset_lbms_count(ctrl->pcie->port);
130135
}
131136

132137
static int pciehp_enable_slot(struct controller *ctrl);

drivers/pci/hotplug/pciehp_hpc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ int pciehp_check_link_status(struct controller *ctrl)
319319
return -1;
320320
}
321321

322-
pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status);
322+
__pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status);
323323

324324
if (!found) {
325325
ctrl_info(ctrl, "Slot(%s): No device found\n",

drivers/pci/pci.c

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4744,7 +4744,7 @@ int pcie_retrain_link(struct pci_dev *pdev, bool use_lt)
47444744
* to track link speed or width changes made by hardware itself
47454745
* in attempt to correct unreliable link operation.
47464746
*/
4747-
pcie_capability_write_word(pdev, PCI_EXP_LNKSTA, PCI_EXP_LNKSTA_LBMS);
4747+
pcie_reset_lbms_count(pdev);
47484748
return rc;
47494749
}
47504750

@@ -6193,38 +6193,66 @@ u32 pcie_bandwidth_available(struct pci_dev *dev, struct pci_dev **limiting_dev,
61936193
EXPORT_SYMBOL(pcie_bandwidth_available);
61946194

61956195
/**
6196-
* pcie_get_speed_cap - query for the PCI device's link speed capability
6196+
* pcie_get_supported_speeds - query Supported Link Speed Vector
61976197
* @dev: PCI device to query
61986198
*
6199-
* Query the PCI device speed capability. Return the maximum link speed
6200-
* supported by the device.
6199+
* Query @dev supported link speeds.
6200+
*
6201+
* Implementation Note in PCIe r6.0 sec 7.5.3.18 recommends determining
6202+
* supported link speeds using the Supported Link Speeds Vector in the Link
6203+
* Capabilities 2 Register (when available).
6204+
*
6205+
* Link Capabilities 2 was added in PCIe r3.0, sec 7.8.18.
6206+
*
6207+
* Without Link Capabilities 2, i.e., prior to PCIe r3.0, Supported Link
6208+
* Speeds field in Link Capabilities is used and only 2.5 GT/s and 5.0 GT/s
6209+
* speeds were defined.
6210+
*
6211+
* For @dev without Supported Link Speed Vector, the field is synthesized
6212+
* from the Max Link Speed field in the Link Capabilities Register.
6213+
*
6214+
* Return: Supported Link Speeds Vector (+ reserved 0 at LSB).
62016215
*/
6202-
enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev)
6216+
u8 pcie_get_supported_speeds(struct pci_dev *dev)
62036217
{
62046218
u32 lnkcap2, lnkcap;
6219+
u8 speeds;
62056220

62066221
/*
6207-
* Link Capabilities 2 was added in PCIe r3.0, sec 7.8.18. The
6208-
* implementation note there recommends using the Supported Link
6209-
* Speeds Vector in Link Capabilities 2 when supported.
6210-
*
6211-
* Without Link Capabilities 2, i.e., prior to PCIe r3.0, software
6212-
* should use the Supported Link Speeds field in Link Capabilities,
6213-
* where only 2.5 GT/s and 5.0 GT/s speeds were defined.
6222+
* Speeds retain the reserved 0 at LSB before PCIe Supported Link
6223+
* Speeds Vector to allow using SLS Vector bit defines directly.
62146224
*/
62156225
pcie_capability_read_dword(dev, PCI_EXP_LNKCAP2, &lnkcap2);
6226+
speeds = lnkcap2 & PCI_EXP_LNKCAP2_SLS;
6227+
6228+
/* Ignore speeds higher than Max Link Speed */
6229+
pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnkcap);
6230+
speeds &= GENMASK(lnkcap & PCI_EXP_LNKCAP_SLS, 0);
62166231

62176232
/* PCIe r3.0-compliant */
6218-
if (lnkcap2)
6219-
return PCIE_LNKCAP2_SLS2SPEED(lnkcap2);
6233+
if (speeds)
6234+
return speeds;
62206235

6221-
pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnkcap);
6236+
/* Synthesize from the Max Link Speed field */
62226237
if ((lnkcap & PCI_EXP_LNKCAP_SLS) == PCI_EXP_LNKCAP_SLS_5_0GB)
6223-
return PCIE_SPEED_5_0GT;
6238+
speeds = PCI_EXP_LNKCAP2_SLS_5_0GB | PCI_EXP_LNKCAP2_SLS_2_5GB;
62246239
else if ((lnkcap & PCI_EXP_LNKCAP_SLS) == PCI_EXP_LNKCAP_SLS_2_5GB)
6225-
return PCIE_SPEED_2_5GT;
6240+
speeds = PCI_EXP_LNKCAP2_SLS_2_5GB;
6241+
6242+
return speeds;
6243+
}
62266244

6227-
return PCI_SPEED_UNKNOWN;
6245+
/**
6246+
* pcie_get_speed_cap - query for the PCI device's link speed capability
6247+
* @dev: PCI device to query
6248+
*
6249+
* Query the PCI device speed capability.
6250+
*
6251+
* Return: the maximum link speed supported by the device.
6252+
*/
6253+
enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev)
6254+
{
6255+
return PCIE_LNKCAP2_SLS2SPEED(dev->supported_speeds);
62286256
}
62296257
EXPORT_SYMBOL(pcie_get_speed_cap);
62306258

drivers/pci/pci.h

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,17 @@ void pci_disable_bridge_window(struct pci_dev *dev);
318318
struct pci_bus *pci_bus_get(struct pci_bus *bus);
319319
void pci_bus_put(struct pci_bus *bus);
320320

321+
#define PCIE_LNKCAP_SLS2SPEED(lnkcap) \
322+
({ \
323+
((lnkcap) == PCI_EXP_LNKCAP_SLS_64_0GB ? PCIE_SPEED_64_0GT : \
324+
(lnkcap) == PCI_EXP_LNKCAP_SLS_32_0GB ? PCIE_SPEED_32_0GT : \
325+
(lnkcap) == PCI_EXP_LNKCAP_SLS_16_0GB ? PCIE_SPEED_16_0GT : \
326+
(lnkcap) == PCI_EXP_LNKCAP_SLS_8_0GB ? PCIE_SPEED_8_0GT : \
327+
(lnkcap) == PCI_EXP_LNKCAP_SLS_5_0GB ? PCIE_SPEED_5_0GT : \
328+
(lnkcap) == PCI_EXP_LNKCAP_SLS_2_5GB ? PCIE_SPEED_2_5GT : \
329+
PCI_SPEED_UNKNOWN); \
330+
})
331+
321332
/* PCIe link information from Link Capabilities 2 */
322333
#define PCIE_LNKCAP2_SLS2SPEED(lnkcap2) \
323334
((lnkcap2) & PCI_EXP_LNKCAP2_SLS_64_0GB ? PCIE_SPEED_64_0GT : \
@@ -328,6 +339,15 @@ void pci_bus_put(struct pci_bus *bus);
328339
(lnkcap2) & PCI_EXP_LNKCAP2_SLS_2_5GB ? PCIE_SPEED_2_5GT : \
329340
PCI_SPEED_UNKNOWN)
330341

342+
#define PCIE_LNKCTL2_TLS2SPEED(lnkctl2) \
343+
((lnkctl2) == PCI_EXP_LNKCTL2_TLS_64_0GT ? PCIE_SPEED_64_0GT : \
344+
(lnkctl2) == PCI_EXP_LNKCTL2_TLS_32_0GT ? PCIE_SPEED_32_0GT : \
345+
(lnkctl2) == PCI_EXP_LNKCTL2_TLS_16_0GT ? PCIE_SPEED_16_0GT : \
346+
(lnkctl2) == PCI_EXP_LNKCTL2_TLS_8_0GT ? PCIE_SPEED_8_0GT : \
347+
(lnkctl2) == PCI_EXP_LNKCTL2_TLS_5_0GT ? PCIE_SPEED_5_0GT : \
348+
(lnkctl2) == PCI_EXP_LNKCTL2_TLS_2_5GT ? PCIE_SPEED_2_5GT : \
349+
PCI_SPEED_UNKNOWN)
350+
331351
/* PCIe speed to Mb/s reduced by encoding overhead */
332352
#define PCIE_SPEED2MBS_ENC(speed) \
333353
((speed) == PCIE_SPEED_64_0GT ? 64000*1/1 : \
@@ -360,12 +380,16 @@ static inline int pcie_dev_speed_mbps(enum pci_bus_speed speed)
360380
return -EINVAL;
361381
}
362382

383+
u8 pcie_get_supported_speeds(struct pci_dev *dev);
363384
const char *pci_speed_string(enum pci_bus_speed speed);
364-
enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev);
365-
enum pcie_link_width pcie_get_width_cap(struct pci_dev *dev);
366385
void __pcie_print_link_status(struct pci_dev *dev, bool verbose);
367386
void pcie_report_downtraining(struct pci_dev *dev);
368-
void pcie_update_link_speed(struct pci_bus *bus, u16 link_status);
387+
388+
static inline void __pcie_update_link_speed(struct pci_bus *bus, u16 linksta)
389+
{
390+
bus->cur_bus_speed = pcie_link_speed[linksta & PCI_EXP_LNKSTA_CLS];
391+
}
392+
void pcie_update_link_speed(struct pci_bus *bus);
369393

370394
/* Single Root I/O Virtualization */
371395
struct pci_sriov {
@@ -680,6 +704,17 @@ static inline void pcie_set_ecrc_checking(struct pci_dev *dev) { }
680704
static inline void pcie_ecrc_get_policy(char *str) { }
681705
#endif
682706

707+
#ifdef CONFIG_PCIEPORTBUS
708+
void pcie_reset_lbms_count(struct pci_dev *port);
709+
int pcie_lbms_count(struct pci_dev *port, unsigned long *val);
710+
#else
711+
static inline void pcie_reset_lbms_count(struct pci_dev *port) {}
712+
static inline int pcie_lbms_count(struct pci_dev *port, unsigned long *val)
713+
{
714+
return -EOPNOTSUPP;
715+
}
716+
#endif
717+
683718
struct pci_dev_reset_methods {
684719
u16 vendor;
685720
u16 device;

drivers/pci/pcie/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
pcieportdrv-y := portdrv.o rcec.o
66

7-
obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o
7+
obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o bwctrl.o
88

99
obj-y += aspm.o
1010
obj-$(CONFIG_PCIEAER) += aer.o err.o

0 commit comments

Comments
 (0)