I am doing some testing on my server and want to lower the width to my PCIe device (or its PCIe bridge).
In case it is relevant, I figured out how to lower my speed based on the PCI Spec with Linux's setpci and changing the Link Control 2 Register's "Target Link Speed". This allows me to drop from a 8GT/s to 5GT/s or even 2.5GT/s.
Here is an example of that working:
Server:~ # setpci -s 83:04.0 98.w=1:ff
Server:~ # setpci -s 83:04.0 78.w=20:20
Server:~ # ./check_speed_width
84:00.0 has reported reduced PCIe speed: 2.5GT/s instead of 8GT/s
bridge device 83:04.0 has reported reduced PCIe speed: 2.5GT/s instead of 8GT/s
Server:~ # setpci -s 83:04.0 98.w=2:ff
Server:~ # setpci -s 83:04.0 78.w=20:20
Server:~ # ./check_speed_width
84:00.0 has reported reduced PCIe speed: 5GT/s instead of 8GT/s
bridge device 83:04.0 has reported reduced PCIe speed: 5GT/s instead of 8GT/s
Some of my ideas so far to lower width are:
Maybe I just missed a writable register? Target Link Speed is a register with read and write capabilities. When it comes to the Width registers, I only see read-only registers listed in the PCI spec.
Maybe there is a way to disable a some of the lanes separate from the PCIe spec?
I know that stuff can train/initialize to lower widths if it is having problems. So maybe I can inject errors onto a particular lane and cause it to drop the lane?