Module Name: src Committed By: martin Date: Tue Jul 4 14:35:21 UTC 2017
Modified Files: src/sys/dev/pci [netbsd-8]: pci_subr.c pcireg.h Log Message: Pull up following revision(s) (requested by msaitoh in ticket #80): sys/dev/pci/pci_subr.c: revision 1.184 sys/dev/pci/pci_subr.c: revision 1.185 sys/dev/pci/pci_subr.c: revision 1.186 sys/dev/pci/pci_subr.c: revision 1.187 sys/dev/pci/pci_subr.c: revision 1.188 sys/dev/pci/pci_subr.c: revision 1.189 sys/dev/pci/pcireg.h: revision 1.131 Add missing return to print the Slot Power Limit Value correctly. Fix to print the following bit fields correctly. - Supported Link Speeds Vector in LCAP2 - Lower SKP OS Generation Supported Speed Vector in LCAP2 - Lower SKP OS Reception Supported Speed Vector in LCAP2 - Enable Lower SKP OS Generation Vector in LCTL3 Note that the above bitfields start from 0 and the follwing bitfields start from 1: - Maximum Link Speed in LCAP - Current Link Speed in LCSR - Target Link Speed in LCSR2 For the Target Link Speed in LCSR2, 0 is allowed for a device which supports 2.5GT/s only (and this check also works for devices which compliant to versions of the base specification prior to 3.0. Tested with BCM5709: - Target Link Speed: unknown value (0) + Target Link Speed: 2.5GT/s For Attention Indicator Control bit and Power Indicator Control bit, it's allowed to be a read only value 0 if corresponding capability register bit is 0. Fix a bug that LTR's latency in L1 PM Substates capability and Latency Tolerance Reporting capability isn't printed correctly. Fix printf format/argument. To generate a diff of this commit: cvs rdiff -u -r1.183 -r1.183.2.1 src/sys/dev/pci/pci_subr.c cvs rdiff -u -r1.130 -r1.130.2.1 src/sys/dev/pci/pcireg.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/pci_subr.c diff -u src/sys/dev/pci/pci_subr.c:1.183 src/sys/dev/pci/pci_subr.c:1.183.2.1 --- src/sys/dev/pci/pci_subr.c:1.183 Mon May 29 07:09:20 2017 +++ src/sys/dev/pci/pci_subr.c Tue Jul 4 14:35:21 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: pci_subr.c,v 1.183 2017/05/29 07:09:20 msaitoh Exp $ */ +/* $NetBSD: pci_subr.c,v 1.183.2.1 2017/07/04 14:35:21 martin Exp $ */ /* * Copyright (c) 1997 Zubin D. Dittia. All rights reserved. @@ -40,7 +40,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.183 2017/05/29 07:09:20 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.183.2.1 2017/07/04 14:35:21 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_pci.h" @@ -1606,18 +1606,39 @@ pci_print_pcie_compl_timeout(uint32_t va } } -static const char * const pcie_linkspeeds[] = {"2.5", "2.5", "5.0", "8.0"}; +static const char * const pcie_linkspeeds[] = {"2.5", "5.0", "8.0"}; +/* + * Print link speed. This function is used for the following register bits: + * Maximum Link Speed in LCAP + * Current Link Speed in LCSR + * Target Link Speed in LCSR2 + * All of above bitfield's values start from 1. + * For LCSR2, 0 is allowed for a device which supports 2.5GT/s only (and + * this check also works for devices which compliant to versions of the base + * specification prior to 3.0. + */ static void -pci_print_pcie_linkspeed(pcireg_t val) +pci_print_pcie_linkspeed(int regnum, pcireg_t val) { - if (val > __arraycount(pcie_linkspeeds)) + if ((regnum == PCIE_LCSR2) && (val == 0)) + printf("2.5GT/s\n"); + else if ((val < 1) || (val > __arraycount(pcie_linkspeeds))) printf("unknown value (%u)\n", val); else - printf("%sGT/s\n", pcie_linkspeeds[val]); + printf("%sGT/s\n", pcie_linkspeeds[val - 1]); } +/* + * Print link speed "vector". + * This function is used for the following register bits: + * Supported Link Speeds Vector in LCAP2 + * Lower SKP OS Generation Supported Speed Vector in LCAP2 + * Lower SKP OS Reception Supported Speed Vector in LCAP2 + * Enable Lower SKP OS Generation Vector in LCTL3 + * All of above bitfield's values start from 0. + */ static void pci_print_pcie_linkspeedvector(pcireg_t val) { @@ -1788,7 +1809,7 @@ pci_conf_print_pcie_cap(const pcireg_t * reg = regs[o2i(capoff + PCIE_LCAP)]; printf(" Link Capabilities Register: 0x%08x\n", reg); printf(" Maximum Link Speed: "); - pci_print_pcie_linkspeed(reg & PCIE_LCAP_MAX_SPEED); + pci_print_pcie_linkspeed(PCIE_LCAP, reg & PCIE_LCAP_MAX_SPEED); printf(" Maximum Link Width: x%u lanes\n", (unsigned int)__SHIFTOUT(reg, PCIE_LCAP_MAX_WIDTH)); printf(" Active State PM Support: "); @@ -1871,7 +1892,8 @@ pci_conf_print_pcie_cap(const pcireg_t * reg = regs[o2i(capoff + PCIE_LCSR)]; printf(" Link Status Register: 0x%04x\n", reg >> 16); printf(" Negotiated Link Speed: "); - pci_print_pcie_linkspeed(__SHIFTOUT(reg, PCIE_LCSR_LINKSPEED)); + pci_print_pcie_linkspeed(PCIE_LCSR, + __SHIFTOUT(reg, PCIE_LCSR_LINKSPEED)); printf(" Negotiated Link Width: x%u lanes\n", (unsigned int)__SHIFTOUT(reg, PCIE_LCSR_NLW)); onoff("Training Error", reg, PCIE_LCSR_LINKTRAIN_ERR); @@ -1885,8 +1907,10 @@ pci_conf_print_pcie_cap(const pcireg_t * } if (check_slot == true) { + pcireg_t slcap; + /* Slot Capability Register */ - reg = regs[o2i(capoff + PCIE_SLCAP)]; + slcap = reg = regs[o2i(capoff + PCIE_SLCAP)]; printf(" Slot Capability Register: 0x%08x\n", reg); onoff("Attention Button Present", reg, PCIE_SLCAP_ABP); onoff("Power Controller Present", reg, PCIE_SLCAP_PCP); @@ -1914,35 +1938,44 @@ pci_conf_print_pcie_cap(const pcireg_t * onoff("Command Completed Interrupt Enabled", reg, PCIE_SLCSR_CCE); onoff("Hot-Plug Interrupt Enabled", reg, PCIE_SLCSR_HPE); - printf(" Attention Indicator Control: "); - switch ((reg & PCIE_SLCSR_AIC) >> 6) { - case 0x0: - printf("reserved\n"); - break; - case PCIE_SLCSR_IND_ON: - printf("on\n"); - break; - case PCIE_SLCSR_IND_BLINK: - printf("blink\n"); - break; - case PCIE_SLCSR_IND_OFF: - printf("off\n"); - break; + /* + * For Attention Indicator Control and Power Indicator Control, + * it's allowed to be a read only value 0 if corresponding + * capability register bit is 0. + */ + if (slcap & PCIE_SLCAP_AIP) { + printf(" Attention Indicator Control: "); + switch ((reg & PCIE_SLCSR_AIC) >> 6) { + case 0x0: + printf("reserved\n"); + break; + case PCIE_SLCSR_IND_ON: + printf("on\n"); + break; + case PCIE_SLCSR_IND_BLINK: + printf("blink\n"); + break; + case PCIE_SLCSR_IND_OFF: + printf("off\n"); + break; + } } - printf(" Power Indicator Control: "); - switch ((reg & PCIE_SLCSR_PIC) >> 8) { - case 0x0: - printf("reserved\n"); - break; - case PCIE_SLCSR_IND_ON: - printf("on\n"); - break; - case PCIE_SLCSR_IND_BLINK: - printf("blink\n"); - break; - case PCIE_SLCSR_IND_OFF: - printf("off\n"); - break; + if (slcap & PCIE_SLCAP_PIP) { + printf(" Power Indicator Control: "); + switch ((reg & PCIE_SLCSR_PIC) >> 8) { + case 0x0: + printf("reserved\n"); + break; + case PCIE_SLCSR_IND_ON: + printf("on\n"); + break; + case PCIE_SLCSR_IND_BLINK: + printf("blink\n"); + break; + case PCIE_SLCSR_IND_OFF: + printf("off\n"); + break; + } } printf(" Power Controller Control: Power %s\n", reg & PCIE_SLCSR_PCC ? "off" : "on"); @@ -2151,10 +2184,11 @@ pci_conf_print_pcie_cap(const pcireg_t * /* Link Control 2 */ reg = regs[o2i(capoff + PCIE_LCSR2)]; + /* If the vector is 0, LCAP2 is not implemented */ printf(" Link Control 2: 0x%04x\n", reg & 0xffff); printf(" Target Link Speed: "); - pci_print_pcie_linkspeed(__SHIFTOUT(reg, - PCIE_LCSR2_TGT_LSPEED)); + pci_print_pcie_linkspeed(PCIE_LCSR2, + __SHIFTOUT(reg, PCIE_LCSR2_TGT_LSPEED)); onoff("Enter Compliance Enabled", reg, PCIE_LCSR2_ENT_COMPL); onoff("HW Autonomous Speed Disabled", reg, PCIE_LCSR2_HW_AS_DIS); @@ -2741,6 +2775,7 @@ pci_conf_print_pcie_power(uint8_t base, break; } printf("%s\n", s); + return; } for (unsigned int i = scale; i > 0; i--) @@ -3468,18 +3503,15 @@ pci_conf_print_ltr_cap(const pcireg_t *r pcireg_t reg; printf("\n Latency Tolerance Reporting\n"); - reg = regs[o2i(extcapoff + PCI_LTR_MAXSNOOPLAT)] & 0xffff; - printf(" Max Snoop Latency Register: 0x%04x\n", reg); - printf(" Max Snoop LatencyValue: %u\n", - (pcireg_t)__SHIFTOUT(reg, PCI_LTR_MAXSNOOPLAT_VAL)); - printf(" Max Snoop LatencyScale: %uns\n", - PCI_LTR_SCALETONS(__SHIFTOUT(reg, PCI_LTR_MAXSNOOPLAT_SCALE))); - reg = regs[o2i(extcapoff + PCI_LTR_MAXNOSNOOPLAT)] >> 16; - printf(" Max No-Snoop Latency Register: 0x%04x\n", reg); - printf(" Max No-Snoop LatencyValue: %u\n", - (pcireg_t)__SHIFTOUT(reg, PCI_LTR_MAXNOSNOOPLAT_VAL)); - printf(" Max No-Snoop LatencyScale: %uns\n", - PCI_LTR_SCALETONS(__SHIFTOUT(reg, PCI_LTR_MAXNOSNOOPLAT_SCALE))); + reg = regs[o2i(extcapoff + PCI_LTR_MAXSNOOPLAT)]; + printf(" Max Snoop Latency Register: 0x%04x\n", reg & 0xffff); + printf(" Max Snoop Latency: %juns\n", + (uintmax_t)(__SHIFTOUT(reg, PCI_LTR_MAXSNOOPLAT_VAL) + * PCI_LTR_SCALETONS(__SHIFTOUT(reg, PCI_LTR_MAXSNOOPLAT_SCALE)))); + printf(" Max No-Snoop Latency Register: 0x%04x\n", reg >> 16); + printf(" Max No-Snoop Latency: %juns\n", + (uintmax_t)(__SHIFTOUT(reg, PCI_LTR_MAXNOSNOOPLAT_VAL) + * PCI_LTR_SCALETONS(__SHIFTOUT(reg, PCI_LTR_MAXNOSNOOPLAT_SCALE)))); } static void Index: src/sys/dev/pci/pcireg.h diff -u src/sys/dev/pci/pcireg.h:1.130 src/sys/dev/pci/pcireg.h:1.130.2.1 --- src/sys/dev/pci/pcireg.h:1.130 Mon May 29 07:09:20 2017 +++ src/sys/dev/pci/pcireg.h Tue Jul 4 14:35:21 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: pcireg.h,v 1.130 2017/05/29 07:09:20 msaitoh Exp $ */ +/* $NetBSD: pcireg.h,v 1.130.2.1 2017/07/04 14:35:21 martin Exp $ */ /* * Copyright (c) 1995, 1996, 1999, 2000 @@ -1877,7 +1877,7 @@ struct pci_rom { #define PCI_LTR_MAXNOSNOOPLAT 0x04 /* Max No-Snoop Latency */ #define PCI_LTR_MAXNOSNOOPLAT_VAL __BITS(25, 16) /* Max No-Snoop LatencyValue*/ #define PCI_LTR_MAXNOSNOOPLAT_SCALE __BITS(28, 26) /*Max NoSnoop LatencyScale*/ -#define PCI_LTR_SCALETONS(x) ((32 << (x)) / 32) +#define PCI_LTR_SCALETONS(x) (1 << ((x) * 5)) /* * Extended capability ID: 0x0019