All of lore.kernel.org
 help / color / mirror / Atom feed
* pcie_get_minimum_link returns 0 width
       [not found] <20130825100157.GA16500@lb-tlvb-yuvalmin.il.broadcom.com>
@ 2013-08-25 11:21 ` Yuval Mintz
  2013-08-26 18:27   ` Keller, Jacob E
  2013-08-26 22:05   ` Bjorn Helgaas
  0 siblings, 2 replies; 16+ messages in thread
From: Yuval Mintz @ 2013-08-25 11:21 UTC (permalink / raw)
  To: jacob.e.keller; +Cc: bhelgaas, linux-pci, netdev

Hi,

I tried adding support for the newly added 'pcie_get_minimum_link' into the
bnx2x driver, but found out the some of my devices started showing width x0.

By adding debug prints, I've found out there were devices up the chain that
Showed 0 when their PCI_EXP_LNKSTA was read by said function.
However, when I tried looking via lspci the output claimed the width was x4.

lspci -vt output:
[0000:00]-+-00.0  Intel Corporation 5000P Chipset Memory Controller Hub
	     +-02.0-[09-12]--+-00.0-[0a-11]--+-00.0-[0b-0d]--
					     +-01.0-[0e-10]--+-00.0  Broadcom
					Corporation NetXtreme II BCM57710
					10-Gigabit PCIe [Everest]

Where:
00:02.0 PCI bridge: Intel Corporation 5000 Series Chipset PCI Express x4 Port
2 (rev 93)
09:00.0 PCI bridge: Intel Corporation 6311ESB/6321ESB PCI Express Upstream
Port (rev 01)
0a:01.0 PCI bridge: Intel Corporation 6311ESB/6321ESB PCI Express
Downstream Port E2 (rev 01)
0e:00.0 Ethernet controller: Broadcom Corporation NetXtreme II BCM57710
10-Gigabit PCIe [Everest] (rev 01)

The output for "lspci -vvvv | grep LnkSta for all four is:
LnkSta:	Speed 2.5GT/s, Width x4, TrErr- Train- SlotClk+ DLActive- BWMgmt-
ABWMgmt-

But added prints inside the function's loop show:
LnkSta 1041 [000e:00.00]
LnkSta 0000 [000a:01.00]
LnkSta 0000 [0009:00.00]
LnkSta 3041 [0000:02.00]
(PCI_EXP_LNKSTA value, bus->number, PCI_SLOT, PCI_FUNC)

Thanks,
Yuval

^ permalink raw reply	[flat|nested] 16+ messages in thread

* RE: pcie_get_minimum_link returns 0 width
  2013-08-25 11:21 ` pcie_get_minimum_link returns 0 width Yuval Mintz
@ 2013-08-26 18:27   ` Keller, Jacob E
  2013-08-26 22:05   ` Bjorn Helgaas
  1 sibling, 0 replies; 16+ messages in thread
From: Keller, Jacob E @ 2013-08-26 18:27 UTC (permalink / raw)
  To: Yuval Mintz; +Cc: bhelgaas, linux-pci, netdev

> -----Original Message-----
> From: Yuval Mintz [mailto:yuvalmin@broadcom.com]
> Sent: Sunday, August 25, 2013 4:22 AM
> To: Keller, Jacob E
> Cc: bhelgaas@google.com; linux-pci@vger.kernel.org;
> netdev@vger.kernel.org
> Subject: pcie_get_minimum_link returns 0 width
> 
> Hi,
> 
> I tried adding support for the newly added 'pcie_get_minimum_link' into
> the
> bnx2x driver, but found out the some of my devices started showing
> width x0.
> 
> By adding debug prints, I've found out there were devices up the chain
> that
> Showed 0 when their PCI_EXP_LNKSTA was read by said function.
> However, when I tried looking via lspci the output claimed the width was
> x4.
> 
> lspci -vt output:
> [0000:00]-+-00.0  Intel Corporation 5000P Chipset Memory Controller
> Hub
> 	     +-02.0-[09-12]--+-00.0-[0a-11]--+-00.0-[0b-0d]--
> 					     +-01.0-[0e-10]--+-00.0
> Broadcom
> 					Corporation NetXtreme II
> BCM57710
> 					10-Gigabit PCIe [Everest]
> 
> Where:
> 00:02.0 PCI bridge: Intel Corporation 5000 Series Chipset PCI Express x4
> Port
> 2 (rev 93)
> 09:00.0 PCI bridge: Intel Corporation 6311ESB/6321ESB PCI Express
> Upstream
> Port (rev 01)
> 0a:01.0 PCI bridge: Intel Corporation 6311ESB/6321ESB PCI Express
> Downstream Port E2 (rev 01)
> 0e:00.0 Ethernet controller: Broadcom Corporation NetXtreme II
> BCM57710
> 10-Gigabit PCIe [Everest] (rev 01)
> 
> The output for "lspci -vvvv | grep LnkSta for all four is:
> LnkSta:	Speed 2.5GT/s, Width x4, TrErr- Train- SlotClk+ DLActive-
> BWMgmt-
> ABWMgmt-
> 
> But added prints inside the function's loop show:
> LnkSta 1041 [000e:00.00]
> LnkSta 0000 [000a:01.00]
> LnkSta 0000 [0009:00.00]
> LnkSta 3041 [0000:02.00]
> (PCI_EXP_LNKSTA value, bus->number, PCI_SLOT, PCI_FUNC)
> 
> Thanks,
> Yuval

Interesting... It looks like the entire LnkSta  read failed for the two in the middle..  I don't know how much I can help on this issue because I don't have a machine that exhibits this symptom.. Any suggestions?

Regards,
Jake

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: pcie_get_minimum_link returns 0 width
  2013-08-25 11:21 ` pcie_get_minimum_link returns 0 width Yuval Mintz
  2013-08-26 18:27   ` Keller, Jacob E
@ 2013-08-26 22:05   ` Bjorn Helgaas
  2013-08-26 23:36     ` Yuval Mintz
  1 sibling, 1 reply; 16+ messages in thread
From: Bjorn Helgaas @ 2013-08-26 22:05 UTC (permalink / raw)
  To: Yuval Mintz; +Cc: jacob.e.keller, linux-pci, netdev

On Sun, Aug 25, 2013 at 5:21 AM, Yuval Mintz <yuvalmin@broadcom.com> wrote:
> Hi,
>
> I tried adding support for the newly added 'pcie_get_minimum_link' into the
> bnx2x driver, but found out the some of my devices started showing width x0.
>
> By adding debug prints, I've found out there were devices up the chain that
> Showed 0 when their PCI_EXP_LNKSTA was read by said function.
> However, when I tried looking via lspci the output claimed the width was x4.

I don't see a 'pcie_get_minimum_link()' function in my current tree
(git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git "next"
branch).  Maybe seeing your patch (with the debug prints) would give
me a hook for somewhere to start looking.

Can you figure out why lspci shows the correct value and this kernel
interface does not?  The current lspci source is in
git://git.kernel.org/pub/scm/utils/pciutils/pciutils.git and the
relevant code is probably in cap_express_link() here:
http://git.kernel.org/cgit/utils/pciutils/pciutils.git/tree/ls-caps.c#n750

> lspci -vt output:
> [0000:00]-+-00.0  Intel Corporation 5000P Chipset Memory Controller Hub
>              +-02.0-[09-12]--+-00.0-[0a-11]--+-00.0-[0b-0d]--
>                                              +-01.0-[0e-10]--+-00.0  Broadcom
>                                         Corporation NetXtreme II BCM57710
>                                         10-Gigabit PCIe [Everest]
>
> Where:
> 00:02.0 PCI bridge: Intel Corporation 5000 Series Chipset PCI Express x4 Port
> 2 (rev 93)
> 09:00.0 PCI bridge: Intel Corporation 6311ESB/6321ESB PCI Express Upstream
> Port (rev 01)
> 0a:01.0 PCI bridge: Intel Corporation 6311ESB/6321ESB PCI Express
> Downstream Port E2 (rev 01)
> 0e:00.0 Ethernet controller: Broadcom Corporation NetXtreme II BCM57710
> 10-Gigabit PCIe [Everest] (rev 01)
>
> The output for "lspci -vvvv | grep LnkSta for all four is:
> LnkSta: Speed 2.5GT/s, Width x4, TrErr- Train- SlotClk+ DLActive- BWMgmt-
> ABWMgmt-
>
> But added prints inside the function's loop show:
> LnkSta 1041 [000e:00.00]
> LnkSta 0000 [000a:01.00]
> LnkSta 0000 [0009:00.00]
> LnkSta 3041 [0000:02.00]
> (PCI_EXP_LNKSTA value, bus->number, PCI_SLOT, PCI_FUNC)
>
> Thanks,
> Yuval
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* RE: pcie_get_minimum_link returns 0 width
  2013-08-26 22:05   ` Bjorn Helgaas
@ 2013-08-26 23:36     ` Yuval Mintz
  2013-08-26 23:57       ` Bjorn Helgaas
  0 siblings, 1 reply; 16+ messages in thread
From: Yuval Mintz @ 2013-08-26 23:36 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: jacob.e.keller, linux-pci, netdev

> > Hi,
> >
> > I tried adding support for the newly added 'pcie_get_minimum_link' into
> the
> > bnx2x driver, but found out the some of my devices started showing width
> x0.
> >
> > By adding debug prints, I've found out there were devices up the chain that
> > Showed 0 when their PCI_EXP_LNKSTA was read by said function.
> > However, when I tried looking via lspci the output claimed the width was
> x4.
> 
> I don't see a 'pcie_get_minimum_link()' function in my current tree
> (git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git "next"
> branch).  Maybe seeing your patch (with the debug prints) would give
> me a hook for somewhere to start looking.

You've acked the patch and it was applied in net-next; Obviously it has yet
to migrate to your tree. 

> 
> Can you figure out why lspci shows the correct value and this kernel
> interface does not?  The current lspci source is in
> git://git.kernel.org/pub/scm/utils/pciutils/pciutils.git and the
> relevant code is probably in cap_express_link() here:
> http://git.kernel.org/cgit/utils/pciutils/pciutils.git/tree/ls-caps.c#n750

Traced the read as going via the pci-sysfs. Where should I look for the bus's
read ops?

Thanks,
Yuval

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: pcie_get_minimum_link returns 0 width
  2013-08-26 23:36     ` Yuval Mintz
