Re: PCI VPD checksum ambiguity

From: Bjorn Helgaas
Date: Mon Apr 07 2025 - 18:22:26 EST


On Wed, Apr 02, 2025 at 04:03:42PM +0530, Pavan Chebbi wrote:
> > > >
> > > > Any idea how devices in the field populate their VPD?
>
> I took a quick look at our manufacturing tool, and it does look like
> the computation simply starts at address 0.
>
> > > > Can you share any VPD dumps from devices that include an RV keyword
> > > > item?
>
> A couple of devices I could find: hope it helps..
> 000100: 822f0042 726f6164 636f6d20 4e657458 7472656d 65204769 67616269 74204574
> 000120: 6865726e 65742043 6f6e7472 6f6c6c65 7200904b 00504e08 42434d39 35373230
> 000140: 45430931 30363637 392d3135 534e0a30 31323334 35363738 394d4e04 31346534
> 000160: 52561d1d 00000000 00000000 00000000 000000
>
> 000100: 822f0042 726f6164 636f6d20 4e657458 7472656d 65204769 67616269 74204574
> 000120: 6865726e 65742043 6f6e7472 6f6c6c65 7200904b 00504e08 42434d39 35373139
> 000140: 45430931 30363637 392d3135 534e0a30 31323334 35363738 394d4e04 31346534
> 000160: 52561d15 00000000 00000000 00000000 00000000 00000000 00000000 00000000

Thanks a lot for this!

I put each of these in a file ("vpd.txt") and computed the checksum
with this:

addr=0; sum=0; xxd -r -c 32 vpd.txt | xxd -p -g1 -c1 x.bin | while read X; do sum=$(($sum + "0x$X")); printf "addr 0x%04x: 0x%02x sum 0x%02x\n" $addr "0x$X" $(($sum % 256)); addr=$(($addr + 1)); done

In both cases the sum came out to 0x00 as it should.

So it looks like Broadcom interpreted the spec the same way Linux
pci_vpd_check_csum() does: the checksum includes all bytes from the
beginning of VPD up to and including the RV checksum byte, not just
the VPD-R list.

These dumps start at 0x100 (not 0), which seems a little weird. But
"xxd -r" assumes zeros for the 0-0xff range, so it doesn't affect the
checksum.

I manually decoded the first one, which looked like this. Nothing
surprising here:

00000100: 822f 0042 726f 6164 636f 6d20 4e65 7458 ./.Broadcom NetX
00000110: 7472 656d 6520 4769 6761 6269 7420 4574 treme Gigabit Et
00000120: 6865 726e 6574 2043 6f6e 7472 6f6c 6c65 hernet Controlle
00000130: 7200 r.

82 == large resource tag 0x02 (Identifier String), data item length 0x2f
"Broadcom NetXtreme Gigabit Ethernet Controller"

00000132: 904b 0050 4e08 4243 4d39 3537 3230 .K.PN.BCM95720
00000140: 4543 0931 3036 3637 392d 3135 534e 0a30 EC.106679-15SN.0
00000150: 3132 3334 3536 3738 394d 4e04 3134 6534 123456789MN.14e4
00000160: 5256 1d1d 0000 0000 0000 0000 0000 0000 RV..............
00000170: 0000 00 ...

90 == large resource tag 1_0000b (0x10, VPD-R), data item length 0x4b
50 4e PN keyword, length 0x08: 4243 4d39 3537 3230: "BCM95720"
45 43 EC keyword, length 0x09: 31 3036 3637 392d 3135: "106679-15"
53 4e SN keyword, length 0x0a: 30 3132 3334 3536 3738 39: "0123456789"
4d 4e MN keyword, length 0x04: 3134 6534: "14e4"
52 56 RV keyword, length 0x1d: 1d
(last byte of VPD-R is 0x162 + 0x1d == 0x17f)

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/pci/vpd.c?id=v6.14#n520