Download raw body.
sys/octeon: fix PCIe config tag layout
tech@, visa@,
Octeon PCIe config-space MMIO uses a 12-bit register field; function,
device, and bus begin at bits 12, 15, and 20.
octpcie_make_tag() and octpcie_decompose_tag() used the conventional PCI
tag layout instead, so config accesses to non-zero device or function
numbers used the wrong MMIO offset.
On SRX300 this breaks enumeration of the second Broadcom switch function
at 0:0:1, which reads back garbage until the tag layout is corrected.
FreeBSD had Cavium’s SDK header:
https://github.com/freebsd/freebsd-src/blob/release/13.5.0/sys/contrib/octeon-sdk/cvmx-pcie.h#L89-L93
where it states:
89 uint64_t bus : 8; /* Target bus number sent in the ID in the request. */
90 uint64_t dev : 5; /* Target device number sent in the ID in the request. Note that Dev must be
91 zero for type 0 configuration requests. */
92 uint64_t func : 3; /* Target function number sent in the ID in the request. */
93 uint64_t reg : 12; /* Selects a register in the configuration space of the target. */
which I read as:
- reg in bits 11:0
- func in bits 14:12
- dev in bits 19:15
- bus in bits 27:20
On SRX300 it changes dmesg as:
@@ -59,6 +59,7 @@
octpcie0 at iobus0: 3 ports
pci0 at octpcie0 bus 0
vendor "Broadcom", unknown product 0x8343 (class network subclass ethernet, rev 0x01) at pci0 dev 0 function 0 not configured
+vendor "Broadcom", unknown product 0x8343 (class network subclass ethernet, rev 0x01) at pci0 dev 0 function 1 not configured
octpcie0 port 1: link timeout
octpcie0 port 2: reset timeout
umass0 at uhub1 port 1 configuration 1 interface 0 "Swissbit USB Flash Module" rev 2.00/1.00 addr 2
On ER4 I don see any change in dmesg.
Ok?
Index: sys/arch/octeon/dev/octpcie.c
===================================================================
RCS file: /home/cvs/src/sys/arch/octeon/dev/octpcie.c,v
diff -u -p -r1.2 octpcie.c
--- sys/arch/octeon/dev/octpcie.c 22 Sep 2019 04:43:24 -0000 1.2
+++ sys/arch/octeon/dev/octpcie.c 20 Apr 2026 11:04:57 -0000
@@ -723,18 +723,18 @@ octpcie_bus_maxdevs(void *v, int busno)
pcitag_t
octpcie_make_tag(void *unused, int b, int d, int f)
{
- return (b << 16) | (d << 11) | (f << 8);
+ return (b << 20) | (d << 15) | (f << 12);
}
void
octpcie_decompose_tag(void *unused, pcitag_t tag, int *bp, int *dp, int *fp)
{
if (bp != NULL)
- *bp = (tag >> 16) & 0xff;
+ *bp = (tag >> 20) & 0xff;
if (dp != NULL)
- *dp = (tag >> 11) & 0x1f;
+ *dp = (tag >> 15) & 0x1f;
if (fp != NULL)
- *fp = (tag >> 8) & 0x7;
+ *fp = (tag >> 12) & 0x7;
}
int
--
wbr, Kirill
sys/octeon: fix PCIe config tag layout