@ 2013-08-26 23:57       ` Bjorn Helgaas
  2013-08-27  7:40         ` Yuval Mintz
  0 siblings, 1 reply; 16+ messages in thread
From: Bjorn Helgaas @ 2013-08-26 23:57 UTC (permalink / raw)
  To: Yuval Mintz; +Cc: jacob.e.keller, linux-pci, netdev

On Mon, Aug 26, 2013 at 5:36 PM, Yuval Mintz <yuvalmin@broadcom.com> wrote:
>> > Hi,
>> >
>> > I tried adding support for the newly added 'pcie_get_minimum_link' into
>> the
>> > bnx2x driver, but found out the some of my devices started showing width
>> x0.
>> >
>> > By adding debug prints, I've found out there were devices up the chain that
>> > Showed 0 when their PCI_EXP_LNKSTA was read by said function.
>> > However, when I tried looking via lspci the output claimed the width was
>> x4.
>>
>> I don't see a 'pcie_get_minimum_link()' function in my current tree
>> (git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git "next"
>> branch).  Maybe seeing your patch (with the debug prints) would give
>> me a hook for somewhere to start looking.
>
> You've acked the patch and it was applied in net-next; Obviously it has yet
> to migrate to your tree.

Oh, yeah, that's right.  I knew it sounded familiar, but I didn't
remember where it went.

Looking at its implementation, one obvious difference is that
pcie_get_minimum_link() traverses up the hierarchy and keeps track of
the minimum values it finds.  lspci, on the other hand, just reads
PCI_EXP_LNKSTA from a single device and decodes it.

You said lspci reports x4 for every device from the Root Port all the
way down to your NIC, so I would think the minimum from
pcie_get_minimum_link() would be x4.  But apparently it's not.  Maybe
there's a bug in it.  Can you post the complete "lspci -vv" output
along with your debug patch and output?

Bjorn

^ permalink raw reply	[flat|nested] 16+ messages in thread

* RE: pcie_get_minimum_link returns 0 width
  2013-08-26 23:57       ` Bjorn Helgaas
@ 2013-08-27  7:40         ` Yuval Mintz
  2013-08-27 13:57           ` Bjorn Helgaas
  0 siblings, 1 reply; 16+ messages in thread
From: Yuval Mintz @ 2013-08-27  7:40 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: jacob.e.keller, linux-pci, netdev

> On Mon, Aug 26, 2013 at 5:36 PM, Yuval Mintz <yuvalmin@broadcom.com>
> wrote:
> >> > Hi,
> >> >
> >> > I tried adding support for the newly added 'pcie_get_minimum_link' into
> >> the
> >> > bnx2x driver, but found out the some of my devices started showing
> width
> >> x0.
> >> >
> >> > By adding debug prints, I've found out there were devices up the chain
> that
> >> > Showed 0 when their PCI_EXP_LNKSTA was read by said function.
> >> > However, when I tried looking via lspci the output claimed the width was
> >> x4.
> Looking at its implementation, one obvious difference is that
> pcie_get_minimum_link() traverses up the hierarchy and keeps track of
> the minimum values it finds.  lspci, on the other hand, just reads
> PCI_EXP_LNKSTA from a single device and decodes it.
> 
> You said lspci reports x4 for every device from the Root Port all the
> way down to your NIC, so I would think the minimum from
> pcie_get_minimum_link() would be x4.  But apparently it's not.  Maybe
> there's a bug in it.  Can you post the complete "lspci -vv" output
> along with your debug patch and output?
> 
> Bjorn

Here's the patch:
---
 drivers/pci/pci.c |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index c71e78c..72cb87b 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3601,13 +3601,19 @@ int pcie_get_minimum_link(struct pci_dev *dev, enum pci_bus_speed *speed,
 		enum pcie_link_width next_width;
 
 		ret = pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta);
-		if (ret)
+		if (ret) {
+			printk(KERN_ERR "Failed to Read LNKSTA\n");
 			return ret;
+		}
 
 		next_speed = pcie_link_speed[lnksta & PCI_EXP_LNKSTA_CLS];
 		next_width = (lnksta & PCI_EXP_LNKSTA_NLW) >>
 			PCI_EXP_LNKSTA_NLW_SHIFT;
 
+		printk(KERN_ERR "LnkSta %04x [%04x:%02x.%02x]\n",
+		       lnksta, dev->bus->number, PCI_SLOT(dev->devfn),
+		       PCI_FUNC(dev->devfn));
+
 		if (next_speed < *speed)
 			*speed = next_speed;
 
-- 
1.7.1

And here are the lscpi results for 09:00.0 and 0a:01.0
(The two devices for which the loop returns 0 width):

Sysfs do read [Pos 0, len 64]
09:00.0 Class 0604: Device 8086:3500 (rev 01)
	Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR+ FastB2B- DisINTx-
	Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
	Latency: 0, Cache Line Size: 64 bytes
	Bus: primary=09, secondary=0a, subordinate=11, sec-latency=0
	Memory behind bridge: fb800000-fd7fffff
	Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort+ <SERR- <PERR-
	BridgeCtl: Parity+ SERR+ NoISA- VGA- MAbort- >Reset- FastB2B-
		PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
	Capabilities: Sysfs do read [Pos 68, len 4]
[44] Express (v1) Upstream Port, MSI 00
Sysfs do read [Pos 72, len 16]
		DevCap:	MaxPayload 256 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
			ExtTag- AttnBtn- AttnInd- PwrInd- RBE- FLReset-SlotPowerLimit 0.000W
		DevCtl:	Report errors: Correctable- Non-Fatal+ Fatal+ Unsupported-
			RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
			MaxPayload 256 bytes, MaxReadReq 4096 bytes
		DevSta:	CorrErr- UncorrErr- FatalErr+ UnsuppReq+ AuxPwr- TransPend-
		LnkCap:	Port #0, Speed 2.5GT/s, Width x8, ASPM L0s, Latency L0 unlimited, L1 unlimited
			ClockPM- Surprise- LLActRep- BwNot-
		LnkCtl:	ASPM Disabled; Disabled- Retrain- CommClk-
			ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
		LnkSta:	Speed 2.5GT/s, Width x4, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
	Capabilities: Sysfs do read [Pos 112, len 4]
[70] Power Management version 2
		Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Sysfs do read [Pos 116, len 4]
		Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
	Capabilities: Sysfs do read [Pos 128, len 4]
[80] Sysfs do read [Pos 132, len 4]
Subsystem: Device 0000:0000
Sysfs do read [Pos 256, len 4]
	Capabilities: [100 v1] Advanced Error Reporting
Sysfs do read [Pos 260, len 24]
		UESta:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq+ ACSViol-
		UEMsk:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq+ ACSViol-
		UESvrt:	DLP+ SDES- TLP+ FCP+ CmpltTO+ CmpltAbrt+ UnxCmplt+ RxOF+ MalfTLP+ ECRC- UnsupReq+ ACSViol-
		CESta:	RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr-
		CEMsk:	RxErr+ BadTLP+ BadDLLP+ Rollover+ Timeout+ NonFatalErr-
		AERCap:	First Error Pointer: 14, GenCap- CGenEn- ChkCap- ChkEn-
	Kernel driver in use: pcieport
	Kernel modules: shpchp

Sysfs do read [Pos 0, len 64]
0a:01.0 Class 0604: Device 8086:3514 (rev 01)
	Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR+ FastB2B- DisINTx-
	Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
	Latency: 0, Cache Line Size: 64 bytes
	Bus: primary=0a, secondary=0e, subordinate=10, sec-latency=0
	Memory behind bridge: fb800000-fd7fffff
	Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort+ <SERR- <PERR-
	BridgeCtl: Parity+ SERR+ NoISA- VGA- MAbort- >Reset- FastB2B-
		PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
	Capabilities: Sysfs do read [Pos 68, len 4]
[44] Express (v1) Downstream Port (Slot-), MSI 00
Sysfs do read [Pos 72, len 16]
		DevCap:	MaxPayload 256 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
			ExtTag- RBE- FLReset-
		DevCtl:	Report errors: Correctable- Non-Fatal+ Fatal+ Unsupported-
			RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
			MaxPayload 256 bytes, MaxReadReq 4096 bytes
		DevSta:	CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
		LnkCap:	Port #2, Speed 2.5GT/s, Width x4, ASPM L0s, Latency L0 unlimited, L1 unlimited
			ClockPM- Surprise- LLActRep- BwNot-
		LnkCtl:	ASPM Disabled; Disabled- Retrain- CommClk-
			ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
		LnkSta:	Speed 2.5GT/s, Width x4, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
	Capabilities: Sysfs do read [Pos 96, len 4]
[60] MSI: Enable- Count=1/1 Maskable- 64bit+
Sysfs do read [Pos 100, len 10]
		Address: 0000000000000000  Data: 0000
	Capabilities: Sysfs do read [Pos 112, len 4]
[70] Power Management version 2
		Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Sysfs do read [Pos 116, len 4]
		Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
	Capabilities: Sysfs do read [Pos 128, len 4]
[80] Sysfs do read [Pos 132, len 4]
Subsystem: Device 0000:0000
Sysfs do read [Pos 256, len 4]
	Capabilities: [100 v1] Advanced Error Reporting
Sysfs do read [Pos 260, len 24]
		UESta:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
		UEMsk:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq+ ACSViol-
		UESvrt:	DLP+ SDES- TLP+ FCP+ CmpltTO+ CmpltAbrt+ UnxCmplt+ RxOF+ MalfTLP+ ECRC- UnsupReq+ ACSViol-
		CESta:	RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr-
		CEMsk:	RxErr+ BadTLP+ BadDLLP+ Rollover+ Timeout+ NonFatalErr-
		AERCap:	First Error Pointer: 00, GenCap- CGenEn- ChkCap- ChkEn-
	Kernel driver in use: pcieport
	Kernel modules: shpchp

Thanks,
Yuval

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: pcie_get_minimum_link returns 0 width
  2013-08-27  7:40         ` Yuval Mintz
