Howdy,

I've been working with a four port PCIe card built from Broadcom 5714 with
a 5704 behind the PCIx bridge that the 5714 externalizes.  These cards
are built by Silicom.

When we would run 'ethtool -d' against either of the secondary (ie,
5704's) interfaces, we would get all sorts of nasty PCIe behavior--
on our SN (SGI IA64) platform, this would generate lots of PCI platform
errors and on a Dell 1850 (IA32 w/ PCIe backplane), it would simply hang
the machine.

It appears that the trouble is in the routine tg3_get_regs() which is
reading through undocumented and reserved register space at the offsets
0x5000 and 0x5400 (RX_CPU_BASE and TX_CPU_BASE).  In both cases, it was
reading a contiguous chunk of 0x280 words and probably hitting one or
more registers that now have adverse affects when the 5704 is behind
this 5714 bridge.  We did not experience the problem when the 5704 is
directly on a PCIx bus.  So, it's a sneeky one.

In any case, I offer the following patch which seeks to read only
the documented registers in the RX_CPU_BASE and TX_CPU_BASE regions.
This solved our problem on the test platforms.

----

Prevent tg3_get_regs() from reading reserved and undocumented registers
at RX_CPU_BASE and TX_CPU_BASE offsets which caused hostile behavior
on PCIe platforms.

diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -7151,8 +7151,13 @@ do {     p = (u32 *)(orig_p + (reg));            \
        GET_REG32_LOOP(BUFMGR_MODE, 0x58);
        GET_REG32_LOOP(RDMAC_MODE, 0x08);
        GET_REG32_LOOP(WDMAC_MODE, 0x08);
-       GET_REG32_LOOP(RX_CPU_BASE, 0x280);
-       GET_REG32_LOOP(TX_CPU_BASE, 0x280);
+       GET_REG32_LOOP(RX_CPU_MODE, 1);
+       GET_REG32_LOOP(RX_CPU_STATE, 1);
+       GET_REG32_LOOP(RX_CPU_PGMCTR, 1);
+       GET_REG32_LOOP(RX_CPU_HWBKPT, 1);
+       GET_REG32_LOOP(TX_CPU_MODE, 1);
+       GET_REG32_LOOP(TX_CPU_STATE, 1);
+       GET_REG32_LOOP(TX_CPU_PGMCTR, 1);
        GET_REG32_LOOP(GRCMBOX_INTERRUPT_0, 0x110);
        GET_REG32_LOOP(FTQ_RESET, 0x120);
        GET_REG32_LOOP(MSGINT_MODE, 0x0c);

diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -1124,7 +1124,15 @@
 /* 0x280 --> 0x400 unused */
 
 #define RX_CPU_BASE                    0x00005000
+#define RX_CPU_MODE                    0x00005000
+#define RX_CPU_STATE                   0x00005004
+#define RX_CPU_PGMCTR                  0x0000501c
+#define RX_CPU_HWBKPT                  0x00005034
+
 #define TX_CPU_BASE                    0x00005400
+#define TX_CPU_MODE                    0x00005400
+#define TX_CPU_STATE                   0x00005404
+#define TX_CPU_PGMCTR                  0x0000541c
 
 /* Mailboxes */
 #define GRCMBOX_INTERRUPT_0            0x00005800 /* 64-bit */

-- 
Chris Elmquist          mailto:[EMAIL PROTECTED]      (651)683-3093
                        Silicon Graphics, Inc.     Eagan, MN
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to