diff options
| author | Pyun YongHyeon <yongari@FreeBSD.org> | 2010-03-24 17:29:32 +0000 |
|---|---|---|
| committer | Pyun YongHyeon <yongari@FreeBSD.org> | 2010-03-24 17:29:32 +0000 |
| commit | f305cd92af559a18988abb5a9fb4ccdeb7a5278b (patch) | |
| tree | 751fd19ba2d17d4264a87529d57910c13ffe9238 /sys/dev | |
| parent | 51e48a8ee4b9bc131841d5d7acedb7b661870f06 (diff) | |
Notes
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/bge/if_bge.c | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index 222de4decdfd..6748c1c61b58 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -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. */ |