@ 2013-08-27 13:57           ` Bjorn Helgaas
  2013-08-27 16:13             ` Bjorn Helgaas
  2013-08-27 16:44             ` [PATCH] PCI: correctly check availability of PCIe Link Cap/Status/Control registers Jiang Liu
  0 siblings, 2 replies; 16+ messages in thread
From: Bjorn Helgaas @ 2013-08-27 13:57 UTC (permalink / raw)
  To: Yuval Mintz; +Cc: jacob.e.keller, linux-pci, netdev, Jiang Liu

[+cc Jiang]

On Tue, Aug 27, 2013 at 1:40 AM, Yuval Mintz <yuvalmin@broadcom.com> wrote:
>> On Mon, Aug 26, 2013 at 5:36 PM, Yuval Mintz <yuvalmin@broadcom.com>
>> wrote:
>> >> > Hi,
>> >> >
>> >> > I tried adding support for the newly added 'pcie_get_minimum_link' into
>> >> the
>> >> > bnx2x driver, but found out the some of my devices started showing
>> width
>> >> x0.
>> >> >
>> >> > By adding debug prints, I've found out there were devices up the chain
>> that
>> >> > Showed 0 when their PCI_EXP_LNKSTA was read by said function.
>> >> > However, when I tried looking via lspci the output claimed the width was
>> >> x4.
>> Looking at its implementation, one obvious difference is that
>> pcie_get_minimum_link() traverses up the hierarchy and keeps track of
>> the minimum values it finds.  lspci, on the other hand, just reads
>> PCI_EXP_LNKSTA from a single device and decodes it.
>>
>> You said lspci reports x4 for every device from the Root Port all the
>> way down to your NIC, so I would think the minimum from
>> pcie_get_minimum_link() would be x4.  But apparently it's not.  Maybe
>> there's a bug in it.  Can you post the complete "lspci -vv" output
>> along with your debug patch and output?
>>
>> Bjorn
>
> Here's the patch:
> ---
>  drivers/pci/pci.c |    8 +++++++-
>  1 files changed, 7 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index c71e78c..72cb87b 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -3601,13 +3601,19 @@ int pcie_get_minimum_link(struct pci_dev *dev, enum pci_bus_speed *speed,
>                 enum pcie_link_width next_width;
>
>                 ret = pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta);
> -               if (ret)
> +               if (ret) {
> +                       printk(KERN_ERR "Failed to Read LNKSTA\n");
>                         return ret;
> +               }
>
>                 next_speed = pcie_link_speed[lnksta & PCI_EXP_LNKSTA_CLS];
>                 next_width = (lnksta & PCI_EXP_LNKSTA_NLW) >>
>                         PCI_EXP_LNKSTA_NLW_SHIFT;
>
> +               printk(KERN_ERR "LnkSta %04x [%04x:%02x.%02x]\n",
> +                      lnksta, dev->bus->number, PCI_SLOT(dev->devfn),
> +                      PCI_FUNC(dev->devfn));

I think pcie_cap_has_lnkctl() is incorrect: it currently thinks only
Root Ports, Endpoints, and Legacy Endpoints have link registers.  But
I think switch ports (Upstream Ports and Downstream Ports) also have
link registers (PCIe spec r3.0, sec 7.8).  Jiang?

>                 if (next_speed < *speed)
>                         *speed = next_speed;
>
> --
> 1.7.1
>
> And here are the lscpi results for 09:00.0 and 0a:01.0
> (The two devices for which the loop returns 0 width):
>
> Sysfs do read [Pos 0, len 64]
> 09:00.0 Class 0604: Device 8086:3500 (rev 01)
>         Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR+ FastB2B- DisINTx-
>         Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
>         Latency: 0, Cache Line Size: 64 bytes
>         Bus: primary=09, secondary=0a, subordinate=11, sec-latency=0
>         Memory behind bridge: fb800000-fd7fffff
>         Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort+ <SERR- <PERR-
>         BridgeCtl: Parity+ SERR+ NoISA- VGA- MAbort- >Reset- FastB2B-
>                 PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
>         Capabilities: Sysfs do read [Pos 68, len 4]
> [44] Express (v1) Upstream Port, MSI 00
> Sysfs do read [Pos 72, len 16]
>                 DevCap: MaxPayload 256 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
>                         ExtTag- AttnBtn- AttnInd- PwrInd- RBE- FLReset-SlotPowerLimit 0.000W
>                 DevCtl: Report errors: Correctable- Non-Fatal+ Fatal+ Unsupported-
>                         RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
>                         MaxPayload 256 bytes, MaxReadReq 4096 bytes
>                 DevSta: CorrErr- UncorrErr- FatalErr+ UnsuppReq+ AuxPwr- TransPend-
>                 LnkCap: Port #0, Speed 2.5GT/s, Width x8, ASPM L0s, Latency L0 unlimited, L1 unlimited
>                         ClockPM- Surprise- LLActRep- BwNot-
>                 LnkCtl: ASPM Disabled; Disabled- Retrain- CommClk-
>                         ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
>                 LnkSta: Speed 2.5GT/s, Width x4, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
>         Capabilities: Sysfs do read [Pos 112, len 4]
> [70] Power Management version 2
>                 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
> Sysfs do read [Pos 116, len 4]
>                 Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
>         Capabilities: Sysfs do read [Pos 128, len 4]
> [80] Sysfs do read [Pos 132, len 4]
> Subsystem: Device 0000:0000
> Sysfs do read [Pos 256, len 4]
>         Capabilities: [100 v1] Advanced Error Reporting
> Sysfs do read [Pos 260, len 24]
>                 UESta:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq+ ACSViol-
>                 UEMsk:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq+ ACSViol-
>                 UESvrt: DLP+ SDES- TLP+ FCP+ CmpltTO+ CmpltAbrt+ UnxCmplt+ RxOF+ MalfTLP+ ECRC- UnsupReq+ ACSViol-
>                 CESta:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr-
>                 CEMsk:  RxErr+ BadTLP+ BadDLLP+ Rollover+ Timeout+ NonFatalErr-
>                 AERCap: First Error Pointer: 14, GenCap- CGenEn- ChkCap- ChkEn-
>         Kernel driver in use: pcieport
>         Kernel modules: shpchp
>
> Sysfs do read [Pos 0, len 64]
> 0a:01.0 Class 0604: Device 8086:3514 (rev 01)
>         Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR+ FastB2B- DisINTx-
>         Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
>         Latency: 0, Cache Line Size: 64 bytes
>         Bus: primary=0a, secondary=0e, subordinate=10, sec-latency=0
>         Memory behind bridge: fb800000-fd7fffff
>         Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort+ <SERR- <PERR-
>         BridgeCtl: Parity+ SERR+ NoISA- VGA- MAbort- >Reset- FastB2B-
>                 PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
>         Capabilities: Sysfs do read [Pos 68, len 4]
> [44] Express (v1) Downstream Port (Slot-), MSI 00
> Sysfs do read [Pos 72, len 16]
>                 DevCap: MaxPayload 256 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
>                         ExtTag- RBE- FLReset-
>                 DevCtl: Report errors: Correctable- Non-Fatal+ Fatal+ Unsupported-
>                         RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
>                         MaxPayload 256 bytes, MaxReadReq 4096 bytes
>                 DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
>                 LnkCap: Port #2, Speed 2.5GT/s, Width x4, ASPM L0s, Latency L0 unlimited, L1 unlimited
>                         ClockPM- Surprise- LLActRep- BwNot-
>                 LnkCtl: ASPM Disabled; Disabled- Retrain- CommClk-
>                         ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
>                 LnkSta: Speed 2.5GT/s, Width x4, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
>         Capabilities: Sysfs do read [Pos 96, len 4]
> [60] MSI: Enable- Count=1/1 Maskable- 64bit+
> Sysfs do read [Pos 100, len 10]
>                 Address: 0000000000000000  Data: 0000
>         Capabilities: Sysfs do read [Pos 112, len 4]
> [70] Power Management version 2
>                 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
> Sysfs do read [Pos 116, len 4]
>                 Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
>         Capabilities: Sysfs do read [Pos 128, len 4]
> [80] Sysfs do read [Pos 132, len 4]
> Subsystem: Device 0000:0000
> Sysfs do read [Pos 256, len 4]
>         Capabilities: [100 v1] Advanced Error Reporting
> Sysfs do read [Pos 260, len 24]
>                 UESta:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
>                 UEMsk:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq+ ACSViol-
>                 UESvrt: DLP+ SDES- TLP+ FCP+ CmpltTO+ CmpltAbrt+ UnxCmplt+ RxOF+ MalfTLP+ ECRC- UnsupReq+ ACSViol-
>                 CESta:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr-
>                 CEMsk:  RxErr+ BadTLP+ BadDLLP+ Rollover+ Timeout+ NonFatalErr-
>                 AERCap: First Error Pointer: 00, GenCap- CGenEn- ChkCap- ChkEn-
>         Kernel driver in use: pcieport
>         Kernel modules: shpchp
>
> Thanks,
> Yuval
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: pcie_get_minimum_link returns 0 width
  2013-08-27 13:57           ` Bjorn Helgaas
@ 2013-08-27 16:13             ` Bjorn Helgaas
  2013-08-27 16:44             ` [PATCH] PCI: correctly check availability of PCIe Link Cap/Status/Control registers Jiang Liu
  1 sibling, 0 replies; 16+ messages in thread
