On Tue, 2005-12-20 at 14:09 -0600, Chris Elmquist wrote:
> 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.

Yes, reading the reserved registers will cause timeouts on the PCIE bus
and that will likely hang or cause NMIs.

> 
> 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.

I ACK this patch. But you should probably use GET_REG32_1() on the
individual registers instead of GET_REG32_LOOP().

Thanks.

> 
> ----
> 
> 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 */
> 

-
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