svn commit: r205616 - stable/7/sys/dev/bge

Pyun YongHyeon yongari at FreeBSD.org
Wed Mar 24 17:32:21 UTC 2010


Author: yongari
Date: Wed Mar 24 17:32:20 2010
New Revision: 205616
URL: http://svn.freebsd.org/changeset/base/205616

Log:
  MFC r204975,204978-204979,204981:
  r204975:
    Enable hardware fixes for BCM5704 B0 as recommended by data sheet.
  r204978:
    Set maximum read byte count to 2048 for PCI-X BCM5703/5704 devices.
    Also disable relaxed ordering as recommended by data sheet for
    PCI-X devices. For PCI-X BCM5704, set maximum outstanding split
    transactions to 0 as indicated by data sheet.
    For BCM5703 in PCI-X mode, DMA read watermark should be less than
    or equal to maximum read byte count configuration. Enforce this
    limitation in DMA read watermark configuration.
  r204979:
    Fix typo in r204975.
  r204981:
    Fix typo in r204978.

Modified:
  stable/7/sys/dev/bge/if_bge.c
Directory Properties:
  stable/7/sys/   (props changed)
  stable/7/sys/cddl/contrib/opensolaris/   (props changed)
  stable/7/sys/contrib/dev/acpica/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/dev/bge/if_bge.c
==============================================================================
--- stable/7/sys/dev/bge/if_bge.c	Wed Mar 24 17:29:32 2010	(r205615)
+++ stable/7/sys/dev/bge/if_bge.c	Wed Mar 24 17:32:20 2010	(r205616)
@@ -1342,6 +1342,7 @@ static int
 bge_chipinit(struct bge_softc *sc)
 {
 	uint32_t dma_rw_ctl;
+	uint16_t val;
 	int i;
 
 	/* Set endianness before we access any non-PCI registers. */
@@ -1362,6 +1363,17 @@ bge_chipinit(struct bge_softc *sc)
 	    i < BGE_STATUS_BLOCK_END + 1; i += sizeof(uint32_t))
 		BGE_MEMWIN_WRITE(sc, i, 0);
 
+	if (sc->bge_chiprev == BGE_CHIPREV_5704_BX) {
+		/*
+		 *  Fix data corruption caused by non-qword write with WB.
+		 *  Fix master abort in PCI mode.
+		 *  Fix PCI latency timer.
+		 */
+		val = pci_read_config(sc->bge_dev, BGE_PCI_MSI_DATA + 2, 2);
+		val |= (1 << 10) | (1 << 12) | (1 << 13);
+		pci_write_config(sc->bge_dev, BGE_PCI_MSI_DATA + 2, val, 2);
+	}
+
 	/*
 	 * Set up the PCI DMA control register.
 	 */
@@ -1378,6 +1390,15 @@ bge_chipinit(struct bge_softc *sc)
 			dma_rw_ctl |= (sc->bge_asicrev == BGE_ASICREV_BCM5780) ?
 			    BGE_PCIDMARWCTL_ONEDMA_ATONCE_GLOBAL :
 			    BGE_PCIDMARWCTL_ONEDMA_ATONCE_LOCAL;
+		} else if (sc->bge_asicrev == BGE_ASICREV_BCM5703) {
+			/*
+			 * In the BCM5703, the DMA read watermark should
+			 * be set to less than or equal to the maximum
+			 * memory read byte count of the PCI-X command
+			 * register.
+			 */
+			dma_rw_ctl |= BGE_PCIDMARWCTL_RD_WAT_SHIFT(4) |
+			    BGE_PCIDMARWCTL_WR_WAT_SHIFT(3);
 		} else if (sc->bge_asicrev == BGE_ASICREV_BCM5704) {
 			/* 1536 bytes for read, 384 bytes for write. */
 			dma_rw_ctl |= BGE_PCIDMARWCTL_RD_WAT_SHIFT(7) |
@@ -3158,7 +3179,26 @@ bge_reset(struct bge_softc *sc)
 	pci_write_config(dev, BGE_PCI_CACHESZ, cachesize, 4);
 	pci_write_config(dev, BGE_PCI_CMD, command, 4);
 	write_op(sc, BGE_MISC_CFG, BGE_32BITTIME_66MHZ);
-
+	/*
+	 * Disable PCI-X relaxed ordering to ensure status block update
+	 * comes first then packet buffer DMA. Otherwise driver may
+	 * read stale status block.
+	 */
+	if (sc->bge_flags & BGE_FLAG_PCIX) {
+		devctl = pci_read_config(dev,
+		    sc->bge_pcixcap + PCIXR_COMMAND, 2);
+		devctl &= ~PCIXM_COMMAND_ERO;
+		if (sc->bge_asicrev == BGE_ASICREV_BCM5703) {
+			devctl &= ~PCIXM_COMMAND_MAX_READ;
+			devctl |= PCIXM_COMMAND_MAX_READ_2048;
+		} else if (sc->bge_asicrev == BGE_ASICREV_BCM5704) {
+			devctl &= ~(PCIXM_COMMAND_MAX_SPLITS |
+			    PCIXM_COMMAND_MAX_READ);
+			devctl |= PCIXM_COMMAND_MAX_READ_2048;
+		}
+		pci_write_config(dev, sc->bge_pcixcap + PCIXR_COMMAND,
+		    devctl, 2);
+	}
 	/* Re-enable MSI, if neccesary, and enable the memory arbiter. */
 	if (BGE_IS_5714_FAMILY(sc)) {
 		/* This chip disables MSI on reset. */


More information about the svn-src-all mailing list