From: Bjorn Helgaas @ 2013-08-27 16:13 UTC (permalink / raw)
  To: Yuval Mintz; +Cc: jacob.e.keller, linux-pci, netdev, Jiang Liu

On Tue, Aug 27, 2013 at 07:57:20AM -0600, Bjorn Helgaas wrote:
> [+cc Jiang]
> 
> On Tue, Aug 27, 2013 at 1:40 AM, Yuval Mintz <yuvalmin@broadcom.com> wrote:
> >> On Mon, Aug 26, 2013 at 5:36 PM, Yuval Mintz <yuvalmin@broadcom.com>
> >> wrote:
> >> >> > Hi,
> >> >> >
> >> >> > I tried adding support for the newly added 'pcie_get_minimum_link' into
> >> >> the
> >> >> > bnx2x driver, but found out the some of my devices started showing
> >> width
> >> >> x0.
> >> >> >
> >> >> > By adding debug prints, I've found out there were devices up the chain
> >> that
> >> >> > Showed 0 when their PCI_EXP_LNKSTA was read by said function.
> >> >> > However, when I tried looking via lspci the output claimed the width was
> >> >> x4.
> >> Looking at its implementation, one obvious difference is that
> >> pcie_get_minimum_link() traverses up the hierarchy and keeps track of
> >> the minimum values it finds.  lspci, on the other hand, just reads
> >> PCI_EXP_LNKSTA from a single device and decodes it.
> >>
> >> You said lspci reports x4 for every device from the Root Port all the
> >> way down to your NIC, so I would think the minimum from
> >> pcie_get_minimum_link() would be x4.  But apparently it's not.  Maybe
> >> there's a bug in it.  Can you post the complete "lspci -vv" output
> >> along with your debug patch and output?
> >>
> >> Bjorn
> >
> > Here's the patch:
> > ---
> >  drivers/pci/pci.c |    8 +++++++-
> >  1 files changed, 7 insertions(+), 1 deletions(-)
> >
> > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> > index c71e78c..72cb87b 100644
> > --- a/drivers/pci/pci.c
> > +++ b/drivers/pci/pci.c
> > @@ -3601,13 +3601,19 @@ int pcie_get_minimum_link(struct pci_dev *dev, enum pci_bus_speed *speed,
> >                 enum pcie_link_width next_width;
> >
> >                 ret = pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta);
> > -               if (ret)
> > +               if (ret) {
> > +                       printk(KERN_ERR "Failed to Read LNKSTA\n");
> >                         return ret;
> > +               }
> >
> >                 next_speed = pcie_link_speed[lnksta & PCI_EXP_LNKSTA_CLS];
> >                 next_width = (lnksta & PCI_EXP_LNKSTA_NLW) >>
> >                         PCI_EXP_LNKSTA_NLW_SHIFT;
> >
> > +               printk(KERN_ERR "LnkSta %04x [%04x:%02x.%02x]\n",
> > +                      lnksta, dev->bus->number, PCI_SLOT(dev->devfn),
> > +                      PCI_FUNC(dev->devfn));
> 
> I think pcie_cap_has_lnkctl() is incorrect: it currently thinks only
> Root Ports, Endpoints, and Legacy Endpoints have link registers.  But
> I think switch ports (Upstream Ports and Downstream Ports) also have
> link registers (PCIe spec r3.0, sec 7.8).  Jiang?

Yuval, can you try the patch below?


PCI: Allow access to link-related registers for switch and bridge ports

From: Bjorn Helgaas <bhelgaas@google.com>

Every PCIe device has a link, except Root Complex Integrated Endpoints
and Root Complex Event Collectors.  Previously we didn't give access
to PCIe capability link-related registers for Upstream Ports, Downstream
Ports, and bridges, so attempts to read PCI_EXP_LNKCTL returned zero.
See PCIe spec r3.0, sec 7.8 and 1.3.2.3.

Reported-by: Yuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 drivers/pci/access.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index 1cc2366..46dd5ad 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -485,9 +485,8 @@ static inline bool pcie_cap_has_lnkctl(const struct pci_dev *dev)
 	int type = pci_pcie_type(dev);
 
 	return pcie_cap_version(dev) > 1 ||
-	       type == PCI_EXP_TYPE_ROOT_PORT ||
-	       type == PCI_EXP_TYPE_ENDPOINT ||
-	       type == PCI_EXP_TYPE_LEG_END;
+	       !(type == PCI_EXP_TYPE_RC_END ||
+	         type == PCI_EXP_TYPE_RC_EC);
 }
 
 static inline bool pcie_cap_has_sltctl(const struct pci_dev *dev)

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH] PCI: correctly check availability of PCIe Link Cap/Status/Control registers
  2013-08-27 13:57           ` Bjorn Helgaas
  2013-08-27 16:13             ` Bjorn Helgaas
@ 2013-08-27 16:44             ` Jiang Liu
  2013-08-27 17:07               ` Bjorn Helgaas
  1 sibling, 1 reply; 16+ messages in thread
From: Jiang Liu @ 2013-08-27 16:44 UTC (permalink / raw)
  To: Bjorn Helgaas, Yuval Mintz, jacob . e . keller @ intel . com, Yu Zhao
  Cc: liuj97, Jiang Liu, linux-pci @ vger . kernel . org

From: Jiang Liu <jiang.liu@huawei.com>

PCIe Base Spec 1.0 Section 5.8 states that "The PCI Express Capabilities,
Device Capabilities, Device Status/Control, Link Capabilities and
Link Status/Control registers are required for all PCI Express devices."

And PCIe Base Spec 3.0 Section 7.8 states that "The Link Capabilities,
Link Status, and Link Control registers are required for all Root Ports,
Switch Ports, Bridges, and Endpoints that are not Root Complex Integrated
Endpoints."

Changeset 1b6b8ce2ac372e "PCI: only save/restore existent registers in the
PCIe capability" introduces pcie_cap_has_lnkctl(), which assumes:
1) PCIe root port, endpoint and legacy endpoint with 1.0 PCIe Capability
   implement Link Cap/Status/Control registers.
2) All PCIe devices with 2.0 PCIe Capability implemnet Link Cap/Status/
   Control registers.

The above assumptions don't conform to PCIe base specifications, so change
pcie_cap_has_lnkctl() to follow PCIe specifications.

Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
---
Hi Bjorn,
	Yuval has a PCIe 1.0 swither, so triggers the bug.  I'm not sure
why Yu Zhao has implemented pcie_cap_has_linctl() in that way, any special
consideration here?

Hi Yuval,
	Could you please help to test this patch? Due to hardware resource
constraints, I have just compiled the patch on my laptop without testing.

Thanks!

---
 drivers/pci/access.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index 1cc2366..23ff366 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -484,10 +484,14 @@ static inline bool pcie_cap_has_lnkctl(const struct pci_dev *dev)
 {
 	int type = pci_pcie_type(dev);
 
-	return pcie_cap_version(dev) > 1 ||
-	       type == PCI_EXP_TYPE_ROOT_PORT ||
-	       type == PCI_EXP_TYPE_ENDPOINT ||
-	       type == PCI_EXP_TYPE_LEG_END;
+	return	pcie_cap_version(dev) == 1 ||
+		type == PCI_EXP_TYPE_ENDPOINT ||
+		type == PCI_EXP_TYPE_LEG_END ||
+		type == PCI_EXP_TYPE_ROOT_PORT ||
+		type == PCI_EXP_TYPE_UPSTREAM ||
+		type == PCI_EXP_TYPE_DOWNSTREAM ||
+		type == PCI_EXP_TYPE_PCI_BRIDGE ||
+		type == PCI_EXP_TYPE_PCIE_BRIDGE;
 }
 
 static inline bool pcie_cap_has_sltctl(const struct pci_dev *dev)
-- 
1.8.1.2


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH] PCI: correctly check availability of PCIe Link Cap/Status/Control registers
  2013-08-27 16:44             ` [PATCH] PCI: correctly check availability of PCIe Link Cap/Status/Control registers Jiang Liu
@ 2013-08-27 17:07               ` Bjorn Helgaas
  2013-08-27 18:02                 ` Keller, Jacob E
  2013-08-28  0:08                 ` Jiang Liu
  0 siblings, 2 replies; 16+ messages in thread
From: Bjorn Helgaas @ 2013-08-27 17:07 UTC (permalink / raw)
  To: Jiang Liu
  Cc: Yuval Mintz, jacob . e . keller @ intel . com, Yu Zhao,
	Jiang Liu, linux-pci @ vger . kernel . org

On Tue, Aug 27, 2013 at 10:44 AM, Jiang Liu <liuj97@gmail.com> wrote:
> From: Jiang Liu <jiang.liu@huawei.com>
>
> PCIe Base Spec 1.0 Section 5.8 states that "The PCI Express Capabilities,
> Device Capabilities, Device Status/Control, Link Capabilities and
> Link Status/Control registers are required for all PCI Express devices."

And spec 1.1 amended that (in sec 7.8, not 5.8) to say that the link
registers are not required for Root Complex Integrated Endpoints.
Integrated endpoints and event collectors don't have links, so even if
some RC-integrated devices do implement link registers per spec 1.0, I
don't think there's any point in allowing access to them.

