Skip to content

Commit 79c731e

Browse files
ij-intelbjorn-helgaas
authored andcommitted
PCI: Track Flit Mode Status & print it with link status
PCIe r6.0 added Flit mode, which mainly alters HW behavior, but there are some OS visible changes. The OS visible changes include differences in the layout of some capabilities and interpretation of the TLP headers (in diagnostics situations). To be able to determine which mode the PCIe Link is using, store the Flit Mode Status (PCIe r6.1 sec 7.5.3.20) information in addition to the Link speed into struct pci_bus in pcie_update_link_speed(). Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Ilpo Järvinen <[email protected]> [bhelgaas: use unsigned int:1 instead of bool, update flit_mode setting] Signed-off-by: Bjorn Helgaas <[email protected]>
1 parent fab874e commit 79c731e

File tree

5 files changed

+17
-9
lines changed

5 files changed

+17
-9
lines changed

drivers/pci/hotplug/pciehp_hpc.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ int pciehp_check_link_status(struct controller *ctrl)
292292
{
293293
struct pci_dev *pdev = ctrl_dev(ctrl);
294294
bool found;
295-
u16 lnk_status;
295+
u16 lnk_status, linksta2;
296296

297297
if (!pcie_wait_for_link(pdev, true)) {
298298
ctrl_info(ctrl, "Slot(%s): No link\n", slot_name(ctrl));
@@ -319,7 +319,8 @@ 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_capability_read_word(pdev, PCI_EXP_LNKSTA2, &linksta2);
323+
__pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status, linksta2);
323324

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

drivers/pci/pci.c

+8-4
Original file line numberDiff line numberDiff line change
@@ -6190,21 +6190,25 @@ void __pcie_print_link_status(struct pci_dev *dev, bool verbose)
61906190
enum pci_bus_speed speed, speed_cap;
61916191
struct pci_dev *limiting_dev = NULL;
61926192
u32 bw_avail, bw_cap;
6193+
char *flit_mode = "";
61936194

61946195
bw_cap = pcie_bandwidth_capable(dev, &speed_cap, &width_cap);
61956196
bw_avail = pcie_bandwidth_available(dev, &limiting_dev, &speed, &width);
61966197

6198+
if (dev->bus && dev->bus->flit_mode)
6199+
flit_mode = ", in Flit mode";
6200+
61976201
if (bw_avail >= bw_cap && verbose)
6198-
pci_info(dev, "%u.%03u Gb/s available PCIe bandwidth (%s x%d link)\n",
6202+
pci_info(dev, "%u.%03u Gb/s available PCIe bandwidth (%s x%d link)%s\n",
61996203
bw_cap / 1000, bw_cap % 1000,
6200-
pci_speed_string(speed_cap), width_cap);
6204+
pci_speed_string(speed_cap), width_cap, flit_mode);
62016205
else if (bw_avail < bw_cap)
6202-
pci_info(dev, "%u.%03u Gb/s available PCIe bandwidth, limited by %s x%d link at %s (capable of %u.%03u Gb/s with %s x%d link)\n",
6206+
pci_info(dev, "%u.%03u Gb/s available PCIe bandwidth, limited by %s x%d link at %s (capable of %u.%03u Gb/s with %s x%d link)%s\n",
62036207
bw_avail / 1000, bw_avail % 1000,
62046208
pci_speed_string(speed), width,
62056209
limiting_dev ? pci_name(limiting_dev) : "<unknown>",
62066210
bw_cap / 1000, bw_cap % 1000,
6207-
pci_speed_string(speed_cap), width_cap);
6211+
pci_speed_string(speed_cap), width_cap, flit_mode);
62086212
}
62096213

62106214
/**

drivers/pci/pci.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -406,9 +406,10 @@ const char *pci_speed_string(enum pci_bus_speed speed);
406406
void __pcie_print_link_status(struct pci_dev *dev, bool verbose);
407407
void pcie_report_downtraining(struct pci_dev *dev);
408408

409-
static inline void __pcie_update_link_speed(struct pci_bus *bus, u16 linksta)
409+
static inline void __pcie_update_link_speed(struct pci_bus *bus, u16 linksta, u16 linksta2)
410410
{
411411
bus->cur_bus_speed = pcie_link_speed[linksta & PCI_EXP_LNKSTA_CLS];
412+
bus->flit_mode = (linksta2 & PCI_EXP_LNKSTA2_FLIT) ? 1 : 0;
412413
}
413414
void pcie_update_link_speed(struct pci_bus *bus);
414415

drivers/pci/probe.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -788,10 +788,11 @@ EXPORT_SYMBOL_GPL(pci_speed_string);
788788
void pcie_update_link_speed(struct pci_bus *bus)
789789
{
790790
struct pci_dev *bridge = bus->self;
791-
u16 linksta;
791+
u16 linksta, linksta2;
792792

793793
pcie_capability_read_word(bridge, PCI_EXP_LNKSTA, &linksta);
794-
__pcie_update_link_speed(bus, linksta);
794+
pcie_capability_read_word(bridge, PCI_EXP_LNKSTA2, &linksta2);
795+
__pcie_update_link_speed(bus, linksta, linksta2);
795796
}
796797
EXPORT_SYMBOL_GPL(pcie_update_link_speed);
797798

include/linux/pci.h

+1
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,7 @@ struct pci_bus {
681681
struct bin_attribute *legacy_mem; /* Legacy mem */
682682
unsigned int is_added:1;
683683
unsigned int unsafe_warn:1; /* warned about RW1C config write */
684+
unsigned int flit_mode:1; /* Link in Flit mode */
684685
};
685686

686687
#define to_pci_bus(n) container_of(n, struct pci_bus, dev)

0 commit comments

Comments
 (0)