svn commit: r233495 - in stable/9/sys: dev/bge i386/conf
Pyun YongHyeon
yongari at FreeBSD.org
Mon Mar 26 04:36:23 UTC 2012
Author: yongari
Date: Mon Mar 26 04:36:22 2012
New Revision: 233495
URL: http://svn.freebsd.org/changeset/base/233495
Log:
MFC r232848:
Add workaround for PCI-X BCM5704 controller that live behind
AMD-8131 PCI-X bridge. The bridge seems to reorder write access to
mailbox registers such that it caused watchdog timeouts by
out-of-order TX completions.
Tested by: Michael L. Squires <mikes <> siralan dot org >
Modified:
stable/9/sys/dev/bge/if_bge.c
stable/9/sys/dev/bge/if_bgereg.h
Directory Properties:
stable/9/sys/ (props changed)
stable/9/sys/amd64/include/xen/ (props changed)
stable/9/sys/boot/ (props changed)
stable/9/sys/boot/i386/efi/ (props changed)
stable/9/sys/boot/ia64/efi/ (props changed)
stable/9/sys/boot/ia64/ski/ (props changed)
stable/9/sys/boot/powerpc/boot1.chrp/ (props changed)
stable/9/sys/boot/powerpc/ofw/ (props changed)
stable/9/sys/cddl/contrib/opensolaris/ (props changed)
stable/9/sys/conf/ (props changed)
stable/9/sys/contrib/dev/acpica/ (props changed)
stable/9/sys/contrib/octeon-sdk/ (props changed)
stable/9/sys/contrib/pf/ (props changed)
stable/9/sys/contrib/x86emu/ (props changed)
stable/9/sys/fs/ (props changed)
stable/9/sys/fs/ntfs/ (props changed)
stable/9/sys/i386/conf/XENHVM (props changed)
Modified: stable/9/sys/dev/bge/if_bge.c
==============================================================================
--- stable/9/sys/dev/bge/if_bge.c Mon Mar 26 04:30:46 2012 (r233494)
+++ stable/9/sys/dev/bge/if_bge.c Mon Mar 26 04:36:22 2012 (r233495)
@@ -380,6 +380,8 @@ static void bge_dma_free(struct bge_soft
static int bge_dma_ring_alloc(struct bge_softc *, bus_size_t, bus_size_t,
bus_dma_tag_t *, uint8_t **, bus_dmamap_t *, bus_addr_t *, const char *);
+static int bge_mbox_reorder(struct bge_softc *);
+
static int bge_get_eaddr_fw(struct bge_softc *sc, uint8_t ether_addr[]);
static int bge_get_eaddr_mem(struct bge_softc *, uint8_t[]);
static int bge_get_eaddr_nvram(struct bge_softc *, uint8_t[]);
@@ -635,6 +637,8 @@ bge_writembx(struct bge_softc *sc, int o
off += BGE_LPMBX_IRQ0_HI - BGE_MBX_IRQ0_HI;
CSR_WRITE_4(sc, off, val);
+ if ((sc->bge_flags & BGE_FLAG_MBOX_REORDER) != 0)
+ CSR_READ_4(sc, off);
}
/*
@@ -2609,10 +2613,10 @@ bge_dma_alloc(struct bge_softc *sc)
* XXX
* watchdog timeout issue was observed on BCM5704 which
* lives behind PCI-X bridge(e.g AMD 8131 PCI-X bridge).
- * Limiting DMA address space to 32bits seems to address
- * it.
+ * Both limiting DMA address space to 32bits and flushing
+ * mailbox write seem to address the issue.
*/
- if (sc->bge_flags & BGE_FLAG_PCIX)
+ if (sc->bge_pcixcap != 0)
lowaddr = BUS_SPACE_MAXADDR_32BIT;
}
error = bus_dma_tag_create(bus_get_dma_tag(sc->bge_dev),
@@ -2775,6 +2779,56 @@ bge_can_use_msi(struct bge_softc *sc)
}
static int
+bge_mbox_reorder(struct bge_softc *sc)
+{
+ /* Lists of PCI bridges that are known to reorder mailbox writes. */
+ static const struct mbox_reorder {
+ const uint16_t vendor;
+ const uint16_t device;
+ const char *desc;
+ } const mbox_reorder_lists[] = {
+ { 0x1022, 0x7450, "AMD-8131 PCI-X Bridge" },
+ };
+ devclass_t pci, pcib;
+ device_t bus, dev;
+ int count, i;
+
+ count = sizeof(mbox_reorder_lists) / sizeof(mbox_reorder_lists[0]);
+ pci = devclass_find("pci");
+ pcib = devclass_find("pcib");
+ dev = sc->bge_dev;
+ bus = device_get_parent(dev);
+ for (;;) {
+ dev = device_get_parent(bus);
+ bus = device_get_parent(dev);
+ device_printf(sc->bge_dev, "dev : %s%d, bus : %s%d\n",
+ device_get_name(dev), device_get_unit(dev),
+ device_get_name(bus), device_get_unit(bus));
+ if (device_get_devclass(dev) != pcib)
+ break;
+ for (i = 0; i < count; i++) {
+ device_printf(sc->bge_dev,
+ "probing dev : %s%d, vendor : 0x%04x "
+ "device : 0x%04x\n",
+ device_get_name(dev), device_get_unit(dev),
+ pci_get_vendor(dev), pci_get_device(dev));
+ if (pci_get_vendor(dev) ==
+ mbox_reorder_lists[i].vendor &&
+ pci_get_device(dev) ==
+ mbox_reorder_lists[i].device) {
+ device_printf(sc->bge_dev,
+ "enabling MBOX workaround for %s\n",
+ mbox_reorder_lists[i].desc);
+ return (1);
+ }
+ }
+ if (device_get_devclass(bus) != pci)
+ break;
+ }
+ return (0);
+}
+
+static int
bge_attach(device_t dev)
{
struct ifnet *ifp;
@@ -3094,6 +3148,16 @@ bge_attach(device_t dev)
if (BGE_IS_5714_FAMILY(sc) && (sc->bge_flags & BGE_FLAG_PCIX))
sc->bge_flags |= BGE_FLAG_40BIT_BUG;
/*
+ * Some PCI-X bridges are known to trigger write reordering to
+ * the mailbox registers. Typical phenomena is watchdog timeouts
+ * caused by out-of-order TX completions. Enable workaround for
+ * PCI-X devices that live behind these bridges.
+ * Note, PCI-X controllers can run in PCI mode so we can't use
+ * BGE_FLAG_PCIX flag to detect PCI-X controllers.
+ */
+ if (sc->bge_pcixcap != 0 && bge_mbox_reorder(sc) != 0)
+ sc->bge_flags |= BGE_FLAG_MBOX_REORDER;
+ /*
* Allocate the interrupt, using MSI if possible. These devices
* support 8 MSI messages, but only the first one is used in
* normal operation.
Modified: stable/9/sys/dev/bge/if_bgereg.h
==============================================================================
--- stable/9/sys/dev/bge/if_bgereg.h Mon Mar 26 04:30:46 2012 (r233494)
+++ stable/9/sys/dev/bge/if_bgereg.h Mon Mar 26 04:36:22 2012 (r233495)
@@ -2828,6 +2828,7 @@ struct bge_softc {
#define BGE_FLAG_RX_ALIGNBUG 0x04000000
#define BGE_FLAG_SHORT_DMA_BUG 0x08000000
#define BGE_FLAG_4K_RDMA_BUG 0x10000000
+#define BGE_FLAG_MBOX_REORDER 0x20000000
uint32_t bge_phy_flags;
#define BGE_PHY_NO_WIRESPEED 0x00000001
#define BGE_PHY_ADC_BUG 0x00000002
More information about the svn-src-stable-9
mailing list