> And PCIe Base Spec 3.0 Section 7.8 states that "The Link Capabilities,
> Link Status, and Link Control registers are required for all Root Ports,
> Switch Ports, Bridges, and Endpoints that are not Root Complex Integrated
> Endpoints."
>
> Changeset 1b6b8ce2ac372e "PCI: only save/restore existent registers in the
> PCIe capability" introduces pcie_cap_has_lnkctl(), which assumes:
> 1) PCIe root port, endpoint and legacy endpoint with 1.0 PCIe Capability
>    implement Link Cap/Status/Control registers.
> 2) All PCIe devices with 2.0 PCIe Capability implemnet Link Cap/Status/
>    Control registers.
>
> The above assumptions don't conform to PCIe base specifications, so change
> pcie_cap_has_lnkctl() to follow PCIe specifications.
>
> Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
> ---
> Hi Bjorn,
>         Yuval has a PCIe 1.0 swither, so triggers the bug.  I'm not sure
> why Yu Zhao has implemented pcie_cap_has_linctl() in that way, any special
> consideration here?
>
> Hi Yuval,
>         Could you please help to test this patch? Due to hardware resource
> constraints, I have just compiled the patch on my laptop without testing.
>
> Thanks!
>
> ---
>  drivers/pci/access.c | 12 ++++++++----
>  1 file changed, 8 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/pci/access.c b/drivers/pci/access.c
> index 1cc2366..23ff366 100644
> --- a/drivers/pci/access.c
> +++ b/drivers/pci/access.c
> @@ -484,10 +484,14 @@ static inline bool pcie_cap_has_lnkctl(const struct pci_dev *dev)
>  {
>         int type = pci_pcie_type(dev);
>
> -       return pcie_cap_version(dev) > 1 ||
> -              type == PCI_EXP_TYPE_ROOT_PORT ||
> -              type == PCI_EXP_TYPE_ENDPOINT ||
> -              type == PCI_EXP_TYPE_LEG_END;
> +       return  pcie_cap_version(dev) == 1 ||
> +               type == PCI_EXP_TYPE_ENDPOINT ||
> +               type == PCI_EXP_TYPE_LEG_END ||
> +               type == PCI_EXP_TYPE_ROOT_PORT ||
> +               type == PCI_EXP_TYPE_UPSTREAM ||
> +               type == PCI_EXP_TYPE_DOWNSTREAM ||
> +               type == PCI_EXP_TYPE_PCI_BRIDGE ||
> +               type == PCI_EXP_TYPE_PCIE_BRIDGE;
>  }
>
>  static inline bool pcie_cap_has_sltctl(const struct pci_dev *dev)
> --
> 1.8.1.2
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] PCI: correctly check availability of PCIe Link Cap/Status/Control registers
  2013-08-27 17:07               ` Bjorn Helgaas
@ 2013-08-27 18:02                 ` Keller, Jacob E
  2013-08-27 18:11                   ` Bjorn Helgaas
  2013-08-28  0:08                 ` Jiang Liu
  1 sibling, 1 reply; 16+ messages in thread
From: Keller, Jacob E @ 2013-08-27 18:02 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Jiang Liu, Yuval Mintz, Zhao, Yu, Jiang Liu,
	linux-pci @ vger . kernel . org

T24gVHVlLCAyMDEzLTA4LTI3IGF0IDExOjA3IC0wNjAwLCBCam9ybiBIZWxnYWFzIHdyb3RlOg0K
PiBPbiBUdWUsIEF1ZyAyNywgMjAxMyBhdCAxMDo0NCBBTSwgSmlhbmcgTGl1IDxsaXVqOTdAZ21h
aWwuY29tPiB3cm90ZToNCj4gPiBGcm9tOiBKaWFuZyBMaXUgPGppYW5nLmxpdUBodWF3ZWkuY29t
Pg0KPiA+DQo+ID4gUENJZSBCYXNlIFNwZWMgMS4wIFNlY3Rpb24gNS44IHN0YXRlcyB0aGF0ICJU
aGUgUENJIEV4cHJlc3MgQ2FwYWJpbGl0aWVzLA0KPiA+IERldmljZSBDYXBhYmlsaXRpZXMsIERl
dmljZSBTdGF0dXMvQ29udHJvbCwgTGluayBDYXBhYmlsaXRpZXMgYW5kDQo+ID4gTGluayBTdGF0
dXMvQ29udHJvbCByZWdpc3RlcnMgYXJlIHJlcXVpcmVkIGZvciBhbGwgUENJIEV4cHJlc3MgZGV2
aWNlcy4iDQo+IA0KPiBBbmQgc3BlYyAxLjEgYW1lbmRlZCB0aGF0IChpbiBzZWMgNy44LCBub3Qg
NS44KSB0byBzYXkgdGhhdCB0aGUgbGluaw0KPiByZWdpc3RlcnMgYXJlIG5vdCByZXF1aXJlZCBm
b3IgUm9vdCBDb21wbGV4IEludGVncmF0ZWQgRW5kcG9pbnRzLg0KPiBJbnRlZ3JhdGVkIGVuZHBv
aW50cyBhbmQgZXZlbnQgY29sbGVjdG9ycyBkb24ndCBoYXZlIGxpbmtzLCBzbyBldmVuIGlmDQo+
IHNvbWUgUkMtaW50ZWdyYXRlZCBkZXZpY2VzIGRvIGltcGxlbWVudCBsaW5rIHJlZ2lzdGVycyBw
ZXIgc3BlYyAxLjAsIEkNCj4gZG9uJ3QgdGhpbmsgdGhlcmUncyBhbnkgcG9pbnQgaW4gYWxsb3dp
bmcgYWNjZXNzIHRvIHRoZW0uDQo+IA0KDQpEb2VzIHRoaXMgbWVhbiB0aGF0IHBjaWVfZ2V0X21p
bmltdW1fbGluayBzaG91bGQgYmUgbW9kaWZpZWQgdG8gY2hlY2sgdG8NCm1ha2Ugc3VyZSB0aGUg
ZGV2aWNlIGhhcyBhIGxpbmtzdGF0dXMsIGFuZCBvbmx5IGtlZXAgdHJhY2sgb2YgdmFsdWVzIGZv
cg0Kd2hpY2ggdGhlcmUgaXMgYSBtaW5pbXVtPw0KDQpUaGFua3MsDQpKYWtlDQoNCj4gPiBBbmQg
UENJZSBCYXNlIFNwZWMgMy4wIFNlY3Rpb24gNy44IHN0YXRlcyB0aGF0ICJUaGUgTGluayBDYXBh
YmlsaXRpZXMsDQo+ID4gTGluayBTdGF0dXMsIGFuZCBMaW5rIENvbnRyb2wgcmVnaXN0ZXJzIGFy
ZSByZXF1aXJlZCBmb3IgYWxsIFJvb3QgUG9ydHMsDQo+ID4gU3dpdGNoIFBvcnRzLCBCcmlkZ2Vz
LCBhbmQgRW5kcG9pbnRzIHRoYXQgYXJlIG5vdCBSb290IENvbXBsZXggSW50ZWdyYXRlZA0KPiA+
IEVuZHBvaW50cy4iDQo+ID4NCj4gPiBDaGFuZ2VzZXQgMWI2YjhjZTJhYzM3MmUgIlBDSTogb25s
eSBzYXZlL3Jlc3RvcmUgZXhpc3RlbnQgcmVnaXN0ZXJzIGluIHRoZQ0KPiA+IFBDSWUgY2FwYWJp
bGl0eSIgaW50cm9kdWNlcyBwY2llX2NhcF9oYXNfbG5rY3RsKCksIHdoaWNoIGFzc3VtZXM6DQo+
ID4gMSkgUENJZSByb290IHBvcnQsIGVuZHBvaW50IGFuZCBsZWdhY3kgZW5kcG9pbnQgd2l0aCAx
LjAgUENJZSBDYXBhYmlsaXR5DQo+ID4gICAgaW1wbGVtZW50IExpbmsgQ2FwL1N0YXR1cy9Db250
cm9sIHJlZ2lzdGVycy4NCj4gPiAyKSBBbGwgUENJZSBkZXZpY2VzIHdpdGggMi4wIFBDSWUgQ2Fw
YWJpbGl0eSBpbXBsZW1uZXQgTGluayBDYXAvU3RhdHVzLw0KPiA+ICAgIENvbnRyb2wgcmVnaXN0
ZXJzLg0KPiA+DQo+ID4gVGhlIGFib3ZlIGFzc3VtcHRpb25zIGRvbid0IGNvbmZvcm0gdG8gUENJ
ZSBiYXNlIHNwZWNpZmljYXRpb25zLCBzbyBjaGFuZ2UNCj4gPiBwY2llX2NhcF9oYXNfbG5rY3Rs
KCkgdG8gZm9sbG93IFBDSWUgc3BlY2lmaWNhdGlvbnMuDQo+ID4NCj4gPiBTaWduZWQtb2ZmLWJ5
OiBKaWFuZyBMaXUgPGppYW5nLmxpdUBodWF3ZWkuY29tPg0KPiA+IC0tLQ0KPiA+IEhpIEJqb3Ju
LA0KPiA+ICAgICAgICAgWXV2YWwgaGFzIGEgUENJZSAxLjAgc3dpdGhlciwgc28gdHJpZ2dlcnMg
dGhlIGJ1Zy4gIEknbSBub3Qgc3VyZQ0KPiA+IHdoeSBZdSBaaGFvIGhhcyBpbXBsZW1lbnRlZCBw
Y2llX2NhcF9oYXNfbGluY3RsKCkgaW4gdGhhdCB3YXksIGFueSBzcGVjaWFsDQo+ID4gY29uc2lk
ZXJhdGlvbiBoZXJlPw0KPiA+DQo+ID4gSGkgWXV2YWwsDQo+ID4gICAgICAgICBDb3VsZCB5b3Ug
cGxlYXNlIGhlbHAgdG8gdGVzdCB0aGlzIHBhdGNoPyBEdWUgdG8gaGFyZHdhcmUgcmVzb3VyY2UN
Cj4gPiBjb25zdHJhaW50cywgSSBoYXZlIGp1c3QgY29tcGlsZWQgdGhlIHBhdGNoIG9uIG15IGxh
cHRvcCB3aXRob3V0IHRlc3RpbmcuDQo+ID4NCj4gPiBUaGFua3MhDQo+ID4NCj4gPiAtLS0NCj4g
PiAgZHJpdmVycy9wY2kvYWNjZXNzLmMgfCAxMiArKysrKysrKy0tLS0NCj4gPiAgMSBmaWxlIGNo
YW5nZWQsIDggaW5zZXJ0aW9ucygrKSwgNCBkZWxldGlvbnMoLSkNCj4gPg0KPiA+IGRpZmYgLS1n
aXQgYS9kcml2ZXJzL3BjaS9hY2Nlc3MuYyBiL2RyaXZlcnMvcGNpL2FjY2Vzcy5jDQo+ID4gaW5k
ZXggMWNjMjM2Ni4uMjNmZjM2NiAxMDA2NDQNCj4gPiAtLS0gYS9kcml2ZXJzL3BjaS9hY2Nlc3Mu
Yw0KPiA+ICsrKyBiL2RyaXZlcnMvcGNpL2FjY2Vzcy5jDQo+ID4gQEAgLTQ4NCwxMCArNDg0LDE0
IEBAIHN0YXRpYyBpbmxpbmUgYm9vbCBwY2llX2NhcF9oYXNfbG5rY3RsKGNvbnN0IHN0cnVjdCBw
Y2lfZGV2ICpkZXYpDQo+ID4gIHsNCj4gPiAgICAgICAgIGludCB0eXBlID0gcGNpX3BjaWVfdHlw
ZShkZXYpOw0KPiA+DQo+ID4gLSAgICAgICByZXR1cm4gcGNpZV9jYXBfdmVyc2lvbihkZXYpID4g
MSB8fA0KPiA+IC0gICAgICAgICAgICAgIHR5cGUgPT0gUENJX0VYUF9UWVBFX1JPT1RfUE9SVCB8
fA0KPiA+IC0gICAgICAgICAgICAgIHR5cGUgPT0gUENJX0VYUF9UWVBFX0VORFBPSU5UIHx8DQo+
ID4gLSAgICAgICAgICAgICAgdHlwZSA9PSBQQ0lfRVhQX1RZUEVfTEVHX0VORDsNCj4gPiArICAg
ICAgIHJldHVybiAgcGNpZV9jYXBfdmVyc2lvbihkZXYpID09IDEgfHwNCj4gPiArICAgICAgICAg
ICAgICAgdHlwZSA9PSBQQ0lfRVhQX1RZUEVfRU5EUE9JTlQgfHwNCj4gPiArICAgICAgICAgICAg
ICAgdHlwZSA9PSBQQ0lfRVhQX1RZUEVfTEVHX0VORCB8fA0KPiA+ICsgICAgICAgICAgICAgICB0
eXBlID09IFBDSV9FWFBfVFlQRV9ST09UX1BPUlQgfHwNCj4gPiArICAgICAgICAgICAgICAgdHlw
ZSA9PSBQQ0lfRVhQX1RZUEVfVVBTVFJFQU0gfHwNCj4gPiArICAgICAgICAgICAgICAgdHlwZSA9
PSBQQ0lfRVhQX1RZUEVfRE9XTlNUUkVBTSB8fA0KPiA+ICsgICAgICAgICAgICAgICB0eXBlID09
IFBDSV9FWFBfVFlQRV9QQ0lfQlJJREdFIHx8DQo+ID4gKyAgICAgICAgICAgICAgIHR5cGUgPT0g
UENJX0VYUF9UWVBFX1BDSUVfQlJJREdFOw0KPiA+ICB9DQo+ID4NCj4gPiAgc3RhdGljIGlubGlu
ZSBib29sIHBjaWVfY2FwX2hhc19zbHRjdGwoY29uc3Qgc3RydWN0IHBjaV9kZXYgKmRldikNCj4g
PiAtLQ0KPiA+IDEuOC4xLjINCj4gPg0KDQoNCg==

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] PCI: correctly check availability of PCIe Link Cap/Status/Control registers
  2013-08-27 18:02                 ` Keller, Jacob E
@ 2013-08-27 18:11                   ` Bjorn Helgaas
  2013-08-27 22:28                     ` Yuval Mintz
  0 siblings, 1 reply; 16+ messages in thread
From: Bjorn Helgaas @ 2013-08-27 18:11 UTC (permalink / raw)
  To: Keller, Jacob E
  Cc: Jiang Liu, Yuval Mintz, Zhao, Yu, Jiang Liu,
	linux-pci @ vger . kernel . org

On Tue, Aug 27, 2013 at 12:02 PM, Keller, Jacob E
<jacob.e.keller@intel.com> wrote:
> On Tue, 2013-08-27 at 11:07 -0600, Bjorn Helgaas wrote:
>> On Tue, Aug 27, 2013 at 10:44 AM, Jiang Liu <liuj97@gmail.com> wrote:
>> > From: Jiang Liu <jiang.liu@huawei.com>
>> >
>> > PCIe Base Spec 1.0 Section 5.8 states that "The PCI Express Capabilities,
>> > Device Capabilities, Device Status/Control, Link Capabilities and
>> > Link Status/Control registers are required for all PCI Express devices."
>>
>> And spec 1.1 amended that (in sec 7.8, not 5.8) to say that the link
>> registers are not required for Root Complex Integrated Endpoints.
>> Integrated endpoints and event collectors don't have links, so even if
>> some RC-integrated devices do implement link registers per spec 1.0, I
>> don't think there's any point in allowing access to them.
>>
>
> Does this mean that pcie_get_minimum_link should be modified to check to
> make sure the device has a linkstatus, and only keep track of values for
> which there is a minimum?

That doesn't seem necessary to me.  pcie_get_minimum_link() is only
looking at bridge devices (Downstream Ports, Upstream Ports, and Root
Ports).  All of those are required to implement the Link Status
register, so I think checking would be unnecessary complication.

The RC-integrated devices can't be bridges, so pcie_get_minimum_link()
should never even iterate over any of them.

>> > And PCIe Base Spec 3.0 Section 7.8 states that "The Link Capabilities,
>> > Link Status, and Link Control registers are required for all Root Ports,
>> > Switch Ports, Bridges, and Endpoints that are not Root Complex Integrated
>> > Endpoints."
>> >
>> > Changeset 1b6b8ce2ac372e "PCI: only save/restore existent registers in the
>> > PCIe capability" introduces pcie_cap_has_lnkctl(), which assumes:
>> > 1) PCIe root port, endpoint and legacy endpoint with 1.0 PCIe Capability
>> >    implement Link Cap/Status/Control registers.
>> > 2) All PCIe devices with 2.0 PCIe Capability implemnet Link Cap/Status/
>> >    Control registers.
>> >
>> > The above assumptions don't conform to PCIe base specifications, so change
>> > pcie_cap_has_lnkctl() to follow PCIe specifications.
>> >
>> > Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
>> > ---
>> > Hi Bjorn,
>> >         Yuval has a PCIe 1.0 swither, so triggers the bug.  I'm not sure
>> > why Yu Zhao has implemented pcie_cap_has_linctl() in that way, any special
>> > consideration here?
>> >
>> > Hi Yuval,
>> >         Could you please help to test this patch? Due to hardware resource
>> > constraints, I have just compiled the patch on my laptop without testing.
>> >
>> > Thanks!
>> >
>> > ---
>> >  drivers/pci/access.c | 12 ++++++++----
>> >  1 file changed, 8 insertions(+), 4 deletions(-)
>> >
>> > diff --git a/drivers/pci/access.c b/drivers/pci/access.c
>> > index 1cc2366..23ff366 100644
>> > --- a/drivers/pci/access.c
>> > +++ b/drivers/pci/access.c
>> > @@ -484,10 +484,14 @@ static inline bool pcie_cap_has_lnkctl(const struct pci_dev *dev)
>> >  {
>> >         int type = pci_pcie_type(dev);
>> >
>> > -       return pcie_cap_version(dev) > 1 ||
>> > -              type == PCI_EXP_TYPE_ROOT_PORT ||
>> > -              type == PCI_EXP_TYPE_ENDPOINT ||
>> > -              type == PCI_EXP_TYPE_LEG_END;
>> > +       return  pcie_cap_version(dev) == 1 ||
>> > +               type == PCI_EXP_TYPE_ENDPOINT ||
>> > +               type == PCI_EXP_TYPE_LEG_END ||
>> > +               type == PCI_EXP_TYPE_ROOT_PORT ||
>> > +               type == PCI_EXP_TYPE_UPSTREAM ||
>> > +               type == PCI_EXP_TYPE_DOWNSTREAM ||
>> > +               type == PCI_EXP_TYPE_PCI_BRIDGE ||
>> > +               type == PCI_EXP_TYPE_PCIE_BRIDGE;
>> >  }
>> >
>> >  static inline bool pcie_cap_has_sltctl(const struct pci_dev *dev)
>> > --
>> > 1.8.1.2
>> >
>
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* RE: [PATCH] PCI: correctly check availability of PCIe Link Cap/Status/Control registers
  2013-08-27 18:11                   ` Bjorn Helgaas
@ 2013-08-27 22:28                     ` Yuval Mintz
  0 siblings, 0 replies; 16+ messages in thread
From: Yuval Mintz @ 2013-08-27 22:28 UTC (permalink / raw)
  To: Bjorn Helgaas, Keller, Jacob E
  Cc: Jiang Liu, Zhao, Yu, Jiang Liu, linux-pci @ vger . kernel . org

> On Tue, Aug 27, 2013 at 12:02 PM, Keller, Jacob E
> >> > From: Jiang Liu <jiang.liu@huawei.com>
> >> > ---
> >> > Hi Bjorn,
> >> >         Yuval has a PCIe 1.0 swither, so triggers the bug.  I'm not sure
> >> > why Yu Zhao has implemented pcie_cap_has_linctl() in that way, any
> special
> >> > consideration here?
> >> >
> >> > Hi Yuval,
> >> >         Could you please help to test this patch? Due to hardware resource
> >> > constraints, I have just compiled the patch on my laptop without testing.
> >> >

Hi,

Don't know whether your fix is correct or not (I'm leaving that to you PCI guys),
but it solved my issue - width now returns as x4. Thanks.

Tested-by: Yuval Mintz <yuvalmin@broadcom.com>

> >> > Thanks!
> >> >
> >> > ---
> >> >  drivers/pci/access.c | 12 ++++++++----
> >> >  1 file changed, 8 insertions(+), 4 deletions(-)
> >> >
> >> > diff --git a/drivers/pci/access.c b/drivers/pci/access.c
> >> > index 1cc2366..23ff366 100644
> >> > --- a/drivers/pci/access.c
> >> > +++ b/drivers/pci/access.c
> >> > @@ -484,10 +484,14 @@ static inline bool pcie_cap_has_lnkctl(const
> struct pci_dev *dev)
> >> >  {
> >> >         int type = pci_pcie_type(dev);
> >> >
> >> > -       return pcie_cap_version(dev) > 1 ||
> >> > -              type == PCI_EXP_TYPE_ROOT_PORT ||
> >> > -              type == PCI_EXP_TYPE_ENDPOINT ||
> >> > -              type == PCI_EXP_TYPE_LEG_END;
> >> > +       return  pcie_cap_version(dev) == 1 ||
> >> > +               type == PCI_EXP_TYPE_ENDPOINT ||
> >> > +               type == PCI_EXP_TYPE_LEG_END ||
> >> > +               type == PCI_EXP_TYPE_ROOT_PORT ||
> >> > +               type == PCI_EXP_TYPE_UPSTREAM ||
> >> > +               type == PCI_EXP_TYPE_DOWNSTREAM ||
> >> > +               type == PCI_EXP_TYPE_PCI_BRIDGE ||
> >> > +               type == PCI_EXP_TYPE_PCIE_BRIDGE;
> >> >  }
> >> >
> >> >  static inline bool pcie_cap_has_sltctl(const struct pci_dev *dev)
> >> > --
> >> > 1.8.1.2
> >> >
> >
> >



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] PCI: correctly check availability of PCIe Link Cap/Status/Control registers
  2013-08-27 17:07               ` Bjorn Helgaas
  2013-08-27 18:02                 ` Keller, Jacob E
@ 2013-08-28  0:08                 ` Jiang Liu
  2013-08-28 12:58                   ` Bjorn Helgaas
  1 sibling, 1 reply; 16+ messages in thread
From: Jiang Liu @ 2013-08-28  0:08 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Yuval Mintz, jacob . e . keller @ intel . com, Yu Zhao,
	Jiang Liu, linux-pci @ vger . kernel . org

On 08/28/2013 01:07 AM, Bjorn Helgaas wrote:
> On Tue, Aug 27, 2013 at 10:44 AM, Jiang Liu <liuj97@gmail.com> wrote:
>> From: Jiang Liu <jiang.liu@huawei.com>
>>
>> PCIe Base Spec 1.0 Section 5.8 states that "The PCI Express Capabilities,
>> Device Capabilities, Device Status/Control, Link Capabilities and
>> Link Status/Control registers are required for all PCI Express devices."
> 
> And spec 1.1 amended that (in sec 7.8, not 5.8) to say that the link
> registers are not required for Root Complex Integrated Endpoints.
> Integrated endpoints and event collectors don't have links, so even if
> some RC-integrated devices do implement link registers per spec 1.0, I
> don't think there's any point in allowing access to them.
Hi Bjorn,
	Sorry, I haven't noticed that PCIe Base spec 1.1 has modified
the definition without changing the PCIe capability version. So seems
we should remove the "pcie_cap_version(dev) == 1" check and just
verify PCIe express device types. Which form do you prefer?

!(type == PCI_EXP_TYPE_RC_END || type == PCI_EXP_TYPE_RC_EC)
or
type == PCI_EXP_TYPE_ENDPOINT ||
type == PCI_EXP_TYPE_LEG_END ||
type == PCI_EXP_TYPE_ROOT_PORT ||
type == PCI_EXP_TYPE_UPSTREAM ||
type == PCI_EXP_TYPE_DOWNSTREAM ||
type == PCI_EXP_TYPE_PCI_BRIDGE ||
type == PCI_EXP_TYPE_PCIE_BRIDGE;

Regards!
Gerry

> 
>> And PCIe Base Spec 3.0 Section 7.8 states that "The Link Capabilities,
>> Link Status, and Link Control registers are required for all Root Ports,
>> Switch Ports, Bridges, and Endpoints that are not Root Complex Integrated
>> Endpoints."
>>
>> Changeset 1b6b8ce2ac372e "PCI: only save/restore existent registers in the
>> PCIe capability" introduces pcie_cap_has_lnkctl(), which assumes:
>> 1) PCIe root port, endpoint and legacy endpoint with 1.0 PCIe Capability
>>    implement Link Cap/Status/Control registers.
>> 2) All PCIe devices with 2.0 PCIe Capability implemnet Link Cap/Status/
>>    Control registers.
>>
>> The above assumptions don't conform to PCIe base specifications, so change
>> pcie_cap_has_lnkctl() to follow PCIe specifications.
>>
>> Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
>> ---
>> Hi Bjorn,
>>         Yuval has a PCIe 1.0 swither, so triggers the bug.  I'm not sure
>> why Yu Zhao has implemented pcie_cap_has_linctl() in that way, any special
>> consideration here?
>>
>> Hi Yuval,
>>         Could you please help to test this patch? Due to hardware resource
>> constraints, I have just compiled the patch on my laptop without testing.
>>
>> Thanks!
>>
>> ---
>>  drivers/pci/access.c | 12 ++++++++----
>>  1 file changed, 8 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/pci/access.c b/drivers/pci/access.c
>> index 1cc2366..23ff366 100644
>> --- a/drivers/pci/access.c
>> +++ b/drivers/pci/access.c
>> @@ -484,10 +484,14 @@ static inline bool pcie_cap_has_lnkctl(const struct pci_dev *dev)
>>  {
>>         int type = pci_pcie_type(dev);
>>
>> -       return pcie_cap_version(dev) > 1 ||
>> -              type == PCI_EXP_TYPE_ROOT_PORT ||
>> -              type == PCI_EXP_TYPE_ENDPOINT ||
>> -              type == PCI_EXP_TYPE_LEG_END;
>> +       return  pcie_cap_version(dev) == 1 ||
>> +               type == PCI_EXP_TYPE_ENDPOINT ||
>> +               type == PCI_EXP_TYPE_LEG_END ||
>> +               type == PCI_EXP_TYPE_ROOT_PORT ||
>> +               type == PCI_EXP_TYPE_UPSTREAM ||
>> +               type == PCI_EXP_TYPE_DOWNSTREAM ||
>> +               type == PCI_EXP_TYPE_PCI_BRIDGE ||
>> +               type == PCI_EXP_TYPE_PCIE_BRIDGE;
>>  }
>>
>>  static inline bool pcie_cap_has_sltctl(const struct pci_dev *dev)
>> --
>> 1.8.1.2
>>


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] PCI: correctly check availability of PCIe Link Cap/Status/Control registers
  2013-08-28  0:08                 ` Jiang Liu
@ 2013-08-28 12:58                   ` Bjorn Helgaas
  2013-08-28 17:23                     ` [PATCH v2] " Jiang Liu
  0 siblings, 1 reply; 16+ messages in thread
From: Bjorn Helgaas @ 2013-08-28 12:58 UTC (permalink / raw)
  To: Jiang Liu
  Cc: Yuval Mintz, jacob . e . keller @ intel . com, Yu Zhao,
	Jiang Liu, linux-pci @ vger . kernel . org

On Tue, Aug 27, 2013 at 6:08 PM, Jiang Liu <liuj97@gmail.com> wrote:
> On 08/28/2013 01:07 AM, Bjorn Helgaas wrote:
>> On Tue, Aug 27, 2013 at 10:44 AM, Jiang Liu <liuj97@gmail.com> wrote:
>>> From: Jiang Liu <jiang.liu@huawei.com>
>>>
>>> PCIe Base Spec 1.0 Section 5.8 states that "The PCI Express Capabilities,
>>> Device Capabilities, Device Status/Control, Link Capabilities and
>>> Link Status/Control registers are required for all PCI Express devices."
>>
>> And spec 1.1 amended that (in sec 7.8, not 5.8) to say that the link
>> registers are not required for Root Complex Integrated Endpoints.
>> Integrated endpoints and event collectors don't have links, so even if
>> some RC-integrated devices do implement link registers per spec 1.0, I
>> don't think there's any point in allowing access to them.
> Hi Bjorn,
>         Sorry, I haven't noticed that PCIe Base spec 1.1 has modified
> the definition without changing the PCIe capability version. So seems
> we should remove the "pcie_cap_version(dev) == 1" check and just
> verify PCIe express device types. Which form do you prefer?

The "pcie_cap_version(dev) > 1" test is based on the spec r3.0
language to the effect that "For Functions that do not implement the
[Device, Link, Slot, Root] registers, these spaces must be hardwired
to 0b."  That means that for v2 capabilities, we don't need to check
the device type at all.  I think we should keep that check so the
structure of pcie_cap_has_lnkctl() remains similar to
pcie_cap_has_sltctl() and pcie_cap_has_rtctl().

It might be more obvious what we're doing if we restructured them all
in the form of:

    if (pcie_cap_version(dev) == 1)
        return type == PCI_EXP_TYPE_ROOT_PORT ||
                type == PCI_EXP_TYPE_ENDPOINT ||
                ...;
    return true;

That would make it more clear that for v1 capabilities, we have to
make extra checks, and for v2 capabilities, we rely on the r3.0 spec
language.

> !(type == PCI_EXP_TYPE_RC_END || type == PCI_EXP_TYPE_RC_EC)
> or
> type == PCI_EXP_TYPE_ENDPOINT ||
> type == PCI_EXP_TYPE_LEG_END ||
> type == PCI_EXP_TYPE_ROOT_PORT ||
> type == PCI_EXP_TYPE_UPSTREAM ||
> type == PCI_EXP_TYPE_DOWNSTREAM ||
> type == PCI_EXP_TYPE_PCI_BRIDGE ||
> type == PCI_EXP_TYPE_PCIE_BRIDGE;

I don't really care which of these styles we use.  Either way seems
future-proof, since no new device type should ever be added with a v1
capability.  Yours has the advantage of being stated in the positive,
which is a good aid to understanding.

>>> And PCIe Base Spec 3.0 Section 7.8 states that "The Link Capabilities,
>>> Link Status, and Link Control registers are required for all Root Ports,
>>> Switch Ports, Bridges, and Endpoints that are not Root Complex Integrated
>>> Endpoints."
>>>
>>> Changeset 1b6b8ce2ac372e "PCI: only save/restore existent registers in the
>>> PCIe capability" introduces pcie_cap_has_lnkctl(), which assumes:
>>> 1) PCIe root port, endpoint and legacy endpoint with 1.0 PCIe Capability
>>>    implement Link Cap/Status/Control registers.
>>> 2) All PCIe devices with 2.0 PCIe Capability implemnet Link Cap/Status/
>>>    Control registers.
>>>
>>> The above assumptions don't conform to PCIe base specifications, so change
>>> pcie_cap_has_lnkctl() to follow PCIe specifications.
>>>
>>> Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
>>> ---
>>> Hi Bjorn,
>>>         Yuval has a PCIe 1.0 swither, so triggers the bug.  I'm not sure
>>> why Yu Zhao has implemented pcie_cap_has_linctl() in that way, any special
>>> consideration here?
>>>
>>> Hi Yuval,
>>>         Could you please help to test this patch? Due to hardware resource
>>> constraints, I have just compiled the patch on my laptop without testing.
>>>
>>> Thanks!
>>>
>>> ---
>>>  drivers/pci/access.c | 12 ++++++++----
>>>  1 file changed, 8 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/drivers/pci/access.c b/drivers/pci/access.c
>>> index 1cc2366..23ff366 100644
>>> --- a/drivers/pci/access.c
>>> +++ b/drivers/pci/access.c
>>> @@ -484,10 +484,14 @@ static inline bool pcie_cap_has_lnkctl(const struct pci_dev *dev)
>>>  {
>>>         int type = pci_pcie_type(dev);
>>>
>>> -       return pcie_cap_version(dev) > 1 ||
>>> -              type == PCI_EXP_TYPE_ROOT_PORT ||
>>> -              type == PCI_EXP_TYPE_ENDPOINT ||
>>> -              type == PCI_EXP_TYPE_LEG_END;
>>> +       return  pcie_cap_version(dev) == 1 ||
>>> +               type == PCI_EXP_TYPE_ENDPOINT ||
>>> +               type == PCI_EXP_TYPE_LEG_END ||
>>> +               type == PCI_EXP_TYPE_ROOT_PORT ||
>>> +               type == PCI_EXP_TYPE_UPSTREAM ||
>>> +               type == PCI_EXP_TYPE_DOWNSTREAM ||
>>> +               type == PCI_EXP_TYPE_PCI_BRIDGE ||
>>> +               type == PCI_EXP_TYPE_PCIE_BRIDGE;
>>>  }
>>>
>>>  static inline bool pcie_cap_has_sltctl(const struct pci_dev *dev)
>>> --
>>> 1.8.1.2
>>>
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH v2] PCI: correctly check availability of PCIe Link Cap/Status/Control registers
  2013-08-28 12:58                   ` Bjorn Helgaas
@ 2013-08-28 17:23                     ` Jiang Liu
  0 siblings, 0 replies; 16+ messages in thread
From: Jiang Liu @ 2013-08-28 17:23 UTC (permalink / raw)
  To: Bjorn Helgaas, Yuval Mintz, jacob . e . keller @ intel . com
  Cc: liuj97, Jiang Liu, linux-pci @ vger . kernel . org

From: Jiang Liu <jiang.liu@huawei.com>

According to PCIe Base Specification 3.0, devices are guarenteed to
return zero for unimplemented V2 PCI Express Capability registers.
But there's no such guarantee for unimplemented V1 PCI Express
Capability registers, so we need to explicitly check availability of
V1 PCI Express Capability registers and return zero for unimplemented
registers.

Changeset 1b6b8ce2ac372e "PCI: only save/restore existent registers in
the PCIe capability" introduces pcie_cap_has_lnkctl(), which assumes that
PCIe root port, endpoint and legacy endpoint with 1.0 PCIe Capability
implement Link Cap/Status/Control registers.

On the other hand, section 7.8 of PCIe Base Spec V1.1 and V3.0 states that
"The Link Capabilities, Link Status, and Link Control registers are
required for all Root Ports, Switch Ports, Bridges, and Endpoints that
are not Root Complex Integrated Endpoints."
That means Link Capability/Status/Control registers are also available
for PCIe Upstream Port, Downstream Port, PCIe-to-PCI bridge and PCI-to-PCIe
bridge. So change pcie_cap_has_lnkctl() to follow PCIe specifications.

Also refine pcie_cap_has_sltctl() and pcie_cap_has_rtctl() for readability.

Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Reported-by: Yuval Mintz <yuvalmin@broadcom.com>
---
 drivers/pci/access.c | 39 ++++++++++++++++++++++++++++-----------
 1 file changed, 28 insertions(+), 11 deletions(-)

diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index 1cc2366..b9af3d1 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -470,6 +470,13 @@ void pci_cfg_access_unlock(struct pci_dev *dev)
 }
 EXPORT_SYMBOL_GPL(pci_cfg_access_unlock);
 
+/*
+ * According to PCIe base spec 3.0, devices are guarenteed to return zero for
+ * unimplemented V2 PCI Express Capability registers. But there's no such
+ * guarantee for unimplemented V1 PCI Express Capability registers, so
+ * explicitly check availability of V1 PCI Express Capability registers
+ * and return zero for unimplemented registers.
+ */
 static inline int pcie_cap_version(const struct pci_dev *dev)
 {
 	return pcie_caps_reg(dev) & PCI_EXP_FLAGS_VERS;
@@ -484,29 +491,39 @@ static inline bool pcie_cap_has_lnkctl(const struct pci_dev *dev)
 {
 	int type = pci_pcie_type(dev);
 
-	return pcie_cap_version(dev) > 1 ||
-	       type == PCI_EXP_TYPE_ROOT_PORT ||
-	       type == PCI_EXP_TYPE_ENDPOINT ||
-	       type == PCI_EXP_TYPE_LEG_END;
+	if (pcie_cap_version(dev) == 1)
+		return	type == PCI_EXP_TYPE_ENDPOINT ||
+			type == PCI_EXP_TYPE_LEG_END ||
+			type == PCI_EXP_TYPE_ROOT_PORT ||
+			type == PCI_EXP_TYPE_UPSTREAM ||
+			type == PCI_EXP_TYPE_DOWNSTREAM ||
+			type == PCI_EXP_TYPE_PCI_BRIDGE ||
+			type == PCI_EXP_TYPE_PCIE_BRIDGE;
+
+	return true;
 }
 
 static inline bool pcie_cap_has_sltctl(const struct pci_dev *dev)
 {
 	int type = pci_pcie_type(dev);
 
-	return pcie_cap_version(dev) > 1 ||
-	       type == PCI_EXP_TYPE_ROOT_PORT ||
-	       (type == PCI_EXP_TYPE_DOWNSTREAM &&
-		pcie_caps_reg(dev) & PCI_EXP_FLAGS_SLOT);
+	if (pcie_cap_version(dev) == 1)
+		return type == PCI_EXP_TYPE_ROOT_PORT ||
+		       (type == PCI_EXP_TYPE_DOWNSTREAM &&
+			pcie_caps_reg(dev) & PCI_EXP_FLAGS_SLOT);
+
+	return true;
 }
 
 static inline bool pcie_cap_has_rtctl(const struct pci_dev *dev)
 {
 	int type = pci_pcie_type(dev);
 
-	return pcie_cap_version(dev) > 1 ||
-	       type == PCI_EXP_TYPE_ROOT_PORT ||
-	       type == PCI_EXP_TYPE_RC_EC;
+	if (pcie_cap_version(dev) == 1)
+		return type == PCI_EXP_TYPE_ROOT_PORT ||
+		       type == PCI_EXP_TYPE_RC_EC;
+
+	return true;
 }
 
 static bool pcie_capability_reg_implemented(struct pci_dev *dev, int pos)
-- 
1.8.1.2


^ permalink raw reply related	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2013-08-28 17:25 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20130825100157.GA16500@lb-tlvb-yuvalmin.il.broadcom.com>
2013-08-25 11:21 ` pcie_get_minimum_link returns 0 width Yuval Mintz
2013-08-26 18:27   ` Keller, Jacob E
2013-08-26 22:05   ` Bjorn Helgaas
2013-08-26 23:36     ` Yuval Mintz
2013-08-26 23:57       ` Bjorn Helgaas
2013-08-27  7:40         ` Yuval Mintz
2013-08-27 13:57           ` Bjorn Helgaas
2013-08-27 16:13             ` Bjorn Helgaas
2013-08-27 16:44             ` [PATCH] PCI: correctly check availability of PCIe Link Cap/Status/Control registers Jiang Liu
2013-08-27 17:07               ` Bjorn Helgaas
2013-08-27 18:02                 ` Keller, Jacob E
2013-08-27 18:11                   ` Bjorn Helgaas
2013-08-27 22:28                     ` Yuval Mintz
2013-08-28  0:08                 ` Jiang Liu
2013-08-28 12:58                   ` Bjorn Helgaas
2013-08-28 17:23                     ` [PATCH v2] " Jiang Liu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.